前言:之前一直没有系统学习一下rabbitmq,只Google突击学习一下就上手,最近在看《rabbitmq in action》,记一下理解后的要点。
常用脚本命令:
- 前台启动:rabbitmq-server
- 以后台守护进程启动:rabbitmq-server -detached
- 启动后查看状态:rabbitmqctl status
- 停止节点:rabbitmqctl stop ,包括rabbitmq和erlang,这个命令会优雅关闭,rabbitmqctl会和本地节点通信指示其干净关闭,也可以关闭不同的节点,传入-n rabbit@[hostname]
- 只关闭rabbitmq,不关闭erlang:rabbitmqctl stop_app
默认exchange:
刚开始学的时候,并没有关注exchange,但仍然能把消息发到队列,这是因为指定了默认路由器:
channel.basicPublish("", "hello", null, message.getBytes());
注意第一个参数设置了空字符串,就是指定了默认exchange;第二个参数是已经声明了的queue的name,注意,queue可以自动生成name:
String queueName = channel.queueDeclare().getQueue();
也可以自定义,但必须有个name绑定到exchange。
channel:
一个tcp连接中存在多个channel。官方建议在一个多线程消费者中,每个线程都对应一个独立的channel,不要在多个线程中共用一个channel
分发机制:
rabbitmq采用轮询分发机制,也就是说,如果有2个消费者a和b,a每5秒处理一条消息,b每一秒处理一条消息,生产者发了6条消息到队列中,最终的结果是,a分发到3条消息用15秒处理了,b也分发到3条消息,3秒处理了,然后空闲等待,这明显不合理。
如何解决?使用channel.basicQos(1),这个配置的意思是,rabbitmq每次只能发1条消息给轮询到的消费者,当消费者ack之后,才会再发下一条。
exchange:
- fanout:这是广播交换器交换器。比如声明了一个广播交换器q1,客户端a,b,c,d分别创建了4个不同name的queue,并绑定到q1,q1会分别把消息分发到4个不同的queue。也就是说,广播交换器不关心routing key,所有绑定的队列,都会发
- direct:direct交换器。比如声明了一个direct交换器q2,客户端a绑定一个队列到q2,并声明routing key = “error”,客户端b绑定一个队列到q2,并声明routing key = “info”;那么客户端a,b只会接收到对应routing key的消息
- topic:topic交换器。这个交换器规定routing key必须满足a.a.a.a这种格式,并规定了2中通配符,*表示1个a;#可以表示多个a
- 例如:routing key = *.a*,可以匹配b.a.c,但是无法匹配a.c,b.a,b.a.c.d
- 例如:routing key = a.#,可以匹配a.b,a.b.c
vhost:多租户模式。试想,你启动了一个rabbitmq服务,它被应用在很多功能模块上,比如账号服务,订单服务,你要保证两个服务的队列是完全独立的,再往后,服务越来越多,一个是要保证queue和exchange的命名不冲突,另一个是要区分不同的服务,很麻烦,除非运行多个rabbitmq。
vhost就类似于虚拟机,虽然只启动了一个rabbitmq集群,但是通过vhost,可以创建很多个虚拟的rabbitmq,之间相互隔离,每个虚拟的rabbitmq都有单独的queue,exchange,和绑定关系
目前我知道的创建vhost方式只有通过rabbitmqctl命令或者通过web控制台来创建。
网友评论