当前位置:网站首页>The king scheme in distributed locks - redisson

The king scheme in distributed locks - redisson

2022-06-25 07:10:00 Wukong chat architecture

The first part explains how to use Redis There are five ways to implement distributed lock , But we still have a better King's plan , Just use Redisson.

Cache series :

Cache practice ( One ):20 chart |6 Thousand characters | Cache practice ( Part 1 )

Cache practice ( Two ):Redis Distributed lock | Five evolution schemes from bronze to diamond

So let's see Redis What does the official website say ,

and Java Version of The framework of distributed locking is Redisson. This article will be based on my open source project PassJava To integrate Redisson.

I put Back end front end Applet All uploaded to the same warehouse , You can go through Github or Code cloud visit . The address is as follows :

Github: https://github.com/Jackson0714/PassJava-Platform

Code cloud :https://gitee.com/jayh2018/PassJava-Platform

Tutorial :www.passjava.cn

Before the actual battle , Let's first look at the use of Redisson Principle .

One 、Redisson What is it? ?

If you were using it before Redis Words , That use Redisson It'll get twice the result with half the effort ,Redisson Provides the use of Redis The simplest and most convenient way .

Redisson The aim is to promote the user's understanding of Redis Separation of concerns (Separation of Concern), This allows users to focus more on processing business logic .

Redisson It's a Redis On the basis of implementation Java In memory data grid (In-Memory Data Grid).

Two 、 Integrate Redisson

Spring Boot Integrate Redisson There are two options :

  • Program configuration .

  • File mode configuration .

This article describes how to integrate... In a procedural way Redisson.

2.1 introduce Maven rely on

stay passjava-question Micro service pom.xml introduce redisson Of maven rely on .

<!-- https://mvnrepository.com/artifact/org.redisson/redisson --><dependency>    <groupId>org.redisson</groupId>    <artifactId>redisson</artifactId>    <version>3.15.5</version></dependency>

2.2 Custom configuration class

The following code is single node Redis Configuration of .

@Configurationpublic class MyRedissonConfig {    /**     *  Yes  Redisson  It's all used through  RedissonClient  object      * @return     * @throws IOException     */    @Bean(destroyMethod="shutdown"//  After the service is stopped, it is called  shutdown  Method .    public RedissonClient redisson() throws IOException {        // 1. Create a configuration         Config config = new Config();        //  Cluster pattern         // config.useClusterServers().addNodeAddress("127.0.0.1:7004", "127.0.0.1:7001");        // 2. according to  Config  Create  RedissonClient  Example .        config.useSingleServer().setAddress("redis://127.0.0.1:6379");        return Redisson.create(config);    }}

2.3 Test configuration class

Create a new unit test method .

@AutowiredRedissonClient redissonClient;@Testpublic void TestRedisson() {    System.out.println(redissonClient);}

We run this test method , Print out redissonClient

[email protected]77f66138

3、 ... and 、 Distributed reentrant locking

3.1 Re entry lock test

be based on Redis Of Redisson Distributed reentrant locking RLockJava Object implementation java.util.concurrent.locks.Lock Interface . It also provides asynchronous (Async) Reflex (Reactive) and RxJava2 standard The interface of .

RLock lock = redisson.getLock("anyLock");//  The most common use method lock.lock();

We use it passjava This open source project tests two points of reentrant locks :

  • (1) Multiple threads preempt locks , Does the back lock need to wait ?

  • (2) If the service of the thread seizing the lock stops , Will the lock be released ?

3.1.1 Verification one : Is the reentrant lock blocked ?

To verify the above two points , I wrote a demo Program : The flow of the code is to set up WuKong-lock lock , Then lock it , Print thread ID, wait for 10 Release the lock in seconds , Finally, the response is returned :“test lock ok”.

@ResponseBody@GetMapping("test-lock")public String TestLock() {    // 1. Get the lock , As long as the name of the lock is the same , The acquired lock is the same lock .    RLock lock = redisson.getLock("WuKong-lock");    // 2. Lock     lock.lock();    try {        System.out.println(" Locking success , Execute subsequent code . Threads  ID:" + Thread.currentThread().getId());        Thread.sleep(10000);    } catch (Exception e) {        //TODO    } finally {        lock.unlock();        // 3. Unlock         System.out.println("Finally, Lock release successful . Threads  ID:" + Thread.currentThread().getId());    }    return "test lock ok";}

Verify the first point first , With two http Request to test the preemptive lock .

Requested URL:

http://localhost:11000/question/v1/redisson/test/test-lock

The thread corresponding to the first thread ID by 86,10 Seconds later , Release the lock . in the meantime , The second thread needs to wait for the lock to be released .

After the first thread releases the lock , The second thread gets the lock ,10 Seconds later , Release the lock .

Draw a flow chart , Help you understand . As shown in the figure below :

  • First step : Threads A stay 0 seconds , Grab the lock ,0.1 Seconds later , Start executing wait 10 s.

  • The second step : Threads B stay 0.1 Second attempt to preempt lock , Failed to get lock ( By A Take over ).

  • The third step : Threads A stay 10.1 Seconds later , Release the lock .

  • Step four : Threads B stay 10.1 The lock is seized in seconds , And then wait 10 Release the lock in seconds .

So we can draw a conclusion ,Redisson Re entrant lock for (lock) It blocks other threads , Need to wait for other threads to release .

3.1.2 Verification II : The service stopped , Will the lock be released ?

If the thread A In the process of waiting , The service suddenly stopped , So will the lock be released ? If not released , It becomes a deadlock , Blocking other threads to acquire locks .

Let's look at threads first A After getting the lock ,Redis The result of the client query , As shown in the figure below :

WuKong-lock Valuable , And you can see TTL It's getting smaller and smaller , explain WuKong-lock It comes with an expiration date .

Through observation , after 30 Seconds later ,WuKong-lock It's gone . explain Redisson After shutdown , The occupied lock will be released automatically .

So what's the principle ? Here is a concept , watchdog .

3.2 The watchdog principle

If it's responsible for storing this distributed lock Redisson After the node goes down , And when the lock is in the locked state , This lock will be locked . To avoid this happening ,Redisson There is a monitoring lock inside watchdog , Its function is to Redisson Before the instance is closed , Keep extending the validity of lock .

By default , The timeout for the watchdog to check the lock is 30 Second , You can also modify Config.lockWatchdogTimeout To specify otherwise .

If we don't make it lock Timeout for , Just use 30 Seconds as the default time for the watchdog . As long as the lock is successful , Will start a Timing task : every other 10 Seconds to reset the expiration time of the lock , The expiration date is 30 second .

As shown in the figure below :

When the server goes down , Because the lock is valid for 30 second , So in the 30 Automatically unlock in seconds .(30 Seconds is equal to the lock occupancy time before the outage + Time taken by subsequent locks ).

As shown in the figure below :

3.3 Set lock expiration time

We can also set the expiration time for the lock , Let it unlock automatically .

As shown below , Set lock 8 Automatically expired in seconds .

lock.lock(8, TimeUnit.SECONDS);

If the business execution time exceeds 8 second , Releasing the lock manually will report an error , As shown in the figure below :

image-20210521102640573

image-20210521102640573

So if we set the automatic expiration time of the lock , Then the execution time of the business must be less than the automatic expiration time of the lock , Otherwise you will report an error .

Four 、 The king plan

In the last article, I explained five solutions to distributed locking :《 The evolution from bronze to diamond 》, This article is mainly about how to use Redisson stay Spring Boot Project implementation of distributed lock scheme .

because Redisson Very powerful , The implementation of distributed lock is very simple , So called The king plan .

Schematic diagram is as follows :

The code is as follows :

// 1. Set distributed locks RLock lock = redisson.getLock("lock");// 2. Occupancy lock lock.lock();// 3. Executive business ...// 4. Release the lock lock.unlock();

And before Redis Compared with , Concise and many .

5、 ... and 、 Distributed read and write locks

be based on Redis Of Redisson Distributed reentrant read-write locks RReadWriteLock Java Object implementation java.util.concurrent.locks.ReadWriteLock Interface . Read lock and write lock are inherited RLock Interface .

Write lock is a pat lock ( The mutex ), Read lock is a shared lock .

  • Read the lock + Read the lock : It's not locked , Can read concurrently .

  • Read the lock + Write lock : The write lock needs to wait for the read lock to release the lock .

  • Write lock + Write lock : Mutually exclusive , Need to wait for the other party's lock to release .

  • Write lock + Read the lock : The read lock needs to wait for the write lock to release .

The sample code is as follows :

RReadWriteLock rwlock = redisson.getReadWriteLock("anyRWLock");//  The most common use method rwlock.readLock().lock();//  or rwlock.writeLock().lock();

in addition Redisson It is also provided by means of locking leaseTime To specify the lock time . After this time, the lock is automatically unlocked .

// 10 Automatically unlock after seconds //  Don't need to call unlock Method to manually unlock rwlock.readLock().lock(10, TimeUnit.SECONDS);//  or rwlock.writeLock().lock(10, TimeUnit.SECONDS);//  Try to lock , Waiting for the most 100 second , After the lock 10 Seconds auto unlock boolean res = rwlock.readLock().tryLock(10010, TimeUnit.SECONDS);//  or boolean res = rwlock.writeLock().tryLock(10010, TimeUnit.SECONDS);...lock.unlock();

6、 ... and 、 Distributed semaphores

be based on Redis Of Redisson Of distributed semaphores (Semaphore)Java object RSemaphore Adopted with java.util.concurrent.Semaphore Similar interface and usage . It also provides asynchronous (Async) Reflex (Reactive) and RxJava2 standard The interface of .

About the use of semaphores, you can imagine this scene , There are three parking spaces , When three parking spaces are full , The other cars don't stop . You can compare parking spaces to signals , Now there are three signals , Stop once , Using a signal , When the car leaves, it releases a signal .

We use it Redisson To demonstrate the above parking space scene .

First, define a way to occupy a parking space :

/***  Parking , Take up parking space *  in total  3  A parking space */@ResponseBody@RequestMapping("park")public String park() throws InterruptedException {  //  Acquisition semaphore ( The parking lot )  RSemaphore park = redisson.getSemaphore("park");  //  Get a signal ( Parking space )  park.acquire();  return "OK";}

Another way to get out of a parking space :

/** *  Release the parking space  *  in total  3  A parking space  */@ResponseBody@RequestMapping("leave")public String leave() throws InterruptedException {    //  Acquisition semaphore ( The parking lot )    RSemaphore park = redisson.getSemaphore("park");    //  Release a signal ( Parking space )    park.release();    return "OK";}

For simplicity , I use Redis The client added a key:“park”, The value is equal to 3, The representative semaphore is park, There are three values .

And then use postman send out park Request a parking space .

And then in redis Client view park Value , It was found that it had been changed to 2 了 . Continue to call twice , Find out park Is equal to 0, When called the fourth time , You will find that the request is always in Waiting for the , It means there are not enough parking spaces . If you want to be unobstructed , It can be used tryAcquire or tryAcquireAsync.

Let's call the method of leaving the parking space again ,park The value of becomes 1, Represents the remaining parking space 1 individual .

Be careful : Release semaphore operation multiple times , The remaining semaphore will continue to increase , Not to 3 Then it was capped .

Other distributed locks :

  • Fair lock (Fair Lock)

  • interlocking (MultiLock)

  • Red lock (RedLock)

  • Read-write lock (ReadWriteLock)

  • Expiring semaphore (PermitExpirableSemaphore)

  • atresia (CountDownLatch)

There are other distributed locks that will not be expanded in this article , Interested students can view the official documents .

Reference material :

https://github.com/redisson/redisson

 Insert picture description here  Insert picture description here

原网站

版权声明
本文为[Wukong chat architecture]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/176/202206250508484452.html