Technologiczne, Gadżety, Telefony Komórkowe, Pobieranie Aplikacji!

Jak budować i wdrażać mikrousługi za pomocą Pythona

We współczesnym rozwoju oprogramowania mikrousługi stały się kluczową architekturą, umożliwiającą skalowalność, elastyczność i efektywne zarządzanie złożonymi systemami.

Mikrousługi to małe, niezależne aplikacje, które wykonują określone zadania, umożliwiając elastyczne wdrażanie i skalowanie. To modułowe podejście do projektowania oprogramowania rozluźnia powiązanie między komponentami, zwiększając elastyczność i łatwość zarządzania w całym procesie rozwoju.

Artykuł zawiera przegląd mikrousług, ich funkcjonalności i tworzenia przy użyciu Pythona. Demonstruje również wdrażanie mikrousług w Kinsta przy użyciu pliku Dockerfile.

Czym są mikrousługi?

Mikrousługi to niezależne, autonomiczne usługi w ramach aplikacji, z których każda odpowiada na określone potrzeby biznesowe. Komunikują się za pośrednictwem lekkich interfejsów API lub brokerów wiadomości, tworząc kompleksowy system.

W przeciwieństwie do systemów monolitycznych, które skalują się całkowicie na podstawie popytu, mikrousługi umożliwiają skalowanie poszczególnych komponentów o dużym natężeniu ruchu. Ta architektura ułatwia łatwe zarządzanie błędami i aktualizacje funkcji, przeciwdziałając ograniczeniom monolitycznym.

Korzystanie z mikrousług niesie ze sobą szereg korzyści, takich jak:

  • Elastyczność i skalowalność — Rozdzielenie poszczególnych usług pozwala na zwiększenie liczby węzłów, na których działa wystąpienie określonej usługi o dużym natężeniu ruchu.
  • Modułowość kodu — Każda usługa może wykorzystywać odrębny stos technologii, co oznacza, że ​​możesz wybrać najlepsze narzędzia programistyczne dla każdej z nich.

Jednak architekturze mikrousług towarzyszą pewne wyzwania:

  • Monitorowanie wielu usług — Monitorowanie poszczególnych usług w systemie staje się trudne, gdy instancje danej usługi są wdrażane i dystrybuowane w kilku węzłach. Trudność ta jest szczególnie widoczna podczas awarii sieci lub innych problemów z systemem.
  • Koszt — Tworzenie aplikacji mikrousługowych może być znacznie droższe niż budowanie systemów monolitycznych ze względu na koszty związane z zarządzaniem wieloma usługami. Każda usługa wymaga własnej infrastruktury i zasobów, co może stać się kosztowne — szczególnie podczas skalowania systemu.

Jak zaprojektować mikrousługę za pomocą Pythona

Teraz, gdy już znasz korzyści płynące ze stosowania architektury mikrousług, czas zbudować ją w Pythonie.

W tym przykładzie załóżmy, że chcesz zbudować aplikację internetową e-commerce. Witryna ma kilka komponentów, w tym katalog produktów, listę zamówień oraz system przetwarzania płatności i dzienniki, z których każdy musisz wdrożyć jako niezależną usługę. Ponadto musisz ustanowić metodę komunikacji między usługami, aby przesyłać dane między tymi usługami, np. HTTP, w sposób wydajny.

Zbudujmy mikrousługę przy użyciu Pythona, aby zarządzać katalogiem produktów. Mikrousługa będzie pobierać dane o produktach ze wskazanego źródła i zwracać dane w formacie JSON.

Wymagania wstępne

Aby skorzystać z tego samouczka, upewnij się, że posiadasz:

1. Utwórz swój projekt

  1. Aby rozpocząć, utwórz folder dla swojego projektu o nazwie kolba-mikrousługa i bieżący katalog do katalogu projektu.
  2. Następnie uruchom python3 –version, aby sprawdzić, czy Python został prawidłowo zainstalowany na Twoim komputerze.
  3. Zainstaluj virtualenv, aby utworzyć odizolowane środowisko programistyczne dla mikrousługi Flask, uruchamiając poniższe polecenie:
    pip3 install virtualenv
  4. Utwórz środowisko wirtualne, uruchamiając następujące polecenie:
    virtualenv venv
  5. Na koniec należy aktywować środowisko wirtualne za pomocą jednego z poniższych poleceń, w zależności od systemu operacyjnego komputera:
    # Windows: 
    .\venv\Scripts\activate
    # Unix or macOS:
    source venv/bin/activate

2. Skonfiguruj serwer Flask

W katalogu głównym utwórz wymagania.txt plik i dodaj te zależności.

flask
requests

Uruchom polecenie pip3 w terminalu, aby zainstalować zależności.

pip install -r requirements.txt

Następnie utwórz nowy folder w katalogu głównym i nadaj mu nazwę Usługi. W tym folderze utwórz nowy plik, produkty.pyi dodaj poniższy kod, aby skonfigurować serwer Flask.

import requests
import os
from flask import Flask, jsonify
app = Flask(__name__)
port = int(os.environ.get('PORT', 5000))

@app.route("/")
def home():
    return "Hello, this is a Flask Microservice"
if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0", port=port)

W powyższym kodzie skonfigurowano podstawowy serwer Flask. Inicjuje on aplikację Flask, definiuje pojedynczą trasę dla głównego adresu URL („/”) i po uzyskaniu dostępu wyświetla komunikat „Hello, this is a Flask Microservice”. Serwer działa na określonym porcie, uzyskanym ze zmiennej środowiskowej lub domyślnie na porcie 5000, i uruchamia się w trybie debugowania, przygotowując się do obsługi przychodzących żądań.

3. Zdefiniuj punkty końcowe interfejsu API

Po skonfigurowaniu serwera utwórz punkt końcowy interfejsu API dla mikrousługi pobierającej dane produktu z publicznie dostępny API. Dodaj ten kod do produkty.py plik:

BASE_URL = "https://dummyjson.com"
@app.route('/products', methods=['GET'])
def get_products():
    response = requests.get(f"{BASE_URL}/products")
    if response.status_code != 200:
        return jsonify({'error': response.json()['message']}), response.status_code
    products = []
    for product in response.json()['products']:
        product_data = {
            'id': product['id'],
            'title': product['title'],
            'brand': product['brand'],
            'price': product['price'],
            'description': product['description']
        }
        products.append(product_data)
    return jsonify({'data': products}), 200 if products else 204

Powyższy kod tworzy punkt końcowy /products na serwerze Flask. Po uzyskaniu dostępu za pomocą żądania GET pobiera dane produktu z fikcyjnego interfejsu API. Jeśli się powiedzie, przetwarza pobrane dane, wyodrębnia szczegóły produktu i zwraca informacje w formacie JSON. W przypadku błędów lub braku dostępnych danych odpowiada odpowiednim komunikatem o błędzie i kodem statusu.

4. Przetestuj mikrousługę

W tym momencie udało Ci się pomyślnie skonfigurować prostą mikrousługę. Aby uruchomić usługę, uruchom serwer deweloperski, który zacznie działać pod adresem http://localhost:5000.

flask --app services/products run

Następnie możesz wysłać żądanie GET do punktu końcowego /products przy użyciu klienta Postman. Powinieneś zobaczyć odpowiedź podobną do tej na zrzucie ekranu poniżej.

Testowanie żądania GET interfejsu API HTTP w programie Postman.

Jak wdrożyć uwierzytelnianie i autoryzację w mikrousłudze Python

Podczas tworzenia mikrousług ważne jest wdrożenie solidnych środków bezpieczeństwa, takich jak uwierzytelnianie i autoryzacja. Zabezpieczenie mikrousługi zapewnia, że ​​tylko autoryzowani użytkownicy mogą uzyskać dostęp do usługi i z niej korzystać, chroniąc poufne dane i zapobiegając złośliwym atakom.

Jedną ze skutecznych metod wdrażania bezpiecznego uwierzytelniania i autoryzacji w mikrousługach są JSON Web Tokens (JWT).

JWT to szeroko stosowany otwarty standard, który zapewnia bezpieczny i wydajny sposób przesyłania informacji uwierzytelniających między klientami a serwerami. Są to kompaktowe, szyfrowane i podpisane cyfrowo tokeny, które przekazujesz wraz z żądaniami HTTP. Gdy dołączasz JWT do każdego żądania, serwer może szybko zweryfikować tożsamość i uprawnienia użytkownika.

Aby wdrożyć uwierzytelnianie JWT w mikrousłudze, wykonaj następujące czynności:

  1. Dodaj pakiet pyjwt języka Python do swojego wymagania.txt skompiluj plik i zainstaluj ponownie zależności za pomocą pip install -r requirements.txt.
  2. Ponieważ usługa nie posiada dedykowanej bazy danych, utwórz użytkownicy.json plik w katalogu głównym swojego projektu, aby przechowywać listę autoryzowanych użytkowników. Wklej poniższy kod w pliku:
    [
        {   
            "id": 1,
            "username": "admin",
            "password": "admin"
        
        }
    ]

    Informacje

    Dzięki naszej usłudze hostingu baz danych możesz łatwo skonfigurować preferowaną bazę danych (PostgreSQL, MariaDB, Redis i MySQL) na potrzeby swoich mikrousług.

  3. Następnie w twoim usługi/produkty.py plik, zamień polecenia importu na następujące:
    import requests 
    from flask import Flask, jsonify, request, make_response
    import jwt
    from functools import wraps
    import json
    import os
    from jwt.exceptions import DecodeError

    Importujesz te moduły, aby obsługiwać żądania HTTP, tworzyć aplikacje Flask, zarządzać danymi JSON, wdrażać uwierzytelnianie oparte na JWT i obsługiwać wyjątki, co umożliwia korzystanie z szerokiej gamy funkcji w serwerze Flask.

  4. Dodaj poniższy kod poniżej instancji aplikacji Flask, aby wygenerować klucz tajny, który będzie używany do podpisywania tokenów JWT.
    app.config['SECRET_KEY'] = os.urandom(24)
  5. Aby zweryfikować JWT, utwórz funkcję dekoratora i dodaj następujący kod nad trasami API w kodzie serwera Flask. Ta funkcja dekoratora uwierzytelni i zweryfikuje użytkowników przed uzyskaniem dostępu do chronionych tras.
    def token_required(f):
        @wraps(f)
        def decorated(*args, **kwargs):
            token = request.cookies.get('token')
            if not token:
                return jsonify({'error': 'Authorization token is missing'}), 401
            try:
                data = jwt.decode(token, app.config['SECRET_KEY'], algorithms=["HS256"])
                current_user_id = data['user_id']
            except DecodeError:
                return jsonify({'error': 'Authorization token is invalid'}), 401
            return f(current_user_id, *args, **kwargs)
        return decorated

    Ta funkcja dekoratora sprawdza przychodzące żądania HTTP pod kątem tokenu autoryzacji JWT, który powinien znajdować się w nagłówkach żądania lub plikach cookie. Jeśli token jest nieobecny lub nieprawidłowy, dekorator wysyła komunikat o nieautoryzowanym kodzie stanu jako odpowiedź.

    Odwrotnie, jeśli obecny jest prawidłowy token, dekorator wyodrębnia identyfikator użytkownika po jego zdekodowaniu. Ten proces zabezpiecza chronione punkty końcowe API, udzielając dostępu tylko autoryzowanym użytkownikom.

  6. Zdefiniuj punkt końcowy interfejsu API do uwierzytelniania użytkownika, korzystając z poniższego kodu.
    with open('users.json', 'r') as f:
        users = json.load(f)
    @app.route('/auth', methods=['POST'])
    def authenticate_user():
        if request.headers['Content-Type'] != 'application/json':
            return jsonify({'error': 'Unsupported Media Type'}), 415
        username = request.json.get('username')
        password = request.json.get('password')
        for user in users:
            if user['username'] == username and user['password'] == password:
                token = jwt.encode({'user_id': user['id']}, app.config['SECRET_KEY'],algorithm="HS256")
                response = make_response(jsonify({'message': 'Authentication successful'}))
                response.set_cookie('token', token)
                return response, 200
        return jsonify({'error': 'Invalid username or password'}), 401

    Aby uwierzytelnić i autoryzować użytkowników, punkt końcowy API /auth sprawdza poświadczenia w ładunku JSON żądania POST w porównaniu z listą dozwolonych użytkowników. Jeśli poświadczenia są prawidłowe, generuje token JWT przy użyciu identyfikatora użytkownika i tajnego klucza aplikacji i ustawia token jako plik cookie w odpowiedzi. Użytkownicy mogą teraz używać tego tokena do wykonywania kolejnych żądań API.

    Po utworzeniu punktu końcowego /auth użyj Postmana, aby wysłać żądanie HTTP POST do http://localhost:5000/auth. W treści żądania uwzględnij dane uwierzytelniające użytkownika pozorowanego administratora, którego utworzyłeś.

    Żądanie Postmana pokazujące treść żądania.

    Jeśli żądanie zostanie zrealizowane pomyślnie, interfejs API wygeneruje token JWT, umieści go w plikach cookie programu Postman i wyśle ​​uwierzytelnioną odpowiedź potwierdzającą powodzenie żądania.

  7. Na koniec zaktualizuj punkt końcowy interfejsu API GET, aby sprawdzić i zweryfikować token JWT, korzystając z poniższego kodu:
    @app.route('/products', methods=['GET'])
    @token_required
    def get_products(current_user_id):
        headers = {'Authorization': f'Bearer {request.cookies.get("token")}'}    
        response = requests.get(f"{BASE_URL}/products", headers=headers)
        if response.status_code != 200:
            return jsonify({'error': response.json()['message']}), response.status_code
        products = []
        for product in response.json()['products']:
            product_data = {
                'id': product['id'],
                'title': product['title'],
                'brand': product['brand'],
                'price': product['price'],
                'description': product['description']
            }
            products.append(product_data)
        return jsonify({'data': products}), 200 if products else 204

Jak konteneryzować mikrousługi Pythona za pomocą Dockera

Docker to platforma, która pakuje aplikacje i ich zależności w odizolowanym środowisku programistycznym. Pakowanie mikrousług w kontenerach usprawnia ich procesy wdrażania i zarządzania na serwerach, ponieważ każda usługa działa i wykonuje się niezależnie w swoim kontenerze.

Aby umieścić mikrousługę w kontenerze, należy utworzyć obraz Dockera z pliku Dockerfile, który określa zależności wymagane do uruchomienia aplikacji w kontenerze. Utwórz Plik Dockerfile w katalogu głównym swojego projektu i dodaj następujące instrukcje:

FROM python:3.9-alpine
WORKDIR /app
COPY requirements.txt ./
RUN pip install -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["python", "./services/products.py"]

Przed utworzeniem obrazu należy zapoznać się z poniższymi poleceniami:

  • FROM — instruuje Docker, którego obrazu bazowego użyć. Obraz bazowy to wstępnie zbudowana instancja zawierająca oprogramowanie i zależności do uruchomienia aplikacji Flask w kontenerze.
  • WORKDIR — Ustawia określony katalog w kontenerze jako katalog roboczy.
  • COPY requirements.txt ./ — Kopiuje zależności w pliku wymagania.txt plik do kontenera wymagania.txt plik.
  • URUCHOM — uruchamia określone polecenie w celu zainstalowania zależności wymaganych przez obraz.
  • KOPIUJ . . — Kopiuje wszystkie pliki z katalogu głównego projektu do katalogu roboczego wewnątrz kontenera.
  • EXPOSE — Określa port, na którym kontener będzie nasłuchiwał żądań. Jednak Docker nie publikuje portu na komputerze hosta.
  • CMD — określa domyślne polecenie, które ma zostać wykonane po uruchomieniu kontenera.

Następnie dodaj .dockerignore plik w katalogu głównym projektu, aby określić pliki, które obraz Docker powinien wykluczyć. Ograniczenie zawartości obrazu zmniejszy jego ostateczny rozmiar i powiązany czas kompilacji.

/venv
/services/__pycache__/
.gitignore

Teraz uruchom poniższe polecenie, aby zbudować obraz Dockera:

docker build -t flask-microservice .

Na koniec, po skompilowaniu obrazu, możesz uruchomić mikrousługę w kontenerze Docker, używając następującego polecenia:

docker run -p 5000:5000 flask-microservice

To polecenie uruchomi kontener Docker, w którym uruchomiona zostanie mikrousługa, i udostępni port 5000 kontenera portowi 5000 maszyny hosta, umożliwiając wysyłanie żądań HTTP z przeglądarki internetowej lub programu Postman przy użyciu adresu URL http://localhost:5000.

Wdrażanie mikrousług Python z Kinsta

Kinsta oferuje zarządzane rozwiązania hostingowe dla aplikacji internetowych i baz danych — możesz bezproblemowo wdrażać i zarządzać mikrousługami Python i interfejsami API zaplecza w środowisku produkcyjnym.

Aby skonfigurować mikrousługę Flask do wdrożenia za pomocą MyKinsta, wykonaj następujące kroki:

  1. Najpierw utwórz nowy Plik proc w katalogu głównym i dodaj poniższy kod. Określa on polecenie uruchomienia mikrousługi Flask na serwerze Gunicorn WSGI HTTP firmy Kinsta dla aplikacji Python.
    web: gunicorn services.wsgi
  2. W twoim wymagania.txt plik, dodaj zależność Gunicorn:
    gunicorn==20.1.*
  3. Następnie utwórz nowy usługi/wsgi.py plik i dodaj poniższy kod.
    from services.products import app as application
    if __name__ == "__main__":
                    application.run()
  4. Utwórz .gitignore plik w folderze głównym projektu i dodaj następujące elementy:
    services/__pycache__
    venv
  5. Na koniec utwórz nowe repozytorium w serwisie GitHub i prześlij pliki swojego projektu.

Gdy repozytorium będzie gotowe, wykonaj poniższe kroki, aby wdrożyć mikrousługę Flask w Kinsta:

  1. Zaloguj się lub utwórz konto, aby wyświetlić panel MyKinsta.
  2. Autoryzuj Kinsta u swojego dostawcy Git (Bitbucket, GitHub lub GitLab).
  3. Trzask Aplikacje na pasku bocznym po lewej stronie, a następnie kliknij Dodaj aplikację.
  4. Na pulpicie kliknij Dodaj usługęi wybierz Aplikacja.
  5. Wybierz repozytorium i gałąź, z której chcesz dokonać wdrożenia.
  6. Nadaj swojej aplikacji unikalną nazwę i wybierz lokalizacja centrum danych.
  7. Aby skonfigurować Zbudować środowisko, wybierz opcję użycia Plik Dockerfile aby zbudować obraz kontenera.
  8. Podaj ścieżkę do pliku Dockerfile i kontekst.
  9. Na koniec przejrzyj inne informacje i kliknij Utwórz aplikację.

Przetestuj mikrousługę

Po pomyślnym zakończeniu procesu wdrażania kliknij podany przycisk Adres URL aby przetestować mikrousługę, tworząc żądania HTTP w Postman. Utwórz żądanie GET do punktu końcowego root.

Żądanie HTTP API GET do punktu końcowego produktu mikrousługi.

Aby uwierzytelnić i wygenerować token JWT, wyślij żądanie POST do punktu końcowego interfejsu API /auth, przekazując w treści żądania dane uwierzytelniające administratora.

Żądanie POST interfejsu API HTTP do punktu końcowego uwierzytelniania mikrousługi.

Na koniec, po pomyślnym uwierzytelnieniu, należy wysłać żądanie GET do punktu końcowego /products w celu pobrania danych.

Żądanie HTTP API GET do punktu końcowego produktu mikrousług.

Streszczenie

W miarę jak aplikacje stają się coraz większe i bardziej złożone, kluczowe staje się przyjęcie wzorców architektonicznych, które umożliwiają skalowanie systemów oprogramowania bez nadwyrężania dostępnych zasobów.

Architektura mikrousług zapewnia skalowalność, elastyczność rozwoju i łatwość konserwacji, dzięki czemu zarządzanie złożonymi aplikacjami staje się łatwiejsze.

Kinsta upraszcza proces hostowania mikrousług. Pozwala bez wysiłku korzystać z preferowanej bazy danych i wygodnie hostować zarówno aplikację, jak i bazę danych za pośrednictwem ujednoliconego pulpitu.


Uzyskaj wszystkie swoje aplikacje, bazy danych i witryny WordPress online i pod jednym dachem. Nasza pełna funkcji, wydajna platforma w chmurze obejmuje:

  • Łatwa konfiguracja i zarządzanie w panelu MyKinsta
  • Wsparcie ekspertów 24/7
  • Najlepszy sprzęt i sieć Google Cloud Platform, oparte na Kubernetes dla maksymalnej skalowalności
  • Integracja Cloudflare na poziomie korporacyjnym zapewniająca szybkość i bezpieczeństwo
  • Globalny zasięg odbiorców dzięki nawet 37 centrom danych i 260 punktom obecności na całym świecie

Zacznij od bezpłatnego okresu próbnego naszego hostingu aplikacji lub hostingu baz danych. Zapoznaj się z naszymi planami lub porozmawiaj z działem sprzedaży, aby znaleźć najlepsze rozwiązanie.

Jeremy Holcombe Kinsta

Starszy redaktor w Kinsta, programista stron internetowych WordPress i autor treści. Poza wszystkim, co dotyczy WordPressa, lubię plażę, golfa i filmy. Mam też problemy z wysokimi ludźmi.