mysql 互斥锁导致宕机_记一次线上 redis 使用分布式锁坑

起因

早上grafana 发来邮件警告系统异常过多..

登录 grafana 查看.

ea5ae731727304a563b764a2d06699d0.png

排查

登录 kibana 查看相关日志.

发现错误一:

Caused by: redis.clients.jedis.exceptions.JedisConnectionException: java.net.UnknownHostException: redis.marathon.l4lb.thisdcos.directory

at redis.clients.jedis.Connection.connect(Connection.java:207)

at redis.clients.jedis.BinaryClient.connect(BinaryClient.java:93)

at redis.clients.jedis.BinaryJedis.connect(BinaryJedis.java:1767)

at redis.clients.jedis.JedisFactory.makeObject(JedisFactory.java:106)

at org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:868)

at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:435)

at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:363)

at redis.clients.util.Pool.getResource(Pool.java:49)

... 119 common frames omitted

Caused by: java.net.UnknownHostException: redis.marathon.l4lb.thisdcos.directory

at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:184)

at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)

at java.net.Socket.connect(Socket.java:589)

at redis.clients.jedis.Connection.connect(Connection.java:184)

... 126 common frames omitted

dcos vip 映射 ip 出错,导致服务中找不到 redis

再查看 grafana redis 监控,发现 redis io,setnx 命令都异常.如下图

07d8610125d6c5ffdd929b447421b1df.png

排查相关服务. 发现下面代码

while (!flag && start <= System.currentTimeMillis() + time) {

flag = redisTemplate.execute(new RedisCallback() {

@Override

public Boolean doInRedis(RedisConnection connection) throws DataAccessException {

Jedis jedis = (Jedis) connection.getNativeConnection();

if (jedis.setnx(key, UID) == 1L) {

jedis.expire(key, LOCK_DEATH_TIME);//300秒过期,防止死锁.如果在这步前jvm挂了,会导致一直死锁.

LOCK_MAP.put(RedisLock.this, 1);

setExclusiveOwnerThread(Thread.currentThread());

return true;

}

return false;

}

});

在 setnx 方法的时候没有休眠,导致一直循环..

解决方案,while 加入 sleep

while (!flag && start <= System.currentTimeMillis() + time) {

flag = redisTemplate.execute(new RedisCallback() {

@Override

public Boolean doInRedis(RedisConnection connection) throws DataAccessException {

Jedis jedis = (Jedis) connection.getNativeConnection();

if (jedis.setnx(key, UID) == 1L) {

jedis.expire(key, LOCK_DEATH_TIME);//300秒过期,防止死锁.如果在这步前jvm挂了,会导致一直死锁.

LOCK_MAP.put(RedisLock.this, 1);

setExclusiveOwnerThread(Thread.currentThread());

return true;

}

//循环竞争锁的时候添加休眠

try {

TimeUnit.MILLISECONDS.sleep(20L);

} catch (InterruptedException e) {

log.error("lock error", e);

}

log.info("竞争锁: " + key);

return false;

}

});

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值