在openstack中使用兩種通訊方式,一種是Restful API,另外一種是遠程過程調用RPC。本片文章主要講解openstack中RPC的使用方式,以及如何在咱們本身的架構中使用RPC。html
在我前面的一篇文章《基於Rabbitmq的RPC調用》中已經簡單的介紹過RPC,Rabbitmq兩種技術,openstack中的RPC調用實現是本身的通用庫oslo_message,該庫是對基於Rabbitmq實現的RPC的一個封裝。api
1、技術介紹瀏覽器
nova模塊是openstack中最核心的服務,nova模塊使用了衆多的RPC服務將業務解耦,如:nova-api; nova-conductor; nova-scheduler; nova-compute等。每個服務都是一個RPC的服務端,同時每個服務都是一個RPC的客戶端。服務器
service服務啓動的就是nova的RPC服務多線程
nova各個服務啓動時就是開啓了一個RPC的服務端,在調用其餘服務時會建立一個客戶端,經過客戶端調用到相應的服務。以nova建立虛擬機爲例,在上圖的第三步中,nova-scheduler選擇好計算節點,將建立虛擬機的信息經過RPC發送給計算節點。代碼通過RPC客戶端的封裝和調用,本文的重點就是如何調用RPC客戶端。
架構
cctxt = self.client.prepare(version=version)
cctxt.cast(context,'select_destinations',**kw)
這裏的client是 rpc.get_client(target,serializer=serializer),見下圖。函數
經過查找rpc的導入路徑,能夠發現rpc是從nova模塊中導入。url
rpc.py 在get_client函數中,返回了messaging的調用。
spa
這裏的messaging就是來自oslo_messaging庫。命令行
從rpc.py中可知,客戶端來自messaging,其實就是oslo_messaging。因此可以看出openstack中RPC的實現封裝在oslo_messagin庫當中。
oslo_messaging其內部的實現暫時先無論,咱們已經知道了調用其接口就能駕馭這個已經封裝好的oslo_messaging庫來完成本身的一些功能。下面就模擬openstack使用oslo_messaging來完成本身的功能。
2、代碼移植
要使用oslo_messagin封裝好的RPC,主要步驟分爲以下幾步:
一、安裝oslo_messaging庫
pip install oslo_messaging oslo_config
二、安裝rabbitmq
apt-get install rabbitmq-server
三、建立消息隊列用戶名
rabbitmqctl add_user openstack stack2018
四、設置權限
rabbitmqctl set_permissions openstack ".*" ".*" ".*"
其中步驟2,步驟3,步驟4對很對讀者來講確定十分眼熟,不錯,流程和openstack安裝Message queue是同樣同樣的。
五、建立配置文件
my.conf
[DEFAULT] url = 'rabbit://openstack:stack2018@127.0.0.1:5672/'
用戶名:openstack ,密碼:stack2018
六、調用oslo_messaging,完成客戶端和服務器端
oslo_message_server.py
#coding:utf-8
from oslo_config import cfg
import oslo_messaging
import time
class ServerControlEndpoint(object):
def __init__(self, server):
self.server = server
def stop(self, ctx):
if self.server:
self.server.stop()
class AddEndpoint(object):
def add(self, ctx, a,b):
print 'revice message'
return a+b
#從配置文件中加載transport_url。在openstack中,帳號、密碼、端口號等都是從配置文件中讀取,支持可配置的。
#配置文件的內容經過oslo_config庫讀取。
opts = [
cfg.StrOpt('url', default='0.0.0.0'),
]
CONF = cfg.CONF
CONF.register_opts(opts)
CONF(default_config_files=['my.conf'])
#transport_url是指定實現RPC的底層技術,可使rabbitmq,也能夠是別的技術
#從my.conf文件中讀取到該URL。
transport_url = CONF.url
transport = oslo_messaging.get_transport(cfg.CONF,transport_url)
#target用來指定該rpc server監聽在哪些隊列上。
#target指定了2個參數:topic和server。
target = oslo_messaging.Target(topic='test', server='server1')
#可供別人調用的方法類
endpoints = [
ServerControlEndpoint(None),
AddEndpoint(),
]
#建立Server對象時,須要指定Transport、Target和一組endpoint
server = oslo_messaging.get_rpc_server(transport, target, endpoints,
executor='blocking')
try:
server.start()
print 'The Server!'
while True:
time.sleep(1)
except KeyboardInterrupt:
print("Stopping server")
server.stop()
service文件中使用兩個openstack通用庫,除了oslo_messaging以外,還有一個oslo_config。首先說oslo_config,這個庫的主要功能是從配置文件或者命令行中讀取特定信息。在openstack的安裝過程當中,須要配置各類參數,例如nova.conf中配置rabbitmq。
一樣,咱們在配置文件中也配置了transport_url,經過oslo_config讀取配置的值。下面的client也是同樣,經過oslo_config讀取配置信息。另一個就是主角oslo_messaging的調用。建立一個RPC的服務端,須要四個參數,分別是:
他們的功能分別是:
經過這四個參數,造成一個可調用的RPC服務端,服務以阻塞的方式在後臺運行。
oslo_message_client.py
#coding:utf-8
from oslo_config import cfg
import oslo_messaging
opts = [
cfg.StrOpt('url', default='helloworld'),
]
CONF = cfg.CONF
CONF.register_opts(opts)
CONF(default_config_files=['my.conf'])
transport_url = CONF.url
transport = oslo_messaging.get_transport(cfg.CONF,transport_url)
target = oslo_messaging.Target(topic='test')
client = oslo_messaging.RPCClient(transport, target)
r = client.call({}, 'add', a=2,b=3)
print 'result :',r
#Target對象的屬性在RPCClient對象構造以後,還能夠經過prepare()方法修改,
#能夠修改的屬性包括exchange,topic,namespace,version,server,fanout和retry。
#修改後的target屬性只在這個prepare()方法返回的對象中有效。
cctxt = client.prepare(version='1.0')
r_two = cctxt.call({},'add',a=2,b=3)
print 'result_two :',r_two
客戶端調用了oslo_messaging.RPCClient()方法,這個方式就是openstack調用oslo_messaging庫的方法。經過傳入參數:transport:消息處理的端點;target:消息隊列中topic的路由關鍵字,可以準肯定位到要發送的消息隊列的。另外若是建立的client客戶端是共用的,而具體使用時還要修改本身的特性的話,可使用client.prepare這個方法來修改client的參數。例如代碼中使用該方法修改了client的版本號。這樣和openstack的代碼就是保持了一致。
七、開啓服務
先開啓服務器
運行客戶端,調用遠程函數
一次RPC的遠程調用就完成了,同時這也是貼近openstack源碼的RPC使用方式,很方便在本身的架構中移植這種現有的技術。
最後還有一個小彩蛋。在安裝rabbitmq的主機上,進入路徑 cd /usr/lib/rabbitmq/bin/,而後執行命令
rabbitmq-plugins enable rabbitmq_management
在瀏覽器中進入地址 http://localhost:15672,使用帳號 guest/guest 登陸,能打開rabbitmq的監控界面。
原文出處:https://www.cnblogs.com/goldsunshine/p/10205058.html