Przejdź do głównej zawartości

Rozwój systemów rozproszonych z AI

Rozwój systemów rozproszonych z AI działa kontraktowo: interfejsy serwisów definiuje się przed implementacją, więc Cursor, Claude Code i Codex generują i walidują kod względem współdzielonej specyfikacji zamiast zgadywać zachowanie innego serwisu. Kroki sagi, propagację kontekstu śladu i migracje schematów z podwójną publikacją buduje się i weryfikuje pojedynczo, bo awarie kryją się między serwisami.

Zmieniasz jedno pole w API serwisu Order, a trzy inne serwisy zaczynają zwracać błędy 500 na środowisku staging. Ślad jest niekompletny, bo dwa serwisy nigdy nie przekazały kontekstu śladu, saga przetwarzająca płatności po cichu pominęła krok kompensacji, a twój dashboard dyżurny świeci na zielono, podczas gdy klienci nie mogą sfinalizować zakupu. Trzy serwisy, trzy repozytoria, trzy różne zespoły — a narzędzie AI, którym sterujesz, widzi tylko to jedno otwarte repozytorium.

To właśnie w tej luce asystenci AI są najbardziej przydatni i najbardziej niebezpieczni: szybko generują wiarygodny szkielet wielu serwisów, ale „wygeneruj cały system produkcyjny” daje ci kod, którego nie jesteś w stanie zweryfikować. Ten przewodnik obejmuje te części, w których AI jest naprawdę dobre — szkicowanie zrębów serwisów, przekazywanie kontekstu śladu, pisanie nudnej logiki kompensacji — przy jednoczesnym utrzymaniu pętli weryfikacji na tyle ciasnej, że bez wahania wdrożysz wynik.

Co daje ten przepływ pracy dla systemów rozproszonych

Dział zatytułowany „Co daje ten przepływ pracy dla systemów rozproszonych”
  • Pliki reguł dla każdego narzędzia, które dają agentowi widzącemu jedno repozytorium brakujący kontekst integracji między serwisami
  • Gotowe prompty do projektowania granic serwisów, rozszerzania istniejącego kontraktu od strony endpointu i audytu klienta względem kontraktu, który rzekomo implementuje
  • Przepis na sagę budowaną po jednym kroku, każdy wraz z kompensacją i testem, który najpierw nie przechodzi
  • Plan migracji schematu z podwójną publikacją, który przeprowadza producentów i konsumentów przez zmianę wersji bez wzajemnego psucia się
  • Debugowanie oparte na śladzie i przyrostowe instrumentowanie OpenTelemetry, które zweryfikujesz w Jaegerze, zanim zrobisz z niego szablon
  • Realne, zweryfikowane serwery MCP do monitorowania (Sentry, Grafana, Dynatrace) i infrastruktury (Docker, Kubernetes, AWS) — wraz z dokładnymi poleceniami instalacji
  • Kroki naprawcze na tryby awarii, które naprawdę dają się we znaki: zerwany kontekst śladu, brakująca kompensacja w sadze, dryf kontraktów i błędy uwierzytelniania MCP

Dlaczego jedno otwarte repozytorium to za mało kontekstu

Dział zatytułowany „Dlaczego jedno otwarte repozytorium to za mało kontekstu”

Mikrousługi dzielą system na repozytoria, języki i zespoły. Narzędzia AI widzą jedno repozytorium naraz, co oznacza, że domyślne założenie modelu — że ten serwis jest samodzielną aplikacją — jest błędne dokładnie w tych miejscach, które psują produkcję. Lekarstwem jest zakodowanie kontraktów i konwencji między serwisami wewnątrz każdego repozytorium, tak by kontekst integracji był zawsze załadowany niezależnie od tego, czy pamiętasz o nim wspomnieć.

Przechowuj definicje kontraktów w repozytorium serwisu i nazwij je w pliku reguł:

.cursor/rules
This service (order-service) communicates with:
- payment-service: REST API, OpenAPI spec at /contracts/payment-api.yaml
- inventory-service: Events via RabbitMQ, schemas at /contracts/inventory-events.json
- notification-service: Events via RabbitMQ, schemas at /contracts/notification-events.json
When implementing any integration:
1. Always read the relevant contract file first
2. Generate client code from the contract, do not hand-write it
3. Include retry logic with exponential backoff for all HTTP calls
4. Include dead-letter queue handling for all event consumers

Użyj @contracts/payment-api.yaml, aby wciągnąć konkretny kontrakt do konwersacji.

Drugą połową problemu kontekstu jest żywa infrastruktura: pozwolenie AI, by ją odpytywało, bije pozwalanie mu zgadywać. Ale ekosystem jest pełen łudząco podobnych paczek npm — sentry-mcp to mało popularna zaślepka, a nie serwer Sentry. Korzystaj z tych zweryfikowanych serwerów. Konfiguracja MCP jest identyczna w Cursorze, Claude Code i Codeksie: wszystkie trzy czytają te same definicje serwerów (.mcp.json dla Claude Code, .cursor/mcp.json dla Cursora, ~/.codex/config.toml dla Codeksa), więc poniższe polecenia działają niezależnie od tego, którego narzędzia używasz.

  1. Sentry (błędy, ślady, wydania) — użyj oficjalnego, hostowanego serwera z OAuth, bez tokena do zarządzania:

    Okno terminala
    claude mcp add --transport http sentry https://mcp.sentry.dev/mcp

    Dla samodzielnie hostowanego Sentry oficjalną paczką npm jest @sentry/mcp-server:

    Okno terminala
    claude mcp add sentry -- npx -y @sentry/mcp-server@latest --access-token=YOUR_TOKEN
  2. Grafana (dashboardy, zapytania Loki/Prometheus, incydenty) — oficjalny serwer to grafana/mcp-grafana, binarka Go dystrybuowana przez Dockera (nie ma paczki npm mcp-grafana):

    Okno terminala
    claude mcp add grafana -- docker run --rm -i \
    -e GRAFANA_URL=http://localhost:3000 \
    -e GRAFANA_SERVICE_ACCOUNT_TOKEN=YOUR_TOKEN \
    grafana/mcp-grafana -t stdio
  3. Dynatrace (APM, wykrywanie anomalii przez AI) — oficjalna paczka jest publikowana przez organizację Dynatrace OSS i wymaga Node 22.10+:

    Okno terminala
    DT_ENVIRONMENT=https://YOUR.apps.dynatrace.com \
    claude mcp add dynatrace -- npx -y @dynatrace-oss/dynatrace-mcp-server@latest
  1. Docker — oficjalny MCP jest dostarczany z MCP Toolkit w Docker Desktop; uruchamiasz bramę zamiast paczki npm:

    Okno terminala
    claude mcp add docker -- docker mcp gateway run

    W Cursorze dodaj serwer typu polecenie w Settings → MCP, wskazując na to samo docker mcp gateway run.

  2. Kuberneteskubernetes-mcp-server to prawdziwa paczka; używa twojego bieżącego kontekstu kubeconfig:

    Okno terminala
    claude mcp add k8s -- npx -y kubernetes-mcp-server@latest
  3. AWS — AWS Labs publikuje serwery o konkretnym przeznaczeniu (nie jeden monolityczny obraz). Wybierz ten, którego potrzebujesz, i polegaj na standardowym łańcuchu poświadczeń AWS, zamiast wpisywać klucze na sztywno:

    Okno terminala
    claude mcp add aws-api -- uvx awslabs.aws-api-mcp-server@latest

    Przejrzyj pełny katalog na awslabs.github.io/mcp. Dla Google Cloud wdróż własny serwer MCP na Cloud Run — zobacz cloud.google.com/run/docs.

AI szybko szkicuje propozycje ograniczonych kontekstów, ale granice to decyzja biznesowa — traktuj wynik jako pierwszą wersję do dyskusji, a nie wyrok. Zacznij wąsko: poproś o granice wraz z uzasadnieniem, abyś mógł wychwycić, gdzie model pomylił warstwę techniczną z domeną.

Gdy uzgodnisz już granice, projektuj po jednym serwisie naraz. Oprzyj się pokusie „wygeneruj wszystkie serwisy” — nie da się zrecenzować zrzutu siedmiu serwisów, a to właśnie w kontraktach między nimi kryją się błędy.

Powyższy prompt projektuje kontrakt od zera. Na co dzień rozszerzasz taki, który już istnieje, a dyscyplina jest ta sama, tylko odwrócona: zmień specyfikację, pozwól specyfikacji wygenerować kod i przejrzyj specyfikację, zanim pojawi się choć linia implementacji.

Kontrakty zaczynają dryfować w chwili, gdy ktoś ręcznie edytuje klienta. AI dobrze to wyłapuje i do audytu potrzebuje tylko twojej strony granicy — drugą stroną jest plik kontraktu. Każde narzędzie ma dla tego audytu naturalną formę:

Compare our order-service HTTP client for the payment service
against the payment-api.yaml contract:
1. Are we handling all documented error codes?
2. Are we sending all required headers?
3. Are we respecting rate limits and timeouts from the spec?
4. Are there any fields we're ignoring in responses that we should handle?

Uruchamiaj ten audyt w CI, a nie tylko na żądanie: to npm run validate-contracts łamiące build powstrzymuje dryf przed dotarciem na produkcję.

Wzorzec saga to miejsce, gdzie wygenerowany przez AI kod rozproszony najczęściej wygląda dobrze, a jest błędny. Tryb awarii jest zawsze taki sam: ścieżka szczęśliwa działa, ale krok kompensacji nie jest idempotentny albo brakuje budżetu czasowego (timeout). Lekarstwem jest budowanie po jednym kroku naraz, każdego wraz z jego kompensacją i najpierw testem, który nie przechodzi, a potem obserwowanie, jak zmienia się na zielony.

Otwórz repozytorium serwisu Order i przełącz się w tryb Agent. Poproś o jeden krok sagi wraz z testem, który nie przechodzi, uruchom test w terminalu Cursora i zaakceptuj diff dopiero, gdy zmieni się na zielony. Użyj punktu kontrolnego (checkpoint) przed każdym krokiem, abyś mógł cofnąć złą kompensację bez utraty poprzednich kroków. Widok inline diff w Cursorze ułatwia wychwycenie, gdy model „naprawił” test, osłabiając asercję zamiast kodu.

Powiąż każdy krok z obserwowalnym sprawdzeniem: gdy model twierdzi, że krok działa, uruchom ten jeden test, który dowodzi, że kompensacja się odpala. Jeśli nie potrafisz wyrazić testu, nie możesz ufać kodowi.

Konfiguracje service mesh i bramy są dla AI bardzo opłacalne — ale znów, przyrostowo. Zacznij od najmniejszej konfiguracji, którą da się zweryfikować jednym poleceniem (curl, istioctl analyze), a potem nakładaj wagi canary i wyłączniki obwodu.

W przepływach sterowanych zdarzeniami nawracający błąd produkcyjny to zerwany ślad: serwis konsumuje wiadomość Kafki, ale nigdy nie wyodrębnia i ponownie nie wstrzykuje kontekstu śladu, więc ślad urywa się w ślepym zaułku. Gdy prosisz AI o podłączenie konsumentów, uczyń propagację kontekstu jawnym, przetestowanym wymaganiem — a nie kwestią dodaną na końcu.

Gdy coś jednak pęknie na granicy, pracuj od śladu wstecz, a nie od serwisu, który akurat masz otwarty. Podaj AI oś czasu śladu i tego jednego konsumenta, którego podejrzewasz, i zmuś je do wyjaśnienia, dlaczego awaria jest sporadyczna — to pytanie odróżnia prawdziwą diagnozę od wiarygodnie brzmiącej.

Zmiana formatu danych przekraczającego granicę serwisu to nie zmiana kodu, tylko choreografia. Producenci i konsumenci wdrażają się niezależnie, więc jedyna bezpieczna ścieżka to taka, w której stary i nowy format są poprawne jednocześnie.

  1. Zdefiniuj nową wersję schematu

    Dodaj nowy schemat obok starego. Jeszcze go nie zastępuj.

  2. Zaktualizuj producentów, aby publikowali obie wersje

    Serwis produkujący wysyła zdarzenia w obu formatach — starym i nowym — w okresie przejściowym.

  3. Zaktualizuj konsumentów, aby akceptowali obie wersje

    Każdy konsumujący serwis obsługuje obie wersje schematu elegancko.

  4. Zweryfikuj, że wszyscy konsumenci zostali zaktualizowani

    Monitoruj, czy żaden serwis nie konsumuje jeszcze starego formatu — metryką, nie założeniem.

  5. Usuń stary schemat

    Dopiero po migracji wszystkich konsumentów przestań produkować stary format i go usuń.

Nowoczesna obserwowalność wykroczyła poza dashboardy ku wykrywaniu anomalii sterowanemu AI i analizie podstawowych przyczyn świadomej topologii — ale wciąż zdobywasz ją po jednym serwisie naraz. Podejście „zinstrumentuj 8 serwisów i 3 bazy danych w jednym promcie” daje konfigurację, której nie da się zwalidować. Zinstrumentuj jeden serwis od początku do końca, potwierdź, że span pojawia się w Jaegerze, a potem zrób z tego szablon.

Gdy ten pierwszy ślad już dotrze, szersza instrumentacja jest szablonem, a nie zakładem, i warto poprosić o cały kształt naraz — spany, skorelowane logi, health checki i metryki — bo każdy element da się teraz zweryfikować względem działającej bazy odniesienia.

Z podłączonymi serwerami MCP Grafany i Sentry możesz domknąć pętlę bez opuszczania edytora: poproś AI, by wyciągnęło faktyczny wskaźnik błędów albo najwolniejszy ślad dla serwisu i przeanalizowało go, zamiast robić zrzut ekranu dashboardu.

Funkcja taka jak „punkty lojalnościowe” dotyka serwisów Customer, Order, Payment i Notification. To problem koordynacji — a nie kod poszczególnych serwisów — czyni to trudnym, a trzy narzędzia podchodzą do tego naprawdę odmiennie.

Otwórz wszystkie cztery repozytoria serwisów w jednym wieloźródłowym workspace, aby agent widział każdy kontrakt naraz. Zaprojektuj najpierw kontrakty OpenAPI/zdarzeń, a potem użyj agenta w tle do zaimplementowania każdego serwisu w kolejności zależności, recenzując diffy per repozytorium. Punkty kontrolne na poziomie pliku w Cursorze pozwalają cofnąć zmiany jednego serwisu bez rozplątywania pozostałych. Najlepsze, gdy chcesz wizualnie obserwować i sterować diffem każdego serwisu.

Gdy psują się systemy rozproszone wspomagane przez AI

Dział zatytułowany „Gdy psują się systemy rozproszone wspomagane przez AI”

Systemy rozproszone psują się w sposób, którego nie wychwytuje sposób myślenia o pojedynczym serwisie. Oto tryby awarii, które naprawdę wychodzą na jaw przy pracy wspomaganej AI, i sposoby na wyjście z nich.

  1. Kontekst śladu urywa się na granicy asynchronicznej. Żądanie pojawia się w Jaegerze przez dwa skoki, a potem znika. Konsument nie wyodrębnił kontekstu śladu z nagłówków wiadomości. Przeszukaj konsumenta pod kątem wyodrębniania kontekstu; jeśli go brak, poproś AI o dodanie propagacji opartej na nagłówkach oraz testu, który potwierdza, że znany traceId przetrwa skok (zobacz prompt dla Kafki powyżej). Nie ufaj „dodałem śledzenie” — zweryfikuj traceId od początku do końca.

  2. Saga zostawia osierocony stan. Płatność się powiodła, ale zapasy nigdy nie zostały zwolnione po awarii w dół strumienia. Kompensacja jest brakująca lub nieidempotentna. Odtwórz problem, wstrzykując awarię na kroku po tym, który podejrzewasz, i potwierdź, że kompensacja odpala się dokładnie raz. Przebuduj ten krok z promptem „najpierw test, który nie przechodzi”; nigdy nie akceptuj logiki kompensacji bez testu, który ją wyzwala.

  3. AI traktuje każdy serwis jak samodzielną aplikację. Wygenerowany kod ignoruje kontrakt, wymyśla kształt endpointu albo pomija konwencje ponawiania i kolejek dead-letter, których trzyma się każdy inny serwis. Repozytorium nie ma sekcji integracyjnej w .cursor/rules / CLAUDE.md / AGENTS.md — dodaj ją, jawnie nazywając pliki kontraktów, zanim obwinisz model.

  4. Wygenerowany kod klienta nie pasuje do kontraktu. Regeneruj klientów z kontraktów, nie pisz ich ręcznie. Potem wstaw audyt zgodności do CI, żeby dryf łamał build, zamiast wychodzić na jaw jako 422 na produkcji.

  5. Zmiana kontraktu psuje serwisy w dół strumienia na produkcji. Pominąłeś fazę podwójnej publikacji. Uruchamiaj obie wersje schematu jednocześnie podczas migracji i użyj metryki śledzenia wersji, aby potwierdzić, że każdy konsument się przeniósł, zanim usuniesz stary format.

  6. Uwierzytelnianie serwera MCP zawodzi lub nic nie zwraca. Narzędzie się łączy, ale każde zapytanie kończy się błędem albo zwraca pustkę. Zwykle to brakujący/wygasły token lub błędna zmienna środowiskowa (GRAFANA_SERVICE_ACCOUNT_TOKEN, DT_ENVIRONMENT, nieukończony OAuth Sentry). Uruchom claude mcp list, aby potwierdzić, że serwer jest połączony, sprawdź ponownie zmienne środowiskowe względem poleceń instalacji powyżej, a dla hostowanego serwera Sentry ponownie przejdź przepływ OAuth. Jeśli npm view <pkg> pokazuje podejrzanie niską liczbę pobrań, zainstalowałeś podróbkę — przeinstaluj oficjalną paczkę z przestrzenią nazw.

  7. AI wygenerowało „rozproszony monolit”. Serwisy, które muszą być wdrażane razem, albo dwa serwisy zapisujące do tej samej tabeli. To wada projektowa, której model sam z siebie nie zgłosi. Poproś go o audyt: „Wypisz każde miejsce, gdzie dwa serwisy współdzielą bazę danych, ścieżkę zapisu lub muszą być wdrażane w blokadzie”. Rozwiąż te przypadki, zanim podzielisz dalej — współdzielone ścieżki zapisu niweczą sens mikrousług.

  8. Debugowanie rozproszone wciąż trwa wieczność. AI pomaga znacznie mniej, gdy ma do dyspozycji tylko surowe pliki logów do ręcznego korelowania. Najpierw zainwestuj w warstwę obserwowalności: ustrukturyzowane logi niosące traceId, prawdziwy backend śladów i serwer MCP, który potrafi odpytać jedno i drugie. Powyższy prompt oparty na śladzie jest wart dokładnie tyle, ile ślad, który mu podasz.

  9. Automatyczne cofnięcie canary nigdy się nie odpala. Wdrożenie poszło źle, ale pozostało na 100%. Próg cofnięcia odwołuje się do metryki, która nie jest emitowana, albo nazwa metryki jest błędna. Potwierdź, że metryki golden signals istnieją w Prometheus/Grafanie (użyj MCP Grafany, aby je odpytać), zanim zaczniesz polegać na automatycznym cofaniu, i przetestuj ścieżkę cofnięcia na staging z celowo wadliwym buildem.