项目要做一个消息服务器,最近疯狂百度查找资料终于搭建完事儿了. 刚开始一脸懵逼,学习了这么久总算是入门儿
因为只是一个消息服务器,业务不算太复杂,所以我使用spring boot 来做(省事!)
spring boot 的创建在这里就不发了,我想写的是搭建的思路,因为代码网上铺天盖地的多的是.
首先我们需要一个消息生产者(Producer)--生产者将消息发送到消费者(netty websocket),--然后再由websocket去
分发接受到的消息.
注意: 安装rocketmq 是要先配置环境变量的.(配置网上查);
首先要开启rocketmq 的两个服务nameserver(老版本叫这个,新的叫mqnamesrv.cmd)
在dos窗口里到安装的bin目录下输入start mqnamesrv.cmd 启动 ,
然后在输入命令: start mqbroker.cmd -n 127.0.0.1:9876 autoCreateTopicEnable=true 启动broker
生产者:
1: DefaultMQProducer producer = new DefaultMQProducer("随便起"); //生产者组名
2: producer.setNamesrvAddr("localhost:9876"); //指定nameServer的ip和端口;
3: producer.start(); //Producer对象在使用之前必须要调用start初始化,初始化一次即可
4: Message message = new Message("topic","tag","keys","消息内容".getbytes()); //创建消息对象
topic: 一个组里面可以有多个,(可以理解为一个主题);
tag: 一个topic又分为多个tag.(一个主题又有多个单元);
keys:
5: producer.send(message); //发送消息
6: producer.shutdown(); 清理发送过的消息
消费方:
1: DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("组名"); //监听组名得是生产者的组名
2: consumer .setNamesrvAddr("localhost:9876"); //指定nameServer的ip和端口;
3: consumer.subscribe("topic", "tag"); //订阅topic下为tag的消息 如果第二个参数为 "*",即topic下的所有消息.
4: consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET); //设置第一次启动消费的方式. (见名知意,从第一次的消息开始消费,还可以选择从最后一个消息消费)
5: ConsumerListener consumerListener = new ConsumerListener(); //创建监听器
consumer.registerMessageListener(consumerListener);
consumer.start(); //只需要start一次就够了
注意: 该监听器是由我们自己写的实现MessageListenerOrderly接口的实现类.(因为如果写成内部类的话在项目中启动它只能监听一次,就会失效(这是rocketmq的一个坑!!),所以必须分开来写.).
下面这个是实现MessageListenerOrderly接口的实现类:
public ConsumeOrderlyStatus consumeMessage(List<MessageExt> list, ConsumeOrderlyContext context) {
try {
// 设置自动提交
context.setAutoCommit(true);
for (MessageExt msg : list) {
System.err.println("接受内容:" + new String(msg.getBody()));
//在这里我们可以对接受到的消息进行各种操作.
} catch (Exception e) {
e.printStackTrace();
}
return ConsumeOrderlyStatus. SUCCESS;
}
注意: 如果我们要把生产者消息放入到spring 容器或者其他缓存中,在消费方去注入取出的话是会报空指针的,因为监听器是比spring容器要先加载的(又是个大坑!). 所以想要缓存生产者消息的时候要注意怎么设计代码能把消息传递给消费方这个得看自己的业务需求来做.总之不能在消费方去注入比如redis不然取不到数据...
简单的rocketmq 生产者 消费者就完成了.
///下面是关于rocketmq的一些详细介绍///
rocketmq会打印生产者--消费者产生的消息日志和程序工作日志(默认是在本机账户的logs文件夹下),我们可以通过对D:\NewWorker\RocketMQ\conf下的4个xml文件中将所有${user.logs}修改成自定义日志的路径.(我的安装路径是D:\new...).这里的是关于生产者的日志配置信息.消费者的比较麻烦需要到我们的maven本地仓库中找到rocketmq-client-3.2.6.jar 这个jar打开会看到有log4j_rocketmq_client.xml---logback_rocketmq_client.xml两个配置文件,修改里面的${user.logs}改成自定义的日志路径替换掉两个xml就可以了.(如果日志所在的磁盘空间低于20%项目启动时会报错,磁盘无线大的可以忽略).
rocketmq有两种消费模式:
集群消费(常用):
一个ConsumerGroup中的Consumer实例平均分摊消费消息。例如某个Topic有9条消息,其中一个ConsumerGroup有3个实例(可能是3个进程,或者3台机器),那么每个实例只消费其中部分,消费完的消息不能被其他实例消费。
广播消费:
一条消息被多个consumer消费,即使这些consumer属于同一个ConsumerGroup,消息也会被ConsumerGroup中的每个Consumer都消费一次,广播消费中ConsumerGroup概念可以认为在消息划分方面无意义。
DefaultMQPushConsumer模式: 消息发送者将消息发送到Broker,然后Broker主动推送给订阅了该消息的消费者。
DefaultMQPullConsumer模式: 消息发送者将消息发送到Broker上,然后由消息消费者自发的向Broker拉取消息。
consumer里面可以设置很多信息点击DefaultMQPushConsumer或者DefaultMQPullConsumer进入源码可以发现:
比如线程数量 , 如果是多用户推送消息它会自动的开启线程来执行分发消息.消息一旦消费成功会返回ConsumeOrderlyStatus.SUCCESS标志,之前消费的信息会被清空掉,否则会一直在队列中等待.
就先写这么多吧,第一次纯手工打造的,写的不好但希望能帮助到更多有需要的人!还有好多内容暂时没想出来就先到这吧,基本的流程是能跑通的.还得赶到Netty websocket场呢.