まず、モデル
- P(プロデューサー):メーカー - 送信メッセージ
- Q(キュー):メッセージ・キュー(図赤四角) - 格納されたメッセージ
- C(消費者):消費者は - メッセージを受け取ります
フェア分布(フェアディスパッチ)である消費者1(C1)のRabbitMQの対処を教え、メッセージ受信フィードバックを送信手動で処理さが続くキュー(待ち行列)からのメッセージを、取得した後は終わった、そしてそれは、キューからメッセージを取得します。消費者1(C1)メッセージ処理サービスを取得した後、消費者2(C2)また、フィードバックメッセージの処理の後にキューからメッセージを取得した後はまた、その後、手動でレシートを送信私は完成した処理をRabbitMQの教えてくれるこれは、キューからメッセージを再取得します。2つのコンシューマ(C1&C2)は、短いビジネスは時間消費者を処理するようにすると、よりハンドル以外のメッセージなので、「有能」、作業効率を向上させることができること、処理されたビジネスのニュースを得るために、お互いを待つ必要はありません。
第二に、ノートへの公平な配分(フェア派遣)のポイント
図1に示すように、消費者が1つのプライマリメッセージを受信することを保証するために(Channel.basicQos(1) )。
図2に示すように、手動で消費者フィードバックの公平な分配を使用する必要性は、自動応答(手動に対するACK、特に消費者コードのコメントが反映される)をオフにしなければなりません。
三、Javaプログラミング
1、ジャーを参照し、AMQPプロトコルパケットを導入し、およびツールRabbitMQの接続を作成し、3つの単純なRabbitMQのキュー(単純なキュー)。
図2は、プロデューサによって送信されたメッセージを作成します。
package com.rabbitMQ.workfair;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitMQ.util.ConnectionUtils;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
/**
* 工作对列之公平分发(Fair dispatch)-生产者
* @author zhoujin
* @data 2019-1-17
*/
public class WorkFairProducer {
private static final String QUEUE_NAME = "work_fair_queue";
public static void main(String[] args) {
Connection conn = null;
Channel channel = null;
try {
// 1.获取连接
conn = ConnectionUtils.getConnection();
// 2.从连接中获取通道
channel = conn.createChannel();
// 3.申明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
/*
* 4.限制发送给同一个消费者不得超过一条消息
* 每个消费者发送确认消息之前,消息队列不发送下一条消息至消费者,一次只处理一条消息
*/
channel.basicQos(1);
// 5.发送消息入队列
for (int i = 1; i <= 20; i++) {
String message = "This is fair work queue, 发送第" + i + "条消息!";
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
Thread.sleep(i * 200);
}
System.out.println("======================= Fair work Queue send message end! =======================");
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
try {
ConnectionUtils.closeConnection(channel, conn);
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
}
}
3.作成1は、消費者のメッセージを受信します。
package com.rabbitMQ.workfair;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitMQ.util.ConnectionUtils;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.AMQP.BasicProperties;
/**
* 工作对列之公平分发(Fair dispatch)-消费者1
* @author zhoujin
* @data 2019-1-17
*/
public class WorkFairFirstConsumer {
private static final String QUEUE_NAME = "work_fair_queue";
public static void main(String[] args) {
try {
// 1.获取连接
Connection conn = ConnectionUtils.getConnection();
// 2.从连接中获取通道
final Channel channel = conn.createChannel();
// 3.声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
// 4.保证一次只接受一条消息
channel.basicQos(1);
// 5.创建消费者
DefaultConsumer consumer = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag,
Envelope envelope, BasicProperties properties,
byte[] body) throws IOException {
String message = new String(body, "UTF-8");
System.out.println("======================= The first fair work consumer received a message! 【Content:" + message + "】 =======================");
// 休眠,模拟业务处理
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 6.手动发送反馈回执
channel.basicAck(envelope.getDeliveryTag(), false);
}
}
};
// 7.监听队列(关闭自动应答,即第二个参数设置为false)
channel.basicConsume(QUEUE_NAME, false, consumer);
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
}
作成4. 消費者2がメッセージを受け取ります。
package com.rabbitMQ.workfair;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitMQ.util.ConnectionUtils;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.AMQP.BasicProperties;
/**
* 工作对列之公平分发(Fair dispatch)-消费者2
* @author zhoujin
* @data 2019-1-18
*/
public class WorkFairSecondConsumer {
private static final String QUEUE_NAME = "work_fair_queue";
public static void main(String[] args) {
try {
// 1.获取连接
Connection conn = ConnectionUtils.getConnection();
// 2.从连接中获取通道
final Channel channel = conn.createChannel();
// 3.声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
// 4.保证一次只接受一条消息
channel.basicQos(1);
// 5.创建消费者
DefaultConsumer consumer = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag,
Envelope envelope, BasicProperties properties,
byte[] body) throws IOException {
String message = new String(body, "UTF-8");
System.out.println("======================= The second fair work consumer received a message! 【Content:" + message + "】 =======================");
// 休眠,模拟业务处理
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 6.手动反馈回执
channel.basicAck(envelope.getDeliveryTag(), false);
}
}
};
// 7.监听队列(关闭自动应答,即第二个参数设置为false)
channel.basicConsume(QUEUE_NAME, false, consumer);
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
}
第四に、コードとコンソール出力を実行します
1、2つの、消費者のコードを実行しています。
なぜ消費者は、最初のコードを実行していますか?
最初のスタートの生産者(プロデューサー)場合には、生産者(プロデューサー)、すぐにキュー(待ち行列)内にメッセージを送信します。あなたが最初のコンシューマ(消費者)を起動したときしかし、それは見、もはやニュースではありません別のコンシューマ(消費者)、キュー(待ち行列)の開始につながる、すぐにキュー(待ち行列)のメッセージを始めるだろう現象を受けます。
2、プロデューサーのコードを実行します。
2.1、プロデューサコンソール出力
2.2、最初の消費者コンソール出力
2.3、第二消費者コンソール出力
V.の概要
それは、コンソール出力2つのコンシューマによって分かるように、消費者1(C1)の動作メッセージ9を処理する、長く2秒であり、消費者2(C2)サービス期間は、メッセージ11を処理し、1秒、あります。両方の消費者は長い間ほとんど差ストリップの数は同じ程度のメッセージを処理するので、ビジネスを扱っているので、次の2つの処理事業は、結果を表示するときに長いギャップが大きくなる試すことができます。メッセージ・データの処理中にほとんどであるが、参照コンシューマ2(C2)連続加工品2、3及び5を、回転の6データ取得順序は、メッセージではなく、また、「マイティを反映しますより多くの私たちは、「公正分布(公正派遣を)働きます。