在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