rocketmq——入门
1、介绍
rocketmq是一款阿里出的消息队列,java语言开发,目前交由apache开源,据说阿里内部大规模部署
数据显示rocketmq的qps能达到10万级,跟rabbitmq性能差不多但是社区比rabbitmq活跃,比kafka性能低一点但是响应比kafka快
2、架构组成
一般分为NameServer、Broker、Producer、Consumer
2.1、Broker
负责消息的接收、存储和发送
2.2、NameServer
负责管理broker的注册信息,并为consumer和producer提供路由和负载,找到自己要发送和订阅的broker
2.3、producer
消息的生产者
2.4、consumer
消息的消费者
3、术语
3.1、topic
在使用消息队列时,一般会给一类业务类型的消息起一个类别的名称,供producer和consumer指定队列进行生产和消费,就是消息主题
3.2、queue
存放消息的队列
每个topic有多个queue,个数可以设置,这些queue可以分布在不同的broker上
3.3、tag
与topic类似,topic之间一般没有共同的关联,一个topic下可以有多个相似的tag
比如你要学java,订阅了一个叫java的topic,里面还分为很多细类,比如jvm、spring、mybatis、netty等,这些细类就是tag
3.4、group
组,分为生产者组和消费者组
生产者组就是生产者的集群
消费者组是消费者的集群,集群个数要和queue的个数相同,因为同一个queue同一时间只能有一个消费者消费上面的消息
同一个消费者组的消费者,允许订阅不同tag甚至不同topic,但是非常建议让同组下消费者订阅的topic和tag保持一致
4、安装部署
这里我使用docker安装,如果你没有docker可以先下一个,我个人觉得docker管理这些中间件还挺方便
下载地址和下载教程给你放好了https://www.docker.com/get-started,或者你可以百度一下,一大堆教程
4.1、下载rocketmq-docker源码
下载地址:https://github.com/apache/rocketmq-docker
4.2、构建docker镜像
下载之后进入image-build目录,执行下面指令,构建docker镜像:
build-image.sh 4.8.0 alpine
alpine和centos只是内嵌的操作系统版本不同,据说alpine更小一点,我们就用它
4.3、启动
启动NameServer
docker run --name rmqnamesrv -d -p 9876:9876 apacherocketmq/rocketmq:4.8.0-alpine sh mqnamesrv
启动Broker
由于我这里是mac环境,所以指定NameServer的IP为docker.for.mac.host.internal,实际上就是你NamesServer所在服务器的IP
docker run --name rmqbroker -d -p 10911:10911 -p 10909:10909 -e "NAMESRV_ADDR=docker.for.mac.host.internal:9876" apacherocketmq/rocketmq:4.8.0-alpine sh mqbroker
修改brokerIP
brokerIP默认为docker的IP,需要你改成宿主机的IP,不然后面的producer和consumer是访问不了的
进入broker容器:
docker exec -it rmqbroker bash
进入到/home/rocketmq/rocketmq-4.8.0/conf目录下,修改broker.conf:
brokerClusterName = DefaultCluster
brokerName = broker-a
brokerId = 0
## brokerIP1这行原来是没有的,需要你设置为docker镜像的宿主机IP
## 我的docker装在我的mac上,就设置的docker.for.mac.host.internal
brokerIP1 = docker.for.mac.host.internal
deleteWhen = 04
fileReservedTime = 48
brokerRole = ASYNC_MASTER
flushDiskType = ASYNC_FLUSH
这时broker.conf还没有起作用,因为broker默认不使用任何配置文件,需要我们修改启动脚本
进入/home/rocketmq/rocketmq-4.8.0/bin目录,修改mqbroker:
if [ -z "$ROCKETMQ_HOME" ] ; then
## resolve links - $0 may be a link to maven's home
PRG="$0"
# need this for relative symlinks
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG="`dirname "$PRG"`/$link"
fi
done
saveddir=`pwd`
ROCKETMQ_HOME=`dirname "$PRG"`/..
# make it fully qualified
ROCKETMQ_HOME=`cd "$ROCKETMQ_HOME" && pwd`
cd "$saveddir"
fi
export ROCKETMQ_HOME
## 这行原来是这样的
## sh ${ROCKETMQ_HOME}/bin/runbroker.sh org.apache.rocketmq.broker.BrokerStartup $@
## 在后面加-c ${ROCKETMQ_HOME}/conf/broker.conf,表示使用刚才我们改动的配置文件启动
sh ${ROCKETMQ_HOME}/bin/runbroker.sh org.apache.rocketmq.broker.BrokerStartup $@ -c ${ROCKETMQ_HOME}/conf/broker.conf
最后exit回车,退出容器重启:
docker stop rmqbroker
docker start rmqbroker
4.4、rocketmq-console(选)
rocketmq的控制台,虽然界面做的比较烂,但是里面的统计功能还不错
也是先下载源码:
https://github.com/apache/rocketmq-externals
里面有个rocketmq-console目录,进去之后构建镜像:
mvn clean package -Dmaven.test.skip=true docker:build
启动:
-Dcom.rocketmq.sendMessageWithVIPChannel=false是不用虚拟IP
docker run --name rmqconsoleng -e "JAVA_OPTS=-Drocketmq.namesrv.addr=docker.for.mac.host.internal:9876 -Dcom.rocketmq.sendMessageWithVIPChannel=false" -p 8080:8080 -t apacherocketmq/rocketmq-console-ng
然后你就可以访问控制台主页面了
4、快速使用
我们写一个简单地springboot项目,来快速体验一把
Maven依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
</dependencies>
springboot配置文件:
server.port=8081
rocketmq.name-server=localhost:9876
rocketmq.consumer.topic=fastking
rocketmq.producer.group=fastking-group
为了方便演示,我们把生产者和消费者放到一个服务里:
Controller,做http请求:
@RestController
public class DemoController {
@Autowired
private RocketMQTemplate rocketMQTemplate;
@GetMapping("/demo")
public String demo(){
final GenericMessage<String> message = new GenericMessage<>("hello world");
//第一个参数是topic,第二个参数是消息,不一定非是String类型,也可以是对象,发送的时候会被序列化
rocketMQTemplate.send("fastking",message);
return "success";
}
}
Listener,监听队列中的消息:
//consumerGroup表示消费者组名,topic表示订阅的topic,可选selectorExpression表示你订阅的tag
@Component
@RocketMQMessageListener(consumerGroup = "fastking-group",topic = "fastking")
public class DemoListener implements RocketMQListener<String> {
@Override
public void onMessage(String s) {
System.out.println("收到了消息:"+s);
}
}
发送一条get请求,http://localhost:8081/demo,程序中能收到消息,打印出“收到了消息:hello world”