部署多台独立的redis;
redis的配置:
package com.online.taxi.order.config;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
@Component
public class RedisConfig {
@Autowired
RedisSentinelProperties properties;
//以下为红锁
@Bean(name = "redissonRed1")
@Primary
public RedissonClient redissonRed1(){
Config config = new Config();
config.useSingleServer().setAddress("127.0.0.1:6379").setDatabase(0);
return Redisson.create(config);
}
@Bean(name = "redissonRed2")
public RedissonClient redissonRed2(){
Config config = new Config();
config.useSingleServer().setAddress("127.0.0.1:6380").setDatabase(0);
return Redisson.create(config);
}
@Bean(name = "redissonRed3")
public RedissonClient redissonRed3(){
Config config = new Config();
config.useSingleServer().setAddress("127.0.0.1:6381").setDatabase(0);
return Redisson.create(config);
}
}
分布式锁的接口
package com.online.taxi.order.service;
public interface GrabService {
/**
* 司机抢单
* @param orderId
* @param driverId
* @return
*/
public String grabOrder(int orderId , int driverId);
}
分布式锁的实现类,里面需要注入需要抢占资源的业务类(使用分布式锁的服务都集合在该类中)
package com.online.taxi.order.service.impl;
import com.online.taxi.order.constant.RedisKeyConstant;
import com.online.taxi.order.service.GrabService;
import com.online.taxi.order.service.OrderService;
import org.redisson.RedissonRedLock;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
@Service("grabRedisRedissonRedLockLockService")
public class GrabRedisRedissonRedLockLockServiceImpl implements GrabService {
@Autowired
@Qualifier("redissonRed1")
private RedissonClient redissonRed1;
@Autowired
@Qualifier("redissonRed2")
private RedissonClient redissonRed2;
@Autowired
@Qualifier("redissonRed3")
private RedissonClient redissonRed3;
@Autowired
OrderService orderService;
@Override
public String grabOrder(int orderId , int driverId){
//生成key
String lockKey = (RedisKeyConstant.GRAB_LOCK_ORDER_KEY_PRE + orderId).intern();
//redisson锁 哨兵
// RLock rLock = redisson.getLock(lockKey);
// rLock.lock();
//redisson锁 单节点
// RLock rLock = redissonRed1.getLock(lockKey);
//红锁 redis son
RLock rLock1 = redissonRed1.getLock(lockKey);
RLock rLock2 = redissonRed2.getLock(lockKey);
RLock rLock3 = redissonRed3.getLock(lockKey);
RedissonRedLock rLock = new RedissonRedLock(rLock1,rLock2,rLock3);
try {
rLock.lock();
try {
TimeUnit.MINUTES.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 此代码默认 设置key 超时时间30秒,过10秒,再延时
System.out.println("司机:"+driverId+" 执行抢单逻辑");
boolean b = orderService.grab(orderId, driverId);
if(b) {
System.out.println("司机:"+driverId+" 抢单成功");
}else {
System.out.println("司机:"+driverId+" 抢单失败");
}
} finally {
rLock.unlock();
}
return null;
}
}
图解析:部署了5台独立的redis,当线程1获取锁成功(1,2,3),然后3挂掉,这时,立马启动,线程2进来,就会获取锁成功3(3,4,5),这时就违反了分布式锁的原则互斥性
所以,运维应该注意,启动redis时应该延时启动,延时时间视业务执行时长而定
红锁:部署了N台redis 抢占分布式锁 的个数>=redis/2+1,则表示分布式锁获取成功