jsonrpc庫,jsonrpc20

本文目錄一覽:

如何通過zabbix 獲取監控數據

zabbix基本架構:

1.Server

zabbix系統核心進程,輪詢並捕獲數據、發送通知等。是zabbix agent和zabbix proxy彙報數據的對象。server自身可遠程檢測網絡服務。所有的前後端配置、統計信息、可操作數據存儲於此。包含server、前段界面和後端DB幾部分。

2.Agent

部署在被監控主機上用於監控本地資源和應用並向zabbix server彙報結果。使用本地系統調用故非常高效。有主動和被動兩種檢測模式。被動模式下agent根據server或proxy的具體請求來返回數據。主動模式下先主動由server獲取監控項列表在檢測並返回新的數據。採用主動或被動檢測取決於相應監控項的配置。

3.Proxy

可以自由選擇部署或者不部署,主要用於分擔server的負載。在集中化監控遠程位置、分支、網絡的場景中是很好的解決方案。可從被監控設備收集數據緩存在proxy本地後傳遞給其所屬的zabbix server。proxy需要單獨的數據庫。

4.Java gateway

java實現的守護進程用於監控JMX類型的應用程序。

5.Sender

命令行工具zabbix_sender,用於向zabbix server發送性能數據和可用性數據。多用於用戶腳本定期向server發送數據。

如:

shell cd bin

shell ./zabbix_sender -z zabbix -s “Linux DB3” -k db.connections -o 43

6.Get

命令行工具zabbix_get,用於同agent通信從agent獲取數據。可用於zabbix agents的troubleshooting。

如:

shell cd bin

shell ./zabbix_get -s 127.0.0.1 -p 10050 -k “system.cpu.load[all,avg1]”

#zabbix術語表:

host

需要被監控的設備,如交換機、路由器、WEB服務器、DB服務器等

host group

被監控設備的邏輯分組,如DB服務器一組、WEB服務器一組等。可包含主機和模板。用於權限控制

item

需要被監控的項,如CPU空閑率、某一塊磁盤的使用率等

trigger

用於評估收到的監控值是否超出設定的閾值的邏輯表達式

event

如trigger狀態改變等值得注意的事件

action

預先定義的響應event的一系列operations

escalation

執行action中的operations的定製場景;一連串的發送通知、執行遠程命令

media

傳遞notification的方式

notification

通過media發送給用戶的關於某個event的消息

remote command

在被監控機器上觸發並自動執行的預定義命令

template

用於簡化和加速主機上大規模監控任務的部署。包含一系列項目,如items, triggers, graphs, screens, applications, low-level discovery rules

application

邏輯組中的一組items

web scenario

一個或多個HTTP request用以檢查web站點可用性

frontend

zabbix的web界面

zabbix api

允許通過JSON RPC 協議創建、更新和獲取zabbix對象如,hosts, items, graphs and others。或者執行其他任務

zabbix server

zabbix核心,履行監控,與zabbix proxies、zabbix client交互、計算trigger、發送notification、存儲數據等任務

zabbix agent

部署在被監控主機上用於監控本地資源和應用

zabbix proxy

可代zabbix server收集數據分擔處理負載

#zabbix配置:

可通過WEB界面或者模板進行配置

需配置內容包括users、user groups、hosts、host groups、items、Triggers、Events、notification、templates、visualisation等。

最終配置會被存儲在後端database中。

參考:

zabbix取數方式

1.zabbix api

基於WEB的API,通過JSON PRC協議獲取或更改zabbix配置,並可用於獲取歷史監控數據。clients和API間的request和response使用JSON格式。包含一系列可從功能上分為不同組別的方法。

發起HTTP請求的格式類似如下:

POST HTTP/1.1

Content-Type: application/json-rpc

{“jsonrpc”:”2.0″,”method”:”apiinfo.version”,”id”:1,”auth”:null,”params”:{}}

其中是zabbix前端的地址;Content-Type必須指明且為application/json-rpc, application/json or application/jsonrequest三者之一。{“jsonrpc”:”2.0″,”method”:”apiinfo.version”,”id”:1,”auth”:null,”params”:{}}是請求的具體內容。

一些實例:

*登錄認證

{

“jsonrpc”: “2.0”,

“method”: “user.login”,

“params”: {

“user”: “Admin”,

“password”: “zabbix”

},

“id”: 1,

“auth”: null

}

其中:

jsonrpc:指明JSON-RPC協議版本,這裡是2.0版本

method:指明調用的API方法,這裡是用戶登錄

params:需要傳遞給API method的參數,這裡是用戶名和密碼

id:本次請求的標識符

auth:用戶認證令牌,目前尚無所以為null

若參數無誤response將會包含用戶認證令牌,如:

{

“jsonrpc”: “2.0”,

“result”: “0424bd59b807674191e7d77572075f33”,

“id”: 1

}

*獲取hosts信息

{

“jsonrpc”: “2.0”,

“method”: “host.get”,

“params”: {

“output”: [

“hostid”,

“host”

],

“selectInterfaces”: [

“interfaceid”,

“ip”

]

},

“id”: 2,

“auth”: “0424bd59b807674191e7d77572075f33”

}

本例使用可用的用戶認證令牌通過host.get方法獲取所配置的主機的ID 、name等信息,返回如下

{

“jsonrpc”: “2.0”,

“result”: [

{

“hostid”: “10084”,

“host”: “Zabbix server”,

“interfaces”: [

{

“interfaceid”: “1”,

“ip”: “127.0.0.1”

}

]

}

],

“id”: 2

}

為了考慮性能影響、盡量僅列出所需項而非返回所有數據

*創建新監控項

例如在上一步獲取的host上建立新的監控項、監控/home/joe/目錄的剩餘空間

{

“jsonrpc”: “2.0”,

“method”: “item.create”,

“params”: {

“name”: “Free disk space on $1”,

“key_”: “vfs.fs.size[/home/joe/,free]”,

“hostid”: “10084”,

“type”: 0,

“value_type”: 3,

“interfaceid”: “1”,

“delay”: 30

},

“auth”: “0424bd59b807674191e7d77572075f33”,

“id”: 3

}

其中params參數中的幾個關鍵參數含義如下:

name:監控項的名稱,這個可以自己靈活定義,其中的$1代表key_中的第一個參數,此處為/home/joe/

key_:預定義的監控項,zabbix提供了一系列此類監控內容,此處需從其中進行選擇。

hostid:即上步獲得的hostid

value_type:監控數據值的類型,不同的數字代表不同的類型,此處的3代表整型

delay:zabbix取數時間間隔,此處為30秒取一次

返回結果如下:

{

“jsonrpc”: “2.0”,

“result”: {

“itemids”: [

“24759”

]

},

“id”: 3

}

itemid為生成的監控項的id

*獲取歷史數據:

從歷史記錄表獲取itemids為23296的按clock降序排列的十條記錄

history參數可能的取值

0 – float;

1 – string;

2 – log;

3 – integer;

4 – text.

{

“jsonrpc”: “2.0”,

“method”: “history.get”,

“params”: {

“output”: “extend”,

“history”: 0,

“itemids”: “23296”,

“sortfield”: “clock”,

“sortorder”: “DESC”,

“limit”: 10

},

“auth”: “038e1d7b1735c6a5436ee9eae095879e”,

“id”: 1

}

返回結果:

{

“jsonrpc”: “2.0”,

“result”: [

{

“itemid”: “23296”,

“clock”: “1351090996”,

“value”: “0.0850”,

“ns”: “563157632”

},

{

“itemid”: “23296”,

“clock”: “1351090936”,

“value”: “0.1600”,

“ns”: “549216402”

},

…]

}

*錯誤處理

下例忘記了groups這個參數

{

“jsonrpc”: “2.0”,

“method”: “host.create”,

“params”: {

“host”: “Linux server”,

“interfaces”: [

{

“type”: 1,

“main”: 1,

“useip”: 1,

“ip”: “192.168.3.1”,

“dns”: “”,

“port”: “10050”

}

]

},

“id”: 3,

“auth”: “0424bd59b807674191e7d77572075f33”

}

返回結果如下,包含的不是result屬性而是error屬性

{

“jsonrpc”: “2.0”,

“error”: {

“code”: -32602,

“message”: “Invalid params.”,

“data”: “No groups for host \”Linux server\”.”

},

“id”: 3

}

對於獲取監控數據來說,比較關心的應該是history.get這個方法。這種方式實際上最終還是由後台數據庫獲取的。方法提供了豐富的參數,使用非常靈活。但對於一次性大規模的取出大量主機大量監控項的大批數據不太適合。

Dubbo——HTTP 協議 + JSON-RPC

Protocol 還有一個實現分支是 AbstractProxyProtocol,如下圖所示:

從圖中我們可以看到:gRPC、HTTP、WebService、Hessian、Thrift 等協議對應的 Protocol 實現,都是繼承自 AbstractProxyProtocol 抽象類。

目前互聯網的技術棧百花齊放,很多公司會使用 Node.js、Python、Rails、Go 等語言來開發 一些 Web 端應用,同時又有很多服務會使用 Java 技術棧實現,這就出現了大量的跨語言調用的需求。Dubbo 作為一個 RPC 框架,自然也希望能實現這種跨語言的調用,目前 Dubbo 中使用“HTTP 協議 + JSON-RPC”的方式來達到這一目的,其中 HTTP 協議和 JSON 都是天然跨語言的標準,在各種語言中都有成熟的類庫。

下面就重點來分析 Dubbo 對 HTTP 協議的支持。首先,會介紹 JSON-RPC 的基礎,並通過一個示例,快速入門,然後介紹 Dubbo 中 HttpProtocol 的具體實現,也就是如何將 HTTP 協議與 JSON-RPC 結合使用,實現跨語言調用的效果。

Dubbo 中支持的 HTTP 協議實際上使用的是 JSON-RPC 協議。

JSON-RPC 是基於 JSON 的跨語言遠程調用協議。Dubbo 中的 dubbo-rpc-xml、dubbo-rpc-webservice 等模塊支持的 XML-RPC、WebService 等協議與 JSON-RPC 一樣,都是基於文本的協議,只不過 JSON 的格式比 XML、WebService 等格式更加簡潔、緊湊。與 Dubbo 協議、Hessian 協議等二進制協議相比,JSON-RPC 更便於調試和實現,可見 JSON-RPC 協議還是一款非常優秀的遠程調用協議。

在 Java 體系中,有很多成熟的 JSON-RPC 框架,例如 jsonrpc4j、jpoxy 等,其中,jsonrpc4j 本身體積小巧,使用方便,既可以獨立使用,也可以與 Spring 無縫集合,非常適合基於 Spring 的項目。

下面先來看看 JSON-RPC 協議中請求的基本格式:

JSON-RPC請求中各個字段的含義如下:

在 JSON-RPC 的服務端收到調用請求之後,會查找到相應的方法並進行調用,然後將方法的返回值整理成如下格式,返回給客戶端:

JSON-RPC響應中各個字段的含義如下:

Dubbo 使用 jsonrpc4j 庫來實現 JSON-RPC 協議,下面使用 jsonrpc4j 編寫一個簡單的 JSON-RPC 服務端示例程序和客戶端示例程序,並通過這兩個示例程序說明 jsonrpc4j 最基本的使用方式。

首先,需要創建服務端和客戶端都需要的 domain 類以及服務接口。先來創建一個 User 類,作為最基礎的數據對象:

接下來創建一個 UserService 接口作為服務接口,其中定義了 5 個方法,分別用來創建 User、查詢 User 以及相關信息、刪除 User:

UserServiceImpl 是 UserService 接口的實現類,其中使用一個 ArrayList 集合管理 User 對象,具體實現如下:

整個用戶管理業務的核心大致如此。下面我們來看服務端如何將 UserService 與 JSON-RPC 關聯起來。

首先,創建 RpcServlet 類,它是 HttpServlet 的子類,並覆蓋了 HttpServlet 的 service() 方法。我們知道,HttpServlet 在收到 GET 和 POST 請求的時候,最終會調用其 service() 方法進行處理;HttpServlet 還會將 HTTP 請求和響應封裝成 HttpServletRequest 和 HttpServletResponse 傳入 service() 方法之中。這裡的 RpcServlet 實現之中會創建一個 JsonRpcServer,並在 service() 方法中將 HTTP 請求委託給 JsonRpcServer 進行處理:

最後,創建一個 JsonRpcServer 作為服務端的入口類,在其 main() 方法中會啟動 Jetty 作為 Web 容器,具體實現如下:

這裡使用到的 web.xml 配置文件如下:

完成服務端的編寫之後,下面再繼續編寫 JSON-RPC 的客戶端。在 JsonRpcClient 中會創建 JsonRpcHttpClient,並通過 JsonRpcHttpClient 請求服務端:

在 AbstractProxyProtocol 的 export() 方法中,首先會根據 URL 檢查 exporterMap 緩存,如果查詢失敗,則會調用 ProxyFactory.getProxy() 方法將 Invoker 封裝成業務接口的代理類,然後通過子類實現的 doExport() 方法啟動底層的 ProxyProtocolServer,並初始化 serverMap 集合。具體實現如下:

在 HttpProtocol 的 doExport() 方法中,與前面介紹的 DubboProtocol 的實現類似,也要啟動一個 RemotingServer。為了適配各種 HTTP 服務器,例如,Tomcat、Jetty 等,Dubbo 在 Transporter 層抽象出了一個 HttpServer 的接口。

dubbo-remoting-http 模塊的入口是 HttpBinder 接口,它被 @SPI 註解修飾,是一個擴展接口,有三個擴展實現,默認使用的是 JettyHttpBinder 實現,如下圖所示:

HttpBinder 接口中的 bind() 方法被 @Adaptive 註解修飾,會根據 URL 的 server 參數選擇相應的 HttpBinder 擴展實現,不同 HttpBinder 實現返回相應的 HttpServer 實現。HttpServer 的繼承關係如下圖所示:

這裡以 JettyHttpServer 為例簡單介紹 HttpServer 的實現,在 JettyHttpServer 中會初始化 Jetty Server,其中會配置 Jetty Server 使用到的線程池以及處理請求 Handler:

可以看到 JettyHttpServer 收到的全部請求將委託給 DispatcherServlet 這個 HttpServlet 實現,而 DispatcherServlet 的 service() 方法會把請求委託給對應接端口的 HttpHandler 處理:

了解了 Dubbo 對 HttpServer 的抽象以及 JettyHttpServer 的核心之後,回到 HttpProtocol 中的 doExport() 方法繼續分析。

在 HttpProtocol.doExport() 方法中會通過 HttpBinder 創建前面介紹的 HttpServer 對象,並記錄到 serverMap 中用來接收 HTTP 請求。這裡初始化 HttpServer 以及處理請求用到的 HttpHandler 是 HttpProtocol 中的內部類,在其他使用 HTTP 協議作為基礎的 RPC 協議實現中也有類似的 HttpHandler 實現類,如下圖所示:

在 HttpProtocol.InternalHandler 中的 handle() 實現中,會將請求委託給 skeletonMap 集合中記錄的 JsonRpcServer 對象進行處理:

skeletonMap 集合中的 JsonRpcServer 是與 HttpServer 對象一同在 doExport() 方法中初始化的。最後,我們來看 HttpProtocol.doExport() 方法的實現:

介紹完 HttpProtocol 暴露服務的相關實現之後,下面再來看 HttpProtocol 中引用服務相關的方法實現,即 protocolBindinRefer() 方法實現。該方法首先通過 doRefer() 方法創建業務接口的代理,這裡會使用到 jsonrpc4j 庫中的 JsonProxyFactoryBean 與 Spring 進行集成,在其 afterPropertiesSet() 方法中會創建 JsonRpcHttpClient 對象:

下面來看 doRefer() 方法的具體實現:

在 AbstractProxyProtocol.protocolBindingRefer() 方法中,會通過 ProxyFactory.getInvoker() 方法將 doRefer() 方法返回的代理對象轉換成 Invoker 對象,並記錄到 Invokers 集合中,具體實現如下:

本文重點介紹了在 Dubbo 中如何通過“HTTP 協議 + JSON-RPC”的方案實現跨語言調用。首先介紹了 JSON-RPC 中請求和響應的基本格式,以及其實現庫 jsonrpc4j 的基本使用;接下來我們還詳細介紹了 Dubbo 中 AbstractProxyProtocol、HttpProtocol 等核心類,剖析了 Dubbo 中“HTTP 協議 + JSON-RPC”方案的落地實現。

從 0 到 1:全面理解 RPC 遠程調用

作者 | Python編程時光

責編 | 胡巍巍

什麼是RPC呢?百度百科給出的解釋是這樣的:“RPC(Remote Procedure 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 Procedure 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 實現是太簡單了,所以這裡我就不多說了,如果有人想要看這方面內容,可以收藏我的博客() ,我會更新補充 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-conductor創建rpc server的代碼,這邊的endpoints就是 nova/manager.py:ConductorManager

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億敗光了!

你點的每個“在看”,我都認真當成了喜歡

怎麼用c#調用json-rpc

其實對於C#調用json-rpc並不點便宜,一般情況下如果是C#調用,可以考慮使用wcf等rpc技術。

對於json/xml等rpc,在C#調用時,應該遵從以下兩個原則:

遠程http協議流調用(使用tcpclient/webclient等類庫將內容調用到本地)。

對本地流(二進制,文本——json/xml,文本——jsonp等)進行反序列化,得到相應的調用。

嚴格來說,這種情況其實不能稱之rpc的,rpc是遠程調用,指的調用遠程方法並返回(不返回)相應的應答,而json/jsonp則是將執行結果以流的方式返回,而這個恰好可以序列化成本地對象,嚴格來說,json/jsonp/xml實際上是讓瀏覽器調用的,瀏覽器本身是javascript的宿主,可以很輕易地反序列json或直接執行jsonp方法。

也就是說,瀏覽器通信使用json/jsonp的這種方案,目的是跨終端。而C#只能出現在頁面後端,如果讓後端去調用業務層邏輯的話,不如直接使用wcf等rpc。使用json/jsonp則是需要自定義序列化的,對於將來的維護等存在一定的問題。

如果把網頁也看作rpc的話,json/jsonp可以算做rpc的,事實上狹義的rpc就是遠程調用,是在業務層上遠程集中封裝。還有是一定的區別的。

python後端開發需要學什麼?

可以參考下面的路徑去學習,祝你學有所成,公司最近在人工智能和自然語言處理的項目後端項目,我也是網上找了很多知識,最後給自己列了一個學習的目錄,按照這個在複習並在總結,希望能幫到你:

計算機基本認知,環境搭建    python環境搭建

計算機基本認識,進制轉換

python注釋使用

python變量使用

python數據類型_Number

python數據類型    str字符串類型

容器類型數據list,tuple,str

容器類型數據set,dict

變量緩存機制

自動類型轉換

Number強制類型轉換  

python運算符的使用    容器類型數據強制類型轉換

字典強轉等長二級容器

運算符_算數_比較

運算符_賦值_成員

運算符_身份_邏輯

運算符_位運算_優先級  

python流程控制    代碼塊

流程控制if

多項巢狀分支

循環結構while

循環判斷經典題

字符串的相關操作  

python循環結構    

關鍵字continue_break_pass

for循環的遍歷_range  

字符串,列表內置方法    

字符串函數

format字符串格式化

format特殊符號的使用

列表的操作

列表函數  

字典,集合內置方法+文件操作    

字典的相關函數

集合操作_函數

文件操作

文件加號模式  

函數,函數參數    文件相關函數 

函數

形參實參

默認形參_關鍵字形參

收集參數

命名關鍵字參數

全局/局部變量,閉包    return返回值

函數名的使用

局部變量_全局變量

函數的嵌套LEGB

關鍵字nonlocal

閉包函數  

遞歸,匿名函數    

locals和globals

閉包特點意義

遞歸含義

斐波那契_尾遞歸

匿名函數lambda  

迭代器,高階函數    迭代器

高階函數_map

高階函數_reduce

高階函數_sorted

高階函數_filter  

推導式    列表推導式

推導式題

集合_字典推導式

生成器表達式

生成器函數  

內置方法,linux基本命令    內置函數

可滑動序列

面試題演練

linux安裝

linux基本命令  

python模塊    序列化模塊

數學模塊

隨機模塊

time模塊  

python模塊    os模塊

os_shutil

os.path模塊

計算文件夾大小

zipfile

tarfile  

導入模塊包,oop面向對象認知    

import_from絕對導入

import_from相對導入(單入口)

oop面向對象

類的封裝性

oop之封裝,繼承    類的相關操作

對象和類的刪除操作

單繼承

多繼承

菱形繼承

oop之多態,魔術方法    多態

魔術方法__new__

單態模式

析構方法__del__  

oop之魔術方法,異常處理    魔術方法__call__

魔術方法__str__repr__

魔術方法__bool_add_len__

了解異常

異常處理語法

主動拋出異常

裝飾器  

裝飾器

靜態綁定方法

property 

正則表達式    單個字符匹配

多個字符匹配

匹配分組

命名分組

正則函數

正則計算器小程序

認識網絡    bs_cs流程

傳輸數據流程

交換機和局域網的網絡通訊

arp協議  

認識tcp/udp協議  

tcp基本語法

tcp循環發消息

udp基本語法

udp循環發消息

黏包  

基於tcp協議下的應用    socketserver並發

文件校驗

服務器合法性校驗

tcp登錄

並發編程之進程    進程

join

守護進程

lock鎖

Semaphore

生產者消費者模型    Event事件

進程隊列Queue

生產者和消費者模型

JoinableQueue

Manager.py

並發編程之線程

.線程

用類定義線程

守護線程

lock保證線程數據安全

信號量_Semaphore

死鎖,互斥鎖,遞歸鎖

線程池,進程池,協成的使用

事件Event

線程隊列

進程池和線程池

回調函數

協程

協程的爬蟲案例

mysql安裝(linux+windows+xshell+navicat)  

掌握數據庫mysql基本操作

mysql登錄,服務啟動

創建賬戶,用戶授權

數據庫,數據表,數據的增刪改查

認識常用數據類型  

數據庫的存儲引擎和約束  

字段約束

約束的刪減

存儲引擎區別用法

數據表之間的關係  

查詢數據表  

單表查詢

多表聯查

子查詢

帶EXISTS關鍵字的子查詢

python操作mysql  

python連接mysql的事務處理

sql注入

python連接mysql增刪改查

mysql數據恢復  

HTML/CSS    html文檔介紹,html標籤,body標籤,head標籤介紹,head標籤中的meta標籤和link標籤和title標籤介紹,body中的標籤分類,基礎標籤,img、a、列表、表格、input、label、select等標籤,作業講解,form標籤介紹和示例講解,css介紹,引入,css選擇器,背景設置,高度寬度,字體效果,邊框、盒子模型、display屬性、float屬性等  

CSS    偽類選擇器,文字裝飾、a標籤補充、定位、權重、小米商城導航欄講解,原型頭像示例講解  

JS基礎/BOM和DOM操作    小米商城作業,js介紹和js引入,js數據類型、流程控制、函數等操作,js中的JSON,BOM對象的彈框、location對象、定時器、直接查找選擇器、間接查找選擇器、值操作、類值操作、樣式操作、button按鈕補充、事件和綁定事件的兩種方式,常用事件練習  

jQuery/Bootstrap    作業講解,jquery介紹,引入、選擇器、篩選器、值操作、文檔操作、刪除和清空標籤、邏輯運算符、克隆、事件冒泡和事件委託、綁定事件的方式,作業講解和模態對話框示例,input事件和頁面載入事件補充、bootstrap介紹和引入、全局css樣式、組件和常用插件

自定義web框架    作業講解、web框架介紹、自定義web框架實現、動態頁面、返回不同的html頁面、函數版、多線程版、返回靜態文件版,wsgiref版等web框架通過socket來實現,還有jinja2的簡單使用  

django下載安裝和URL路由系統    django介紹、MTV和MVC框架介紹、常用指令、目錄結構、pycharm創建django項目、request的常用屬性介紹、登錄示例、url路由系統介紹、有名分組和無名分組,  

視圖/模板    request對象的常用方法和屬性、響應方法介紹和使用,CBV和FBV、CBV和FBV加裝飾器,CBV源碼講解,模板渲染系統介紹,語法、簡單示例、內置過濾器、for循環標籤、if標籤、with標籤、自定義過濾器和標籤、模板繼承等  

Dajngo的ORM(1)    orm介紹,數據庫同步指令使用和流程分析、配置連接mysql模型類中的屬性介紹和常用參數說明,創建表和數據、增加的兩種方法、刪除、更新的兩種方法、查詢的13個api接口  

Dajngo的ORM(2)    單表圖書管理系統展示和添加作業講解、choices屬性、auto_now_add和auto_now參數講解、url別名和反向解析,基於雙下劃線的模糊查詢,多表結構介紹,圖書管理系統編輯和刪除作業講解、多表關係模型類創建和字段說明和參數介紹、多表數據的添加操作,多表的刪除和修改、基於對象的跨表查詢、雙下劃線跨表查詢、查看原生sql語句的方法、聚合查詢、分組查詢、F查詢、Q查詢等  

Ajax與Django/ 中間件    ajax的介紹和簡單示例,ajax登錄示例、列表數據展示示例,ajax操作cookie的補充、中間件介紹、自定義中間件的方法、5個中間件方法的介紹和使用、基於中間件的session登錄認證 

cookie、session以及用戶認證組件    cookie介紹,cookie的流程解析,django操作cookie和其他參數介紹、session的說明、django的session操作等,多表圖書管理系統作業講解  

vue初識、es6基本語法、指令系統    let、const、v-if、v-for、v-html、v-text、v-model、v-show、生命周期鉤子函數、  

組件化開發、組件傳值、axios簡單使用    組件化開發、組件傳值、axios簡單使用、vue-router使用、vue-cli安裝  

項目初始化/首頁    項目介紹、創建、初始化、element-ui的使用,單文件組件的使用和axios在單文件中的使用和配置、vue-cli的介紹和使用、路飛項目頂部導航欄頁面效果搭建,輪播圖組件的使用和調整、購物車頁面搭建和課程詳情頁面搭建,vue-video-player視頻播放插件  

drf組件    序列化器、drf簡單示例、restful規範、反序列化的校驗機制  

drf組件    apiview、request和response對象、modelserializer、序列化器保存數據、read_only和write_only的參數  

drf組件    viewset、drf路由功能、viewset視圖基類的使用、視圖子類、通用視圖類genericapiview/排序、django-filter過濾器、頻率組件、分頁組件、接口文檔、異常處理、xadmin的安裝和使用、認證組件和權限組件  

git、消息隊列    git企業中的使用模式,rabbimq消息隊列的應用  

rpc通信,grpc組件    rpc的概念以及通信模式,最火的grpc組件使用 

輕量級Flask框架    Werkzeug服務介紹、Flask框架介紹  

路由系統、自定義路由擴展  

Cookie、Session、Http請求和響應  

藍圖、消息閃現、中間件  

Flask常用擴展、WTForms、使用SQLAchemy ORM  

Admin、Restful、websocket原理、magic string, payload len,masking key   

請求和上下文、多app應用、離線腳本、自定義擴展 

服務端項目搭建,項目配置(session、數據庫、日誌相關),項目初始化  

jsonrpc模塊基本配置和使用,客戶端展示首頁及登錄註冊葉綿,APICloud頁面控制管理

python進階    並發、同步、異步、鎖,線進程概念以及協程實現原理  

mysql進階課    基礎知識梳理、索引、執行計劃  

mysql進階課    存儲引擎、日誌管理、備份恢復、主從賦值、優化  

redis,mongodb    事務和發布訂閱、RDB和AOF持久化、緩存擊穿、緩存雪崩等原理介紹、 用戶管理和複製集(RS)總結、sharding cluster 分片集群的搭建、分片使用和相關策略等  

算法與設計模式    鏈表、二叉樹、常見算法、二分查找、插入排序、希爾排序、快排、堆排序、哈希查找  

算法與設計模式    設計模式,單例模式、工廠模式、策略模式、觀察者模式  

算法與設計模式    leetcode經典算法解析  

知識體系差不多就這麼多了,再就是項目部分,具體項目要看需求了,學會了釣魚的方法,不怕釣不到魚哦,無論在哪個行業做什麼樣的項目都沒問題呢!

我自己也搜集了一些經典的資料,要是想要加我百度網盤:艾美電商,我發給你!

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/277193.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-19 13:20
下一篇 2024-12-19 13:20

相關推薦

發表回復

登錄後才能評論