一:点对点模式:(P 指消息的生产者 producer C 指消息的 消费者 consumer)
public class SimpleTest {
//模拟生产者将消息放入队列
@Test
public void send() throws Exception{
/*1 创建连接工厂
* 2 配置共创config
* 3 获取连接
* 4获取信道
* 5 从信道声明queue
* 6 发送消息
* 7 释放资源
*/
ConnectionFactory factory=new ConnectionFactory();
factory.setHost("106.23.34.56");
factory.setPort(5672);
factory.setVirtualHost("/tb");
factory.setUsername("admin");
factory.setPassword("123456");
//从工厂获取连接
Connection conn=factory.newConnection();
//从连接获取信道
Channel chan=conn.createChannel();
//利用channel声明第一个队列
chan.queueDeclare("simple", false, false, false, null);
//queue String类型,表示声明的queue对列的名字
//durable Boolean类型,表示是否持久化
//exclusive Boolean类型:当前声明的queue是否专注;true当前连接创建的
//任何channle都可以连接这个queue,false,新的channel不可使用
//autoDelete Boolean类型:在最后连接使用完成后,是否删除队列,false
//arguments Map类型,其他声明参数
//发送消息
String msg="helloworld,nihaoa";
chan.basicPublish("", "simple", null, msg.getBytes());
//exchange String类型,交换机名称,简单模式使用默认交换""
//routingkey String类型,当前的消息绑定的routingkey,简单模式下,与队列同名即可
//props BasicProperties类型,消息的属性字段对象,例如BasicProperties
//可以设置一个deliveryMode的值0 持久化,1 表示不持久化,durable配合使用
//body byte[] :消息字符串的byte数组
}
//模拟消费端
@Test
public void receive() throws Exception{
二:工作队列 (Work queues)
工作队列 默认是Round-robin dispatching 即循环调度 即:轮流所有的消费者 发送消息。当消费者稳定运行时,他们接受的消息数量是一样的。体现在工作任务的派发时,他是"公平派遣"。 工作任务的处理因工作者的能力不同 处理的速度和效率也不同。 假设业务场景:一个项目中有十个子任务【十个子任务的工作量一样时】,我们有两个工作人员(即消费者),我们把任务通过 循环调度派发 给 C1 和 C2 , 当10个任务都完成时 我们的项目才算完成。 若C1 工作效率高 ,C1 完成5个任务只需10个小时,而C2 需要 20 个小时,这时项目用时就等待多了10个小时。这时我们为了加快项目的完成就可以叫C1或者其他空闲的人 多做几个任务。 我们在消费者代码中用 channel.basicQos(1) 保证在接收端一个消息没有处理完时不会接收另一个消息,即接收端发送了ack后才会接收下一个消息。在这种情况下发送端会尝试把消息发送给下一个not busy的接收端。这种模式 即工作竞争模式或者又称消费者竞争模式。即谁先拿到消息,谁来负责 消费。常见的业务场景有抢红包,秒杀。
注意:我们在用这种模式做工作任务的派发时,应尽可能的确保消息能被消费。假设你只有几个工人在做N多个任务 由于工作任务的复杂性,所有的工作任务处理不过来,这时队列就可能会填满,导致RabbitMQ 崩溃。