馬桶??Java 上廁所就能看完的小知識! 歡迎關注、點贊 持續更新!
什么是MQ?
? MQ(Message Quene) : 翻譯為 消息隊列,運用生產者和消費者模型,生產者不斷向消息隊列中生產消息,消費者不斷的從隊列中獲取(消費)消息。因為消息的生產和消費都是異步的,而且只關心消息的發送和接收,沒有業務邏輯的侵入,輕松的實現系統間解耦。
MQ種類介紹
# 1.ActiveMQ
ActiveMQ 是Apache出品,最流行的,能力強勁的開源消息總線。它是一個完全支持JMS規范的的消息中間件。豐富的API,多種集群架構模式讓ActiveMQ在業界成為老牌的消息中間件,在中小型企業頗受歡迎!
# 2.Kafka
Kafka是LinkedIn開源的分布式發布-訂閱消息系統,目前歸屬于Apache頂級項目。Kafka主要特點是基于Pull的模式來處理消息消費,追求高吞吐量,一開始的目的就是用于日志收集和傳輸。0.8版本開始支持復制,不支持事務,對消息的重復、丟失、錯誤沒有嚴格要求,適合產生大量數據的互聯網服務的數據收集業務。
# 3.RocketMQ
RocketMQ是阿里開源的消息中間件,它是純Java開發,具有高吞吐量、高可用性、適合大規模分布式系統應用的特點。RocketMQ思路起源于Kafka,但并不是復制kafka,它對消息的可靠傳輸及事務性做了優化,目前在阿里集團被廣泛應用于交易、充值、流計算、消息推送、日志流式處理、binglog分發等場景。
# 4.RabbitMQ
RabbitMQ是使用Erlang語言開發的開源消息隊列系統,基于AMQP協議來實現。AMQP的主要特征是面向消息、隊列、路由(包括點對點和發布/訂閱)、可靠性、安全。AMQP協議更多用在企業系統內對數據一致性、**穩定性和可靠性**要求很高的場景,對性能和吞吐量的要求還在其次。
RabbitMQ比Kafka可靠,Kafka更適合IO高吞吐的處理,一般應用在大數據日志處理或對實時性(少量延遲),可靠性(少量丟數據)要求稍低的場景使用,比如ELK日志收集。
RabbitMQ引言
什么是rabbitMQ?
RabbitMQ是實現了高級消息隊列協議(AMQP)的開源消息代理軟件(亦稱面向消息的中間件)。RabbitMQ服務器是用Erlang語言編寫的,而群集和故障轉移是構建在開放電信平臺框架上的。
官方教程
: https://www.rabbitmq.com/#getstarted
RabbitMQ安裝
RabbitMQ安裝首先要安裝Erlang
安裝地址:https://www.rabbitmq.com/download.html
具體安裝調試請參考。
RabbitMQ界面初識
主界面
登錄管理界面 username: guest password: guest
Connections:連接。無論是生產者和消費者都需要在與RabbitMQ建立連接的情況下完成消息的生產與消費,這里可以查看相應的消費情況。
Channels:通道。建立連接后會形成相應的通道,消息的投遞與獲取都依賴于通道。
Exchanges: 交換機。用于實現消息的路由功能。
Queues:消息隊列。消息存在在消息隊列中等待消費。
用戶
tags為指定用戶
-
超級管理員(administrator)
可登陸管理控制臺,可查看所有的信息,并且可以對用戶,策略(policy)進行操作。
-
監控者(monitoring)
可登陸管理控制臺,同時可以查看rabbitmq節點的相關信息(進程數,內存使用情況,磁盤使用情況等)
-
策略制定者(policymaker)
可登陸管理控制臺, 同時可以對policy進行管理。但無法查看節點的相關信息(上圖紅框標識的部分)。
-
普通管理者(management)
僅可登陸管理控制臺,無法看到節點信息,也無法對策略進行管理。
-
其他
無法登陸管理控制臺,通常就是普通的生產者和消費者。
虛擬機
為了讓各個用戶互相不干預工作,RabbitMQ 添加了虛擬機概念,就是一個獨立的訪問路徑,不同用戶使用不同路徑,各自有自己的隊列、交換機,互相不會影響。
進入相關新創建的虛擬機。
為創建好的虛擬機綁定對應用戶。
RabbitMQ 消息模型
引入依賴
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.7.2</version>
</dependency>
創建工具
public class RabbitMqConnectionUtil {
private static final ConnectionFactory CONNECTION_FACTORY;
private static Connection connection;
static {
//通過連接工廠并設置相應的ip 端口 用戶名密碼 及綁定的虛擬機創建連接
CONNECTION_FACTORY = new ConnectionFactory();
CONNECTION_FACTORY.setHost("127.0.0.1");
CONNECTION_FACTORY.setPort(5672);
CONNECTION_FACTORY.setUsername("test");
CONNECTION_FACTORY.setPassword("test");
CONNECTION_FACTORY.setVirtualHost("/test");
}
public static Connection createConnection() {
try {
connection = CONNECTION_FACTORY.newConnection();
} catch (IOException | TimeoutException e) {
e.printStackTrace();
}
return connection;
}
public static void close(Channel channel, Connection connection) throws IOException, TimeoutException {
channel.close();
connection.close();
}
}
工作隊列
讓多個消費者綁定到一個隊列,共同消費隊列中的消息。隊列中的消息一旦消費,就會消失,因此任務是不會被重復執行的。
在模型中,有以下概念:
- P:生產者,也就是要發送消息的程序
- C:消費者:消息的接受者,會一直等待消息到來。
- queue:消息隊列,圖中紅色部分。類似一個郵箱,可以緩存消息;生產者向其中投遞消息,消費者從其中取出消息。
生產者如下:
public class Producer {
public static void main(String[] args) throws IOException, TimeoutException {
// 獲取連接
Connection connection = RabbitMqConnectionUtil.createConnection();
// 獲取通道
Channel channel = connection.createChannel();
/**
創建隊列
參數如下:
queue - 隊列的名稱
durable - 宣布一個持久的隊列(隊列不受服務器重啟,數據會消失)
exclusive - 宣布獨占隊列(限于此連接)
autoDelete - 一個自動刪除隊列(服務器將刪除它在使用時不再)
參數 - 其它性質(結構參數)隊列
*/
channel.queueDeclare("work", true, false, false, null);
for (int i = 0; i < 10; i++) {
channel.basicPublish("", "work", null, ("work queue message has been sent --"+i).getBytes());
}
RabbitMqConnectionUtil.close(channel,connection);
}
}
消費者獲取消息:
再創建一個Consumer02 代碼相同。
public class Consumer01 {
public static void main(String[] args) throws IOException {
Connection connection = RabbitMqConnectionUtil.createConnection();
Channel channel = connection.createChannel();
channel.queueDeclare("work", true, false, false, null);
// 獲取對應消息 autoAck 自動確認消息 在這里使用的默認消息消費者
channel.basicConsume("work",true,new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println(new String(body));
}
});
}
}
先運行消費者等待消費隊列中數據,在打開生產者生產消息結果如下:
這種形式是公平分配形式,在程序運行時將對應的未確認消息分配給對應的消費者。然后再進行消費。(自動確認消息)
接下來我們切換為手動確認消息,實現類似于能者多勞的分配模式。
未完待續。。。