zoukankan      html  css  js  c++  java
  • 利用redis实现分布式锁

    一、背景

      在分布式项目中,由于一个服务会有多个实例运行,有些特定的场景需要我们用到分布式锁。

      例如:最近我正在做的交易所项目,其中一个服务是钱包模块,需要每半个小时就去归集用户的资金,这个定时任务只能有一个实例执行,要不然就会导致数据错乱。

    二、解决方案

      针对这种场景,利用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...");
            }
        }

      

  • 相关阅读:
    环境变量设置set env exportFedora Centos日志我的搜狐
    Hadoop Streaming 编程
    业务开发测试HBase之旅三:通过Java Api与HBase交互
    hadoop+zookeeper+hbase安装_dekar_x的空间_百度空间
    HBase Java客户端编程
    Hadoop应用测试
    HBase vs Cassandra: 我们迁移系统的原因
    关于HBase的一些零碎事
    奔流 | 自由、奔放的技术刊物
    Paxos在大型系统中常见的应用场景
  • 原文地址:https://www.cnblogs.com/w3liu/p/10068362.html
Copyright © 2011-2022 走看看