如何在Python中使用ZeroMQ和Docker构建微服务架构
微服务是什么?
微服务是一种架构风格,它包括多个彼此间进行通信的独立进程。在设计上,这些进程具有高度的可扩展性、相互解耦而且一次只完成一个较小的任务。这些服务都拥有自己的资源以及通过网络实现彼此间通信的进程。
相比于靠后端的单体结构来封装所有服务器逻辑的传统客户端-服务器架构(C/S架构)而言,微服务架构的差异性体现在关注点分离(Separation of concern)。这种设计模式更易于维护,使得灵活性、可扩展性及容错能力更强。但是这种分布式架构所的不足之处体现在如果设计不合理就会使得排错及维护变得复杂。
一个简单微服务的例子
让我们来分析这样的一个场景:你正在使用微服务模式构建一个电子商务网店。
对于一个电商网店上的常见商品,好比说iPhone,其详情页会显示:
- 产品的及基本信息
- 你的购买历史
- 哪些人买了iPhone也买了手机套
- 与苹果手机相关的优惠和折扣
- 店家的数据
- 送货方式
- 推荐商品等等
此外,这个简单的产品详情页的接口将有多个版本的来匹配Web、移动端以及用于第三方应用程序的REST API。
在微服务模式中数据分布在多个服务之间。在这个例子中,服务包括:
- 产品详情服务
- 商家服务
- 支付服务
- 优惠及折扣服务
- 库存服务
- 定价服务
- 回顾服务
- 推荐服务
这些独立的服务是如何被访问的呢?
解决办法是使用一个API网管,它作为所有客户端的单一入口并且根据需求调用分布在整个基础架构中的特定微服务。以上模式的行业应用案例是NetFlix API网关,它具有支持不同设备的多个API客户端。你可以点击此处了解更多。
构建一个简单的微服务
目前有很多方法可以用于构建你的微服务。
在本文中我们将使用ZeroMQ来创建两个进程之间的通信。ZeroMQ提供了用于在套接字之上开发可扩展、分布式systed的构建块。它使用椭圆曲线密码体制(第四版)来实现安全性,并提供了即刻开启的通讯模式。
关于ZMQ,还有很多优点。MQ即是针对异步工作而设计的线程化消息队列。谈论太多zeroMQ的内容已经超出了本文的范畴,你可以阅读使用zeromq以及zeromq用于分布式系统。
我们要使用的另一个工具是Docker。本文假设读者对Docker已经有了基础的了解。
ZeroMQ有很多种通讯模式,为了开始我们的工作,让我们用ZeroMQ和Flask来配置一个简单的PUB-SUB。下图展示了组件之间的关系和数据流。

- 1&3 - 一个flask服务器运行在5000端口上而且其URL是
/downcase/。该URL用来接受(GET)请求,而所有格式为的请求将收到回应:答谢字符将会转换为小写字符并返回。 - 2 - 回应的消息也被发送给同一个容器中的ZMQ发布者(Publisher)
- 4,5 - ZMQ订阅者(subscriber)持续监听并将来自ZMQ服务器的消息保存到名为
subscriber.log的文件中
创建服务器
首先看一下我们的Dockerfile
FROM ubuntu:14.04
RUN apt-get update
RUN apt-get install -y --force-yes python python-dev python-setuptools software-properties-common gcc python-pip
RUN apt-get clean all RUN pip install pyzmq RUN pip install Flask ADD zmqserver.py /tmp/zmqserver.py # # Flask Port EXPOSE 5000 # # Zmq Sub Server EXPOSE 4444 CMD ["python","/tmp/zmqserver.py"]
我们选择Ubuntu 14.04作为容器操作系统。我们安装了基本的软件包。通过pip,我们安装pyzmq(zeromq的Python绑定)同时也安装了Flask。接着我们导出端口5000(flask服务器)和4444(发布者运行的端口)。此外,我们复制了包含所有flask及zeromq pythond代码的脚本文件zmqserver.py并运行它。
现在我们来看一下zmqserver.py的内容:
# server.py
import time
import zmq HOST = '127.0.0.1'
PORT = '4444' _context = zmq.Context()
_publisher = _context.socket(zmq.PUB)
url = 'tcp://{}:{}'.format(HOST, PORT) def publish_message(message):
try:
_publisher.bind(url)
time.sleep(1)
_publisher.send(message) except Exception as e:
print "error {}".format(e)
finally: _publisher.unbind(url) from flask import Flask
from flask import request
app = Flask(__name__) @app.route("/downcase/", methods=['GET'])
def lowerString(): _strn = request.args.get('param')
response = 'lower case of {} is {}'.format(_strn, _strn.lower()) publish_message(response)
return response if __name__ == '__main__':
app.run(host='0.0.0.0', debug=False)
ZMQ发布者运行在4444端口上。我们创建了一个context并且声明了URL。我们运行了flask app,它通过URL /downcase/把GET获得的参数Param转换成小写字符,这就是服务的应答。应答的字符串是published,它作为一个消息把相同的字符串返回给浏览器。
为了构建以上的Docker映像(image),我们执行以下的命令:sudo docker build -t docker-zmq-pub
并且在该映像之上执行:docker run --name docker-pub-server -p 5000:5000 -p 4444:4444 -t docker-zmq-pub。
我们把容器中的端口5000和4444映射到这台主机上,于是无论客户端在哪里,它们都可以订阅这个发布者。
订阅者客户端
# client.py
import zmq
import sys
import time
import logging
import os HOST = '127.0.0.1'
PORT = '4444' logging.basicConfig(filename='subscriber.log', level=logging.INFO) class ZClient(object): def __init__(self, host=HOST, port=PORT):
"""Initialize Worker"""
self.host = host
self.port = port
self._context = zmq.Context()
self._subscriber = self._context.socket(zmq.SUB)
print "Client Initiated" def receive_message(self):
"""Start receiving messages"""
self._subscriber.connect('tcp://{}:{}'.format(self.host, self.port))
self._subscriber.setsockopt(zmq.SUBSCRIBE, b"") while True:
print 'listening on tcp://{}:{}'.format(self.host, self.port)
message = self._subscriber.recv()
print message
logging.info(
'{} - {}'.format(message, time.strftime("%Y-%m-%d %H:%M"))) if __name__ == '__main__':
zs = ZClient()
zs.receive_message()
我们声明了发布者的IP地址及端口,当前它运行在同一个的主机上因此地址是127开头。我们在URL tcp://IP:PORT上进行监听。一旦我们收到一个消息,就将其附上时间戳后记录到名为subscriber.log的文件中。运行客户端要做的所有工作就是执行 python <name_of_client_file>.py。如果你在以上的架构上进行构建,它可以很好地充当近实时的日志聚合引擎。
我在Unbuntu主机上对以上的代码进行了测试。这里所用的代码保管在GitHub上。这是一个如何配置ZMQ、Docker和Python服务器的基础讲解,在我的下一片文章中我们会使用我们已经学习的东西构建简单的微服务。
希望这篇文章对你有所帮助。
原
如何在Python中使用ZeroMQ和Docker构建微服务架构的更多相关文章
- 使用 Spring Cloud 和 Docker 构建微服务架构
如何使用Spring Boot.Spring Cloud.Docker和Netflix的一些开源工具来构建一个微服务架构. 本文通过使用Spring Boot.Spring Cloud和Docker构 ...
- 使用Spring Cloud和Docker构建微服务架构
原文:https://dzone.com/articles/microservice-architecture-with-spring-cloud-and-do 作者:Alexander Lukyan ...
- 手把手教你用Spring Cloud和Docker构建微服务
什么是Spring Cloud? Spring Cloud 是Pivotal提供的用于简化分布式系统构建的工具集.Spring Cloud引入了云平台连接器(Cloud Connector)和服务连接 ...
- 基于 Docker 的微服务架构实践
本文来自作者 未闻 在 GitChat 分享的{基于 Docker 的微服务架构实践} 前言 基于 Docker 的容器技术是在2015年的时候开始接触的,两年多的时间,作为一名 Docker 的 D ...
- 使用Spring Boot,Spring Cloud和Docker实现微服务架构
https://github.com/sqshq/PiggyMetrics Microservice Architecture with Spring Boot, Spring Cloud a ...
- 【译文】用Spring Cloud和Docker搭建微服务平台
by Kenny Bastani Sunday, July 12, 2015 转自:http://www.kennybastani.com/2015/07/spring-cloud-docker-mi ...
- 【SFA官方翻译】使用 Kubernetes、Spring Boot 2.0 和 Docker 的微服务快速指南
[SFA官方翻译]使用 Kubernetes.Spring Boot 2.0 和 Docker 的微服务快速指南 原创: Darren Luo SpringForAll社区 今天 原文链接:https ...
- 几种常见的微服务架构方案——ZeroC IceGrid、Spring Cloud、基于消息队列、Docker Swarm
微服务架构是当前很热门的一个概念,它不是凭空产生的,是技术发展的必然结果.虽然微服务架构没有公认的技术标准和规范草案,但业界已经有一些很有影响力的开源微服务架构平台,架构师可以根据公司的技术实力并结合 ...
- Spring Cloud和Docker搭建微服务平台
用Spring Cloud和Docker搭建微服务平台 This blog series will introduce you to some of the foundational concepts ...
随机推荐
- win10更新后 chrome内核浏览器总是打开网页一直加载 甚至打不开 解决方法
https://blog.csdn.net/qq754772661/article/details/81452131 升级win10之后如果出现chrome内核的浏览器网页总是打不开 打开很慢 而ie ...
- submit form to convert to a Java Bean model.
实体类中无需构造函数. Since we haven’t specified a constructor, Java will provide a default constructor that w ...
- 《SQL 基础教程》第二章:查询基础
这一章的结构如下: SELECT 语句基础 算术运算符和比较运算符 逻辑运算符 SELECT 语句可用于查询数据,并且可以设定条件来查询具有特定值的记录.条件的设定就需要算数运算符.比较运算符和逻辑运 ...
- webpack2与promise在IE环境下
webpack2好像说是要自己编译es6,但是结果不是很理想,es6的箭头函数他就没有编译,所以目前还是先用babel来转换吧, 之前用的ajax是axios,底层是promise,但是promise ...
- 553. Optimal Division
题目: Given a list of positive integers, the adjacent integers will perform the float division. For ex ...
- 『TensorFlow』单&双隐藏层自编码器设计
计算图设计 很简单的实践, 多了个隐藏层 没有上节的高斯噪声 网络写法由上节的面向对象改为了函数式编程, 其他没有特别需要注意的,实现如下: import numpy as np import mat ...
- 『TensorFlow』网络操作API_中_损失函数及分类器
一.误差值 度量两个张量或者一个张量和零之间的损失误差,这个可用于在一个回归任务或者用于正则的目的(权重衰减). l2_loss tf.nn.l2_loss(t, name=None) 解释:这个函数 ...
- ThinkPHP5.0源码学习之框架启动流程
ThinkPHP5框架的启动流程图如下: ThinkPHP5的启动流程按照文件分为三步: 1.请求入口(public/index.php) 2.框架启动(thinkphp/start.php) 3.应 ...
- MAC 下 Excel打开UTF-8格式的文件乱码
为了识别 Unicode 文件,Microsoft 建议所有的 Unicode 文件应该以 ZERO WIDTH NOBREAK SPACE字符开头.这作为一个”特征符”或”字节顺序标记(byte-o ...
- pfSense-2.4.4安装教程
一.说明 1.1 pfSense是什么 pfSense是基于FreeBSD的.开源中最为可靠(World's Most Trusted Open Source Firewall)的.可与商业级防火墙一 ...