利用redis實現分布式鎖
阿新 • • 發佈:2018-12-05
Coding urn isp equals beans redis host ini ng-
一、背景
在分布式項目中,由於一個服務會有多個實例運行,有些特定的場景需要我們用到分布式鎖。
例如:最近我正在做的交易所項目,其中一個服務是錢包模塊,需要每半個小時就去歸集用戶的資金,這個定時任務只能有一個實例執行,要不然就會導致數據錯亂。
二、解決方案
針對這種場景,利用redis來實現並發控制是一個不錯的選擇。
1.添加jedis 的 maven依賴
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.7.2</version> <type>jar</type> <scope>compile</scope> </dependency>
2.添加bean文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans default-autowire="byName"> <bean id="redisService" class="com.w3liu.redis.RedisService" init-method="init"> <property name="host"> <value>127.0.0.1</value> </property> <property name="password"> <value>123456</value> </property> <property name="port"> <value>23671</value> </property> <property name="maxIdle"> <value>500</value> </property> <property name="maxTotal"> <value>4000</value> </property> </bean> </beans>
2.封裝核心方法
@Slf4j public class RedisService { public String host; public String port; public String password; private String maxIdle; private String maxTotal; private JedisPool pool; public void init() { int iMaxIdle = Integer.parseInt(maxIdle);int iMaxTotal = Integer.parseInt(maxTotal); JedisPoolConfig config = new JedisPoolConfig(); config.setMaxIdle(iMaxIdle); config.setMaxTotal(iMaxTotal); config.setTestOnBorrow(false); config.setTestOnReturn(false); pool = new JedisPool(config, host, Integer.parseInt(port), 3000, password); } /** * 原子設置一個具有自定義過期時間的值 * * @param key * @param value * @return */ public boolean setnx(String key, String value, int time) { boolean b = false; Jedis jedis = null; try { jedis = pool.getResource(); String re = jedis.set(key, value, "nx", "px", time); if (StringUtils.isNotBlank(re)) b = "OK".equals(re); } finally { if (jedis != null) { jedis.close(); } } return b; } }
3.調用
@Scheduled(cron = "0 0/30 * * * ?") public void doTask() { String lockKey = "LOCK_FLAG"; String uuid = UUID.randomUUID().toString(); if (redisService.setnx(lockKey, uuid, 10 * 60 * 1000)) { log.info("do some thing..."); } }
利用redis實現分布式鎖