Use redission implement distributed semaphores and some pit encountered

Use redission implement distributed semaphores and some pit encountered

1, connected RedissonClient

Config config = Config.fromJSON(redisCfgFile);
 RedissonClient redissonClient = Redisson.create(config);

Creating RedissionClient, created using the json form.

redis is as follows:

{
    "singleServerConfig":{
        "idleConnectionTimeout":10000,
        "pingTimeout":1000,
        "connectTimeout":10000,
        "timeout":6000,
        "retryAttempts":3,
        "retryInterval":1500,
        "reconnectionTimeout":3000,
        "failedAttempts":3,
        "password":"xxxxx",
        "subscriptionsPerConnection":5,
        "clientName":null,
        "address":"redis://xxxx:000",
        "subscriptionConnectionMinimumIdleSize":1,
        "subscriptionConnectionPoolSize":50,
        "connectionMinimumIdleSize":32,
        "connectionPoolSize":64,
        "database":0
    },
    "threads":0,
    "nettyThreads":0,
    "codec":{
        "class":"org.redisson.codec.JsonJacksonCodec"
    },
    "transportMode":"NIO"
}

 

Configuration Description: https://yq.aliyun.com/articles/551640?spm=a2c4e.11153940.0.0.3cc221bavS8pf3 (Reference)

Encountered pit:

1, disconnect

redis use 5.0, redission use 3.10.7, often appear disconnected from the client and server problems

 

Tracing problem, the online version redis decreased, from 5.0 to> 4.0, disconnection does not occur. But redission not supported to disconnect and reconnect, use scheduled tasks to the timing of ping server, disconnect the manual reconnection.

2, the main switch can not be automatically reconnect

public static void init() {
        SCHEDULED_EXECUTOR_SERVICE.scheduleWithFixedDelay(() -> {
            if (RUNNING) {
                try {
                    NodesGroup nodesGroup = redissonClient.getNodesGroup();
                    Collection<Node> allNodes = nodesGroup.getNodes();
                    for (Node n : allNodes) {
                        boolean ping = n.ping();
                        if (!ping) {
                            //ping不通reload client
                            reload (); 
                        } 
                    } 
                } the catch (Exception E) {
                     // throws an exception Client reload 
                    reload (); 
                } 
            } 
        }, 0,. 5 , TimeUnit.SECONDS); 
    }

 

 

3, the line often timed out

 

 

 

Modify the configuration file timeout 3000 -> 6000, because there is a regular task 5s in ping server, so set slightly larger, it will not appear.

2, a distributed semaphore implemented using redission

Redisson carrying a RPermitExpirableSemaphore (distributed semaphore has an expiration date)

The official explanation:

 

 

 Providing an amount of the release time parameter signals for each of the application objects, each license may be their own id to identify, and can be released their id. The license id 128b is a random number. At the same time this distributed semaphore In non-equity model, so is not possible to predict the order of application.

Specific achieve the following:

Apply for a permit

/ ** 
     * @param semaphoreName semaphore IDs 
     * @param identify the person who acquired acquireId 
     * @param total limit 
     * @return int 0- success, others - failed 
     * @Description: specify the name and the total acquisition semaphore 
     * / 
    public  static  int acquireSemaphore (semaphoreName String, String acquireId, Long limit) {
         the try { 
            RedissonClient Client = RedisUtils.getRedissonClient (); 
            RPermitExpirableSemaphore semaphore = client.getPermitExpirableSemaphore (semaphoreName);
            semaphore.trySetPermits (( int ) limit);
            // Each application time semaphores, expire life SEMAPHORE_LIFE_EXPIRE second semaphore 
            semaphore.expire (SEMAPHORE_LIFE_EXPIRE, TimeUnit.SECONDS);
             // number of attempts the init 
            int Time = 0 ;
             the while (MAX_TRY_ACQUIRE_TIME> Time) {
                 // attempts to acquire a semaphore 
                String = permitId semaphore.tryAcquire (getSemaphoreLifeExpire (), getSemaphoreAcquireExpire (), TimeUnit.MILLISECONDS);
                 // Get semaphore failed 
                IF ( null == permitId) { 
                    Time ++;
                     Continue ; 
                }
                // get the semaphore success, mapping between acquireId and permitId of 
                IF (! RedisUtils.hset (getMapName (semaphoreName), acquireId, permitId, getSemaphoreAcquireExpire (), TimeUnit.MILLISECONDS)) {
                     // if it fails to release resources 
                    semaphore.release (permitId);
                     return acquireError (); 
                } 
                return 0 ; 
            } 
        } the catch (Exception E) { 
            e.printStackTrace (); 
            log.error ( "Exception for semaphoreName = {}, {} = acquireId, MSG = {}" , semaphoreName, acquireId, e.getMessage ()); 
        } 
        return acquireError();
    }

 

The application of the license id and acquireId into hash structure, make a map, because of the need to release this license id resources.

Release Semaphore

/ ** 
     * @param semaphoreName semaphore IDs 
     * @param acquireId obtain identity's 
     * @Description: release signal corresponding to the amount 
     * @return : int 0 Success 1 Failure (time-out errors might not be successful release) 
     * @author: chi.zhang 
     * @date: 2020/02/19 
     * / 
    public  static  int ReleaseSemaphore (semaphoreName String, String acquireId) {
         the try { 
            RedissonClient Client = RedisUtils.getRedissonClient (); 
            RPermitExpirableSemaphore semaphore = client.getPermitExpirableSemaphore (semaphoreName);
             // The mapping relationships to find permitId
            PermitId = String RedisUtils.hgetStr (getMapName (semaphoreName), acquireId);
             IF (StringUtils.isNotEmpty (permitId)) {
                 // may be released, so use tryRelease 
                IF (semaphore.tryRelease (permitId)) { 
                    RedisUtils.hdel (getMapName ( semaphoreName), acquireId); 
                } 
            } the else { 
                log.error ( "distributed release semaphore failed, semaphoreName: {}, {} permitId" , semaphoreName, permitId);
                 return releaseError (); 
            } 
        } the catch (Exception E) {  
            e.printStackTrace ();
            lOG.error ("exception for semaphoreName={}, acquireId={}, msg={}", semaphoreName, acquireId, e.getMessage());
            return releaseError();
        }
        return 0;
    }

Guess you like

Origin www.cnblogs.com/zhangchiblog/p/12565913.html