使用Python,RabbitMQ和Nameko的微服务

“Micro-services is the new black” – Splitting the project in to independently scalable services is the currently the best option to ensure the evolution of the code. In Python there is a Framework called “Nameko” which makes it very easy and powerful.

“微服务是新的黑手” –将项目拆分为独立可扩展的服务是当前确保代码发展的最佳选择。 在Python中,有一个叫做“ Nameko”的框架,它使它非常容易和强大。

微服务 (Micro services)

The term “Microservice Architecture” has sprung up over the last few years to describe a particular way of designing software applications as suites of independently deployable services. – M. Fowler

在过去的几年中,出现了“微服务体系结构”一词,用于描述将软件应用程序设计为可独立部署的服务套件的特定方式。 –福勒先生

I recommend reading the Fowler’s posts to understand the theory behind it.

我建议阅读Fowler的文章,以了解其背后的理论。

好吧,我是什么意思? (Ok I so what does it mean?)

In brief a Micro Service Architecture exists when your system is divided in small (single context bound) responsibilities blocks, those blocks doesn’t know each other, they only have a common point of communication, generally a message queue, and does know the communication protocol and interfaces.

简而言之,当您的系统划分为小块(绑定单个上下文)职责块时, 微服务体系结构存在,这些块彼此不认识,它们只有一个公共的通信点,通常是消息队列 ,并且确实知道通信协议和接口。

给我一个真实的例子 (Give me a real-life example)

Consider you have an REST API, that API has an endpoint receiving some data and you need to perform some kind of computation with that data, instead of blocking the caller you can do it asynchronously, return an status “OK – Your request will be processed” to the caller and do it in a background task.

考虑您有一个REST API,该API的端点接收一些数据,您需要对该数据执行某种计算,而不是阻塞调用方,您可以异步进行操作,返回状态“确定–您的请求将被处理”,然后在后台任务中执行。

Also you want to send an email notification when the computation is finished without blocking the main computing process, so it is better to delegate the “email sending” to another service.

另外,您还希望在计算完成后发送电子邮件通知,而不会阻塞主计算过程,因此最好将“电子邮件发送”委托给其他服务。

情境 (Scenario)

enter image description here

给我看看代码! (Show me the code!)

Lets create the system to understand it in practice.

让我们创建一个系统以在实践中理解它。

环境 (Environment)

We need an environment with:

我们需要一个具有以下条件的环境:

  • A running RabbitMQ
  • Python VirtualEnv for services
  • Python VirtualEnv for API
  • 正在运行的RabbitMQ
  • 适用于服务的Python VirtualEnv
  • 适用于API的Python VirtualEnv

兔子 (Rabbit)

The easiest way to have a RabbitMQ in development environment is running its official docker container, considering you have Docker installed run:

考虑到已安装Docker,在开发环境中使用RabbitMQ的最简单方法是运行其官方Docker容器:

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

Go to the browser and access http://localhost:15672 using credentials guest:guest if you can login to RabbitMQ dashboard it means you have it running locally for development.

转到浏览器并使用凭据guest:guest访问http:// localhost:15672,如果您可以登录RabbitMQ仪表板,则意味着您已在本地运行该开发板。

enter image description here

服务环境 (The Service environment)

Now lets create the Micro Services to consume our tasks. We’ll have a service for computing and another for mail, follow the steps.

现在,让我们创建微服务以使用我们的任务。 请按照以下步骤提供用于计算的服务和用于邮件的另一服务。

In a shell create the root project directory

在shell中创建根项目目录

Create and activate a virtualenv (you can also use virtualenv-wrapper)

创建并激活virtualenv(您也可以使用virtualenv-wrapper)

$ virtualenv service_env
$ source service_env/bin/activate
$ virtualenv service_env
$ source service_env/bin/activate
 

Install nameko framework and yagmail

安装nameko框架和yagmail

服务代码 (The service code)

Now having that virtualenv prepared (consider you can run service in a server and API in another) lets code the nameko RPC Services.

现在已经准备好了virtualenv(考虑可以在服务器上运行服务,而在另一台服务器上运行API),则可以为nameko RPC Services编码。

We are going to put both services in a single python module, but you can also split in separate modules and also run them in separate servers if needed.

我们将把这两个服务放在一个单独的python模块中,但是您也可以拆分成单独的模块,并在需要时在单独的服务器中运行它们。

In a file called service.py

在名为service.py的文件中

import yagmail
from nameko.rpc import rpc, RpcProxy


class Mail(object):
    name = "mail"

    @rpc
    def send(self, to, subject, contents):
        yag = yagmail.SMTP('myname@gmail.com', 'mypassword')
        # read the above credentials from a safe place.
        # Tip: take a look at Dynaconf setting module
        yag.send(to, subject, contents)


class Compute(object):
    name = "compute"
    mail = RpcProxy('mail')    

    @rpc
    def compute(self, operation, value, other, email):
        operations = {'sum': lambda x, y: x + y,
                      'mul': lambda x, y: x * y,
                      'div': lambda x, y: x / y,
                      'sub': lambda x, y: x - y}
        try:
            result = operations[operation](value, other)
        except Exception as e:
            self.mail.send.async(email, "An error occurred", str(e))
            raise
        else:
            self.mail.send.async(
                email, 
                "Your operation is complete!", 
                "The result is: %s" % result
            )
            return result
import yagmail
from nameko.rpc import rpc, RpcProxy


class Mail(object):
    name = "mail"

    @rpc
    def send(self, to, subject, contents):
        yag = yagmail.SMTP('myname@gmail.com', 'mypassword')
        # read the above credentials from a safe place.
        # Tip: take a look at Dynaconf setting module
        yag.send(to, subject, contents)


class Compute(object):
    name = "compute"
    mail = RpcProxy('mail')    

    @rpc
    def compute(self, operation, value, other, email):
        operations = {'sum': lambda x, y: x + y,
                      'mul': lambda x, y: x * y,
                      'div': lambda x, y: x / y,
                      'sub': lambda x, y: x - y}
        try:
            result = operations[operation](value, other)
        except Exception as e:
            self.mail.send.async(email, "An error occurred", str(e))
            raise
        else:
            self.mail.send.async(
                email, 
                "Your operation is complete!", 
                "The result is: %s" % result
            )
            return result
 

Now with the above services definition we need to run it as a Nameko RPC service.

现在,使用上面的服务定义,我们需要将其作为Nameko RPC服务运行。

NOTE: We are going to run it in a console and leave it running, but in production it is recommended to put the service to run using supervisord or an alternative.

注意:我们将在控制台中运行它,并使其保持运行状态,但是在生产环境中,建议使用管理员或替代方法使该服务运行。

运行服务,并使其在外壳中运行 (Run the service and let it running in a shell)

测试它 (Testing it)

Go to another shell (with the same virtenv) and test it using nameko shell

转到另一个具有相同nameko shell并使用nameko shell测试它

(service_env)$ nameko shell --broker amqp://guest:guest@localhost
Nameko Python 2.7.9 (default, Apr  2 2015, 15:33:21) 
[GCC 4.9.2] shell on linux2
Broker: amqp://guest:guest@localhost
>>>
(service_env)$ nameko shell --broker amqp://guest:guest@localhost
Nameko Python 2.7.9 (default, Apr  2 2015, 15:33:21) 
[GCC 4.9.2] shell on linux2
Broker: amqp://guest:guest@localhost
>>>
 

You are now in the RPC client testing shell exposing the n.rpc object, play with it

您现在在RPC客户端测试外壳中,公开了n.rpc对象,并对其进行处理

The above should sent an email and we can also call compute service to test it, note that it also spawns an async mail sending with result.

上面应该发送了一封电子邮件,我们也可以调用计算服务进行测试,请注意,它还会产生一个异步邮件发送结果。

>>> n.rpc.compute.compute('sum', 30, 10, "name@email.com")
40
>>> n.rpc.compute.compute('sub', 30, 10, "name@email.com")
20
>>> n.rpc.compute.compute('mul', 30, 10, "name@email.com")
300
>>> n.rpc.compute.compute('div', 30, 10, "name@email.com")
3
>>> n.rpc.compute.compute('sum', 30, 10, "name@email.com")
40
>>> n.rpc.compute.compute('sub', 30, 10, "name@email.com")
20
>>> n.rpc.compute.compute('mul', 30, 10, "name@email.com")
300
>>> n.rpc.compute.compute('div', 30, 10, "name@email.com")
3
 

通过API调用微服务 (Calling the micro-service through the API)

In a different shell (or even a different server) prepare the API environment

在不同的外壳(甚至是不同的服务器)中,准备API环境

Create and activate a virtualenv (you can also use virtualenv-wrapper)

创建并激活virtualenv(您也可以使用virtualenv-wrapper)

Install Nameko, Flask and Flasgger

安装Nameko,Flask和Flasgger

(api_env)$ pip install nameko
(api_env)$ pip install flask
(api_env)$ pip install flasgger
(api_env)$ pip install nameko
(api_env)$ pip install flask
(api_env)$ pip install flasgger
 

NOTE: In api you dont need the yagmail because it is service responsability

注意:在api中,您不需要yagmail,因为它是服务责任

Lets say you have the following code in a file api.py

假设您在api.py文件中有以下代码

Put the above API to run in a different shell or server

将以上API放在其他Shell或服务器中运行

(api_env) $ python api.py 
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
(api_env) $ python api.py 
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 

and then access the url http://localhost:5000/apidocs/index.html you will see the Flasgger UI and you can interact with the api and start producing tasks on queue to the service to consume.

然后访问URL http:// localhost:5000 / apidocs / index.html,您将看到Flasgger UI,并且可以与api交互并开始在队列中生成任务以使用该服务。

[image]

NOTE: You can see the shell where service is running for logging, prints and error messages. You can also access the RabbitMQ dashboard to see if there is some message in process there.

注意:您可以看到运行服务的外壳程序,用于记录日志,打印消息和错误消息。 您也可以访问RabbitMQ仪表板以查看是否有任何消息在处理中。

翻译自: https://www.pybloggers.com/2016/03/microservices-with-python-rabbitmq-and-nameko/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值