Вступ
- Архітектура мікросервісів — це підхід до проектування програмного забезпечення, який поділяє функціональність на менші, незалежні сервіси.
- Структурує застосунок як набір малих, слабко пов'язаних сервісів, кожен з яких відповідає за певну бізнес-можливість.
- Приклад: сервіс аутентифікації (auth service) обробляє запити на аутентифікацію, а сервіс платежів (payment service) відповідає за функціонал платежів.
Потік
Основи
- Автономність: Сервіси незалежні та можуть розроблятися, розгортатися та масштабуватися окремо.
- Малість і фокус: Кожен сервіс виконує одну задачу добре (Принцип єдиної відповідальності).
- Децентралізоване управління даними: Кожен сервіс може мати свою власну базу даних.
- Комунікація через API: Сервіси взаємодіють через легкі протоколи (наприклад, HTTP/REST).
- Ізоляція помилок: Помилка в одному сервісі не призводить до збоїв у всій системі.
Компоненти
Сервіс
- Основний функціональний підрозділ (наприклад, "Сервіс користувачів", "Сервіс платежів").
API Gateway
- Служить єдиною точкою входу для клієнтів.
- Обробляє маршрутизацію, балансування навантаження та безпеку (наприклад, аутентифікація, обмеження частоти запитів).
База даних
- Кожен сервіс зазвичай керує своєю власною базою даних, що забезпечує власність та незалежність даних.
Виявлення сервісів
- Допомагає сервісам знаходити один одного в динамічному середовищі розподіленої системи (наприклад, Consul, Eureka).
Повідомлення
- Сервіси комунікують асинхронно через брокери повідомлень (наприклад, RabbitMQ, Kafka).
Мікросервіси vs Моноліт
Проектування мікросервісів
Принципи
- Обмежені контексти: Сервіси повинні відповідати за певні функції в межах конкретних доменів.
2. Слабка зв'язність: Сервіси взаємодіють мінімально через чітко визначені API.
3. Висока когезія: Сервіси повинні зосереджуватися на одній бізнес-можливості.
4. Окрема база даних для сервісу: Кожен сервіс володіє своїми даними для запобігання тісному з'єднанню.
Розширене
- Логування: Централізоване логування за допомогою ELK стеку (Elasticsearch, Logstash, Kibana).
- Метрики: Моніторинг продуктивності (наприклад, Prometheus, Grafana).
- Трасування: Відстеження запитів між сервісами (наприклад, OpenTelemetry).
- Circuit Breaker: Запобігання каскадним збоям шляхом припинення викликів до несправних сервісів (наприклад, Hystrix, Resilience4j).
- Масштабування: Використання балансувальників навантаження для розподілу запитів (наприклад, Nginx, AWS).
- Орієнтованість на події: Створення роз'єднаних сервісів та систем навколо подій.
Простий додаток "To-Do список"
- Використовуючи традиційну монолітну архітектуру
- Потім, як це може бути реалізовано з використанням архітектури мікросервісів.
Монолітна архітектура
- Додаток є єдиним блоком, де всі функції знаходяться разом.
from flask import Flask, jsonify, request
app = Flask(__name__)
# Вбудоване сховище для задач
tasks = [
{"id": 1, "task": "Купити продукти", "done": False},
{"id": 2, "task": "Вивчити Flask", "done": False},
]
# Маршрути
@app.route('/tasks', methods=['GET'])
def get_tasks():
return jsonify(tasks)
@app.route('/tasks', methods=['POST'])
def add_task():
new_task = request.json
new_task["id"] = len(tasks) + 1
tasks.append(new_task)
return jsonify(new_task), 201
@app.route('/tasks/', methods=['PUT'])
def update_task(id):
task = next((t for t in tasks if t["id"] == id), None)
if task:
task["done"] = request.json.get("done", task["done"])
return jsonify(task)
return jsonify({"error": "Задачу не знайдено"}), 404
@app.route('/tasks/', methods=['DELETE'])
def delete_task(id):
global tasks
tasks = [t for t in tasks if t["id"] != id]
return jsonify({"message": "Задачу видалено"}), 200
if __name__ == "__main__":
app.run(debug=True)
- Увесь додаток знаходиться в одному файлі.
- Маршрути для отримання, створення, оновлення та видалення задач.
Архітектура мікросервісів
- Різні функціональні частини додатка поділяються на окремі сервіси.
Сервіс задач
- Керує задачами (створення, отримання, оновлення).
- Обробляє операції з задачами (create, read).
from flask import Flask, jsonify, request
app = Flask(__name__)
tasks = [{"id": 1, "task": "Купити продукти", "done": False}]
@app.route('/tasks', methods=['GET'])
def get_tasks():
return jsonify(tasks)
@app.route('/tasks', methods=['POST'])
def add_task():
new_task = request.json
new_task["id"] = len(tasks) + 1
tasks.append(new_task)
return jsonify(new_task), 201
if __name__ == "__main__":
app.run(debug=True, port=5001)
Сервіс користувачів
- Керує користувачами (автентифікація, інформація про користувача).
- Обробляє операції з користувачами (create, read).
from flask import Flask, jsonify, request
app = Flask(__name__)
users = [{"id": 1, "username": "john_doe", "password": "12345"}]
@app.route('/users', methods=['GET'])
def get_users():
return jsonify(users)
@app.route('/users', methods=['POST'])
def add_user():
new_user = request.json
new_user["id"] = len(users) + 1
users.append(new_user)
return jsonify(new_user), 201
if __name__ == "__main__":
app.run(debug=True, port=5002)
API Gateway
- Маршрутизує запити до відповідного мікросервісу.
- Спілкується з обома сервісами через HTTP запити.
from flask import Flask, jsonify, request
import requests
app = Flask(__name__)
TASK_SERVICE_URL = 'http://localhost:5001/tasks'
USER_SERVICE_URL = 'http://localhost:5002/users'
@app.route('/tasks', methods=['GET'])
def get_tasks():
response = requests.get(TASK_SERVICE_URL)
return jsonify(response.json())
@app.route('/tasks', methods=['POST'])
def add_task():
task = request.json
response = requests.post(TASK_SERVICE_URL, json=task)
return jsonify(response.json()), 201
@app.route('/users', methods=['GET'])
def get_users():
response = requests.get(USER_SERVICE_URL)
return jsonify(response.json())
@app.route('/users', methods=['POST'])
def add_user():
user = request.json
response = requests.post(USER_SERVICE_URL, json=user)
return jsonify(response.json()), 201
if __name__ == "__main__":
app.run(debug=True, port=5000)
Знайти мене на Github та LinkedIn @r-rahulsingh
Перекладено з: The Microservices Journey