其他分享
首页 > 其他分享> > docker 安装 红锁 实现分布式锁方式

docker 安装 红锁 实现分布式锁方式

作者:互联网

1 docker pull redis
拉取镜像 redis 
2 创建redis 映射配置文件(也就是挂在目录)
mkdir -p /mydata/redis/conf
3 下载redis.conf 文件
wget http://download.redis.io/redis-stable/redis.conf
4 修改conf 文件内容

bind 127.0.0.1 # 这行要注释掉,解除本地连接限制
protected-mode no # 默认yes,如果设置为yes,则只允许在本机的回环连接,其他机器无法连接。
daemonize no # 默认no 为不守护进程模式,docker部署不需要改为yes,docker run -d本身就是后台启动,不然会冲突
requirepass 123456 # 设置密码(可以不设置)
appendonly yes # 持久化

5 复制conf 文件 重新命名 为redis6380.conf,redis6381.conf,redis6382.conf
除了 port 不同 其他均相同
docker run -p 6380:6380 --name order01 -v /mydata/redis/conf/redis6380.conf:/etc/redis/redis6380.conf  -v /mydata/redis/data:/data -d redis redis-server /etc/redis/redis6380.conf --appendonly yes
docker run -p 6381:6381 --name order02 -v /mydata/redis/conf/redis6381.conf:/etc/redis/redis6381.conf  -v /mydata/redis/data:/data -d redis redis-server /etc/redis/redis6381.conf --appendonly yes
docker run -p 6382:6382 --name order03 -v /mydata/redis/conf/redis6382.conf:/etc/redis/redis6382.conf  -v /mydata/redis/data:/data -d redis redis-server /etc/redis/redis6382.conf --appendonly yes

 

 我们创建了三个不同的redis 实例

然后我们需要配置红锁  我们需要导入一下两个依赖

     <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson</artifactId>
            <version>3.3.2</version>
        </dependency>
我们需要实现的功能如下:
  多个司机 同时抢一个订单,在多个订单服务中,只有一个司机能抢到,
因此我们需要依赖分布式锁来实现   具体就是redisson的红锁
DROP TABLE IF EXISTS `tbl_order`;
CREATE TABLE `tbl_order` (
  `order_id` int(8) NOT NULL,
  `order_status` int(8) DEFAULT NULL,
  PRIMARY KEY (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of tbl_order
-- ----------------------------
INSERT INTO `tbl_order` VALUES ('1', '1');
DROP TABLE IF EXISTS `tbl_order_lock`;
CREATE TABLE `tbl_order_lock` (
  `order_id` int(8) NOT NULL,
  `driver_id` int(8) DEFAULT NULL,
  PRIMARY KEY (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

 当多个司机抢一个订单,抢到订单的司机会 将order_status 改为1 并输出抢订单成功  其他没有抢到订单的司机 则输出抢订单失败

     @Component
     public class RedisConfig {
    /*红锁  */
    @Bean(name = "redissonClient01")
    public RedissonClient redissonClient01(){
        Config config = new Config();
        config.useSingleServer().setAddress("192.168.0.137:6380").setDatabase(0);
        RedissonClient redissonClient1 = Redisson.create(config);
        return redissonClient1;
    }
    @Bean(name = "redissonClient02")
    public RedissonClient redissonClient02(){
        Config config = new Config();
        config.useSingleServer().setAddress("192.168.0.137:6381").setDatabase(0);
        RedissonClient redissonClient2 = Redisson.create(config);
        return redissonClient2;
    }
    @Bean(name = "redissonClient03")
    public RedissonClient redissonClient03(){
        Config config = new Config();
        config.useSingleServer().setAddress("192.168.0.137:6382").setDatabase(0);
        RedissonClient redissonClient3 = Redisson.create(config);
        return redissonClient3;
    }
}
@RestController
@RequestMapping("/grab")
public class GrabOrderController {
    @Autowired
    GrabService grabService;
    @GetMapping("/do/{orderId}")
    public String grab(@PathVariable("orderId")int orderId,int driverId){
        System.out.println("orderId:"+orderId+",driverId:"+driverId);
        grabService.grab(orderId,driverId);
        return "";
    }
}
@Service
public class GrabServiceImpl implements GrabService {
    @Autowired
    private RedisConfig redisConfig;
    @Autowired
    TblOrderService tblOrderService;

    /*红锁实现分布式锁*/
    @Override
    public void grab(int orderId, int driverId) {
        /*生成订单key*/
        String RedLockKey = (RedisKeyConstant.GRAB_LOCK_ORDER_KEY_PRE + orderId).intern();
        RLock lock01 = redisConfig.redissonClient01().getLock(RedLockKey);
        RLock lock02 = redisConfig.redissonClient02().getLock(RedLockKey);
        RLock lock03 = redisConfig.redissonClient03().getLock(RedLockKey);
        // 同时加锁:lock01 lock02 lock03
        RedissonRedLock lock = new RedissonRedLock(lock01, lock02, lock03);
        // 红锁在大部分节点上加锁成功就算成功。
        try {
            lock.lock();
            try {
               /* TimeUnit.MINUTES.sleep(1);*/
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("司机:"+driverId+" 执行抢单逻辑");
            /*抢到锁的司机 修改订单状态 为1 */
            boolean grab = tblOrderService.grab(orderId, driverId);
            if(grab){
                System.out.println("司机:"+driverId+" 抢单成功");
                /*就把该司机的driverid 和 订单id 绑定在一起*/
            }else {
                System.out.println("司机:"+driverId+" 抢单失败");
            }
        }
        finally {
            lock.unlock();
        }

    }
}
    @Override
    public boolean grab(int orderId, int driverId) {
        TblOrderEntity order = tblOrderDao.selectById(orderId);

        if(order.getOrderStatus().intValue()==0){
                order.setOrderStatus(1);
                tblOrderDao.updateById(order);
                return true;
        }else
            return false;
    }
}

为了测试 我们启动两个service-order 服务来提供测试

 

启动一台后 修改端口 再次启动该服务

 

 

 然后我们需要 一个api 接口服务来调用我们创建好的这两个服务

 

我们利用openFeign 来远程调用service-order 这两个服务 (loadbalancer) 请求消息会均摊到这两个服务上去

 

 

用Jmeter 测试 一次1秒发送10条消息  每条消息的orderId 相同 但是driverId不同(我们引入Jmeter自带的计数器 来实现driverId的自增)来模拟多个司机在同一时间 堆同一订单 进行抢单操作

因为涉及到的是分布式锁  我们使用的redsson 的红锁来实现分布式锁 

 

 

 

 

 

 

标签:orderId,红锁,int,driverId,redis,conf,docker,order,分布式
来源: https://www.cnblogs.com/Lcch/p/16614476.html