1. Microservices
Микросервисы были очень популярны и о них много говорили в последние год или два.Короче говоря, микросервисы — это способ разработки одного приложения в виде набора, состоящего из множества небольших сервисов, каждый из которых имеет свой собственный процесс и использует облегченный механизм. (обычно API источника HTTP) обеспечивает связь. Вот пример изображения:
Microservices Architecture:
Две приведенные выше картинки уже показали, что такое микросервис, и метод развертывания программного обеспечения должен быть построен на контейнере. Экосистема, связанная с микросервисами, будет более зрелой на языках Java и Go, особенно на Java. Python как серверная часть слабее в этом аспекте.Среда микросервисов может видеть только Nameko, а технология не настолько зрелая.Поскольку текущая сцена Python для бизнеса немного больше, чем язык Go, давайте сначала поиграем с Python.Микросервисы.
2. Service Mesh and Serverless
Что касается микросервисов, то есть еще две популярные концепции, кратко упомянутые ниже.
2.1 Service Mesh
Концепция сервисной сетки Service Mesh поначалу неясна, и некоторые люди в Интернете также говорят о следующем поколении микросервисов.Проще говоря, когда тысячи микросервисов развернуты в Kubernetes, все становится довольно сложным, потому что каждый микросервис требуется проверка работоспособности, обработка ошибок, задержка и т. д. Хотя Kubernetes может обеспечивать проверку работоспособности и автоматическое восстановление, ему также требуется режим прерывателя цепи, обнаружение служб, управление API, проверка шифрования и т. д. Именно эти проблемы необходимо решить Service Mesh.
Более подробное введение:Фил Кальк ADO.com/2017/08/03/…
В качестве инфраструктурного уровня сервисной связи его можно сравнить с приложением или микросервисом TCP/IP, отвечающим за сетевые вызовы, текущие ограничения, предохранитель и мониторинг между сервисами. Для написанных приложений нет необходимости заботиться о TCP / IP (например, приложения RESTful через протокол HTTP), а сервисная сетка используется для достижения целей между приложениями или другими фреймворками.Например, Spring Cloud, теперь просто передайте его сервисная сетка.
Service Mesh имеет следующие характеристики:
- Средний уровень связи между приложениями
- Легкий веб-прокси
- приложение-агностик
- Раздельные повторные попытки/тайм-ауты приложений, мониторинг, отслеживание и обнаружение служб
Архитектура Service Mesh показана на следующем рисунке:
Более популярным программным обеспечением с открытым исходным кодом является Istio, и у меня есть возможность поиграть в него снова.
2.2 Serverless
Архитектура без сервеса, сначала связалась с саммитом технологии AWS, просто означает, что нет необходимости ухода за серверами, и весь вычислительный стек, включая процессы операционной системы, запускающие функциональный код, полностью управляются облачным провайдером. Это еще больше укрепляет концепцию дежобов.
На самом деле я играл в бессерверное приложение AWS Lambda, оно действительно удобно, оно упрощено до функции, а веб-сервисы можно реализовать через API Gateway + Lambda. Взимать плату в зависимости от количества запросов в настоящее время очень жалко, особенно когда количество запросов велико, стоимость намного дороже, чем развертывание приложения на Docker самостоятельно. Таким образом, текущий сценарий бессерверной архитектуры также очень подходит для некоторых разовых задач и очень удобен для сценариев с небольшим количеством запросов, участники-разработчики могут разработать собственное развертывание и больше не нужно заботиться о сервере. . Все операции по эксплуатации и техническому обслуживанию могут быть устранены, а разработчики могут больше сосредоточиться на развитии основного бизнеса, что обеспечивает быстрый запуск и итерацию.
3. Python framework for building microservices
3.1 Nameko Introduce
Nameko — микросервисный фреймворк на Python, находится по адресу https://github.com/nameko/nameko на git, популярность пока невысока, реализовано внедрение официальных документов:
It comes with built-in support for:
- RPC over AMQP
- Asynchronous events (pub-sub) over AMQP
- Simple HTTP GET and POST
- Websocket RPC and subscriptions (experimental)
Проще говоря, RPC построен на AMQP, который реализует публикацию и подписку на AMQP, реализует простые службы HTTP и Websocket RPC.
Это совершенно Педиатрический с экологией Явы. Архитектура использует RabbitMQ в качестве брокера сообщений для обеспечения связи между каждой службой Nameko.
Ознакомьтесь с официальной документацией для более подробной информации.
3.2 Practice
Далее потренируемся на примере бизнес-сценария.
Сцены:Предположим, что в социальном сценарии при комментировании чужой статьи сервер отправляет сообщение автору статьи, чтобы уведомить кого-то о необходимости комментировать, и сначала этот комментарий должен быть зарегистрирован.
Включает в себя 2 микросервиса, сервис регистрации и сервис push, и в то же время имеет интерфейс комментариев.
3.2.1 Окружающая среда Строительство:
- python3.5+
- RabbitMQ
- Redis 3.2.1
- Nameko 2.11.0
- Swagger
- Flask 1.0.2
Во-первых, вам нужно подготовить среду Python 3. Для простоты в качестве хранилища для входа и регистрации пользователей используется Redis, Nameko устанавливается с помощью pip, а RabbitMQ лучше всего устанавливать с Docker.
# RabbitMQ docker 安装命令
docker search rabbitmq
docker pull rabbitmq:3.7-rc-management
docker run -d --hostname my-rabbit --name some-rabbit -p 15672:15672 -p 5672:5672 rabbitmq:3.7-rc-management
# 需要默认运行在5672端口
Doc: https://github.com/docker-library/docs/tree/master/rabbitmq
# nameko 运行服务命令:
nameko run service --broker amqp://guest:guest@localhost
其中 guest:guest是RabbitMQ Docker镜像的用户名和密码
В то же время, чтобы облегчить тестирование API, пользовательский интерфейс Swagger предоставляется через Flasgger для интеграции Flask.
Когда вы готовые среды, начните раздел кода.
3.2.2 код демонстрирует:
├── app
│ └── api.py
├── dependence
│ ├── __init__.py
│ └── services
│ ├── __init__.py
│ ├── config.py
│ └── redis_service.py
└── microservices
├── push.py
└── register.py
Структура кода такая же, как указано выше:
- Служба интерфейса API хранится в приложении.
- зависимость можно понимать как базовый модуль.Многие микросервисы могут зависеть от пакетных сервисов, таких как интерфейсы redis и mysql.Как правило, если вы используете репозиторий Git, вы можете подмодулить к репозиторию конкретного сервиса.Здесь размещаются все тесты в одном репозитории.
- microservices Код микросервиса, здесь 2 сервиса, регистрация и пуш.
Есть 2 функции, которые нужно практиковать:
- Как вызывать микросервисы в коде API
- Как вызывать другие микросервисы в микросервисах
Давайте сначала представим код в зависимости:
# content of redis_service
class RedisService(object):
def __init__(self):
self.redis_instance = RedisClient.get_redis(
config.REDIS_NAME, config.REDIS_HOST, config.REDIS_PORT,
config.REDIS_DB)
self.users_key = "users"
self.users_data_key = "users_data"
def check_registered_and_get_info(self, u_id):
"""
Check if the user is registered and return user information if registered.
"""
user_data = self.redis_instance.hget(self.users_data_key, u_id)
if not user_data:
return False, None
return True, json.loads(user_data)
def check_email_is_registered(self, email):
u_id = self.redis_instance.hget(self.users_key, email)
return u_id
def register(self, u_id, email, data):
self.redis_instance.hset(self.users_key, email, u_id)
result = self.redis_instance.hset(self.users_data_key, u_id,json.dumps(data))
return result
- check_registered_and_get_info Проверить, был ли он зарегистрирован, если он был зарегистрирован, получить информацию о пользователе и вернуться
- check_email_is_registered Проверить, зарегистрирован ли адрес электронной почты дважды
- зарегистрируйтесь, чтобы зарегистрироваться и сохранить информацию о пользователе
Затем посмотрите на часть кода API:
# content of api.py
import time
import random
from flask import Flask, request, jsonify
from flasgger import Swagger
from nameko.standalone.rpc import ClusterRpcProxy
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--port", help="app running port", type=int, default=5000)
parse_args = parser.parse_args()
app = Flask(__name__)
Swagger(app)
CONFIG = {'AMQP_URI': "amqp://guest:guest@localhost"}
Принципал кода отображается отдельно. Эта часть является справочной частью. Nameko и Swagger требуется. Nameko - агент службы RPC, который предоставляет микросервисы. В то же время необходимо предоставить конфигурацию. Содержание является адресом Сообщение брокер, который на самом деле rabbitmq. SWARGER сочетается с колбой, чтобы облегчить тестирование API на веб-интерфейсе.
# content of api.py
@app.route('/api/v1/comment', methods=['POST'])
def comment():
"""
Comment API
Parameters Explain:
timestamp 评论时间
u_id 用户id
content 评论内容
article_id 文章ID
article_u_id 文章作者用户id
parent_comment_id 父评论id (optional)
---
parameters:
- name: body
in: body
required: true
schema:
id: comment
properties:
timestamp:
type: integer
u_id:
type: string
content:
type: string
article_id:
type: integer
article_u_id:
type: integer
parent_comment_id:
type: integer
responses:
code:
description: 0 Comment Success!
message:
description: Error Message!
data:
description: return comment_id
"""
data = request.json
article_u_id = data.get("article_u_id")
u_id = data.get("u_id")
code, message = 0, ""
if not article_u_id or not u_id:
code, message = 10003, "article_u_id or u_id is null."
response = dict(code=code, message=message, data="")
return jsonify(response)
with ClusterRpcProxy(CONFIG) as rpc:
user_data = rpc.register.check_registered(u_id)
if not user_data:
code, message = 10004, "You need to register to comment."
response = dict(code=code, message=message, data="")
return jsonify(response)
# push message
print("Push Message: article_u_id: {}".format(article_u_id))
result, message = rpc.push.push(article_u_id, data.get("content"))
print("push result: {}, message: {}".format(result, message))
# save comment data
print("Save Comment Data: article_id: {} content: {}".format(
data.get("article_id"), data.get("content")))
data = dict(comment_id=int(time.time()))
response = dict(code=0, message="", data=data)
return jsonify(response)
Интерфейс комментариев, часть описания - предоставить описание интерфейса API Swagger (спецификация должна следовать спецификации SWARGER, вы можете проверить официальный документ для получения подробной информации), предоставить идентификатор пользователя комментариев, идентификатор статьи, содержание комментария, И идентификатор пользователя автора статьи (для простоты, непосредственно предоставленного клиентом, обычный сценарий - найти идентификатор пользователя автора на основе идентификатора статьи).
Функция реализована также очень просто.Сначала проверьте службу регистрации, позвонив, чтобы узнать, зарегистрировался ли комментатор.Если нет, он сразу вернется к необходимости зарегистрироваться для комментирования. Если он был зарегистрирован, вызывается push-сервис для отправки push-уведомлений автору. После этого и сохраните информацию о комментарии, верните идентификатор комментария.
Ключевая информация — зарегистрироваться и запустить реализацию микросервиса, а также сохранить информацию о комментариях. Я печатаю ее прямо здесь, не выполняя никаких реальных операций.
@app.route('/api/v1/register', methods=['POST'])
def register():
"""
Register API
Parameters Explain:
timestamp 注册时间
email 注册邮箱
name 名称
language 语言
country 国家
---
parameters:
- name: body
in: body
required: true
schema:
id: data
properties:
timestamp:
type: integer
email:
type: string
name:
type: string
language:
type: string
country:
type: string
responses:
code:
description: 0 register success.
message:
description: Error Message!
data:
description: return u_id
"""
user_data = request.json
email = user_data.get("email")
code, message = 0, ""
if not email:
code, message = 10000, "email is null."
response = dict(code=code, message=message, data="")
return jsonify(response)
u_id = None
with ClusterRpcProxy(CONFIG) as rpc:
u_id, message = rpc.register.register(email, user_data)
if message:
code = 10001
data = dict(u_id=u_id)
response = dict(code=code, message=message, data=data)
return jsonify(response)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=int(parse_args.port), debug=True)
Это последний раздел api.py, который реализует интерфейс регистрации. Короче говоря, он вызывает службу регистрации. Если он был зарегистрирован, он возвращается напрямую, в противном случае он сохраняет информацию о пользователе.
Ключ заключается в реализации службы регистрации.
бегатьpython api.py
Открытымhttp://localhost:5000/apidocs/
Вы можете увидеть следующий интерфейс:
Нажмите на один из API, вы увидите следующий интерфейс:
Очень удобно отлаживать интерфейс API.
Следующий момент — продемонстрировать часть кода микросервиса:
import random
from nameko.rpc import rpc
import sys
sys.path.append("..")
from dependence.services import RedisService
class RegisterService(object):
name = "register"
def __init__(self):
self.redis_handle = RedisService()
@rpc
def check_registered(self, u_id):
is_registered, user_data = self.redis_handle.check_registered_and_get_info(u_id)
if is_registered:
return user_data
return None
@staticmethod
def generate_u_id():
"""
Test Function
"""
return str(random.randint(7000000, 9999999))
@rpc
def register(self, email, user_data):
u_id = self.redis_handle.check_email_is_registered(email)
if u_id:
return u_id, "already registered."
u_id = self.generate_u_id()
register_result = self.redis_handle.register(u_id, email, user_data)
if register_result:
return u_id, ""
return None, "register failed.
Обратите внимание на реализацию register, вам нужно импортировать nameko.rpc, и украсить функцию rpc. Реализация очень простая, код внутри это логическая часть, которая генерирует u_id и сохраняет его в redis.
Таким образом реализуется первая функция, вызывающая микросервис в API.
Далее посмотрите на реализацию Push-сервиса:
import random
from nameko.rpc import rpc, RpcProxy
import sys
sys.path.append("..")
from dependence.services import RedisService
class PushService(object):
name = "push"
register_rpc = RpcProxy("register")
@rpc
def push(self, u_id, content):
user_data = self.register_rpc.check_registered(u_id)
if not user_data:
print("User:{} not existed.".format(u_id))
return False, "not registered."
language, country = user_data["language"], user_data["country"]
# get language push content
print("Push Progress: u_id: {} language: {}, country: {}, content: {}".
format(u_id, language, country, content))
return True, "push success."
В push-сервисе необходимо вызвать службу регистрации, чтобы определить, зарегистрирован ли автор статьи (на самом деле, он должен быть зарегистрирован, чтобы иметь возможность опубликовать статью, которая ссылается на демо здесь). , для вызова микросервиса в микросервисе требуется дополнительный импорт RpcProxy, и сервис регистрации RpcProxy("register"), а потом вызывать его в сервисе, и получать информацию о пользователе, судить о языке и стране, и пушить соответствующий языковое содержание.
В целом, структура Nameko, реализация уровня кода очень проста, легка, проста и практична. Тем не менее, функции не завершены, и сценариев для серверных приложений Python не так много.
3.2.3 Отладка
开三个终端,分别运行:
cd microservices & nameko run push
cd microservices & nameko run register
cd app & python api.py
Открытымhttp://localhost:5000/apidocs/#/
Подготовьте регистрационные данные:
注册信息1
{
"country": "CN",
"email": "nameko@nameko.com",
"language": "ZH",
"name": "xiaohua",
"timestamp": 1553652949
}
注册信息2
{
"country": "CN",
"email": "nameko2@nameko.com",
"language": "ZH",
"name": "xiaoming",
"timestamp": 1553652950
}
Пример операции:
Возвращенные сообщения:
返回信息1
{
"code": 0,
"data": {
"u_id": "7434029"
},
"message": ""
}
返回信息2
{
"code": 0,
"data": {
"u_id": "8240184"
},
"message": ""
}
Вызов push-интерфейса:
Нажмите, чтобы выполнить.
возвращенные сообщения:
информация о печати терминала python api.py:
Push Message: article_u_id: 7434029
push result: True, message: push success.
Save Comment Data: article_id: 100 content: very good.
127.0.0.1 - - [27/Mar/2019 23:24:07] "POST /api/v1/comment HTTP/1.1" 200 -
Здесь демонстрируется микросервис Python, полный код github addressGitHub.com/Хрустальное небо Z…
Далее поговорим о RPC.
Для получения более интересных статей, пожалуйста, обратите внимание на публичный аккаунт «Tiancheng Technology Talk».