Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use springboot to integrate redission and distributed locks

2025-01-30 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article focuses on "how to use springboot to integrate redission and distributed locks", interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Let's let the editor learn how to use springboot to integrate redission and distributed locks.

Catalogue

Springboot Integrated redission and the use of distributed Lock

1. Introduce jar package

2. Add Configuration class

3. Use redission distributed lock

Springboot integrated Redisson lock

I. dependence

II. Configuration file

Third, the use of locks

4. Distributed second kill

Stand-alone version of redis lock is available and Redisson is used for distribution.

Use of springboot integrated redission and distributed locks 1. Introduce jar package org.redisson redisson 3.13.42, add configuration class @ Configurationpublic class RedissonConfig {@ Value ("${spring.redis.host}") private String host; @ Value ("${spring.redis.port}") private String port; @ Value ("${spring.redis.password}") private String password @ Bean public RedissonClient getRedisson () {Config config = new Config (); config.useSingleServer () .setAddress ("redis://" + host + ":" + port) .setPassword (password); return Redisson.create (config);}} 3. Use redission distributed lock @ Autowiredprivate RedissonClient redissonClient; / / method area String key = "aa:bb:cc:01"; RLock rLock = redissonClient.getLock (key); try {

/ / attempt to lock, wait up to 1 second, and unlock automatically 10 seconds after locking

/ / without Watch Dog, automatically release boolean res = rLock.tryLock (1Jing 10, TimeUnit.SECONDS) after 10 seconds; if (! res) {return new GeneralVO (400, "do not repeat submission", false);} finally {rLock.unlock ();} private void redissonDoc () throws InterruptedException {/ / 1. Ordinary reentrant lock RLock lock = redissonClient.getLock ("generalLock"); / / it will keep retrying when it fails to get the lock / / it has Watch Dog automatic extension mechanism to continue 30s to 30s lock.lock () by default; / / try to hold the lock for 10s and stop the retry, return to false / / with Watch Dog automatic extension mechanism default to continue 30s boolean res1 = lock.tryLock (10, TimeUnit.SECONDS) / / keep retrying when you fail to get the lock / / without Watch Dog, automatically release lock.lock (10, TimeUnit.SECONDS) after 10s; / / stop the retry after 100s, return false / without Watch Dog, and automatically release boolean res2 = lock.tryLock (100,10, TimeUnit.SECONDS) after 10s; / / 2. Fair locks guarantee that Redisson client threads will acquire locks RLock fairLock = redissonClient.getFairLock ("fairLock") in the order in which they are requested; / / 3. Read-write locks have the same effect as ReentrantLock read-write locks in JDK RReadWriteLock readWriteLock = redissonClient.getReadWriteLock ("readWriteLock"); readWriteLock.readLock (). Lock (); readWriteLock.writeLock (). Lock ();} Springboot integrated Redisson lock

Redisson is a Java resident memory data grid implemented on the basis of Redis

First, rely on org.redisson redisson 3.15.4 II. Configuration file spring: redis: database: 7 host: 116.62.178.11 port: 6379 password: 1234qwer # spring-boot 1.0 default jedis Spring-boot2.0 default lettuce, lettuce thread safe lettuce: pool: # maximum idle connections in connection pool default 8 max-idle: 8 # minimum idle connections in connection pool default 0 min-idle: 500 # maximum number of connections in connection pool default 8 Negative numbers indicate no limit to max-active: 2000 # maximum blocking wait time for connection pools (using negative values means no limit) default-1 max-wait:-1 cache: type: redis@Configurationpublic class RedissonConfig {@ Value ("${spring.redis.host}") private String host @ Value ("${spring.redis.port}") private int port; @ Value ("${spring.redis.password}") private String password; @ Bean (destroyMethod = "shutdown") RedissonClient redissonClient () throws IOException {Config config = new Config (); config.useSingleServer () .setPassword (password) .setAddress ("redis://" + host + ":" + port) .setDatabase (7) Return Redisson.create (config);}} III. The use of locks

Read-write lock

Public class RedissionDemo {@ Autowired private RedissonClient redissonClient; @ Autowired private RedisTemplate redisTemplate / * read lock summary * * read lock is also called shared lock * write lock is also called exclusive lock (mutex) * read + read is equivalent to no lock and read is read, and lock successfully * write + write blocking state * write + wait for write lock release * read + write wait for read lock to finish before writing * / public String writeValue () {String str = "" RReadWriteLock readWriteLock = redissonClient.getReadWriteLock ("writeLock"); RLock rLock = readWriteLock.writeLock (); try {rLock.lock (); str = UUID.randomUUID (). ToString (); redisTemplate.opsForValue (). Set ("uuid", str); Thread.sleep (30000);} catch (Exception e) {} finally {rLock.unlock () } return str;} / * read lock * * @ return * / public String readValue () {String str = ""; RReadWriteLock readWriteLock = redissonClient.getReadWriteLock ("writeLock"); RLock rLock = readWriteLock.readLock (); rLock.lock (); str = (String) redisTemplate.opsForValue (). Get ("uuid"); rLock.unlock () Return str;}}

Semaphore

Public class RedissionDemo {@ Autowired private RedissonClient redissonClient; @ Autowired private RedisTemplate redisTemplate; / * * semaphore * * @ return * / / parking method @ GetMapping ("/ park") public String park () throws InterruptedException {/ / here is the value of the semaphore. The name of this semaphore must be the same as the RSemaphore park = redissonClient.getSemaphore ("park") that you initialized. / / the value in the semaphore is-1. If it is 0, wait until the semaphore is > 0 park.acquire (); / / tryAcquire is non-blocking waiting / / park.tryAcquire (); return "ok" } public String go () throws InterruptedException {/ / here is the value of the semaphore. The name of this semaphore must be the same as the one you initialized, RSemaphore park = redissonClient.getSemaphore ("park"); / / the value in the semaphore will be + 1, that is, the semaphore park.release (); return "ok";}}

Lock up

Public class RedissionDemo {@ Autowired private RedissonClient redissonClient; @ Autowired private RedisTemplate redisTemplate; / * lock, current limit * * @ return * @ throws InterruptedException * / / lock the door public String lockdoor () throws InterruptedException {RCountDownLatch door = redissonClient.getCountDownLatch ("door"); / / set a class with 20 students door.trySetCount (20) / wait for all 20 students to leave before locking the door door.await (); return "locked the door";} public String leave (Long id) throws InterruptedException {RCountDownLatch door = redissonClient.getCountDownLatch ("door"); / / indicates that a classmate left door.countDown (); return "+ id +" left ";}} 4. Distributed seconds kill.

Second kill process:

@ Service@Slf4jpublic class DistributedSecKillBiz {@ Autowired private RedisTemplate redisTemplate; @ Autowired private RedissonClient redissonClient; / * distributed locks. The only drawback: yoke failure time * yoke yard operation, * unlock, removal lock is also a flaw in atomic operation * * @ return * / public String doKill () {String lock = UUID.randomUUID (). ToString (); String goodsId = "10054"; boolean flag = redisTemplate.opsForValue (). SetIfAbsent (goodsId, lock, 30, TimeUnit.SECONDS) If (flag) {/ / acquired lock successfully try {Long stock = redisTemplate.opsForValue (). Decrement (upActivityKey () + SecKillConstant.CACHE_FOODS_COUNT + goodsId); if (stock > 0) {redisTemplate.opsForValue () .increment (upActivityKey () + SecKillConstant.CACHE_FOODS_COUNT + goodsId) Log.info ("inventory deduction succeeded, remaining:" + stock);} return "insufficient inventory, the item has been snapped up!" ;} catch (Exception e) {} finally {String script = "if redis.call ('get',KEYS [1]) = ARGV [1] then return redis.call (' del',KEYS [1]) else return 0 end"; redisTemplate.execute (new DefaultRedisScript (script, Long.class), Arrays.asList (goodsId), lock);}} return doKill () } / * integrate redission * @ return * / public String doKillDistributed () {String goodsId = "10054"; RLock lock = redissonClient.getLock (upActivityKey () + SecKillConstant.LOCK + goodsId) / / acquire lock successfully try {/ / 1 blocking wait. Default time is 30 seconds / / 2 automatic renewal. If the business is too long and you don't have to worry about the expiration time, if the lock is automatically deleted / / 3 shackles are completed, the current lock will not be renewed automatically, even if the lock is not released manually. 30 seconds automatic release / / lock.lock (30, TimeUnit.SECONDS) / / attention should be paid to lock.lock (); Long stock = redisTemplate.opsForValue (). Decrement (upActivityKey () + SecKillConstant.CACHE_FOODS_COUNT + goodsId); if (stock > 0) {redisTemplate.opsForValue (). Increment (upActivityKey () + SecKillConstant.CACHE_FOODS_COUNT + goodsId); log.info ("inventory reduction succeeded," + stock) } return "insufficient inventory, the item has been snapped up!" ;} catch (Exception e) {} finally {lock.unlock ();} return "fail";} / * get activity * * @ return * / public ActivityBo upActivity () {return new ActivityBo ("Qixi Festival activity", "SEVEN_ACTIVITY", new Date (), new Date ()) } / * active public key * * @ return * / public String upActivityKey () {return SecKillConstant.SEC_KILL + upActivity () .getActivityKey () + ":";} V. Redis lock standalone version is available, distributed Redissonpackage com.yang.yimall.seckill.app.seckill.biz;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.RedisTemplate Import org.springframework.data.redis.core.script.DefaultRedisScript;import org.springframework.stereotype.Service;import java.util.Collections;import java.util.UUID;import java.util.concurrent.TimeUnit;/** * redis lock cluster cannot be renewed with defects * / @ Servicepublic class RedisLock {@ Autowired private RedisTemplate redisTemplate; private String lockName = "lockName"; private ThreadLocal threadLocal = new ThreadLocal () Public void lock (String lockName) {if (tryLock (lockName)) {return;} lock (lockName);} public void lock () {if (tryLock (lockName)) {return;} lock () } / * add key and set expiration time atomic operation * * @ param lockName * @ return * / public boolean tryLock (String lockName) {String uuid = UUID.randomUUID () .toString (); threadLocal.set (uuid); return redisTemplate.opsForValue () .setIfAbsent (lockName, uuid, 30, TimeUnit.SECONDS) Delete if the query has key, atomic operation * / public void unlock () {String script = "if redis.call ('get',KEYS [1]) = ARGV [1] then return redis.call (' del',KEYS [1]) else return 0 end"; redisTemplate.execute (new DefaultRedisScript (script, Long.class), Collections.singletonList (lockName), threadLocal.get ();}}

Use

Public String doKillUp () {String goodsId = "10054"; redisLock.lock (goodsId); / / successful acquisition of lock try {Long stock = redisTemplate.opsForValue (). Decrement (upActivityKey () + SecKillConstant.CACHE_FOODS_COUNT + goodsId); if (stock > 0) {redisTemplate.opsForValue (). Increment (upActivityKey () + SecKillConstant.CACHE_FOODS_COUNT + goodsId) Log.info ("inventory deduction succeeded, remaining:" + stock);} return "insufficient inventory, the item has been snapped up!" ;} catch (Exception e) {} finally {redisLock.unlock ();} return "insufficient inventory, the item has been snapped up!" ;}

At this point, I believe you have a deeper understanding of "how to use springboot to integrate redission and distributed locks". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report