gpt4 book ai didi

java - redis pub sub with jedis , sub crashes with error

转载 作者:IT王子 更新时间:2023-10-29 06:00:35 25 4
gpt4 key购买 nike

全部

我已经安装了最新的 Redis 2.4.16 并尝试将其 Pub/Sub 系统与 java 一起使用。我每秒都会向 channel 发送一条消息。发布者没有问题,但订阅者崩溃并显示消息

异常:

redis.clients.jedis.exceptions.JedisDataException: ERR only (P)SUBSCRIBE / (P)UNSUBSCRIBE / QUIT allowed in this context
at redis.clients.jedis.Protocol.processError(Protocol.java:59)
at redis.clients.jedis.Protocol.process(Protocol.java:66)
at redis.clients.jedis.Protocol.read(Protocol.java:131)
at redis.clients.jedis.Connection.getObjectMultiBulkReply(Connection.java:206)
at redis.clients.jedis.JedisPubSub.process(JedisPubSub.java:88)
at redis.clients.jedis.JedisPubSub.proceed(JedisPubSub.java:83)
at redis.clients.jedis.Jedis.subscribe(Jedis.java:1971)
at com.jedis.test.JedisSub$1.run(JedisSub.java:22)
at java.lang.Thread.run(Thread.java:680)

这是我的代码:

发布者:

        final Jedis jedis = new Jedis("localhost");

ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(10);
newFixedThreadPool.submit(new Runnable() {

@Override
public void run() {
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
jedis.publish("CC", new Date().toString());
}

}
});

订阅者:

        JedisPool jedisPool = new JedisPool(poolConfig,"localhost", 6379, 100);
final Jedis subscriberJedis = jedisPool.getResource();


new Thread(new Runnable() {
@Override
public void run() {
try {
subscriberJedis.subscribe(new JedisPubSub() …..,"CC");
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();

jedisPool.returnResource(subscriberJedis);

池配置:

    JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.maxActive = 10;
poolConfig.maxIdle = 5;
poolConfig.minIdle = 1;
poolConfig.testOnBorrow = true;
poolConfig.numTestsPerEvictionRun = 10;
poolConfig.timeBetweenEvictionRunsMillis = 60000;
poolConfig.maxWait = 3000;
poolConfig.whenExhaustedAction = org.apache.commons.pool.impl.GenericObjectPool.WHEN_EXHAUSTED_FAIL;

为了安装Redis,我简单地使用了命令

make PREFIX=/Users/ggg/dev/dist/redis/ install

在此之后我没有使用./install_server.sh

Jedis 版本为 2.1.0,平台为 Mac OS X。

Note: What I have noticed is subscriber crashes near about 30 seconds after start.

最佳答案

发布者和订阅者的代码都错了。

错误是由于 Redis 连接无法在发布者和订阅者之间共享。实际上,您需要一个用于发布者的连接(或一个连接池),以及一个用于订阅者线程的专用连接。每个进程运行一个订阅者线程通常就足够了。

在这里,您过早地将 subscriberJedis 连接返回到池中,在订阅者线程完成之前,因此连接被共享。

在发布者中:

由于您有一个包含 10 个线程的池,因此您不应在这些线程之间共享唯一连接。这是使用连接池的最佳位置,必须在每个线程中获取和释放连接。

    // This should be a global singleton
JedisPool jedisPool = new JedisPool(poolConfig,"localhost", 6379, 100);

ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(10);
newFixedThreadPool.submit(new Runnable() {

@Override
public void run() {
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Jedis jedis = jedisPool.getResource();
try {
jedis.publish("CC", new Date().toString());
} catch (Exception e) {
e.printStackTrace();
} finally {
jedisPool.returnResource(jedis);
}
}

}
});

在订阅者中:

在订阅者中,您需要专用连接。

    new Thread(new Runnable() {
@Override
public void run() {
Jedis subscriberJedis = new Jedis("localhost");
try {
subscriberJedis.subscribe(new JedisPubSub() …..,"CC");
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();

如果您需要订阅不同的 channel 或模式,最好将其他订阅设置在同一线程和同一连接中。

关于java - redis pub sub with jedis , sub crashes with error,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12119471/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com