java spring redis订阅_redis的订阅在spring mvc中sub方法写在哪好?

建议你看看 dubbo 的源码,其中有用到 Redis 的发布订阅 com.alibaba.dubbo.registry.redis.RedisRegistry.Notifier 这个是订阅的线程类

private class Notifier extends Thread {

private final String service;

private volatile Jedis jedis;

private volatile boolean first = true;

private volatile boolean running = true;

private final AtomicInteger connectSkip = new AtomicInteger();

private final AtomicInteger connectSkiped = new AtomicInteger();

private final Random random = new Random();

private volatile int connectRandom;

private void resetSkip() {

connectSkip.set(0);

connectSkiped.set(0);

connectRandom = 0;

}

private boolean isSkip() {

int skip = connectSkip.get(); // 跳过次数增长

if (skip >= 10) { // 如果跳过次数增长超过10,取随机数

if (connectRandom == 0) {

connectRandom = random.nextInt(10);

}

skip = 10 + connectRandom;

}

if (connectSkiped.getAndIncrement() < skip) { // 检查跳过次数

return true;

}

connectSkip.incrementAndGet();

connectSkiped.set(0);

connectRandom = 0;

return false;

}

public Notifier(String service) {

super.setDaemon(true);

super.setName("DubboRedisSubscribe");

this.service = service;

}

@Override

public void run() {

while (running) {

try {

if (! isSkip()) {

try {

for (Map.Entry entry : jedisPools.entrySet()) {

JedisPool jedisPool = entry.getValue();

try {

jedis = jedisPool.getResource();

try {

if (service.endsWith(Constants.ANY_VALUE)) {

if (! first) {

first = false;

Set keys = jedis.keys(service);

if (keys != null && keys.size() > 0) {

for (String s : keys) {

doNotify(jedis, s);

}

}

resetSkip();

}

jedis.psubscribe(new NotifySub(jedisPool), service); // 阻塞

} else {

if (! first) {

first = false;

doNotify(jedis, service);

resetSkip();

}

jedis.psubscribe(new NotifySub(jedisPool), service + Constants.PATH_SEPARATOR + Constants.ANY_VALUE); // 阻塞

}

break;

} finally {

jedisPool.returnBrokenResource(jedis);

}

} catch (Throwable t) { // 重试另一台

logger.warn("Failed to subscribe service from redis registry. registry: " + entry.getKey() + ", cause: " + t.getMessage(), t);

// 如果在单台redis的情况下,需要休息一会,避免空转占用过多cpu资源

sleep(reconnectPeriod);

}

}

} catch (Throwable t) {

logger.error(t.getMessage(), t);

sleep(reconnectPeriod);

}

}

} catch (Throwable t) {

logger.error(t.getMessage(), t);

}

}

}

public void shutdown() {

try {

running = false;

jedis.disconnect();

} catch (Throwable t) {

logger.warn(t.getMessage(), t);

}

}

}

private class NotifySub extends JedisPubSub {

private final JedisPool jedisPool;

public NotifySub(JedisPool jedisPool) {

this.jedisPool = jedisPool;

}

@Override

public void onMessage(String key, String msg) {

if (logger.isInfoEnabled()) {

logger.info("redis event: " + key + " = " + msg);

}

if (msg.equals(Constants.REGISTER)

|| msg.equals(Constants.UNREGISTER)) {

try {

Jedis jedis = jedisPool.getResource();

try {

doNotify(jedis, key);

} finally {

jedisPool.returnResource(jedis);

}

} catch (Throwable t) { // TODO 通知失败没有恢复机制保障

logger.error(t.getMessage(), t);

}

}

}

@Override

public void onPMessage(String pattern, String key, String msg) {

onMessage(key, msg);

}

@Override

public void onSubscribe(String key, int num) {

}

@Override

public void onPSubscribe(String pattern, int num) {

}

@Override

public void onUnsubscribe(String key, int num) {

}

@Override

public void onPUnsubscribe(String pattern, int num) {

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值