用 Python、 RabbitMQ 和 Nameko 实现微服务

原创 07-17 17:57 首页 Linux中国

"微服务是一股新浪潮" - 现如今,将项目拆分成多个独立的、可扩展的服务是保障代码演变的最好选择。在 Python 的世界里,有个叫做 “Nameko” 的框架,它将微服务的实现变得简单并且强大。

微服务

在最近的几年里,“微服务架构”如雨后春笋般涌现。它用于描述一种特定的软件应用设计方式,这种方式使得应用可以由多个独立部署的服务以服务套件的形式组成。 - M. Fowler

推荐各位读一下 Fowler 的文章[1] 以理解它背后的原理。

好吧,那它究竟意味着什么呢?

简单来说,微服务架构可以将你的系统拆分成多个负责不同任务的小的(单一上下文内)功能块responsibilities blocks,它们彼此互无感知,各自只提供用于通讯的通用指向common point。这个指向通常是已经将通讯协议和接口定义好的消息队列。

这里给大家提供一个真实案例

案例的代码可以通过 github: http://github.com/rochacbruno/nameko-example 访问,查看 service 和 api 文件夹可以获取更多信息。

想象一下,你有一个 REST API ,这个 API 有一个端点(LCTT 译注:REST 风格的 API 可以有多个端点用于处理对同一资源的不同类型的请求)用来接受数据,并且你需要将接收到的数据进行一些运算工作。那么相比阻塞接口调用者的请求来说,异步实现此接口是一个更好的选择。你可以先给用户返回一个 "OK - 你的请求稍后会处理" 的状态,然后在后台任务中完成运算。

同样,如果你想要在不阻塞主进程的前提下,在计算完成后发送一封提醒邮件,那么将“邮件发送”委托给其他服务去做会更好一些。

场景描述

用代码说话

让我们将系统创建起来,在实践中理解它:

环境

我们需要的环境:

  • 运行良好的 RabbitMQ(LCTT 译注:RabbitMQ[2] 是一个流行的消息队列实现)

  • 由 VirtualEnv 提供的 Services 虚拟环境

  • 由 VirtualEnv 提供的 API 虚拟环境

Rabbit

在开发环境中使用 RabbitMQ 最简单的方式就是运行其官方的 docker 容器。在你已经拥有 Docker 的情况下,运行:

  1. docker run -d --hostname my-rabbit --name some-rabbit -p 15672:15672 -p 5672:5672 rabbitmq:3-management

在浏览器中访问 http://localhost:15672 ,如果能够使用 guest:guest 验证信息登录 RabbitMQ 的控制面板,说明它已经在你的开发环境中运行起来了。

服务环境

现在让我们创建微服务来满足我们的任务需要。其中一个服务用来执行计算任务,另一个用来发送邮件。按以下步骤执行:

在 Shell 中创建项目的根目录

  1. $ mkdir myproject

  2. $ cd myproject

用 virtualenv 工具创建并且激活一个虚拟环境(你也可以使用 virtualenv-wrapper)

  1. $ virtualenv service_env

  2. $ source service_env/bin/activate

安装 nameko 框架和 yagmail

  1. (service_env)$ pip install nameko

  2. (service_env)$ pip install yagmail

服务的代码

现在我们已经准备好了 virtualenv 所提供的虚拟环境(可以想象成我们的服务是运行在一个独立服务器上的,而我们的 API 运行在另一个服务器上),接下来让我们编码,实现 nameko 的 RPC 服务。

我们会将这两个服务放在同一个 python 模块中,当然如果你乐意,也可以把它们放在单独的模块里并且当成不同的服务运行:

在名为 service.py 的文件中

  1. import yagmail

  2. from nameko.rpc import rpc, RpcProxy

  3. class Mail(object):

  4.    name = "mail"

  5.    @rpc

  6.    def send(self, to, subject, contents):

  7.        yag = yagmail.SMTP('myname@gmail.com', 'mypassword')

  8.        # 以上的验证信息请从安全的地方进行读取

  9.        # 贴士: 可以去看看 Dynaconf 设置模块

  10.        yag.send(to=to.encode('utf-8),

  11.                 subject=subject.encode('utf-8),

  12.                 contents=[contents.encode('utf-8)])

  13. class Compute(object):

  14.    name = "compute"

  15.    mail = RpcProxy('mail')    

  16.    @rpc

  17.    def compute(self, operation, value, other, email):

  18.        operations = {'sum': lambda x, y: int(x) + int(y),

  19.                      'mul': lambda x, y: int(x) * int(y),

  20.                      'div': lambda x, y: int(x) / int(y),

  21.                      'sub': lambda x, y: int(x) - int(y)}

  22.        try:

  23.            result = operations[operation](value, other)

  24.        except Exception as e:

  25.            self.mail.send.async(email, "An error occurred", str(e))

  26.            raise

  27.        else:

  28.            self.mail.send.async(

  29.                email,

  30.                "Your operation is complete!",

  31.                "The result is: %s" % result

  32.            )

  33.            return result

现在我们已经用以上代码定义好了两个服务,下面让我们将 Nameko RPC service 运行起来。

注意:我们会在控制台中启动并运行它。但在生产环境中,建议大家使用 supervisord 替代控制台命令。

在 Shell 中启动并运行服务

  1. (service_env)$ nameko run service --broker amqp://guest:guest@localhost

  2. starting services: mail, compute

  3. Connected to amqp://guest:**@127.0.0.1:5672//

  4. Connected to amqp://guest:**@127.0.0.1:5672//

测试

在另外一个 Shell 中(使用相同的虚拟环境),用 nameko shell 进行测试:

  1. (service_env)$ nameko shell --broker amqp://guest:guest@localhost

  2. Nameko Python 2.7.9 (default, Apr  2 2015, 15:33:21)

  3. [GCC 4.9.2] shell on linux2

  4. Broker: amqp://guest:guest@localhost

  5. >>>

现在你已经处在 RPC 客户端中了,Shell 的测试工作是通过 n.rpc 对象来进行的,它的使用方法如下:

  1. >>> n.rpc.mail.send("name@email.com", "testing", "Just testing")

上边的代码会发送一封邮件,我们同样可以调用计算服务对其进行测试。需要注意的是,此测试还会附带进行异步的邮件发送。

  1. >>> n.rpc.compute.compute('sum', 30, 10, "name@email.com")

  2. 40

  3. >>> n.rpc.compute.compute('sub', 30, 10, "name@email.com")

  4. 20

  5. >>> n.rpc.compute.compute('mul', 30, 10, "name@email.com")

  6. 300

  7. >>> n.rpc.compute.compute('div', 30, 10, "name@email.com")

  8. 3

在 API 中调用微服务

在另外一个 Shell 中(甚至可以是另外一台服务器上),准备好 API 环境。

用 virtualenv 工具创建并且激活一个虚拟环境(你也可以使用 virtualenv-wrapper)

  1. $ virtualenv api_env

  2. $ source api_env/bin/activate

安装 Nameko、 Flask 和 Flasgger

  1. (api_env)$ pip install nameko

  2. (api_env)$ pip install flask

  3. (api_env)$ pip install flasgger

注意: 在 API 中并不需要 yagmail ,因为在这里,处理邮件是服务的职责

创建含有以下内容的 api.py 文件:

  1. from flask import Flask, request

  2. from flasgger import Swagger

  3. from nameko.standalone.rpc import ClusterRpcProxy

  4. app = Flask(__name__)

  5. Swagger(app)

  6. CONFIG = {'AMQP_URI': "amqp://guest:guest@localhost"}

  7. @app.route('/compute', methods=['POST'])

  8. def compute():

  9.    """

  10.    Micro Service Based Compute and Mail API

  11.    This API is made with Flask, Flasgger and Nameko

  12.    ---

  13.    parameters:

  14.      - name: body

  15.        in: body

  16.        required: true

  17.        schema:

  18.          id: data

  19.          properties:

  20.            operation:

  21.              type: string

  22.              enum:

  23.                - sum

  24.                - mul

  25.                - sub

  26.                - div

  27.            email:

  28.              type: string

  29.            value:

  30.              type: integer

  31.            other:

  32.              type: integer

  33.    responses:

  34.      200:

  35.        description: Please wait the calculation, you'll receive an email with results

  36.    """

  37.    operation = request.json.get('operation')

  38.    value = request.json.get('value')

  39.    other = request.json.get('other')

  40.    email = request.json.get('email')

  41.    msg = "Please wait the calculation, you'll receive an email with results"

  42.    subject = "API Notification"

  43.    with ClusterRpcProxy(CONFIG) as rpc:

  44.        # asynchronously spawning and email notification

  45.        rpc.mail.send.async(email, subject, msg)

  46.        # asynchronously spawning the compute task

  47.        result = rpc.compute.compute.async(operation, value, other, email)

  48.        return msg, 200

  49. app.run(debug=True)

在其他的 shell 或者服务器上运行此文件

  1. (api_env) $ python api.py

  2. * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

然后访问 http://localhost:5000/apidocs/index.html 这个 url,就可以看到 Flasgger 的界面了,利用它可以进行 API 的交互并可以发布任务到队列以供服务进行消费。

注意: 你可以在 shell 中查看到服务的运行日志,打印信息和错误信息。也可以访问 RabbitMQ 控制面板来查看消息在队列中的处理情况。

Nameko 框架还为我们提供了很多高级特性,你可以从 https://nameko.readthedocs.org/en/stable/ 获取更多的信息。

别光看了,撸起袖子来,实现微服务!


via: http://brunorocha.org/python/microservices-with-python-rabbitmq-and-nameko.html

作者: Bruno Rocha[3] 译者: mr-ping[4] 校对: wxy[5]

本文由 LCTT[6] 原创编译,Linux中国[7] 荣誉推出


[1]: http://martinfowler.com/articles/microservices.html
[2]: http://rabbitmq.mr-ping.com/description.html
[3]: http://facebook.com/rochacbruno
[4]: http://www.mr-ping.com
[5]: https://github.com/wxy
[6]: https://github.com/LCTT/TranslateProject
[7]: https://linux.cn/

用 Python、 RabbitMQ 和 Nameko 实现微服务的更多相关文章

  1. 探索解析微服务下的RabbitMQ

    概览 本文主要介绍如何使用RabbitMQ消息代理来实现分布式系统之间的通信,从而促进微服务的松耦合. RabbitMQ,也被称为开源消息代理,它支持多种消息协议,并且可以部署在分布式系统上.它轻量级 ...

  2. 【微服务专题之】.Net6下集成消息队列上-RabbitMQ

    ​ 微信公众号:趣编程ACE关注可了解更多的.NET日常实战开发技巧,如需源码 请公众号后台留言 源码;[如果觉得本公众号对您有帮助,欢迎关注] .Net中RabbitMQ的使用 [微服务专题之].N ...

  3. 一个轻量级的.Net Core微服务快速开发的轮子

    前言     Adnc是一个轻量级的.Net Core微服务快速开发框架,同时也可以应用于单体架构系统的开发.框架基于JWT认证授权.集成了一系列微服务配套组件,代码简洁.易上手.学习成本低.开箱即用 ...

  4. 推荐一款 Python 微服务框架 - Nameko

    1. 前言 大家好,我是安果! 考虑到 Python 性能及效率性,Python Web 端一直不温不火,JAVA 和 Golang 的微服务生态一直很繁荣,也被广泛用于企业级应用开发当中 ​本篇文章 ...

  5. python 微服务开发书中几个方便的python框架

    python 微服务开发是一本讲python 如果进行微服务开发的实战类书籍,里面包含了几个很不错的python 模块,记录下,方便后期回顾学习 处理并发的模块 greenlet && ...

  6. 网易蜂巢微服务架构:用RabbitMQ实现轻量级通信

    本次分享内容由三个部分组成: 微服务架构与MQ RabbitMQ场景分析与优化 RabbitMQ在网易蜂巢中的应用和案例分享 1微服务架构与MQ 微服务架构是一种架构模式,它将单体应用划分成一组微小的 ...

  7. .NET Core微服务之基于EasyNetQ使用RabbitMQ消息队列

    Tip: 此篇已加入.NET Core微服务基础系列文章索引 一.消息队列与RabbitMQ 1.1 消息队列 “消息”是在两台计算机间传送的数据单位.消息可以非常简单,例如只包含文本字符串:也可以更 ...

  8. 微服务实战(三):落地微服务架构到直销系统(构建基于RabbitMq的消息总线)

    从前面文章可以看出,消息总线是EDA(事件驱动架构)与微服务架构的核心部件,没有消息总线,就无法很好的实现微服务之间的解耦与通讯.通常我们可以利用现有成熟的消息代理产品或云平台提供的消息服务来构建自己 ...

  9. 一)surging 微服务框架使用系列之surging 的准备工作rabbitmq安装(转载 https://www.cnblogs.com/alangur/p/8339905.html)

    (一)surging 微服务框架使用系列之surging 的准备工作rabbitmq安装   (1)下载erlang: http://www.erlang.org/download/otp_win64 ...

随机推荐

  1. TCP Provider The semaphore timeout period has expired

    我们一数据库服务器上有个作业最近几天偶尔会遇到下面错误(敏感信息已做处理),主要是报"TCP Provider: The semaphore timeout period has expir ...

  2. SQL SERVER普通用户需要什么权限才能执行sp_configure命令

    SQL SERVER普通用户需要什么权限才能执行sp_configure命令呢? 例如如下存储过程所示 CREATE PROCEDURE PRC_TEST AS BEGIN    exec sp_co ...

  3. Asp.Net MVC+BootStrap+EF6.0实现简单的用户角色权限管理8

    接下来做的是对页面的增删改查与页面与页面按钮之间的联系.先上代码和页面效果 using AuthorDesign.Web.App_Start.Common; using System; using S ...

  4. Rebuild Instance 操作详解 - 每天5分钟玩转 OpenStack(37)

    上一节我们讨论了 snapshot,snapshot 的一个重要作用是对 instance 做备份. 如果 instance 损坏了,可以通过 snapshot 恢复,这个恢复的操作就是 Rebuil ...

  5. Redis学习和环境搭建

    基本的redis教程,搭建,可以参照下面任一教程: 地址一:http://www.yiibai.com/redis/redis_quick_guide.html 地址二:http://www.runo ...

  6. Java IO工作机制分析

    Java的IO类都在java.io包下,这些类大致可分为以下4种: 基于字节操作的 I/O 接口:InputStream 和 OutputStream 基于字符操作的 I/O 接口:Writer 和 ...

  7. JS入门学习,写一个简单的图片库

    <!-- 新手刚开始学JS,每天坚持写点东西 坚持下去,希望能有所进步 .  加油~~ --> <!DOCTYPE html>                         ...

  8. Vijos P1196吃糖果游戏[组合游戏]

    描述 Matrix67和Shadow正在做一个小游戏. 桌子上放着两堆糖果,Matrix67和Shadow轮流对这些糖果进行操作.在每一次操作中,操作者需要吃掉其中一堆糖果,并且把另一堆糖果分成两堆( ...

  9. java程序设计之完数

    题目:一个数如果恰好等于它的因子之和,这个数就称为"完数".例如6=1+2+3.编程 找出1000以内的所有完数. 解题过程也很简单: public class wanshu { ...

  10. Java程序设计之扑克牌

    这段代码的主要实现功能扑克牌的洗牌和发牌功能,一副牌,红桃,黑桃,梅花,方片,A~K,不含大小王. 构造一个class. 首先是声明花色: private String[] sign={"方 ...