Подорож мікросервісів

pic

Вступ

  • Архітектура мікросервісів — це підхід до проектування програмного забезпечення, який поділяє функціональність на менші, незалежні сервіси.
  • Структурує застосунок як набір малих, слабко пов'язаних сервісів, кожен з яких відповідає за певну бізнес-можливість.
  • Приклад: сервіс аутентифікації (auth service) обробляє запити на аутентифікацію, а сервіс платежів (payment service) відповідає за функціонал платежів.

Потік

pic

Основи

  • Автономність: Сервіси незалежні та можуть розроблятися, розгортатися та масштабуватися окремо.
  • Малість і фокус: Кожен сервіс виконує одну задачу добре (Принцип єдиної відповідальності).
  • Децентралізоване управління даними: Кожен сервіс може мати свою власну базу даних.
  • Комунікація через API: Сервіси взаємодіють через легкі протоколи (наприклад, HTTP/REST).
  • Ізоляція помилок: Помилка в одному сервісі не призводить до збоїв у всій системі.

Компоненти

Сервіс

  • Основний функціональний підрозділ (наприклад, "Сервіс користувачів", "Сервіс платежів").

API Gateway

  • Служить єдиною точкою входу для клієнтів.
  • Обробляє маршрутизацію, балансування навантаження та безпеку (наприклад, аутентифікація, обмеження частоти запитів).

База даних

  • Кожен сервіс зазвичай керує своєю власною базою даних, що забезпечує власність та незалежність даних.

Виявлення сервісів

  • Допомагає сервісам знаходити один одного в динамічному середовищі розподіленої системи (наприклад, Consul, Eureka).

Повідомлення

  • Сервіси комунікують асинхронно через брокери повідомлень (наприклад, RabbitMQ, Kafka).

pic

Мікросервіси vs Моноліт

pic

Проектування мікросервісів

Принципи

  1. Обмежені контексти: Сервіси повинні відповідати за певні функції в межах конкретних доменів.

2. Слабка зв'язність: Сервіси взаємодіють мінімально через чітко визначені API.

3. Висока когезія: Сервіси повинні зосереджуватися на одній бізнес-можливості.

4. Окрема база даних для сервісу: Кожен сервіс володіє своїми даними для запобігання тісному з'єднанню.

Розширене

  • Логування: Централізоване логування за допомогою ELK стеку (Elasticsearch, Logstash, Kibana).
  • Метрики: Моніторинг продуктивності (наприклад, Prometheus, Grafana).
  • Трасування: Відстеження запитів між сервісами (наприклад, OpenTelemetry).
  • Circuit Breaker: Запобігання каскадним збоям шляхом припинення викликів до несправних сервісів (наприклад, Hystrix, Resilience4j).
  • Масштабування: Використання балансувальників навантаження для розподілу запитів (наприклад, Nginx, AWS).
  • Орієнтованість на події: Створення роз'єднаних сервісів та систем навколо подій.
    pic

Простий додаток "To-Do список"

  • Використовуючи традиційну монолітну архітектуру
  • Потім, як це може бути реалізовано з використанням архітектури мікросервісів.

Монолітна архітектура

pic

  • Додаток є єдиним блоком, де всі функції знаходяться разом.
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)
  • Увесь додаток знаходиться в одному файлі.
  • Маршрути для отримання, створення, оновлення та видалення задач.

Архітектура мікросервісів

pic

  • Різні функціональні частини додатка поділяються на окремі сервіси.

Сервіс задач

  • Керує задачами (створення, отримання, оновлення).
  • Обробляє операції з задачами (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

Leave a Reply

Your email address will not be published. Required fields are marked *