如何在Python中使用ZeroMQ和Docker構建微服務架構

ghost_wyj 8年前發布 | 29K 次閱讀 Python ZeroMQ 微服務 Python開發

來自: http://dockone.io/article/1068

微服務是什么?

微服務是一種架構風格,它包括多個彼此間進行通信的獨立進程。在設計上,這些進程具有高度的可擴展性、相互解耦而且一次只完成一個較小的任務。這些服務都擁有自己的資源以及通過網絡實現彼此間通信的進程。

相比于靠后端的 單體結構 來封裝所有服務器邏輯的傳統客戶端-服務器架構(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

<pre><code>

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"]

</code></pre>

我們選擇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__)

<p>@app.route("/downcase/", methods=['GET'])</p>

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 &lt;name_of_client_file>.py 。如果你在以上的架構上進行構建,它可以很好地充當近實時的日志聚合引擎。

我在Unbuntu主機上對以上的代碼進行了測試。這里所用的代碼保管在 github 上。這是一個如何配置zmq、docker和python服務器的基礎講解,在我的下一片文章中我們會使用我們已經學習的東西構建簡單的微服務。

希望這篇文章對你有所幫助。

原文鏈接在 這里

</div>

 本文由用戶 ghost_wyj 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!