Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
家好,我是明說網(wǎng)絡(luò)的小明同學(xué)。今天我們來聊一聊物聯(lián)網(wǎng)通協(xié)議MQTT(Message Queuing Telemetry Transport,消息隊列遙測傳輸協(xié)議)。
故事的開頭,我們從MQ(Message Queue)說起。
什么是MQ
MQ,Message queue,消息隊列,就是指保存消息的一個容器。
消息隊列最原始的模型:生產(chǎn)者先將消息投遞一個叫做「隊列」的容器中,然后再從這個容器中取出消息,最后再轉(zhuǎn)發(fā)給消費者。如下圖所示:
那么問題來了,那么為什么生產(chǎn)者不直接將消息發(fā)送給消費者呢?好處在哪里呢?
消息隊列有什么優(yōu)勢呢?
如下圖所示,本身串行的訂單,會員,消息,推薦系統(tǒng)在MQ的加持下,變成了并行,系統(tǒng)和系統(tǒng)之間只依賴于MQ,而不依賴于各類系統(tǒng)。
參考:https://www.zhihu.com/question/54152397
其實,MQ在其中起到了以緩沖的作用。
MQ 解決的最核心的問題:系統(tǒng)解耦(系統(tǒng)之間不相互依賴)和異步(流程不再串行):
從MQ的角度去理解MQTT
而MQTT是專門針對物聯(lián)網(wǎng)設(shè)計的消息隊列!實際上使用的是MQ其中的發(fā)布/訂閱模式
訂閱什么意思呢?舉個例子,訂報紙。設(shè)想一個場景:你從報亭A訂閱了“人民日報”,那么一旦報亭有了"人民日報”,就會給你發(fā)一份。其實,這個“人民日報”在MQTT中就是topic的角色。
如果熟悉設(shè)計模式的同學(xué),一定會聯(lián)想到觀察者模式,簡直是異曲同工之妙啊。
觀察者模式:當對象間存在一對多關(guān)系時,則使用觀察者模式(Observer Pattern)。比如,當一個對象被修改時,則會自動通知依賴它的對象。觀察者模式屬于行為型模式。
觀察者模式 | 菜鳥教程
MQ與MQTT的區(qū)別
名稱 | 解釋 |
mqtt | 一種通信協(xié)議,類似人類交談中的漢語、英語、俄語中的一種語言規(guī)范 |
MQ | 一種通信通道,也叫消息隊列,類似人類交談中的用電話、email、微信的一種通信方式 |
以上為MQ的背景,下面進入正題。
MQTT簡介
隨著 5G 時代的來臨,萬物互聯(lián)的偉大構(gòu)想正在成為現(xiàn)實。海量的設(shè)備接入和設(shè)備管理對網(wǎng)絡(luò)帶寬、通信協(xié)議以及平臺服務(wù)架構(gòu)都帶來了很大挑戰(zhàn)。尤其對于物聯(lián)網(wǎng)設(shè)備來說,電量消耗,資源控制等都尤為重要。在此背景下MQTT應(yīng)運而生。
MQTT(Message Queuing Telemetry Transport,消息隊列遙測傳輸協(xié)議),是一種基于發(fā)布/訂閱(publish/subscribe)模式的"輕量級"通訊協(xié)議,該協(xié)議構(gòu)建于TCP/IP協(xié)議上,由IBM在1999年發(fā)布(由 IBM 的 Andy Stanford-Clark 和 Arcom 的 Arlen Nipper 為了一個通過衛(wèi)星網(wǎng)絡(luò)連接輸油管道的項目開發(fā),之后 IBM 一直將 MQTT 作為一個內(nèi)部協(xié)議在其產(chǎn)品中使用,直到 2010 年,IBM 公開發(fā)布了 MQTT 3.1 版本。在 2014 年,MQTT 協(xié)議正式成為了 OASIS(結(jié)構(gòu)化信息標準促進組織)的標準協(xié)議,來源)。
MQTT最大優(yōu)點在于,可以以極少的代碼和有限的帶寬,為連接遠程設(shè)備提供實時可靠的消息服務(wù)。作為一種低開銷、低帶寬占用的即時通訊協(xié)議,使其在物聯(lián)網(wǎng)、小型設(shè)備、移動應(yīng)用等方面有較廣泛的應(yīng)用。MQTT 3 (當前版本3.1.1)是目前使用的最為廣泛的 MQTT 協(xié)議標準。
為什么選擇MQTT
它的設(shè)計思想是輕巧、開放、簡單、規(guī)范,易于實現(xiàn)。這些特點使得它對很多場景來說都是很好的選擇,特別是對于受限的環(huán)境如機器與機器的通信(M2M)以及物聯(lián)網(wǎng)環(huán)境(IoT)。
MQTT的應(yīng)用場景
MQTT 協(xié)議廣泛應(yīng)用于物聯(lián)網(wǎng)、移動互聯(lián)網(wǎng)、智能硬件、車聯(lián)網(wǎng)、電力、能源等領(lǐng)域。
相關(guān)參考資料
https://www.emqx.cn/mqtt
https://www.runoob.com/w3cnote/mqtt-intro.html
https://www.jianshu.com/p/ecde412d2eeb
MQTT協(xié)議中文版,https://mcxiaoke.gitbooks.io/mqtt-cn/content/
https://zhuanlan.zhihu.com/p/158145940
MQTT通信模型
有別于傳統(tǒng)的客戶端/服務(wù)器通訊協(xié)議,MQTT協(xié)議并不是端到端的,消息傳遞通過代理,包括會話(session)也不是建立在發(fā)布者和訂閱者之間,而是建立在端和代理之間。代理解除了發(fā)布者和訂閱者之間的耦合。這對理解MQTT很重要
通過下面兩個圖理解MQTT(不愧是MQ)
MQTT中的角色
在MQTT中,有三個主要的角色:
角色 | 解釋 | 類比 |
發(fā)布者(Publish) | 可以是一個應(yīng)用程序或一臺設(shè)備 | 類似于報紙發(fā)布者 |
代理(Broker)(服務(wù)器) | MQTT服務(wù)器以稱為"消息代理"(Broker),可以是一個應(yīng)用程序或一臺設(shè)備。它是位于消息發(fā)布者和訂閱者之間 | 類似于以前的報刊亭,會有很多人向報亭發(fā)布報紙,報停會更具不同的訂閱分發(fā)報紙。 |
訂閱者(Subscribe) | 可以是一個應(yīng)用程序或一臺設(shè)備 | 類似于報紙訂閱者 |
需要注意的是,這里的發(fā)布者和訂閱者并不是絕對的。發(fā)布者可以變成訂閱者,訂閱者也可以變成發(fā)布者,甚至是同一臺設(shè)備既可以是發(fā)布者也可以是訂閱者,甚至是broker。
這是與現(xiàn)實中報亭的例子有些區(qū)別的地方,人們可以訂報紙,同時還能發(fā)報紙,甚至是自己給自己賣報紙!
消息
這三個角色之間通過消息進行通信:MQTT傳輸?shù)南⒎譃椋褐黝}(Topic)和負載(payload)兩部分:
mosquitto使用
Mosquitto是一個實現(xiàn)了MQTT3.1協(xié)議的代理服務(wù)器,由MQTT協(xié)議創(chuàng)始人之一的Andy Stanford-Clark開發(fā)
學(xué)習網(wǎng)址:
libmosquitto編程:https://blog.csdn.net/dancer__sky/article/details/77855249
MQTT的學(xué)習之Mosquitto安裝&使用
MQTT服務(wù)端軟件使用:https://zhuanlan.zhihu.com/p/56727359
安全
MQTT安全篇:為何以及如何運用MQTT提供的安全特性來保證物聯(lián)網(wǎng)項目的順利實施 https://zhuanlan.zhihu.com/p/21421094
篇文章,我們聊聊 Redis 的高級特性之一: 發(fā)布訂閱。
Redis 發(fā)布訂閱 (pub/sub) 是一種消息通信模式:發(fā)送者 (pub) 發(fā)送消息,訂閱者 (sub) 接收消息。
圖中,消費者1和消費者2 訂閱了 Redis 服務(wù)的頻道 channel ,當生產(chǎn)者通過 PUBLISH 命令發(fā)送給頻道 channel 時, 這個消息就會被發(fā)送給訂閱它的兩個客戶端。
下表列出了 Redis 發(fā)布訂閱常用命令:
命令 | 用法 | 描述 |
PSUBSCRIBE | PSUBSCRIBE pattern [pattern ...] | 訂閱一個或多個符合給定模式的頻道 |
PUBSUB | PUBSUB subcommand [argument [argument ...]] | 查看訂閱與發(fā)布系統(tǒng)狀態(tài) |
PUBLISH | PUBLISH channel message | 將信息發(fā)送到指定的頻道 |
PUNSUBSCRIBE | PUNSUBSCRIBE [pattern [pattern ...]] | 退訂所有給定模式的頻道 |
SUBSCRIBE | SUBSCRIBE channel [channel ...] | 訂閱給定的一個或多個頻道的信息 |
UNSUBSCRIBE | UNSUBSCRIBE [channel [channel ...]] | 指退訂給定的頻道 |
我們開啟兩個 redis-cli 客戶端,演示了發(fā)布訂閱是如何工作的。
客戶端 A 執(zhí)行訂閱命令:
subscribe mychannel
訂閱命令執(zhí)行成功后:
客戶端 B 執(zhí)行發(fā)布命令:
publish mychannel helloworld
發(fā)布命令執(zhí)行成功后,客戶端 A 就會接收到新的消息:
每個 Redis 服務(wù)器進程都維持著一個表示服務(wù)器狀態(tài)的 redis.h/redisServer 結(jié)構(gòu), 結(jié)構(gòu)的 pubsub_channels 屬性是一個字典, 這個字典就用于保存訂閱頻道的信息:
struct redisServer {
// ...
dict *pubsub_channels;
// ...
};
其中,字典的鍵為正在被訂閱的頻道, 而字典的值則是一個鏈表, 鏈表中保存了所有訂閱這個頻道的客戶端。
下圖中, client2 、 client5 和 client1 就訂閱了 channel1 , 而其他頻道也分別被別的客戶端所訂閱:
當客戶端調(diào)用 SUBSCRIBE 命令時, 程序就將客戶端和要訂閱的頻道在 pubsub_channels 字典中關(guān)聯(lián)起來。
舉個例子,如果客戶端 client10086 執(zhí)行命令 SUBSCRIBE channel1 channel2 channel3 ,那么前面展示的 pubsub_channels 將變成下面這個樣子:
當調(diào)用 PUBLISH channel message 命令, 程序首先根據(jù) channel 定位到字典的鍵, 然后將信息發(fā)送給字典值鏈表中的所有客戶端。
如果某個客戶端執(zhí)行命令 PUBLISH channel1 "hello moto" ,那么 client2 、 client5 和 client1 三個客戶端都將接收到 "hello moto" 信息:
在使用發(fā)布訂閱功能時,需要理解兩點。
1、保證先讓消費者先訂閱隊列,然后再讓生產(chǎn)者發(fā)布消息。
如果消費者異常掛掉并重新上線,它只能接收新的消息。在其下線期間,生產(chǎn)者發(fā)布的消息將無法被消費者接收,因為找不到該消費者,這些消息會被丟棄。
如果所有消費者都下線,那么生產(chǎn)者發(fā)布的消息將因為沒有任何消費者而全部被丟棄。
2、發(fā)布訂閱不具備數(shù)據(jù)持久化的能力
發(fā)布訂閱相關(guān)的操作不會被寫入到 Redis 數(shù)據(jù)庫(RDB)或追加寫入文件(AOF)中。如果 Redis 宕機并重新啟動,Pub/Sub 的數(shù)據(jù)將會全部丟失。
基于上面的分析,發(fā)布訂閱功能特別適合對少量消息丟失不敏感的通知類型的場景
筆者開源了一個短信服務(wù),為了提升系統(tǒng)性能,應(yīng)用信息存儲在本地內(nèi)存中,定時任務(wù)會每隔30秒重新刷新一次緩存,但在分布式部署的場景下,不同應(yīng)用間的數(shù)據(jù)可能沒有及時同步。
我們可以使用 Redis 的發(fā)布訂閱功能,實現(xiàn)本地內(nèi)存的及時刷新。
1、配置 Redis 頻道監(jiān)聽器容器
2、觸發(fā)發(fā)布消息
當應(yīng)用發(fā)送變化時,比如新增、修改、刪除,則調(diào)用發(fā)送消息到頻道方法。
下圖,當我們啟動兩個應(yīng)用,修改應(yīng)用信息時,我們發(fā)現(xiàn)兩個應(yīng)用的本地內(nèi)存都發(fā)生變化了。
參考資料:
https://redisbook.readthedocs.io/en/latest/feature/pubsub.html
022年9月19日,海關(guān)總署發(fā)布2022年第88號(關(guān)于調(diào)整進口貨物報關(guān)單申報要求的)公告,調(diào)整《中華人民共和國海關(guān)進口貨物報關(guān)單》和《中華人民共和國海關(guān)進境貨物備案清單》有關(guān)項目的填報要求。
1、新增“已實施預(yù)防性消毒”申報項目,該項目為勾選項,包括“是”和“否”兩個選項,進口貨物境內(nèi)收貨人或其報關(guān)單代理人如已開展“預(yù)防性消毒”則選擇“是”,否則選擇“否”。
【注】:根據(jù)《新冠肺炎疫情期間現(xiàn)場消毒評價標準》(WS/T 774-2021)規(guī)定:“預(yù)防性消毒為在沒有明確的傳染源存在時,對可能受到病原微生物污染的場所和物品進行的消毒。”
2、實際進境貨物必須填報“已實施預(yù)防性消毒”和“啟運日期”。
公告原文鏈接:http://www.customs.gov.cn/customs/302249/2480148/4590561/index.html
【關(guān)聯(lián)解讀】:
? 對滿足監(jiān)管要求的進口非冷鏈物品,在申報進口貨物報關(guān)單時,必須填報“啟運日期”和“已實施預(yù)防性消毒”兩個字段。
? 該公告內(nèi)容的調(diào)整不免讓我們聯(lián)想到2022年9月7號單一窗口的更新 :“貨物申報系統(tǒng)新增進口非冷鏈貨物高污染風險通知功能”,即對于海關(guān)綜合研判為存在被新冠病毒污染高風險的進口非冷鏈貨物,貨物申報系統(tǒng)通過首頁通知、高污染風險通知查詢、狀態(tài)查詢、訂閱推送等功能及時告知企業(yè)。
?綜合來看,上述的調(diào)整與2022年7月12日,國務(wù)院應(yīng)對新型冠狀病毒肺炎疫情聯(lián)防聯(lián)控機制綜合組發(fā)布的國衛(wèi)明電[2022]270號(關(guān)于進一步優(yōu)化進口物品新冠肺炎疫情防控工作的通知)的內(nèi)容息息相關(guān)。下面,讓小編帶著大家一起回顧一下關(guān)于進口非冷鏈物品的相關(guān)內(nèi)容。
① 其中“裝載入境物品的航空器、船舶、列車、汽車自離開啟運口岸起超過24小時的進口非冷鏈物品”與本公告的“啟運日期”關(guān)聯(lián)起來。
② “已實施預(yù)防性消毒的進口非冷鏈物品”是不是也與“預(yù)防性消毒”關(guān)聯(lián)起來啦。
【小Tips】:
進口貨物報關(guān)單的這一小調(diào)整是不是讓大家也有些迷茫呢。但還是應(yīng)該注意“如實申報”哦,進口貨物收貨人或其報關(guān)代理人都需要額外關(guān)注哦,如果對于這兩個字段的解讀不確定的,可以試著咨詢相關(guān)海關(guān)哦。
資訊來源:公眾號德正木材物流
*請認真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。