rabbitmq 基础操作实践和总结
RabbitMq 项目中陆陆续续的开始使用,但是一直没详细去研究它的监控管理后台。今天就花点时间研究一下。
一、进入后台管理
我安装的是Docker版的带后台管理的management版本,启动好容器之后,浏览器输入http://localhost:15672/ 15672这个是默认绑定的端口号。我们进入到后台:
从上图中,可以看到各种监控数据,如进程数,内存,硬盘空间,Socker连接数等,顶部选项卡也有connection,channels,exchanges ,queues,admin。
二、用户管理操作
我们打开Admin选项卡,新加一个admin管理账号,因为不熟悉操作,我一不小心把guest这个默认用户的tag标记给清空了。然后退出之后就无法再登录,出现以下提示:
提示该用户不是管理员了,无法登录。下面我们利用命令”rabbitmqctl set_user_tags 用户名 adminitrator“给用户赋予管理员角色。因为我用的是Docker,操作步骤如下:
- 使用命令 docker exec -it rabbitmq bash 命令进去rabbitmq管理控制台
- 使用 rabbitmqctl list_users 查看用户列表和角色,发现tag是【】空的
- 使用 rabbitmqctl set_user_tags guest administrator 给guest用户加上管理员角色权限
现在再登录,就没问题了。再次登录进去,我们创建一个admin管理账号,并且加上administrator角色:
点击 add user之后,admin账户创建成功了:
三、用户角色类型
1、超级管理员(administrator)
可登陆管理控制台,可查看所有的信息,并且可以对用户,策略(policy)进行操作。可以做监控所能做的一切,管理用户、虚拟主机和权限,关闭其他用户的连接,管理所有虚拟主机的策略和参数。
2、监控者(monitoring)
可登陆管理控制台,同时可以查看rabbitmq节点的相关信息(进程数,内存使用情况,磁盘使用情况等)。监控用户可以访问管理插件并查看所有连接和通道以及节点相关信息。
3、策略制定者(policymaker)
可登陆管理控制台, 同时可以对policy进行管理。但无法查看节点的相关信息(上图红框标识的部分)。用户可以访问管理插件并管理他们有权访问的虚拟主机的策略和参数。
4、普通管理者(management)
仅可登陆管理控制台,无法看到节点信息,也无法对策略进行管理。
5、其他(none)
无法登陆管理控制台,通常就是普通的生产者和消费者。
6、模拟者(impersonator )
这角色不知道有什么,官方也没有什么解释,网上暂时也没搜到相关说明,如果有知道的欢迎给我留言。
四、增加虚拟主机
这里增加了一个虚拟主机Testhost,如图:
然后回到用户管理界面,给admin用户增加这个testhost主机的权限:
然后再回到用户管理主界面,就可以看到admin的相应权限了:
五、六种工作模式
1. simple简单模式
- 消息产生着§将消息放入队列
- 消息的消费者(consumer) 监听(while) 消息队列,如果队列中有消息,就消费掉,消息被拿走后,自动从队列中删除(隐患 消息可能没有被消费者正确处理,已经从队列中消失了,造成消息的丢失)应用场景:聊天(中间有一个过度的服务器;p端,c端)
2. work工作模式(资源的竞争)
- 消息产生者将消息放入队列消费者可以有多个,消费者1,消费者2,同时监听同一个队列,消息被消费?C1 C2共同争抢当前的消息队列内容,谁先拿到谁负责消费消息(隐患,高并发情况下,默认会产生某一个消息被多个消费者共同使用,可以设置一个开关(syncronize,与同步锁的性能不一样) 保证一条消息只能被一个消费者使用)
- 应用场景:红包;大项目中的资源调度(任务分配系统不需知道哪一个任务执行系统在空闲,直接将任务扔到消息队列中,空闲的系统自动争抢)
3. publish/subscribe发布订阅(共享资源)
- X代表交换机rabbitMQ内部组件,erlang 消息产生者是代码完成,代码的执行效率不高,消息产生者将消息放入交换机,交换机发布订阅把消息发送到所有消息队列中,对应消息队列的消费者拿到消息进行消费
- 相关场景:邮件群发,群聊天,广播(广告)
4. routing路由模式
- 消息生产者将消息发送给交换机按照路由判断,路由是字符串(info) 当前产生的消息携带路由字符(对象的方法),交换机根据路由的key,只能匹配上路由key对应的消息队列,对应的消费者才能消费消息;
- 根据业务功能定义路由字符串
- 从系统的代码逻辑中获取对应的功能字符串,将消息任务扔到对应的队列中业务场景:error 通知;EXCEPTION;错误通知的功能;传统意义的错误通知;客户通知;利用key路由,可以将程序中的错误封装成消息传入到消息队列中,开发者可以自定义消费者,实时接收错误;
5. topic 主题模式(路由模式的一种)
- 星号井号代表通配符
- 星号代表多个单词,井号代表一个单词
- 路由功能添加模糊匹配
- 消息产生者产生消息,把消息交给交换机
- 交换机根据key的规则模糊匹配到对应的队列,由队列的监听消费者接收消息消费
5. rpc模式
如果我们需要在远程电脑上运行一个方法,并且还要等待一个返回结果该怎么办?这种模式我们通常称为远程过程调用,即RPC。
RPC的工作方式是这样的:
- 对于RPC请求,客户端发送一条带有两个属性的消息:replyTo,设置为仅为请求创建的匿名独占队列,和correlationId,设置为每个请求的惟一id值。
- 请求被发送到rpc_queue队列。
- RPC工作进程(即:服务器)在队列上等待请求。当一个请求出现时,它执行任务,并使用replyTo字段中的队列将结果发回客户机。
- 客户机在回应消息队列上等待数据。当消息出现时,它检查correlationId属性。如果匹配请求中的值,则向程序返回该响应数据。
六、分发模式
1.轮询分发 :
使用任务队列的优点之一就是可以轻易的并行工作。如果我们积压了好多工作,我们可以通过增加工作者(消费者)来解决这一问题,使得系统的伸缩性更加容易。
在默认情况下,RabbitMQ将逐个发送消息到在序列中的下一个消费者(而不考虑每个任务的时长等等,且是提前一次性分配,并非一个一个分配)。平均每个消费者获得相同数量的消息。这种方式分发消息机制称为Round-Robin(轮询)。
2.公平分发 :
虽然上面的分配法方式也还行,但是有个问题就是:比如:现在有2个消费者,所有的奇数的消息都是繁忙的,而偶数则是轻松的。按照轮询的方式,奇数的任务交给了第一个消费者,所以一直在忙个不停。偶数的任务交给另一个消费者,则立即完成任务,然后闲得不行。而RabbitMQ则是不了解这些的。这是因为当消息进入队列,RabbitMQ就会分派消息。它不看消费者为应答的数目,只是盲目的将消息发给轮询指定的消费者。
为了解决这个问题,我们使用basicQos( prefetchCount = 1)方法,来限制RabbitMQ只发不超过1条的消息给同一个消费者。当消息处理完毕后,有了反馈,才会进行第二次发送。
还有一点需要注意,使用公平分发,必须关闭自动应答,改为手动应答,代码如下:
// 同一时刻服务器只会发一条消息给消费者 channel.basicQos(1); //开启这行 表示使用手动确认模式 channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
同时改为手动确认:
// 监听队列,false表示手动返回完成状态,true表示自动 channel.basicConsume(QUEUE_NAME, false, consumer);