RPC(Remote Procedure Call Protocol)-远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。
RPC 采用C/S模式。首先,客户机调用进程发送一个有进程参数的调用消息到服务端的消息队列里,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。
关于RPC详情,可参考这里
RabbitMQ:可复用的企业消息系统。
MQ(Message Queue), 消息队列。具体关于队列的理解可以参考本专栏的异步解耦篇(消费者生产者模型)
RabbitMQ安装
#安装配置epel源
rpm -ivh http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
#安装erlang
yum -y install erlang
#安装RabbitMQ
yum -y install rabbitmq-server
在生产和消费模型中来讲 ,使用 RabbitMQ,相当于不再关注内存中的Queue对象了,而是由某台服务器上的RabbitMQ Server实现的消息队列。
client:
#!/usr/bin/env python
# -- coding = 'utf-8' --
# Author Allen Lee
# Python Version 3.5.1
# OS Windows 7
import pika
import sys
class rpc_client:
def __init__(self):
self.connection = pika.BlockingConnection(pika.ConnectionParameters(
host='127.0.0.1'
))
self.channel = connection.channel()
self.channel.exchange_declare(exchange='rpc_channel',
type='fanout')
#收消息时的回调函数
def callback_client(ch,method,properties,body):
print(body)
#发
def put_msg(self):
while True:
message=input('>>: ').strip()
if Len(message) == 0 :
break
channel.basic_publish(exchange='logs_fanout',
routing_key='',
body=message)
connection.close()
#收
def get_msg(self):
while True:
#随机创建队列
result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue
#绑定
self.channel.queue_bind(exchange='rpc_channel',
queue=queue_name)
self.channel.basic_consume(self.callback_client,
queue=queue_name,
no_ack=True)
self.channel.start_consuming()
client = rpc_client()
client.put_msg()
client.get_msg()
server:
#!/usr/bin/env python
# -- coding = 'utf-8' --
# Author Allen Lee
# Python Version 3.5.1
# OS Windows 7
import pika
import subprocess
class rpc_server:
#接收消息放在构造方法中
def __init__(self):
self.connection = pika.BlockingConnection(pika.ConnectionParameters(
host='127.0.0.1'))
self.channel = connection.channel()
self.channel.exchange_declare(exchange='rpc_channel',
type='fanout')
#随机创建队列
result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue
#绑定
self.channel.queue_bind(exchange='rpc_channel',
queue=queue_name)
self.channel.basic_consume(self.callback_server,
queue=queue_name,
no_ack=True)
self.channel.start_consuming()
#将发消息放在callback方法中
def callback_server(ch,method,properties,body):
result = subprocess.Popen(body,shell=True,stdout=subprocess.PIPE)
ret = result.stdout.read()
if not ret:
message = 'there is no such commons'
print(send_data)
else:
message = ret
#将回显发送给client
channel.basic_publish(exchange='rpc_channel',
routing_key='',
body=message)
server = rpc_server()