1. 程式人生 > >利用redis實現分布式鎖

利用redis實現分布式鎖

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實現分布式鎖