3-rabbitmq-发布订阅高级之Topic(按关键字模糊匹配)、rpc介绍(python实现rpc【内置的、zeroRpc】、rabbitmq实现rpc)、微服务项目

1 发布订阅高级之Topic(按关键字模糊匹配)
2 rpc介绍
2.1 rpc是如何通信的
3 python实现rpc
3.1 内置的
3.2 zeroRpc
4 rabbitmq实现rpc
5 微服务项目(请略过,没搞懂)

1 发布订阅高级之Topic(按关键字模糊匹配)

# rabbitmq  消息模式
	- 普通模式:生产者消费者
    	-消息确认
        -持久化 :queue,消息
    - worker模式: 生产者 多个消费者--》轮询
    	-闲置消费
        
    -发布订阅之 fanout模式
    	-发布者---》所有订阅者都能收到
    -发布订阅之 direct模式
    	-消费者只消费某一类消息
        -发布指定: routing_key
        -接收
    -发布订阅之 topic模式   模糊匹配模式
    	###  # 表示任意字符
        ###  * 表示一个单词
    	
        
 # 交换机的四种类型
	-topic
    -fanout
    -direct
    -headers

2 rpc介绍

https://www.cnblogs.com/liuqingzheng/p/16271923.html
    
RPC (Remote Procedure Call)是指远程过程调用,也就是说两台服务器 A,B一个应用部署在A服务器上,
想要调用 B 服务器上应用提供的函数或方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据

# 用来做服务间通信的
	-方式一: 使用 restful调用 同步调用
    -方式二:借助于消息队列 异步通信(微服务案例就是这种方案)
    -方式三:rpc通信:远程过程调用
    
# 为什么要用 RPC?
就是无法在一个进程内,甚至一个计算机内通过本地调用的方式完成的需求,比如比如不同的系统间的通讯,甚至不同的组织间的通讯。由于计算能力需要横向扩展,需要在多台机器组成的集群上部署应用


# 主流rpc框架
	grpc:跨语言---》python调用go服务   https://zhuanlan.zhihu.com/p/425725192
    			   go调用python服务
    dubbo:java用的多

在这里插入图片描述

功能HessianMontanrpcxgRPCThriftDubboDubboxSpring Cloud
开发语言跨语言JavaGo跨语言跨语言JavaJavaJava
分布式(服务治理)×××
多序列化框架支持hessian√(支持Hessian2、Json,可扩展)× 只支持protobuf)×(thrift格式)
多种注册中心×××
管理中心×××
跨编程语言×(支持php client和C server)××××
支持REST××××××
关注度
上手难度
运维成本
开源机构CauchoWeiboApacheGoogleApacheAlibabaDangdangApache

2.1 rpc是如何通信的

1 要解决通讯的问题,主要是通过在客户端和服务器之间建立 TCP 连接,远程过程调用的所有交换的数据都在这个连接里传输。
连接可以是按需连接,调用结束后就断掉,也可以是长连接,多个远程过程调用共享同一个连接。

2 要解决寻址的问题,也就是说,A 服务器上的应用怎么告诉底层的 RPC 框架,
如何连接到 B 服务器(如主机或 IP 地址)以及特定的端口,方法的名称是什么,这样才能完成调用。
比如基于 Web 服务协议栈的 RPC,就要提供一个 endpoint URI,或者是从 UDDI 服务上查找。
如果是 RMI 调用的话,还需要一个 RMI Registry 来注册服务的地址。

3 当 A 服务器上的应用发起远程过程调用时,方法的参数需要通过底层的网络协议如 TCP 传递到 B 服务器,由于网络协议是基于二进制的,
内存中的参数的值要序列化成二进制的形式,也就是序列化(Serialize)或编组(marshal),通过寻址和传输将序列化的二进制发送给 B 服务器。

4 B 服务器收到请求后,需要对参数进行反序列化(序列化的逆操作),恢复为内存中的表达方式,
然后找到对应的方法(寻址的一部分)进行本地调用,然后得到返回值。

5 返回值还要发送回服务器 A 上的应用,也要经过序列化的方式发送,服务器 A 接到后,再反序列化,恢复为内存中的表达方式,交给 A 服务器上的应用。

3 python实现rpc

1 SimpleXMLRPCServer 自带的
SimpleXMLRPCServer是Python标准库中用于实现XML-RPC(远程过程调用)服务器的模块之一。
XML-RPC是一种远程调用协议,通过HTTP协议传输数据,使用XML格式编码方法调用和响应。

2 ZeroRPC
ZeroRPC 是一个基于 ZeroMQ(0MQ)的远程过程调用(RPC)框架。
ZeroMQ是一个高性能消息传递库,而ZeroRPC则建立在其之上,提供了方便的远程调用功能。

3.1 内置的

server端

from xmlrpc.server import SimpleXMLRPCServer


# 通信使用xml格式
class RPCServer(object):

    def __init__(self):
        super(RPCServer, self).__init__()

    def add(self, a, b):
        print('来了')
        return a + b


# SimpleXMLRPCServer
server = SimpleXMLRPCServer(('localhost', 4242), allow_none=True)
server.register_introspection_functions()
server.register_instance(RPCServer())
server.serve_forever()

client端

import time
from xmlrpc.client import ServerProxy


# SimpleXMLRPCServer
def xmlrpc_client():
    print('xmlrpc client')
    c = ServerProxy('http://localhost:4242')

    res = c.add(3, 4)
    print(res)


if __name__ == '__main__':
    xmlrpc_client()

3.2 zeroRpc

server端

import zerorpc


class RPCServer(object):

    def __init__(self):
        super(RPCServer, self).__init__()
        print(self)

    def add(self, a, b):
        print(a, b)
        return a + b + 10


# zerorpc
s = zerorpc.Server(RPCServer())
s.bind('tcp://0.0.0.0:4243')
s.run()

client端

import zerorpc
import time
# zerorpc
def zerorpc_client():
    print('zerorpc client')
    c = zerorpc.Client()
    c.connect('tcp://127.0.0.1:4243')
    res=c.add(2,3)
    print(res)


if __name__ == '__main__':
    zerorpc_client()

4 rabbitmq实现rpc

RabbitMQ 的 RPC 实现可以跨多种编程语言,因为 RabbitMQ 使用的是 AMQP(高级消息队列协议),而 AMQP 是一种开放的、跨语言的消息协议。

在 RabbitMQ 中,RPC 的通信是通过消息队列进行的,因此只要客户端和服务端都能够使用支持 AMQP 的客户端库,它们就可以使用不同的编程语言实现。

例如,一个使用 Python 编写的 RPC 服务端可以与一个使用 Java、JavaScript、Ruby 等其他语言编写的
客户端进行通信,只要它们都能够与 RabbitMQ 进行连接、声明队列、发布和消费消息。

关键是确保客户端和服务端使用的消息格式和通信协议是兼容的。通常情况下,AMQP提供了一致的消息传递机制,
但不同语言的客户端库可能有一些语言特定的实现细节。因此,使用支持 AMQP 的客户端库是跨语言 RPC 实现的关键。

总体而言,RabbitMQ 提供了一种灵活、可扩展的消息传递机制,使得在不同编程语言之间进行 RPC 通信成为可能。
import pika
import uuid


class FibonacciRpcClient(object):
    def __init__(self):
        credentials = pika.PlainCredentials("admin", "admin")
        self.connection = pika.BlockingConnection(pika.ConnectionParameters('10.0.0.101', credentials=credentials))
        self.channel = self.connection.channel()

        # 随机生成一个消息队列(用于接收结果)
        result = self.channel.queue_declare(queue='', exclusive=True)
        self.callback_queue = result.method.queue

        # 监听消息队列中是否有值返回,如果有值则执行 on_response 函数(一旦有结果,则执行on_response)
        self.channel.basic_consume(queue=self.callback_queue, on_message_callback=self.on_response, auto_ack=True)

    def on_response(self, ch, method, props, body):
        if self.corr_id == props.correlation_id:
            self.response = body

    def call(self, n):
        self.response = None
        self.corr_id = str(uuid.uuid4())

        # 客户端 给 服务端 发送一个任务:  任务id = corr_id / 任务内容 = '30' / 用于接收结果的队列名称
        self.channel.basic_publish(exchange='',
                                   routing_key='rpc_queue',  # 服务端接收任务的队列名称
                                   properties=pika.BasicProperties(
                                       reply_to=self.callback_queue,  # 用于接收结果的队列
                                       correlation_id=self.corr_id,  # 任务ID
                                   ),
                                   body=str(n))
        while self.response is None:
            self.connection.process_data_events()

        return self.response


fibonacci_rpc = FibonacciRpcClient()

response = fibonacci_rpc.call(9)
print('返回结果:', response)


import pika
credentials = pika.PlainCredentials("admin","admin")
connection = pika.BlockingConnection(pika.ConnectionParameters('10.0.0.101',credentials=credentials))
channel = connection.channel()

# 声明一个队列rpc_queue
channel.queue_declare(queue='rpc_queue')

def fib(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fib(n - 1) + fib(n - 2)

def on_request(ch, method, props, body):
    n = int(body)

    print(" [.] fib(%s)" % n)
    response = fib(n)

    ch.basic_publish(exchange='',
                     routing_key=props.reply_to,
                     properties=pika.BasicProperties(correlation_id = \
                                                         props.correlation_id),
                     body=str(response))
    ch.basic_ack(delivery_tag=method.delivery_tag)

channel.basic_qos(prefetch_count=1)
channel.basic_consume(queue='rpc_queue', on_message_callback=on_request)

print(" [x] Awaiting RPC requests")
channel.start_consuming()

5 微服务项目

微服务是一种软件架构风格,将一个大型应用程序拆分为一组更小、更独立的服务。
每个服务都有自己的数据库,并通过 API 与其他服务通信。
微服务架构有助于实现敏捷开发、提高可伸缩性和灵活性,并允许团队使用不同的技术栈来构建和维护各个服务。

以下是创建一个微服务项目的一般步骤:
1. **需求分析:**
   - 确定应用程序的功能和业务需求。
   - 划分服务边界,确定哪些功能可以独立作为微服务。
2. **技术栈选择:**
   - 选择适当的技术栈来构建每个微服务。不同的服务可以使用不同的编程语言和框架。
   - 确定服务之间的通信协议和数据格式,例如 RESTful API、GraphQL 等。
3. **服务设计:**
   - 定义每个微服务的接口和数据模型。
   - 考虑服务之间的依赖关系,确保它们可以独立部署和扩展。
4. **数据库选择:**
   - 对于每个微服务,选择适当的数据库。可以是关系型数据库、NoSQL 数据库,或者其他适合特定服务的存储方案。
5. **开发微服务:**
   - 每个团队负责一个或多个微服务的开发。
   - 使用容器化技术(如 Docker)来封装每个微服务,以简化部署和维护。
6. **服务间通信:**
   - 实现服务之间的通信机制,可以是 RESTful API、消息队列、gRPC 等。
   - 考虑服务发现、负载均衡和容错机制。
7. **部署和运维:**
   - 部署微服务到生产环境,可以使用容器编排工具(如 Kubernetes)来简化部署和管理。
   - 设置监控和日志系统,以便实时监控微服务的运行状况。
8. **测试:**
   - 编写单元测试、集成测试和端到端测试,确保微服务的正确性和稳定性。
   - 使用自动化测试工具来简化测试流程。
9. **监控和日志:**
   - 设置监控系统,跟踪微服务的性能指标和错误。
   - 集中处理微服务的日志,以便故障排除和分析。
10. **持续集成和持续部署:**
    - 实现持续集成和持续部署,确保新代码能够快速、安全地部署到生产环境。
11. **安全性:**
    - 实施适当的安全措施,包括身份验证、授权、数据加密等。
12. **扩展性:**
    - 考虑应对应用程序增长的需求,确保微服务体系结构能够水平扩展。
微服务架构的实施可能涉及到多个团队、技术栈和复杂的协调工作。
因此,采用适当的工具和实践,如 API 网关、服务注册与发现、断路器模式等,有助于简化微服务项目的开发和维护。
# 单体应用---》集群化部署

# 大单体拆成多个项目----》分布式架构

# soa  微服务架构


# 分布式事务
	# 这俩事在一个事务中
	flask的user_like表中增加一条记录
	django的product表中数字+1


# 只要 django增加一条产品---》flask的产品表中会增加一条记录


# 主站用java写的---》flask
# 后台管理用django写的--》django

在这里插入图片描述

9)

在这里插入图片描述

在这里插入图片描述

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值