❶ 消息中間件之RabbitMQ
JMS:java Message Service,java消息服務,是一個消息服務的標准或者說是規范,允許應用程序組件基於JavaEE平台創建、發送、接收和讀取消息。它使分布式通信耦合度更低,消息服務更加可靠以及非同步性。
JMS是java的消息服務,JMS的客戶端之間可以通過JMS服務進行非同步的消息傳輸。
p2p:點對點發送,一個消息只能被消費一次
涉及:
消息隊列(Queue)
發送者(Sender)
接收者(Receiver)
每個消息都被發送到一個特定的隊列,接收者從隊列中獲取消息。隊列保留著信息,直到它們被消費或超時。
示意圖:p2p示意圖
特點:
Pub/Sub:發布訂閱,一個消息可以被消費多次
涉及角色:
主題(Topic)
發布者(Publisher)
訂閱者(Subscriber)
客戶端將消息發送到主題。多個發布者將消息發送到Topic,系統將這些消息傳遞給多個訂閱者。
示意圖:Pub/Sub示意圖
特點:
MQ:消息中間件(MOM:Message Orient middleware),消息隊列
作為系統間通信的必備技術,低耦合、可靠傳輸、流量控制、最終一致性
實現非同步消息通信
Apache下
完全支持Java的JMS協議
消息模式:1、點對點 2、發布訂閱
Erlang語言實現的開源的MQ中間件,支持多種協議
主要的通信協議是AMQP,即Advanced Message Queuing Protocol,高級消息隊列協議,是應用協議的一個開放標准,為面向消息的中間件設計。
Apache下開源項目
高性能分布式消息隊列,一般海量數據傳輸,大數據部門用
單機吞吐量:10w/s
阿里 貢獻給了Apache
參考了Kafka實現基於Java 消息中間件
消息傳輸最快
RabbitMQ是一個開源的AMQP實現,服務端用Erlang語言編寫,支持多種客戶端,如:python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX。用於在分布式系統中存儲轉發消息,在易用性、擴展性、高可用性等方面表現不俗。
消息中間件主要用於組件之間的解耦,消息的發送者無需知道消息使用者的存在。AMQP的主要特徵是面向消息、隊列、路由(包括點對點和發布/訂閱)、可靠性、安全。
涉及角色:
可以基於Docker安裝RabbitMQ,記住其埠:
15672:網頁版可視化伺服器數據
5672:客戶端連接的埠號
點對點消息
一個消息只能消費一次
只需要隊列就可以,不需要交換機
消息發送者和消息接收者者可以不同時在線
RabbitMQ特色就在於Exchange,主要有以下類型:
fanout:只要有消息就轉發給綁定的隊列,不會進行消息的路由判斷
direct:會根據路由匹配規則,將消息發送到指定隊列中,注意路由規則不支持特殊字元
topic:會根據路由匹配規則,將消息發送到指定隊列中,注意路由規則支持特殊字元,比如:* #
❷ python用的第三方庫屬於中間件嗎
是的。
Django中間件是用來處理Django的請求request和響應response的框架級別的鉤子,它是一個輕量,低級別的插件系統,用於全局范圍內改變Django的輸入,輸出,每個中間件組件都負責做一些特定的功能。
❸ 從 0 到 1:全面理解 RPC 遠程調用
作者 | Python編程時光
責編 | 胡巍巍
什麼是RPC呢?網路給出的解釋是這樣的:「RPC(Remote Procere Call Protocol)——遠程過程調用協議,它是一種通過網路從遠程計算機程序上請求服務,而不需要了解底層網路技術的協議」。
這個概念聽起來還是比較抽象,沒關系,繼續往後看,後面概念性的東西,我會講得足夠清楚,讓你完全掌握 RPC 的基礎內容。
在 OpenStack 里的進程間通信方式主要有兩種,一種是基於HTTP協議的RESTFul API方式,另一種則是RPC調用。
那麼這兩種方式在應用場景上有何區別呢?
有使用經驗的人,就會知道:
首先,給你提兩個問題,帶著這兩個問題再往下看:
1、RPC 和 REST 區別是什麼?2、為什麼要採用RPC呢?
首先,第一個問題:RPC 和 REST 區別是什麼?
你一定會覺得這個問題很奇怪,是的,包括我,但是你在網路上一搜,會發現類似對比的文章比比皆是,我在想可能很多初學者由於基礎不牢固,才會將不相乾的二者拿出來對比吧。既然是這樣,那為了讓你更加了解陌生的RPC,就從你熟悉得不能再熟悉的 REST 入手吧。
01、所屬類別不同
REST,是Representational State Transfer 的簡寫,中文描述表述性狀態傳遞(是指某個瞬間狀態的資源數據的快照,包括資源數據的內容、表述格式(XML、JSON)等信息。)
REST 是一種軟體架構風格。這種風格的典型應用,就是HTTP。其因為簡單、擴展性強的特點而廣受開發者的青睞。
而RPC 呢,是 Remote Procere Call Protocol 的簡寫,中文描述是遠程過程調用,它可以實現客戶端像調用本地服務(方法)一樣調用伺服器的服務(方法)。
而 RPC 可以基於 TCP/UDP,也可以基於 HTTP 協議進行傳輸的,按理說它和REST不是一個層面意義上的東西,不應該放在一起討論,但是誰讓REST這么流行呢,它是目前最流行的一套互聯網應用程序的API設計標准,某種意義下,我們說 REST 可以其實就是指代 HTTP 協議。
02、使用方式不同
03、面向對象不同
從設計上來看,RPC,所謂的遠程過程調用 ,是面向方法的 ,REST:所謂的 Representational state transfer ,是面向資源的,除此之外,還有一種叫做 SOA,所謂的面向服務的架構,它是面向消息的,這個接觸不多,就不多說了。
04、序列化協議不同
介面調用通常包含兩個部分,序列化和通信協議。
通信協議,上面已經提及了,REST 是 基於 HTTP 協議,而 RPC 可以基於 TCP/UDP,也可以基於 HTTP 協議進行傳輸的。
常見的序列化協議,有:json、xml、hession、protobuf、thrift、text、bytes等,REST 通常使用的是 JSON或者XML,而 RPC 使用的是 JSON-RPC,或者 XML-RPC。
通過以上幾點,我們知道了 REST 和 RPC 之間有很明顯的差異。
然後第二個問題:為什麼要採用RPC呢?
那到底為何要使用 RPC,單純的依靠RESTful API不可以嗎?為什麼要搞這么多復雜的協議,渣渣表示真的學不過來了。
關於這一點,以下幾點僅是我的個人猜想,僅供交流哈:
說了這么多,我們該如何選擇這兩者呢?我總結了如下兩點,供你參考:
「遠程調用」意思就是:被調用方法的具體實現不在程序運行本地,而是在別的某個地方(分布到各個伺服器),調用者只想要函數運算的結果,卻不需要實現函數的具體細節。
光說不練嘴把式,接下來,我將分別用三種不同的方式全面地讓你搞明白 rpc 遠程調用是如何實現的。
01、基於 xml-rpc
Python實現 rpc,可以使用標准庫里的 SimpleXMLRPCServer,它是基於XML-RPC 協議的。
有了這個模塊,開啟一個 rpc server,就變得相當簡單了。執行以下代碼:
有了 rpc server,接下來就是 rpc client,由於我們上面使用的是 XML-RPC,所以 rpc clinet 需要使用xmlrpclib 這個庫。
然後,我們通過 server_proxy 對象就可以遠程調用之前的rpc server的函數了。
SimpleXMLRPCServer是一個單線程的伺服器。這意味著,如果幾個客戶端同時發出多個請求,其它的請求就必須等待第一個請求完成以後才能繼續。
若非要使用 SimpleXMLRPCServer 實現多線程並發,其實也不難。只要將代碼改成如下即可。
02、基於json-rpc
SimpleXMLRPCServer 是基於 xml-rpc 實現的遠程調用,上面我們也提到 除了 xml-rpc 之外,還有 json-rpc 協議。
那 python 如何實現基於 json-rpc 協議呢?
答案是很多,很多web框架其自身都自己實現了json-rpc,但我們要獨立這些框架之外,要尋求一種較為干凈的解決方案,我查找到的選擇有兩種
第一種是 jsonrpclib
第二種是 python-jsonrpc
先來看第一種 jsonrpclib
它與 Python 標准庫的 SimpleXMLRPCServer 很類似(因為它的類名就叫做 SimpleJSONRPCServer ,不明真相的人真以為它們是親兄弟)。或許可以說,jsonrpclib 就是仿照 SimpleXMLRPCServer 標准庫來進行編寫的。
它的導入與 SimpleXMLRPCServer 略有不同,因為SimpleJSONRPCServer分布在jsonrpclib庫中。
服務端
客戶端
再來看第二種python-jsonrpc,寫起來貌似有些復雜。
服務端
客戶端
調用過程如下
還記得上面我提到過的 zabbix API,因為我有接觸過,所以也拎出來講講。zabbix API 也是基於 json-rpc 2.0協議實現的。
因為內容較多,這里只帶大家打個,zabbix 是如何調用的:直接指明要調用 zabbix server 的哪個方法,要傳給這個方法的參數有哪些。
03、基於 zerorpc
以上介紹的兩種rpc遠程調用方式,如果你足夠細心,可以發現他們都是http+rpc 兩種協議結合實現的。
接下來,我們要介紹的這種(zerorpc),就不再使用走 http 了。
zerorpc 這個第三方庫,它是基於TCP協議、 ZeroMQ 和 MessagePack的,速度相對快,響應時間短,並發高。zerorpc 和 pyjsonrpc 一樣,需要額外安裝,雖然SimpleXMLRPCServer不需要額外安裝,但是SimpleXMLRPCServer性能相對差一些。
調用過程如下
客戶端除了可以使用zerorpc框架實現代碼調用之外,它還支持使用「命令行」的方式調用。
客戶端可以使用命令行,那服務端是不是也可以呢?
是的,通過 Github 上的文檔幾個 demo 可以體驗到這個第三方庫做真的是優秀。
比如我們可以用下面這個命令,創建一個rpc server,後面這個 time Python 標准庫中的 time 模塊,zerorpc 會將 time 注冊綁定以供client調用。
經過了上面的學習,我們已經學會了如何使用多種方式實現rpc遠程調用。
通過對比,zerorpc 可以說是脫穎而出,一支獨秀。
為此,我也做了一番思考:
OpenStack 組件繁多,在一個較大的集群內部每個組件內部通過rpc通信頻繁,如果都採用rpc直連調用的方式,連接數會非常地多,開銷大,若有些 server 是單線程的模式,超時會非常的嚴重。
OpenStack 是復雜的分布式集群架構,會有多個 rpc server 同時工作,假設有 server01,server02,server03 三個server,當 rpc client 要發出rpc請求時,發給哪個好呢?這是問題一。
你可能會說輪循或者隨機,這樣對大家都公平。這樣的話還會引出另一個問題,倘若請求剛好發到server01,而server01剛好不湊巧,可能由於機器或者其他因為導致服務沒在工作,那這個rpc消息可就直接失敗了呀。要知道做為一個集群,高可用是基本要求,如果出現剛剛那樣的情況其實是很尷尬的。這是問題二。
集群有可能根據實際需要擴充節點數量,如果使用直接調用,耦合度太高,不利於部署和生產。這是問題三。
引入消息中間件,可以很好的解決這些問題。
解決問題一:消息只有一份,接收者由AMQP的負載演算法決定,默認為在所有Receiver中均勻發送(round robin)。
解決問題二:有了消息中間件做緩沖站,client 可以任性隨意的發,server 都掛掉了?沒有關系,等 server 正常工作後,自己來消息中間件取就行了。
解決問題三:無論有多少節點,它們只要認識消息中間件這一個中介就足夠了。
既然講到了消息隊列,如果你之前沒有接觸過這塊內容,最好花幾分鍾的時間跟我好好過下關於消息隊列的幾個基礎概念。
首先,RPC只是定義了一個通信介面,其底層的實現可以各不相同,可以是 socket,也可以是今天要講的 AMQP。
AMQP(Advanced Message Queuing Protocol)是一種基於隊列的可靠消息服務協議,作為一種通信協議,AMQP同樣存在多個實現,如Apache Qpid,RabbitMQ等。
以下是 AMQP 中的幾個必知的概念:
Publisher:消息發布者
Queue:用來保存消息的存儲空間,消息沒有被receiver前,保存在隊列中。
Exchange:用來接收Publisher發出的消息,根據Routing key 轉發消息到對應的Message Queue中,至於轉到哪個隊列里,這個路由演算法又由exchange type決定的。
Exchange type:主要四種描述exchange的類型。
direct:消息路由到滿足此條件的隊列中(queue,可以有多個):routing key = binding key
topic:消息路由到滿足此條件的隊列中(queue,可以有多個):routing key 匹配 binding pattern. binding pattern是類似正則表達式的字元串,可以滿足復雜的路由條件。
fanout:消息路由到多有綁定到該exchange的隊列中。
binding :binding是用來描述exchange和queue之間的關系的概念,一個exchang可以綁定多個隊列,這些關系由binding建立。前面說的binding key /binding pattern也是在binding中給出。
為了讓你明白這幾者的關系,我畫了一張模型圖。
關於AMQP,有幾下幾點值得注意:
前面鋪墊了那麼久,終於到了講真實應用的場景。在生產中RPC是如何應用的呢?
其他模型我不太清楚,在 OpenStack 中的應用模型是這樣的
至於為什麼要如此設計,前面我已經給出了自己的觀點。
接下來,就是源碼解讀 OpenStack ,看看其是如何通過rpc進行遠程調用的。如若你對此沒有興趣(我知道很多人對此都沒有興趣,所以不浪費大家時間),可以直接跳過這一節,進入下一節。
目前Openstack中有兩種RPC實現,一種是在oslo messaging,一種是在openstack.common.rpc。
openstack.common.rpc是舊的實現,oslo messaging是對openstack.common.rpc的重構。openstack.common.rpc在每個項目中都存在一份拷貝,oslo messaging即將這些公共代碼抽取出來,形成一個新的項目。oslo messaging也對RPC API 進行了重新設計,對多種 transport 做了進一步封裝,底層也是用到了kombu這個AMQP庫。(註:Kombu 是Python中的messaging庫。Kombu旨在通過為AMQ協議提供慣用的高級介面,使Python中的消息傳遞盡可能簡單,並為常見的消息傳遞問題提供經過驗證和測試的解決方案。)
關於oslo_messaging庫,主要提供了兩種獨立的API:
因為 notify 實現是太簡單了,所以這里我就不多說了,如果有人想要看這方面內容,可以收藏我的博客(http://python-online.cn) ,我會更新補充 notify 的內容。
OpenStack RPC 模塊提供了 rpc.call,rpc.cast, rpc.fanout_cast 三種 RPC 調用方法,發送和接收 RPC 請求。
rpc.call 和 .rpc.cast 從實現代碼上看,他們的區別很小,就是call調用時候會帶有wait_for_reply=True參數,而cast不帶。
要了解 rpc 的調用機制呢,首先要知道 oslo_messaging 的幾個概念主要方法有四個:
transport:RPC功能的底層實現方法,這里是rabbitmq的消息隊列的訪問路徑
transport 就是定義你如何訪連接消息中間件,比如你使用的是 Rabbitmq,那在 nova.conf中應該有一行transport_url的配置,可以很清楚地看出指定了 rabbitmq 為消息中間件,並配置了連接rabbitmq的user,passwd,主機,埠。
target用來表述 RPC 伺服器監聽topic,server名稱和server監聽的exchange,是否廣播fanout。
rpc server 要獲取消息,需要定義target,就像一個門牌號一樣。
rpc client 要發送消息,也需要有target,說明消息要發到哪去。
endpoints:是可供別人遠程調用的對象
RPC伺服器暴露出endpoint,每個 endpoint 包涵一系列的可被遠程客戶端通過 transport 調用的方法。直觀理解,可以參考nova-conctor創建rpc server的代碼,這邊的endpoints就是 nova/manager.py:ConctorManager
dispatcher:分發器,這是 rpc server 才有的概念
只有通過它 server 端才知道接收到的rpc請求,要交給誰處理,怎麼處理?
在client端,是這樣指定要調用哪個方法的。
而在server端,是如何知道要執行這個方法的呢?這就是dispatcher 要乾的事,它從 endpoint 里找到這個方法,然後執行,最後返回。
Serializer:在 python 對象和message(notification) 之間數據做序列化或是反序列化的基類。
主要方法有四個:
每個notification listener都和一個executor綁定,來控制收到的notification如何分配。默認情況下,使用的是blocking executor(具體特性參加executor一節)
模仿是一種很高效的學習方法,我這里根據 OpenStack 的調用方式,抽取出核心內容,寫成一個簡單的 demo,有對 OpenStack 感興趣的可以了解一下,大部分人也可以直接跳過這章節。
注意以下代碼不能直接運行,你還需要配置 rabbitmq 的連接方式,你可以寫在配置文件中,通過 get_transport 從cfg.CONF 中讀取,也可以直接將其寫成url的格式做成參數,傳給 get_transport 。而且還要nova或者其他openstack組件的環境中運行(因為需要有ctxt這個環境變數)
簡單的 rpc client
簡單的 rpc server
【End】
熱 文 推 薦
☞Facebook 發幣 Libra;谷歌十億美金為窮人造房;第四代樹莓派 Raspberry Pi 4 發布 | 開發者周刊
☞WebRTC 將一統實時音視頻天下?
☞小米崔寶秋:小米 AIoT 深度擁抱開源
☞華為在美研發機構 Futurewei 意欲分家?
☞老司機教你如何寫出沒人敢維護的代碼!
☞Python有哪些技術上的優點?比其他語言好在哪兒?
☞上不了北大「圖靈」、清華「姚班」,AI專業還能去哪上?
☞公鏈史記 | 從鴻蒙初辟到萬物生長的十年激盪……
☞邊緣計算容器化是否有必要?
☞馬雲曾經偶像,終於把阿里留下的1400億敗光了!
你點的每個「在看」,我都認真當成了喜歡
❹ 消息中間件(一)MQ詳解及四大MQ比較
一、消息中間件相關知識
1、概述
消息隊列已經逐漸成為企業IT系統內部通信的核心手段。它具有低耦合、可靠投遞、廣播、流量控制、最終一致性等一系列功能,成為非同步RPC的主要手段之一。當今市面上有很多主流的消息中間件,如老牌的ActiveMQ、RabbitMQ,炙手可熱的Kafka,阿里巴巴自主開發RocketMQ等。
2、消息中間件的組成
2.1 Broker
消息伺服器,作為server提供消息核心服務
2.2 Procer
消息生產者,業務的發起方,負責生產消息傳輸給broker,
2.3 Consumer
消息消費者,業務的處理方,負責從broker獲取消息並進行業務邏輯處理
2.4 Topic
2.5 Queue
2.6 Message
消息體,根據不同通信協議定義的固定格式進行編碼的數據包,來封裝業務數據,實現消息的傳輸
3 消息中間件模式分類
3.1 點對點
PTP點對點:使用queue作為通信載體
說明:
消息生產者生產消息發送到queue中,然後消息消費者從queue中取出並且消費消息。
消息被消費以後,queue中不再存儲,所以消息消費者不可能消費到已經被消費的消息。 Queue支持存在多個消費者,但是對一個消息而言,只會有一個消費者可以消費。
說明:
queue實現了負載均衡,將procer生產的消息發送到消息隊列中,由多個消費者消費。但一個消息只能被一個消費者接受,當沒有消費者可用時,這個消息會被保存直到有一個可用的消費者。
4 消息中間件的優勢
4.1 系統解耦
交互系統之間沒有直接的調用關系,只是通過消息傳輸,故系統侵入性不強,耦合度低。
4.2 提高系統響應時間
例如原來的一套邏輯,完成支付可能涉及先修改訂單狀態、計算會員積分、通知物流配送幾個邏輯才能完成;通過MQ架構設計,就可將緊急重要(需要立刻響應)的業務放到該調用方法中,響應要求不高的使用消息隊列,放到MQ隊列中,供消費者處理。
4.3 為大數據處理架構提供服務
通過消息作為整合,大數據的背景下,消息隊列還與實時處理架構整合,為數據處理提供性能支持。
4.4 Java消息服務——JMS
Java消息服務(Java Message Service,JMS)應用程序介面是一個Java平台中關於面向消息中間件(MOM)的API,用於在兩個應用程序之間,或分布式系統中發送消息,進行非同步通信。
5 消息中間件應用場景
5.1 非同步通信
有些業務不想也不需要立即處理消息。消息隊列提供了非同步處理機制,允許用戶把一個消息放入隊列,但並不立即處理它。想向隊列中放入多少消息就放多少,然後在需要的時候再去處理它們。
5.2 解耦
降低工程間的強依賴程度,針對異構系統進行適配。在項目啟動之初來預測將來項目會碰到什麼需求,是極其困難的。通過消息系統在處理過程中間插入了一個隱含的、基於數據的介面層,兩邊的處理過程都要實現這一介面,當應用發生變化時,可以獨立的擴展或修改兩邊的處理過程,只要確保它們遵守同樣的介面約束。
5.3 冗餘
有些情況下,處理數據的過程會失敗。除非數據被持久化,否則將造成丟失。消息隊列把數據進行持久化直到它們已經被完全處理,通過這一方式規避了數據丟失風險。許多消息隊列所採用的」插入-獲取-刪除」範式中,在把一個消息從隊列中刪除之前,需要你的處理系統明確的指出該消息已經被處理完畢,從而確保你的數據被安全的保存直到你使用完畢。
5.4 擴展性
因為消息隊列解耦了你的處理過程,所以增大消息入隊和處理的頻率是很容易的,只要另外增加處理過程即可。不需要改變代碼、不需要調節參數。便於分布式擴容。
5.5 過載保護
在訪問量劇增的情況下,應用仍然需要繼續發揮作用,但是這樣的突發流量無法提取預知;如果以為了能處理這類瞬間峰值訪問為標准來投入資源隨時待命無疑是巨大的浪費。使用消息隊列能夠使關鍵組件頂住突發的訪問壓力,而不會因為突發的超負荷的請求而完全崩潰。
5.6 可恢復性
系統的一部分組件失效時,不會影響到整個系統。消息隊列降低了進程間的耦合度,所以即使一個處理消息的進程掛掉,加入隊列中的消息仍然可以在系統恢復後被處理。
5.7 順序保證
在大多使用場景下,數據處理的順序都很重要。大部分消息隊列本來就是排序的,並且能保證數據會按照特定的順序來處理。
5.8 緩沖
在任何重要的系統中,都會有需要不同的處理時間的元素。消息隊列通過一個緩沖層來幫助任務最高效率的執行,該緩沖有助於控制和優化數據流經過系統的速度。以調節系統響應時間。
5.9 數據流處理
分布式系統產生的海量數據流,如:業務日誌、監控數據、用戶行為等,針對這些數據流進行實時或批量採集匯總,然後進行大數據分析是當前互聯網的必備技術,通過消息隊列完成此類數據收集是最好的選擇。
6 消息中間件常用協議
6.1 AMQP協議
AMQP即Advanced Message Queuing Protocol,一個提供統一消息服務的應用層標准高級消息隊列協議,是應用層協議的一個開放標准,為面向消息的中間件設計。基於此協議的客戶端與消息中間件可傳遞消息,並不受客戶端/中間件不同產品,不同開發語言等條件的限制。
優點:可靠、通用
6.2 MQTT協議
MQTT(Message Queuing Telemetry Transport,消息隊列遙測傳輸)是IBM開發的一個即時通訊協議,有可能成為物聯網的重要組成部分。該協議支持所有平台,幾乎可以把所有聯網物品和外部連接起來,被用來當做感測器和致動器(比如通過Twitter讓房屋聯網)的通信協議。
優點:格式簡潔、佔用帶寬小、移動端通信、PUSH、嵌入式系統
6.3 STOMP協議
STOMP(Streaming Text Orientated Message Protocol)是流文本定向消息協議,是一種為MOM(Message Oriented Middleware,面向消息的中間件)設計的簡單文本協議。STOMP提供一個可互操作的連接格式,允許客戶端與任意STOMP消息代理(Broker)進行交互。
優點:命令模式(非topicqueue模式)
6.4 XMPP協議
XMPP(可擴展消息處理現場協議,Extensible Messaging and Presence Protocol)是基於可擴展標記語言(XML)的協議,多用於即時消息(IM)以及在線現場探測。適用於伺服器之間的准即時操作。核心是基於XML流傳輸,這個協議可能最終允許網際網路用戶向網際網路上的其他任何人發送即時消息,即使其操作系統和瀏覽器不同。
優點:通用公開、兼容性強、可擴展、安全性高,但XML編碼格式佔用帶寬大
6.5 其他基於TCP/IP自定義的協議
有些特殊框架(如:redis、kafka、zeroMq等)根據自身需要未嚴格遵循MQ規范,而是基於TCPIP自行封裝了一套協議,通過網路socket介面進行傳輸,實現了MQ的功能。
7 常見消息中間件MQ介紹
7.1 RocketMQ
阿里系下開源的一款分布式、隊列模型的消息中間件,原名Metaq,3.0版本名稱改為RocketMQ,是阿里參照kafka設計思想使用java實現的一套mq。同時將阿里系內部多款mq產品(Notify、metaq)進行整合,只維護核心功能,去除了所有其他運行時依賴,保證核心功能最簡化,在此基礎上配合阿里上述其他開源產品實現不同場景下mq的架構,目前主要多用於訂單交易系統。
具有以下特點:
官方提供了一些不同於kafka的對比差異:
https://rocketmq.apache.org/docs/motivation/
7.2 RabbitMQ
使用Erlang編寫的一個開源的消息隊列,本身支持很多的協議:AMQP,XMPP, SMTP,STOMP,也正是如此,使的它變的非常重量級,更適合於企業級的開發。同時實現了Broker架構,核心思想是生產者不會將消息直接發送給隊列,消息在發送給客戶端時先在中心隊列排隊。對路由(Routing),負載均衡(Load balance)、數據持久化都有很好的支持。多用於進行企業級的ESB整合。
7.3 ActiveMQ
Apache下的一個子項目。使用Java完全支持JMS1.1和J2EE 1.4規范的 JMS Provider實現,少量代碼就可以高效地實現高級應用場景。可插拔的傳輸協議支持,比如:in-VM, TCP, SSL, NIO, UDP, multicast, JGroups and JXTA transports。RabbitMQ、ZeroMQ、ActiveMQ均支持常用的多種語言客戶端 C++、Java、.Net,、Python、 Php、 Ruby等。
7.4 Redis
使用C語言開發的一個Key-Value的NoSQL資料庫,開發維護很活躍,雖然它是一個Key-Value資料庫存儲系統,但它本身支持MQ功能,所以完全可以當做一個輕量級的隊列服務來使用。對於RabbitMQ和Redis的入隊和出隊操作,各執行100萬次,每10萬次記錄一次執行時間。測試數據分為128Bytes、512Bytes、1K和10K四個不同大小的數據。實驗表明:入隊時,當數據比較小時Redis的性能要高於RabbitMQ,而如果數據大小超過了10K,Redis則慢的無法忍受;出隊時,無論數據大小,Redis都表現出非常好的性能,而RabbitMQ的出隊性能則遠低於Redis。
7.5 Kafka
Apache下的一個子項目,使用scala實現的一個高性能分布式Publish/Subscribe消息隊列系統,具有以下特性:
7.6 ZeroMQ
號稱最快的消息隊列系統,專門為高吞吐量/低延遲的場景開發,在金融界的應用中經常使用,偏重於實時數據通信場景。ZMQ能夠實現RabbitMQ不擅長的高級/復雜的隊列,但是開發人員需要自己組合多種技術框架,開發成本高。因此ZeroMQ具有一個獨特的非中間件的模式,更像一個socket library,你不需要安裝和運行一個消息伺服器或中間件,因為你的應用程序本身就是使用ZeroMQ API完成邏輯服務的角色。但是ZeroMQ僅提供非持久性的隊列,如果down機,數據將會丟失。如:Twitter的Storm中使用ZeroMQ作為數據流的傳輸。
ZeroMQ套接字是與傳輸層無關的:ZeroMQ套接字對所有傳輸層協議定義了統一的API介面。默認支持 進程內(inproc) ,進程間(IPC) ,多播,TCP協議,在不同的協議之間切換只要簡單的改變連接字元串的前綴。可以在任何時候以最小的代價從進程間的本地通信切換到分布式下的TCP通信。ZeroMQ在背後處理連接建立,斷開和重連邏輯。
特性:
二、主要消息中間件的比較
❺ 關於activemq的python客戶端
指點就做不到了。不過5年前用過,挺穩定的,速度也好。 它有現成的API,你只需要將樣例拿過來改一改就可以用了。
中間件這概念似乎是很古老的東西了,你能用中間件,說明你基礎很好,這個應該不是問題。
❻ python後端開發需要學什麼
第一階段:Python語言基礎
主要學習Python最基礎知識,如Python3、數據類型、字元串、函數、類、文件操作等。階段課程結束後,學員需要完成Pygame實戰飛機大戰、2048等項目。
第二階段:Python語言高級
主要學習Python庫、正則表達式、進程線程、爬蟲、遍歷以及MySQL資料庫。
第三階段:Pythonweb開發
主要學習HTML、CSS、JavaScript、jQuery等前端知識,掌握python三大後端框架(Django、 Flask以及Tornado)。需要完成網頁界面設計實戰;能獨立開發網站。
第四階段:linux基礎
主要學習Linux相關的各種命令,如文件處理命令、壓縮解壓命令、許可權管理以及Linux Shell開發等。
第五階段:Linux運維自動化開發
主要學習Python開發Linux運維、Linux運維報警工具開發、Linux運維報警安全審計開發、Linux業務質量報表工具開發、Kali安全檢測工具檢測以及Kali 密碼破解實戰。
第六階段:Python爬蟲
主要學習python爬蟲技術,掌握多線程爬蟲技術,分布式爬蟲技術。
第七階段:Python數據分析和大數據
主要學習numpy數據處理、pandas數據分析、matplotlib數據可視化、scipy數據統計分析以及python 金融數據分析;Hadoop HDFS、python Hadoop MapRece、python Spark core、python Spark SQL以及python Spark MLlib。
第八階段:Python機器學習
主要學習KNN演算法、線性回歸、邏輯斯蒂回歸演算法、決策樹演算法、樸素貝葉斯演算法、支持向量機以及聚類k-means演算法。
關於python後端開發需要學什麼的內容,青藤小編就和您分享到這里了。如果您對python編程有濃厚的興趣,希望這篇文章可以為您提供幫助。如果您還想了解更多關於python編程的技巧及素材等內容,可以點擊本站的其他文章進行學習。
❼ 用Python操作nanomsg(一)——准備
日前因工作需要,整在一點一點熟悉開源跨平台消息中間件: nanomsg ,恰逢最近安裝了 Typora 用於練習Markdown語法,那就一並把學習總結整理記錄下來並同步更新到方便他人和自己日後回看。
nnpy是其中一個對nanomsg的python wrapper,相比於nanomsg-python日漸缺少維護,更推薦使用nnpy。另外,現在也有了nng(nanomsg next negeration),當nanomsg使用熟練後可考慮轉nng。
本文基於Pyhton3.7,當前nnpy的最新版本為 1.4.2 ,依次安裝cmake、nanomsg、cffi和nnpy:
這里使用的開發環境為 Jetbrains Pycharm 2019 + WSL ,WSL使用的是Kali-Linux,其他版本如Ubuntu、Debian等也都可以。
我本機裝的是Python 3.6,點擊右下角當前正在使用的本地解析器名稱 Python 3.6 ,選擇 Add Interpreter
從左側選擇 WSL 後,右側面板自動出來當前的WSL發行版本,注意的是這里默認的解析器路徑為/usr/bin/python,Kali-Linux默認安裝的時候只有python3沒有python,需要手動改為 /usr/bin/python3
而後點擊 OK 完成WSL Interpreter的添加,在右下角選擇 3.7@Kali Linux 即可啟用WSL作為遠程開發環境——不需要SSH、虛擬機或VPS就能在Windows下進行Linux開發,簡直不要太舒服!!
nanomsg提供了如下幾種通信模式,太具體的不介紹,說完會用就明白是怎麼回事兒了:
PipeLine :
PushPub :
Pair :
ReqRep :
Survey :
Bus :
關於各通信模式的驗證請前往本系列後續文章:
❽ 如何用 Python 構建一個簡單的分布式系統
分布式爬蟲概覽
何謂分布式爬蟲?
通俗的講,分布式爬蟲就是多台機器多個
spider
對多個
url
的同時處理問題,分布式的方式可以極大提高程序的抓取效率。
構建分布式爬蟲通暢需要考慮的問題
(1)如何能保證多台機器同時抓取同一個URL?
(2)如果某個節點掛掉,會不會影響其它節點,任務如何繼續?
(3)既然是分布式,如何保證架構的可伸縮性和可擴展性?不同優先順序的抓取任務如何進行資源分配和調度?
基於上述問題,我選擇使用celery作為分布式任務調度工具,是分布式爬蟲中任務和資源調度的核心模塊。它會把所有任務都通過消息隊列發送給各個分布式節點進行執行,所以可以很好的保證url不會被重復抓取;它在檢測到worker掛掉的情況下,會嘗試向其他的worker重新發送這個任務信息,這樣第二個問題也可以得到解決;celery自帶任務路由,我們可以根據實際情況在不同的節點上運行不同的抓取任務(在實戰篇我會講到)。本文主要就是帶大家了解一下celery的方方面面(有celery相關經驗的同學和大牛可以直接跳過了)
Celery知識儲備
celery基礎講解
按celery官網的介紹來說
Celery
是一個簡單、靈活且可靠的,處理大量消息的分布式系統,並且提供維護這樣一個系統的必需工具。它是一個專注於實時處理的任務隊列,同時也支持任務調度。
下面幾個關於celery的核心知識點
broker:翻譯過來叫做中間人。它是一個消息傳輸的中間件,可以理解為一個郵箱。每當應用程序調用celery的非同步任務的時候,會向broker傳遞消息,而後celery的worker將會取到消息,執行相應程序。這其實就是消費者和生產者之間的橋梁。
backend:
通常程序發送的消息,發完就完了,可能都不知道對方時候接受了。為此,celery實現了一個backend,用於存儲這些消息以及celery執行的一些消息和結果。
worker:
Celery類的實例,作用就是執行各種任務。注意在celery3.1.25後windows是不支持celery
worker的!
procer:
發送任務,將其傳遞給broker
beat:
celery實現的定時任務。可以將其理解為一個procer,因為它也是通過網路調用定時將任務發送給worker執行。注意在windows上celery是不支持定時任務的!
下面是關於celery的架構示意圖,結合上面文字的話應該會更好理解
由於celery只是任務隊列,而不是真正意義上的消息隊列,它自身不具有存儲數據的功能,所以broker和backend需要通過第三方工具來存儲信息,celery官方推薦的是
RabbitMQ和Redis,另外mongodb等也可以作為broker或者backend,可能不會很穩定,我們這里選擇Redis作為broker兼backend。
實際例子
先安裝celery
pip
install
celery
我們以官網給出的例子來做說明,並對其進行擴展。首先在項目根目錄下,這里我新建一個項目叫做celerystudy,然後切換到該項目目錄下,新建文件tasks.py,然後在其中輸入下面代碼
這里我詳細講一下代碼:我們先通過app=Celery()來實例化一個celery對象,在這個過程中,我們指定了它的broker,是redis的db
2,也指定了它的backend,是redis的db3,
broker和backend的連接形式大概是這樣
redis://:password@hostname:port/db_number
然後定義了一個add函數,重點是@app.task,它的作用在我看來就是將add()
注冊為一個類似服務的東西,本來只能通過本地調用的函數被它裝飾後,就可以通過網路來調用。這個tasks.py中的app就是一個worker。它可以有很多任務,比如這里的任務函數add。我們再通過在命令行切換到項目根目錄,執行
celery
-A
tasks
worker
-l
info
啟動成功後就是下圖所示的樣子
這里我說一下各個參數的意思,-A指定的是app(即Celery實例)所在的文件模塊,我們的app是放在tasks.py中,所以這里是
tasks;worker表示當前以worker的方式運行,難道還有別的方式?對的,比如運行定時任務就不用指定worker這個關鍵字;
-l
info表示該worker節點的日誌等級是info,更多關於啟動worker的參數(比如-c、-Q等常用的)請使用
celery
worker
--help
進行查看
將worker啟動起來後,我們就可以通過網路來調用add函數了。我們在後面的分布式爬蟲構建中也是採用這種方式分發和消費url的。在命令行先切換到項目根目錄,然後打開python交互端
from
tasks
import
addrs
=
add.delay(2,
2)
這里的add.delay就是通過網路調用將任務發送給add所在的worker執行,這個時候我們可以在worker的界面看到接收的任務和計算的結果。
這里是非同步調用,如果我們需要返回的結果,那麼要等rs的ready狀態true才行。這里add看不出效果,不過試想一下,如果我們是調用的比較占時間的io任務,那麼非同步任務就比較有價值了
上面講的是從Python交互終端中調用add函數,如果我們要從另外一個py文件調用呢?除了通過import然後add.delay()這種方式,我們還可以通過send_task()這種方式,我們在項目根目錄另外新建一個py文件叫做
excute_tasks.py,在其中寫下如下的代碼
from
tasks
import
addif
__name__
==
'__main__':
add.delay(5,
10)
這時候可以在celery的worker界面看到執行的結果
此外,我們還可以通過send_task()來調用,將excute_tasks.py改成這樣
這種方式也是可以的。send_task()還可能接收到為注冊(即通過@app.task裝飾)的任務,這個時候worker會忽略這個消息
定時任務
上面部分講了怎麼啟動worker和調用worker的相關函數,這里再講一下celery的定時任務。
爬蟲由於其特殊性,可能需要定時做增量抓取,也可能需要定時做模擬登陸,以防止cookie過期,而celery恰恰就實現了定時任務的功能。在上述基礎上,我們將tasks.py文件改成如下內容
然後先通過ctrl+c停掉前一個worker,因為我們代碼改了,需要重啟worker才會生效。我們再次以celery
-A
tasks
worker
-l
info這個命令開啟worker。
這個時候我們只是開啟了worker,如果要讓worker執行任務,那麼還需要通過beat給它定時發送,我們再開一個命令行,切換到項目根目錄,通過
這樣就表示定時任務已經開始運行了。
眼尖的同學可能看到我這里celery的版本是3.1.25,這是因為celery支持的windows最高版本是3.1.25。由於我的分布式微博爬蟲的worker也同時部署在了windows上,所以我選擇了使用
3.1.25。如果全是linux系統,建議使用celery4。
此外,還有一點需要注意,在celery4後,定時任務(通過schele調度的會這樣,通過crontab調度的會馬上執行)會在當前時間再過定時間隔執行第一次任務,比如我這里設置的是60秒的間隔,那麼第一次執行add會在我們通過celery
beat
-A
tasks
-l
info啟動定時任務後60秒才執行;celery3.1.25則會馬上執行該任務
❾ python爬取大量數據(百萬級)
當用python爬取大量網頁獲取想要的數據時,最重要的問題是爬蟲中斷問題,python這種腳本語言,一中斷
進程就會退出,怎麼在中斷後繼續上次爬取的任務就至關重要了。這里就重點剖析這個中斷問題。
第一個問題: 簡單點的用動態代理池就能解決,在爬取大量數據的時候,為了速度不受影響,建議使用一些緩
存的中間件將有效的代理 ip 緩存起來,並定時更新。這里推薦 github 這個倉庫
https://github.com/jhao104/proxy_pool , 它會做ip有效性驗證並將 ip 放入 redis ,不過實現過於復雜
了,還用到了 db ,個人覺得最好自己修改一下。困難點的就是它會使用別的請求來進行判斷當前的ip是否
是爬蟲,當我們過於聚焦我們的爬蟲請求而忽略了其他的請求時,可能就會被伺服器判定為爬蟲,進而這個ip
會被列入黑名單,而且你換了ip一樣也會卡死在這里。這種方式呢,簡單點就用 selenium + chrome 一個一個
去爬,不過速度太慢了。還是自己去分析吧,也不會過復雜的。
第二個問題: 網路連接超時是大概率會遇到的問題,有可能是在爬取的時候本地網路波動,也有可能是爬
取的服務端對ip做了限制,在爬取到了一定量級的時候做一些延遲的操作,使得一些通用的 http 庫超時
( urllib )。不過如果是服務端動的手腳一般延遲不會太高,我們只需要人為的設置一個高一點的
timeout 即可(30 秒),最好在爬取開始的時候就對我們要用的爬取庫進行一層封裝,通用起來才好改
動。
第三個問題: 在解析大量靜態頁面的時候,有些靜態頁面的解析規則不一樣,所以我們就必須得做好斷點
續爬的准備了( PS : 如果簡單的忽略錯誤可能會導致大量數據的丟失,這就不明智了)。那麼在調試的過
程中斷點續爬有個解決方案,就是生產者和消費者分離,生產者就是產生待爬 url 的爬蟲,消費者就是爬取
最終數據的爬蟲。最終解析數據就是消費者爬蟲了。他們通過消息中間件連接,生產者往消息中間件發送待
爬取的目標信息,消費者從裡面取就行了,還間接的實現了個分布式爬取功能。由於現在的消費中間件都有
ack 機制,一個消費者爬取鏈接失敗會導致消息消費失敗,進而分配給其他消費者消費。所以消息丟失的
概率極低。不過這里還有個 tips , 消費者的消費超時時間不能太長,會導致消息釋放不及時。還有要開啟
消息中間價的數據持久化功能,不然消息產生過多而消費不及時會撐爆機器內存。那樣就得不償失了。
第四個問題: 這種情況只能 try except catch 住了,不好解決,如果單獨分析的話會耗費點時間。但在
大部分數據 (99%) 都正常的情況下就這條不正常拋棄就行了。主要有了第三個問題的解決方案再出現這
種偶爾中斷的問就方便多了。
希望能幫到各位。