python-37-python微服务框架Nameko

Python微服务框架nameko的简单使用
推荐一款 Python 微服务框架 - Nameko

微服务框架有Istio、Dubbo和nameko三种:
一、Istio
Istio是一个用来连接、管理和保护微服务的开放平台,使用Istio可以建立已部署服务网络,且Istio具备负载均衡、服务间认证、监控等功能。

二、Dubbo
Dubbo是一个利用同步通信实现的分布式微服务框架,其致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。

三、nameko
nameko是一个利用异步通信方式实现的微服务框架,其采用RabbitMQ消息队列作为消息中间件,原理简单,使用方便。

在后端开发方面,Java的使用呢要远比Python广泛,所以Java的微服务框架非常流行,但Python的微服务框架却很少有人问津。在大多数需要微服务的场合下直接用Java的各种工具就可以解决问题,但如果业务代码使用Python写的,那么使用Java工具就不太方便了。
其实Python也有自己的微服务框架,其中用的最多的就是nameko,nameko框架轻便,使用简单,易上手,是一个很不错的微服务框架。

1 微服务

1.1 什么是微服务

首先假设要做一款简化版的微信产品,它只有如下几个功能。那么你的初期系统设计应该是这样的:
(1)微信单体架构
python-37-python微服务框架Nameko_第1张图片

随着时间的迁移,跨年夜,同一时刻,很多人都在发朋友圈,朋友圈接口访问量很大,服务器访问峰值瞬间冲顶,那么我们可以开始做集群操作,也就是整一个服务器做集群操作。

那么我们的注册登录接口、支付接口、聊天接口也有了一个复制集,但此刻这几个接口其实并没有很大的访问量,那我们能不能只将朋友圈的接口做扩容呢?答案当然是可以的,基于微服务架构进行扩容。
(2)微服务架构
python-37-python微服务框架Nameko_第2张图片
直接水平扩展朋友圈服务,如下图,峰值压力有所缓解。
python-37-python微服务框架Nameko_第3张图片
然而在各个功能拆解成一个个的服务之后,由客户端直接访问各个微服务,这样就直接将我们的服务暴露了出来,客户端也需要定制相应的访问策略。这样的设计还是没有那么友好。那么,我们能不能将所有微服务统一到一起呢?且看下图:
(3)微服务架构Plus
python-37-python微服务框架Nameko_第4张图片
在这张示例图中,多了一个API Gateway模块,那API网关是用来干嘛的呢?一般情况下 API 网关有以下任务:路由,安全,限流,缓存,日志,监控,重试,熔断等,然后服务层就纯粹的做业务,也能够很好的保证业务代码的干净,不用关心安全,压力等方面的问题。

(4)微服务的特征与优势
微服务特征:单一职责;轻量级的通信;隔离性,运行在自己的进程中,不会相互干扰;有自己的数据,数据的独立性,每个微服务都有自己的数据库;技术的多样性,选用适合的技术做合适的事。

一个微服务就负责某一个职责,就像朋友圈服务,它就只负责朋友圈的增删查功能,与其他服务独立开来,可以选用不同的技术语言,来满足不同的需求。

微服务的优势:独立性、敏捷性、技术栈灵活、高效团队。

(5)微服务的不足
额外的工作、数据一致性、沟通成本、debug 单元测试困难、需要额外工作。

1.2 微服务框架原理

微服务架构最重要的就是使用什么方式进行服务间通信(也称作服务调用),按照通信方式的不同,主要可以分为同步通信和异步通信两种方式:

1.1.1 同步通信

同步调用比较简单,一致性强,但是容易出调用问题,性能体验上也会差些。同步通信最常用的两种协议是RESTful和RPC,而目前使用最广泛,最有名的两种微服务框架Spring Cloud和Dubbo分别使用了RESTful和RPC协议。RESTful和RPC两种协议各有优势,具体使用要看业务场景。

Dubbo框架是一个非常流行的采用同步通信的分布式微服务框架,下图就是Dubbo框架的工作原理图:
python-37-python微服务框架Nameko_第5张图片
首先一个微服务应用程序需要有服务的生产者和服务的消费者,另外还需要一个注册中心(常见的有zookeeper和RabbitMQ等)来管理和调度服务。

微服务架构的程序运行的一般步骤为:
(1)服务提供方,即生产者启动服务,并将服务提交到注册中心注册服务。
(2)服务需求方,即消费者连接到注册中心,向注册中心发出请求,申请需要的服务。
(3)注册中心根据消费者发出的请求来调度服务,将对应的服务提供者(生产者)的信息发送给消费者。
(4)消费者和生产者之间建立连接,消费者调用服务。
(5)记录服务调用过程中的信息。

1.1.2 异步通信

异步通信一般通过消息中间件来进行服务间通信,消息中间件能为调用之间提供的缓冲,确保消息积压不会冲垮被调用方,同时能保证调用方的服务体验,继续干自己该干的活,不至于被后台性能拖慢。不过需要付出的代价是一致性的减弱。

Nameko框架就是一个采用异步通信方式的微服务框架,采用RabbitMQ消息队列作为消息中间件,原理非常简单,使用起来也很方便。
python-37-python微服务框架Nameko_第6张图片

2 基于Nameko框架的微服务程序

2.1 安装注册中心RabbitMQ

Nameko采用RabbitMQ作为注册中心,所以使用Nameko必须要先安装RabbitMQ。

以docker容器的方式运行RabbitMQ是最为简便快捷的方式,两行命令就搞定了,这里介绍如何使用docker运行RabbitMQ。

第一步:从DockerHub拉取rabbitmq镜像

docker pull rabbitmq:management

第二步:运行RabbitMQ容器

docker run -d --hostname my-rabbit --name rabbit -p 15672:15672 -p 5672:5672 rabbitmq:management
参数分析如下docker run -d 
--hostname my-rabbit 
--name rabbit 
-p 15672:15672 控制台Web访问端口号
-p 5672:5672 应用访问端口
rabbitmq:management

如果需要设置用户名和密码,则使用这条命令

docker run -d --hostname my-rabbit --name rabbit -e RABBITMQ_DEFAULT_USER=user -e RABBITMQ_DEFAULT_PASS=password -p 15672:15672 -p 5672:5672 rabbitmq:management
参数分析如下docker run -d 
--hostname my-rabbit 
--name rabbit 
-e RABBITMQ_DEFAULT_USER=user 
-e RABBITMQ_DEFAULT_PASS=password 
-p 15672:15672 控制台Web访问端口号
-p 5672:5672 应用访问端口
rabbitmq:management

我运行容器时没有设置用户名和密码,所以使用用户名guest,密码guest登录。
http://localhost:15672/
http://192.168.1.10:15672/
在浏览器中通过下面的连接进入到MQ后台Web管理页面
python-37-python微服务框架Nameko_第7张图片
登录成功界面
python-37-python微服务框架Nameko_第8张图片

2.2 服务生产者和服务消费者

pip install nameko

2.2.1 create_service.py

create_service.py发布服务,服务名称为“helloservice”。

from nameko.rpc import rpc

class hello_service:
    name = "helloservice"

    @rpc
    def hello(self):
        print("hello world")
        
    @rpc
    def hi(self):
        print("my name is lucy")

2.2.2 启动注册微服务

使用nameko框架的run命令启动微服务。

nameko run create_service --broker amqp://guest:[email protected]

如果显示信息如下则表示服务成功启动
在这里插入图片描述

2.2.3 invoke_service.py

invoke_service.py调用服务进行消费。

from nameko.standalone.rpc import ClusterRpcProxy

CONFIG = {'AMQP_URI': "amqp://guest:[email protected]"}


def compute():
    with ClusterRpcProxy(CONFIG) as rpc:
        rpc.helloservice.hello()


if __name__ == '__main__':
    compute()

运行invoke_service.py调用服务后在命令行打印出“hello world”,服务被成功调用。
在这里插入图片描述

3 举例如下

3.1 服务生产者producer_service.py

自定一个类,使用name属性定义服务的名称为generate_service。然后使用装饰器rpc注册服务中具体的方法。

from nameko.rpc import rpc

class GenerateService(object):
    # 定义微服务名称
    name = "generate_service"

    @rpc
    def hello_world(self, msg):
        print('hello,I am been called by customer(消费者),返回消息:{}'.format(msg))
        # 返回结果
        return "Hello World!I Am a msg from producer!"

3.2 发布注册服务

使用nameko命令在终端将目标文件中的服务注册到MQ中。

# 注册服务
nameko run producer_service --broker amqp://guest:[email protected]:5672/
参数分析如下
producer_service:目标文件名称
guest:guest:MQ用户名及密码
ip地址:5672:MQ服务器ip地址及应用端口号

3.3 Flask定义API及消费者调用服务

为了演示方便,这里使用Flask编写一个简单的API。
(1)首先,定义MQ连接信息
(2)然后,编写一个API接口,请求方式为GET。
(3)最后,使用nameko中的ClusterRpcProxy拿到消费者对象去调用服务中的具体方法。

from flask import Flask
from nameko.standalone.rpc import ClusterRpcProxy

app = Flask(__name__)

# MQ配置
config_mq = {'AMQP_URI': "amqp://guest:[email protected]"}

@app.route('/hello_world', methods=['GET'])
def call_service():
    with ClusterRpcProxy(config_mq) as rpc:
        # 消费者调用微服务(生产者),获取服务(生产者)的返回值
        # rpc.服务名.方法名
        result = rpc.generate_service.hello_world(msg="xag msg")

        # 返回结果
        return result, 200
if __name__ == '__main__':
    app.run(debug=True)

3.4 测试结果

使用Postman调用上面的API接口,就能完成消费者调用生成者服务中的方法,拿到返回结果的完整流程。
http://127.0.0.1:5000/hello_world。

上面以Flask为例讲解了微服务的搭建的完整流程,如果是其他Web框架(比如Django、FastAPI等)集成微服务流程是类似的。

你可能感兴趣的:(python3,python)