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

Case Analysis of distributed Lock implemented by redis

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

Share

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

< end) { //在获取锁时间内 if (conn.setnx(lockKey, identifier) == 1) {//设置锁成功 conn.expire(lockKey, lockExpire); // 返回value值,用于释放锁时间确认 retIdentifier = identifier; return retIdentifier; } // ttl以秒为单位返回 key 的剩余过期时间,返回-1代表key没有设置超时时间,为key设置一个超时时间 if (conn.ttl(lockKey) == -1) { conn.expire(lockKey, lockExpire); } try { Thread.sleep(10); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } catch (JedisException e) { e.printStackTrace(); } finally { if (conn != null) { conn.close(); } } return retIdentifier; } /** * 释放锁 * @param lockName 锁的key * @param identifier 释放锁的标识 * @return */ public boolean releaseLock(String lockName, String identifier) { Jedis conn = null; String lockKey = "lock:" + lockName; boolean retFlag = false; try { conn = jedisPool.getResource(); while (true) { // 监视lock,准备开始redis事务 conn.watch(lockKey); // 通过前面返回的value值判断是不是该锁,若是该锁,则删除,释放锁 if (identifier.equals(conn.get(lockKey))) { Transaction transaction = conn.multi();//开启redis事务 transaction.del(lockKey); List results = transaction.exec();//提交redis事务 if (results == null) {//提交失败 continue;//继续循环 } retFlag = true;//提交成功 } conn.unwatch();//解除监控 break; } } catch (JedisException e) { e.printStackTrace(); } finally { if (conn != null) { conn.close(); } } return retFlag; }}3.2 分布式锁的业务代码 service业务逻辑层 public interface SkillService { Integer seckill(String goodsId,Long goodsStock);} service业务逻辑层实现层 import com.springlock.lock.DistributedLock;import com.springlock.mapper.GoodsMapper;import com.springlock.pojo.Goods;import com.springlock.service.SkillService;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.stereotype.Service;import javax.annotation.Resource;@Slf4j@Servicepublic class SkillServiceImpl implements SkillService { private final DistributedLock lock = new DistributedLock(); private final static String LOCK_NAME = "goods_stock_resource"; @Resource GoodsMapper goodsMapper; @Autowired private RedisTemplate redisTemplate; @Override public Integer seckill(String goodsId, Long goodsQuantity) { // 加锁,返回锁的value值,供释放锁时候进行判断 String identifier = lock.lockWithTimeout(LOCK_NAME, 5000, 1000); Integer goods_stock = (Integer) redisTemplate.boundHashOps("goods_info").get(goodsId); if (goods_stock >

0 & & goods_stock > = goodsQuantity) {/ / 1. Query the database object Goods goods = goodsMapper.findGoodsById (goodsId); / / 2. Update the inventory quantity in the database goods.setGoods_stock (goods.getGoods_stock ()-goodsQuantity); goodsMapper.updateGoodsStock (goods); / / 3. Synchronize redisTemplate.boundHashOps ("goods_info") .put (goods.getGoods_id (), goods.getGoods_stock ()) in Redis; log.info ("Commodity Id: {}, remaining inventory in Redis: {}", goodsId, goods.getGoods_stock ()); / / release lock lock.releaseLock (LOCK_NAME, identifier); return 1 } else {log.info ("Commodity Id: {}, insufficient inventory! , inventory: {}, purchase quantity: {} ", goodsId, goods_stock, goodsQuantity); / / release lock lock.releaseLock (LOCK_NAME, identifier); return-1;}

Controller layer

Import com.springlock.service.SkillService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Scope;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestController@Scope ("prototype") / / prototype multiple instances, singleton single instance public class SkillController {@ Autowired SkillService skillService; @ RequestMapping ("/ skill") public String skill () {Integer count = skillService.seckill ("1", 1L) Return count > 0? "order issued successfully" + count: "order issued failed" + count;}} 4, distributed lock test

Start the SpringBoot project on two servers with ports 8888 and 9999, respectively. After starting port 8888, modify the profile port to 9999 and start another application

Then use jmeter for concurrent testing, open two thread groups, place orders on behalf of two servers, 20 threads per second, 25 cycles, a total of 1000 orders.

View the console output:

Note: when the concurrency of the lock is too high, there will be a part of the failure rate. Programs written manually will have concurrency problems because of the non-atomic nature of the operation. The implementation of the lock is only to demonstrate the principle and is not suitable for production.

Jmeter aggregation report

After reading this, the article "instance Analysis of redis distributed Lock implementation" has been introduced. If you want to master the knowledge points of this article, you still need to practice and use it yourself. If you want to know more about related articles, welcome to follow the industry information channel.

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