公平分发(fair dipatch)和轮询分发其实基本一致,只是每次分发的机制变了,由原来的平均分配到现在每次只处理一条消息

1.MQ连接工厂类Connection

 package com.mmr.rabbitmq.util;

 import java.io.IOException;

 import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory; public class ConnectionUtils {
/**
* @desc 获取Mq 的链接
* @author zp
* @throws IOException
* @date 2018-7-19
*/
public static Connection getConnection() throws IOException {
// 1.定义一个链接工厂
ConnectionFactory factroy = new ConnectionFactory(); // 2.设置服务地址
factroy.setHost("127.0.0.1"); // 3.设置端口号
factroy.setPort(5672); // 4.vhost 设置数据库
factroy.setVirtualHost("vhtest"); // 5.设置用户名
factroy.setUsername("jerry"); // 6. 设置密码
factroy.setPassword("123456"); // 7.返回链接
return factroy.newConnection();
}
}

2.消息生产者Send,这里的变化是声明了“每个消费者发送确认消息之前,消息队列不发送下一个消息到消费者,一次只处理一个消息” channel.basicQos(intnum);

 package com.mmr.rabbitmq.workfair;

 import java.io.IOException;

 import com.mmr.rabbitmq.util.ConnectionUtils;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection; public class Send { /*
* |--C1
* P-------|--C2
* |--C3
*
* */
private static final String QUEUE_NAME="test_work_queue";
public static void main(String[] args) throws IOException, InterruptedException{
// 获取链接
Connection connection = ConnectionUtils.getConnection(); // 获取通道
Channel channel = connection.createChannel();
// 声明队列
channel.queueDeclare(QUEUE_NAME,false,false,false,null);
/*
* 每个消费者发送确认消息之前,消息队列不发送下一个消息到消费者,一次只处理一个消息
*
* 限制发送给同一个消费者只能发送一条
* */
int prefetchCount =1;
channel.basicQos(prefetchCount); for (int i = 0; i < 50; i++) {
String msg = "hello "+i;
channel.basicPublish("", QUEUE_NAME, null, msg.getBytes());
System.out.println("send msg 的第"+i+"条");
Thread.sleep(i*20);
}
channel.close();
connection.close();
}
}

3.消息处理者(消费者)Recv1 Recv2,这里的区别在于:

(1)每次只处理1条消息channel.basicQos(1);

(2)并且在消息处理完之后会手动返回回执单 channel.basicAck(envelope.getDeliveryTag(), false);

(3)最后将之前的自动应答true改为false boolean autoAck = false;

 package com.mmr.rabbitmq.workfair;

 import java.io.IOException;

 import com.mmr.rabbitmq.util.ConnectionUtils;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.AMQP.BasicProperties; public class Recv1 {
private static final String QUEUE_NAME="test_work_queue";
public static void main(String[] args) throws IOException{
// 获取链接
Connection connection = ConnectionUtils.getConnection(); //获取频道 final Channel channel = connection.createChannel(); // 声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null); // 关闭自动应答
channel.basicQos(1); // 保证每次只被分发一个 // 定义一个消费者
Consumer consumer = new DefaultConsumer(channel){
// 一旦有消息 就会触发这个方法 消息到达
@Override
public void handleDelivery(String consumerTag, Envelope envelope,
BasicProperties properties, byte[] body) throws IOException {
// TODO Auto-generated method stub
// 拿消息
String msg = new String(body,"utf-8"); //搭出来
System.out.println("[1]Recv msg:"+msg);
try {
Thread.sleep(2000);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally{
System.out.println("[1] done");
// 手动回执
channel.basicAck(envelope.getDeliveryTag(), false);
}
}
};
// boolean autoAck = true; // 自动应答改为false
boolean autoAck = false;
channel.basicConsume(QUEUE_NAME, autoAck,consumer); }
}
 package com.mmr.rabbitmq.workfair;

 import java.io.IOException;

 import com.mmr.rabbitmq.util.ConnectionUtils;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.AMQP.BasicProperties; public class Recv2 {
private static final String QUEUE_NAME="test_work_queue";
public static void main(String[] args) throws IOException{
// 获取链接
Connection connection = ConnectionUtils.getConnection(); //获取频道 final Channel channel = connection.createChannel(); // 声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null); // 保证每次只接收一条消息
channel.basicQos(1); // 定义一个消费者
Consumer consumer = new DefaultConsumer(channel){
// 一旦有消息 就会触发这个方法 消息到达
@Override
public void handleDelivery(String consumerTag, Envelope envelope,
BasicProperties properties, byte[] body) throws IOException {
// TODO Auto-generated method stub
// 拿消息
String msg = new String(body,"utf-8"); //搭出来
System.out.println("[2]Recv msg:"+msg);
try {
Thread.sleep(1000);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally{
System.out.println("[2] done");
// 手动回执
channel.basicAck(envelope.getDeliveryTag(), false);
}
}
};
// boolean autoAck = true; // 自动应答改为false
boolean autoAck = false;
channel.basicConsume(QUEUE_NAME, autoAck,consumer); }
}

RabbitMQ简单应用の公平分发(fair dipatch)的更多相关文章

  1. RabbitMQ简单应用の轮训分发

    MQ连接工厂还是之前的那个Connection package com.mmr.rabbitmq.util; import java.io.IOException; import com.rabbit ...

  2. 工作队列work queues 公平分发(fair dispatch) And 消息应答与消息持久化

    生产者 package cn.wh.work; import cn.wh.util.RabbitMqConnectionUtil; import com.rabbitmq.client.Channel ...

  3. RabbitMQ 均衡调度(公平分发机制)

    均衡调度是针对Consumer来说的.现在有两个Consumer请求同一个队列的消息.RabbitMQ会将序号为奇数的消息发给第一个Consumer,会将序号为偶数的消息发送给第二个Consumer. ...

  4. RabbitMQ学习第二记:工作队列的两种分发方式,轮询分发(Round-robin)和 公平分发(Fair dispatch)

    1.什么是RabbitMQ工作队列 我们在应用程序使用消息系统时,一般情况下生产者往队列里插入数据时速度是比较快的,但是消费者消费数据往往涉及到一些业务逻辑处理导致速度跟不上生产者生产数据.因此如果一 ...

  5. 【python】-- RabbitMQ 队列消息持久化、消息公平分发

    RabbitMQ 队列消息持久化 假如消息队列test里面还有消息等待消费者(consumers)去接收,但是这个时候服务器端宕机了,这个时候消息是否还在? 1.队列消息非持久化 服务端(produc ...

  6. rabbitmq 公平分发和消息接收确认(转载)

    原文地址:http://www.jianshu.com/p/f63820fe2638 当生产者投递消息到broker,rabbitmq把消息分发到消费者. 如果设置了autoAck=true 消费者会 ...

  7. RabbitMQ的轮询模式和公平分发

    一.常用的消息模式 我们在工作的使用中,经常会遇到多个消费者监听同一个队列的情况,模型如下图所示: 当有多个消费者时,我们的消息会被哪个消费者消费呢,我们又该如何均衡消费者消费信息的多少呢: 主要有两 ...

  8. RabbitMQ (四) 工作队列之公平分发

    上篇文章讲的轮询分发 : 1个队列,无论多少个消费者,无论消费者处理消息的耗时长短,大家消费的数量都一样. 而公平分发,又叫 : 能者多劳,顾名思义,处理得越快,消费得越多. 生产者 public c ...

  9. rabbitmq简单实例

    JMS组件:activemq(慢)AMQP组件(advance message queue protocol):rabbitmq和kafka 一..消息队列解决了什么问题?异步处理应用解耦流量削锋日志 ...

随机推荐

  1. Elastic 安装篇(1)

    1.Elasticsearch下载安装 https://www.elastic.co/cn/downloads/elasticsearch 解压: 2.安装head https://github.co ...

  2. request.getSession()几种获取情况之间的差异

    一.三种情况如下 HttpSession session = request.getSession(); HttpSession session = request.getSession(true); ...

  3. 非root用户sudo_ssh免密钥

    非root用户sudo_ssh免密钥 目标:从服务器上ssh登陆后sudo免密钥执行相应的命令 环境介绍: 192.168.65.130 web224 # 步骤一: # 每个节点执行(不是必须,但是建 ...

  4. go 学习资源和GitHub库

    go httprouter 源码包 https://github.com/julienschmidt/httprouter 用例 https://github.com/gsingharoy/httpr ...

  5. 实战Google深度学习框架-C5-MNIST数字识别问题

    5.1 MNIST数据处理 MNIST是NIST数据集的一个子集,包含60000张图片作为训练数据,10000张作为测试数据,其中每张图片代表0~9中的一个数字,图片大小为28*28(可以用一个28* ...

  6. C++回顾day02---<引用>---待补充

    一:引用概念---引用就是为一个变量起一个别名 每个变量都是指向一块内存空间的标识,引用就是重新设置一个标识,但是这个标识还是指向同一个内存空间 和指针类似(其实引用本质就是使用了一个常指针 cons ...

  7. 阿里云申请ssl证书配置tomcat访问https

    首先去阿里云上面申请ssl证书,免费的,自己百度去. 申请完ok之后会让你下载一个压缩包,里面有四个文件. 在tomcat安装目录下创建cert文件夹,把这四个文件扔进去 在conf/server.x ...

  8. Eclipse 中报错的阅读顺序

    1 九月 19, 2018 8:49:53 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefin ...

  9. STM32学习笔记:【003】GPIO

    版本:STM32F429 Hal库v1.10 在STM32中,最常用到的功能莫过于GPIO(General Purpose Input Output .通用输入/输出)了,在STM32中,除了除去AD ...

  10. Android面试基础(一)IOC(DI)框架(ViewUtils)讲解_反射和自定义注解类

    1. Android中的IOC(DI)框架 1.1 ViewUtils简介(xUtils中的四大部分之一) IOC: Inverse of Controller 控制反转. DI: Dependenc ...