RabbitMQ RPC模型

RPC(remote procedure call)模型说通俗一点就是客户端发一个请求给远程服务端,让它去执行,然后服务端端再把执行的结果再返回给客户端。

1、服务端

  1. import pika
  2.  
  3. #创建socket实例,声明管道,声明queue
  4. connection = pika.BlockingConnection(pika.ConnectionParameters(host="localhost"))
  5. channel = connection.channel()
  6. channel.queue_declare(queue="rpc_queue")
  7.  
  8. def fib(n):
  9. """
  10. 斐波那契数列
  11. :param n:
  12. :return:
  13. """
  14. if n == 0:
  15. return 0
  16. elif n == 1:
  17. return 1
  18. else:
  19. return fib(n - 1) + fib(n - 2)
  20.  
  21. def on_request(ch, method, props, body): # props 是客户端发过来的消息
  22. n = int(body)
  23. print("fib(%s)" % n)
  24. response = fib(n)
  25. # 发布消息
  26. ch.basic_publish(exchange="",
  27. routing_key=props.reply_to, # props.reply_to从客户端取出双方约定好存放返回结果的queue
  28. properties=pika.BasicProperties # 定义一些基本属性
  29. (correlation_id=props.correlation_id), # props.correlation_id 从客户端取出当前请求的ID返回给客户端做验证
  30. body=str(response))
  31. ch.basic_ack(delivery_tag=method.delivery_tag) # 手动确认消息被消费
  32.  
  33. channel.basic_qos(prefetch_count=1) # 每次最多处理一个客户端发过来的消息
  34. # 消费消息
  35. channel.basic_consume(on_request, # 回调函数
  36. queue="rpc_queue")
  37.  
  38. print("Awaiting RPC requests")
  39. channel.start_consuming()

  

2、客户端

  1. import pika
  2. import uuid
  3. import time
  4.  
  5. class FibonacciRpcClient(object):
  6. """
  7. 斐波那契数列rpc客户端
  8. """
  9.  
  10. def __init__(self):
  11. """
  12. 定义好创建socket实例、声明管道、声明随机产生的唯一queue、消费信息的静态变量
  13. """
  14. self.connection = pika.BlockingConnection(pika.ConnectionParameters
  15. (host="localhost"))
  16. self.channel = self.connection.channel()
  17. result = self.channel.queue_declare(exclusive=True)
  18. self.callback_queue = result.method.queue
  19. self.channel.basic_consume(self.on_response, no_ack=True,
  20. queue=self.callback_queue)
  21.  
  22. def on_response(self, ch, method, props, body):
  23. print("---->", method, props)
  24. # 当服务端返回的id跟当初请求的id一致时,再去读取服务端发送的信息保持数据的一致性
  25. if self.corr_id == props.correlation_id: # 当服务端返回的id跟当初请求的id一致时,保持数据的一致性
  26. self.response = body
  27.  
  28. def call(self,n):
  29. self.response = None
  30. self.corr_id = str(uuid.uuid4())
  31. self.channel.publish(exchange="",
  32. routing_key="rpc_queue", # 双方的request所用的queue
  33. properties=pika.BasicProperties( # 定义基本属性
  34. reply_to=self.callback_queue, # 定义客户端服务端双方response的所用的Q
  35. correlation_id=self.corr_id), # 定义这次request的唯一ID
  36. body=str(n))
  37. while self.response is None:
  38. self.connection.process_data_events() # 非 阻塞版的start_consumer()
  39. print("no msg....")
  40. time.sleep(0.5)
  41. return int(self.response)
  42.  
  43. if __name__ == "__main__":
  44. fibonacci_rpc = FibonacciRpcClient()
  45. print("Requesting fib(8)")
  46. response = fibonacci_rpc.call(8)
  47. print("Got %r" % response)

3、输出

服务端:

  1. Awaiting RPC requests
  2. fib(8)

  

客户端:

  1. Requesting fib(8)
  2. no msg....
  3. ----> <Basic.Deliver(['consumer_tag=ctag1.cf2e7983c7d840db8c68f4571472c18d', 'delivery_tag=1', 'exchange=', 'redelivered=False', 'routing_key=amq.gen-ezXgs0tRO5SldZeRH97VPw'])> <BasicProperties(['correlation_id=601e860d-c93d-4c94-959a-3a39be177f7c'])>
  4. no msg....
    Got 21

  

【python】-- RabbitMQ RPC模型的更多相关文章

  1. Python RabbitMQ RPC实现

    远程调用方法:R(remote)  P(procedure)  C(call) 为了说明如何使用RPC服务,我们将创建一个简单的客户端类. 它将公开一个名为call的方法,它发送一个RPC请求和块,直 ...

  2. Python之路-python(rabbitmq、redis)

    一.RabbitMQ队列 安装python rabbitMQ module pip install pika or easy_install pika or 源码 https://pypi.pytho ...

  3. python RabbitMQ队列/redis

    RabbitMQ队列 rabbitMQ是消息队列:想想之前的我们学过队列queue:threading queue(线程queue,多个线程之间进行数据交互).进程queue(父进程与子进程进行交互或 ...

  4. 认识RabbitMQ交换机模型

    前言 RabbitMQ是消息队列中间件(Message Queue Middleware)中一种,工作虽然有用到,但是却没有形成很好的整体包括,主要是一些基础概念的认识,这里通过阅读<Rabbi ...

  5. Spring - 几种RPC模型的使用与比较

    Spring中,用JMS搞RPC时会用到: org.springframework.jms.remoting.JmsInvokerServiceExporter org.springframework ...

  6. python RabbitMQ队列使用(入门篇)

    ---恢复内容开始--- python RabbitMQ队列使用 关于python的queue介绍 关于python的队列,内置的有两种,一种是线程queue,另一种是进程queue,但是这两种que ...

  7. Python RabbitMQ消息队列

    python内的队列queue 线程 queue:不同线程交互,不能夸进程 进程 queue:只能用于父进程与子进程,或者同一父进程下的多个子进程,进行交互 注:不同的两个独立进程是不能交互的.   ...

  8. python调用rpc实现分布式系统

    rpc 一般俗称,远程过程调用,把本地的函数,放到远端去调用. 通常我们调用一个方法,譬如: sumadd(10, 20),sumadd方法的具体实现要么是用户自己定义,要么存在于该语言的库函数中,也 ...

  9. python RabbitMQ队列使用

    python RabbitMQ队列使用 关于python的queue介绍 关于python的队列,内置的有两种,一种是线程queue,另一种是进程queue,但是这两种queue都是只能在同一个进程下 ...

随机推荐

  1. 2017.9.5 postgresql加密函数的使用

    需要安装的插件的名字:pgcrypto 官网地址:https://www.postgresql.org/docs/9.4/static/pgcrypto.html stackoverflow: htt ...

  2. 2017.6.30 用shiro实现并发登录人数控制(实际项目中的实现)

    之前的学习总结:http://www.cnblogs.com/lyh421/p/6698871.html 1.kickout功能描述 如果将配置文件中的kickout设置为true,则在另处再次登录时 ...

  3. JavaSE入门学习18:Java面向对象之多态

    一Java多态 多态是同一个行为具有多个不同表现形式或形态的能力. 多态性是对象多种表现形式的体现.比方我们说"宠 物"这个对象.它就有非常多不同的表达或实现,比方有小猫.小狗.蜥 ...

  4. JAVA泛化及为什么需要泛化

    泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数. 比如,有一种类型为List,此时该List可以是任意类型的列表,如Integer,String等等. 如果把List类型改为List ...

  5. OpenCV2学习笔记(十五):利用Cmake高速查找OpenCV函数源代码

    在使用OpenCV时,在对一个函数的调用不是非常了解的情况下,通常希望查到该函数的官方声明.而假设想进一步研究OpenCV的函数,则必须深入到源码. 在VS中我们能够选中想要查看的OpenCV函数,点 ...

  6. kali渗透综合靶机(一)--Lazysysadmin靶机

    kali渗透综合靶机(一)--Lazysysadmin靶机 Lazysysadmin靶机百度云下载链接:https://pan.baidu.com/s/1pTg38wf3oWQlKNUaT-s7qQ提 ...

  7. goruntine

    一.出让时间片 runtime.Gosched() 二.同步锁 Go语言包中的sync包提供了两种锁类型:sync.Mutex和sync.RWMutex.Mutex是最简单的一种锁类型,同时也比较暴力 ...

  8. 关于 Nginx 并发连接数

    关于 Nginx 并发连接数 最近在学习使用 nginx , 做一些简单的压力测试时,发现并发连接数最大只能上到 100 多 测试刚开始时的状态 , netstat -n | awk '/^tcp/ ...

  9. iOS时间间隔判断

    如何计算两个NSDate之间的时间间隔呢? timeIntervalSinceDate: Returns the interval between the receiver and another g ...

  10. Python修改文件权限

    os.chmod()方法 此方法通过数值模式更新路径或文件权限.该模式可采取下列值或按位或运算组合之一: stat.S_ISUID: Set user ID on execution. stat.S_ ...