[The PHP] prevent high concurrent repeat request based on the Distributed Lock redis

Requirements:
Let's give a verification system Liezi: (A channel systems, business systems B, C system outside vendors)
(1) B A channel business system call system, verify that the incoming cell phone, ID cards, whether the names of the three elements consistent.
(2) A channel system then calls an external vendor C system.
(3) A system of channel B returns the result to the business system.
This 3 process, (2) process, is the need to call an external vendor billing.
When the system is very high concurrency B business, with the same three elements checksum 100 pen, because it is the same three elements, A channel just call a vendor to know the results. In order to prevent the same time respond to a request has not ended, but also other requests to call an external system, this time on the need to lock handle

Characteristics of distributed lock
atom: the same time, only one thread to obtain a lock machine;
reentrancy: the same object (such as threads, classes) may be repeated recursively the lock without deadlock occurs;
blockable : before you did not get the lock, can only block waiting until the lock;
high availability: program failure occurs even if the machine is damaged, the lock can still get to be acquired, to be released;
high performance: acquiring, releasing the lock operating small consumption.

To achieve: lock, cut locks, lock timeout
implementation can be: mc redis database system files zookeeper

I am now the channel system, when the same service request 100 to pass over, my first request first lock, then request an external vendor systems, so after the results of the response, insert another key, and then remove the lock.
Other requests to go to get the lock, if you have latched on to find waiting wheel, if the lock is gone, go directly to query results.
If the first request fails, the results did not insert in place, continue to acquire locks and go look outside the system.

Acquire a lock:
$ redis-> the SET ( 'Lock: ID card & phone number & name', 1, [ 'nx' , 'ex' => 10]);
release the lock:
is to directly delete the key
lock timeout:
Lock of there are key timeout

The new version of redis set command can be achieved distributed lock can be achieved only if at the same time there is no time to set and two timeouts.

<? PHP
 $ Redis = new new the Redis ();
 $ Redis -> Connect ( "127.0.0.1", 6379 );
 // high concurrent prevent the repeat request 

key // channel system transmission over 
$ lockKey = 'Lock: 18,806,767,777 & 37781991111629092 & taoshihan' ;
 $ resultKey = 'RES: 18,806,767,777 & 37781991111629092 & taoshihan' ; 

// if already queried value, can be returned directly 
$ info = $ Redis -> GET ( $ resultKey );
 IF ( $ info ) {
     Exit ( $ info ); 
} 

// if there is no value to acquire locks 
$ lock = $ Redis -> the SET (lockKey $ ,. 1, [ 'NX', 'EX' => 10 ]);
 IF ( $ Lock ) {
     // requests the external system to obtain a result, such a response result slower 
    SLEEP (. 8 );
     $ info = '{ "name ":" taoshihan "} ' ;
     $ RET = $ Redis -> SET ( $ resultKey , $ info );
     IF ( $ RET ) {
         // remove lock 
        $ Redis -> del ( $ lockKey );
         Exit ( $ info ); 
    } 
} 
echo "Please try again later!";

 

Guess you like

Origin www.cnblogs.com/taoshihan/p/11711098.html