redis消息发布和订阅的运⽤与常见错误解决⽅法
本⽂运⽤程序所在系统:windows7
成人 英文⼀win7 CRT下 redis的常⽤命令:
1 启动redis 服务端:redis-rver
2 启动redis 客户端:redis-cli
3 关闭redis 服务端:redis-cli -a 123456 shutdown (-a 123456在redis设置了密码的情况下使⽤)
4 设置redis连接密码:config t requirepass 123456 (123456 是设置的密码,关闭服务器后密码会失效,需要重新设置)
5 授权登⼊:auth 12345
6 (123456 是设置的密码,当redis设置了密码时,真正使⽤redis设置或读取数据需要密码授权)
6 订阅redis消息频道:SUBSCRIBE china (china是频道名称,可以同时订阅多个频道,以空格隔开)
7 redis频道上发布信息:publish china hello (china是频道名称,hello是消息内容)
显⽰2表⽰当前频道被订阅的数量有2个,本机Java程序也同时订阅了china频道
⼆ Java运⽤程序连接远程Linux环境下redis的常见错误
1 显⽰连接被拒绝
Caud by: redis.ptions.JedisConnectionException: java.ConnectException: Connection refud: connect
分析原因:查看f⽂件内容可以看出,redis默认只运⾏本机连接
解决⽅法:找到如上图的bind 127.0.0.1,改为bind 0.0.0.0,然后重启redis 服务器即可
2 缺乏授权
redis.ptions.JedisDataException: DENIED Redis is running in protected mode becau protected mode is enabled, no bind address was s
分析原因:出现授权的问题⼀般来说连接登⼊可能出现需要密码的问题,或者需要取消保护模式的问题,查看f⽂件内容可以看出模式是保护的模式
觇标
解决⽅法1:找到 如上图的protected-mode yes,改为protected-mode no,,然后重启redis 服务器即可
解决⽅法2:设置redis密码,此时java运⽤程序连接也需要使⽤密码连接
3 最常见的Linux端⼝对外开放的问题
因为redis服务器部署在Linux上,肯定会出现开放端⼝的常见问题
开放端⼝的解决⽅法:
⽅法⼀:命令⾏⽅式
1. 开放端⼝命令: /sbin/iptables -I INPUT -p tcp --dport 8080 -j ACCEPT
2.保存:/etc/rc.d/init.d/iptables save
3.重启服务:/etc/init.d/iptables restart
4.查看端⼝是否开放:/sbin/iptables -L -n
⽅法⼆:直接编辑/etc/sysconfig/iptables⽂件
1.编辑/etc/sysconfig/iptables⽂件:vi /etc/sysconfig/iptables
加⼊内容并保存:-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -j ACCEPT
深绿海
2.重启服务:/etc/init.d/iptables restart
3.查看端⼝是否开放:/sbin/iptables -L -n
三 Java消息订阅发布的运⽤程序案例
依赖的jar:
1 消息订阅的程序⽚段
import redis.clients.jedis.JedisPubSub;
/**
作文培训
* 订阅者
*/
public class Subscriber extends JedisPubSub {//注意这⾥继承了抽象类JedisPubSub
private static final Logger LOGGER = Logger(Subscriber.class);
@Override
public void onMessage(String channel, String message) {
LOGGER.info(String.format("onMessage 接收消息 Message. Channel: %s, Msg: %s", channel, message)); }
@Override
public void onPMessage(String pattern, String channel, String message) {
黑夜之色LOGGER.info(String.format("onPMessage 接收消息 PMessage. Pattern: %s, Channel: %s, Msg: %s",
pattern, channel, message));
}
@Override
public void onSubscribe(String channel, int subscribedChannels) {nature是什么意思
LOGGER.info("onSubscribe 订阅 channel:"+channel+" ;subscribedChannels:"+subscribedChannels)
;
}
@Override
public void onUnsubscribe(String channel, int subscribedChannels) {
LOGGER.info("onUnsubscribe 取消订阅 channel:"+channel+" ;subscribedChannels:"+subscribedChannels); }
@Override
public void onPUnsubscribe(String pattern, int subscribedChannels) {
LOGGER.info("onPUnsubscribe 取消订阅 channel:"+pattern+" ;subscribedChannels:"+subscribedChannels); }
@Override
public void onPSubscribe(String pattern, int subscribedChannels) {
LOGGER.info("onPSubscribe 订阅 channel:"+pattern+" ;subscribedChannels:"+subscribedChannels);
}
}
2 消息发布的程序⽚段
import redis.clients.jedis.Jedis;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* 发布者
*/
高中语文文言文翻译
public class Publisher {
private static final Logger LOGGER = Logger(Publisher.class);
private final Jedis publisherJedis;
private final String channel;
public Publisher(Jedis publisherJedis, String channel) {
this.publisherJedis = publisherJedis;
this.channel = channel;
}
/**
* 不停的读取输⼊,然后发布到channel上⾯,遇到quit则停⽌发布。
*/
public void startPublish() {
LOGGER.info("Type your message (quit for terminate)");
try {
publisherJedis.publish(channel, "先发⼀条初始信息aaaaaaaaaaaaaa");
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); while (true) {
String line = adLine();attend
if (!"quit".equals(line)) {
publisherJedis.publish(channel, line);
} el {
break;
}
}
} catch (IOException e) {
<("IO failure while reading input", e);
}
}
}injection
3 主函数
public class MainClass {
public static final String CHANNEL_NAME = "china";//频道
public static final String REDIS_HOST = "192.168.1.11";
public static final int REDIS_PORT = 6379;
private final static Logger LOGGER = Logger(MainClass.class);
private final static JedisPoolConfig POOL_CONFIG = new JedisPoolConfig();
//private final static JedisPool JEDIS_POOL = new JedisPool(POOL_CONFIG, REDIS_HOST, REDIS_PORT, 10000);
private final static JedisPool JEDIS_POOL = new JedisPool(POOL_CONFIG, REDIS_HOST, REDIS_PORT, 10000,"123456");
public static void main(String[] args) throws Exception {
final Jedis subscriberJedis = Resource();
final Jedis publisherJedis = Resource();
final Subscriber subscriber = new Subscriber();
//订阅线程:接收消息
new Thread(new Runnable() {
public void run() {
try {
LOGGER.info("Subscribing to \"MyChannel\". This thread will be blocked.");
//使⽤subscriber订阅CHANNEL_NAME上的消息,这⼀句之后,线程进⼊订阅模式,阻塞。
subscriberJedis.subscribe(subscriber, CHANNEL_NAME);//订阅
LOGGER.info("Subscription ended.");
} catch (Exception e) {
<("Subscribing failed.", e);
}
}
}).start();
Thread.sleep(2000);
//主线程:发布消息到CHANNEL_NAME频道上
new Publisher(publisherJedis, CHANNEL_NAME).startPublish();//进⼊发布消息程序
publisherJedis.clo();
//Unsubscribe
工程管理方法subscriber.unsubscribe(); //取消订阅
subscriberJedis.clo();
}
}
注:命令窗⼝的消息发布和订阅会与程序中的同步