CodeGym /Kursy /ChatGPT Apps /Skalowanie i wdrożenia: równoważenie obciążenia, klastry ...

Skalowanie i wdrożenia: równoważenie obciążenia, klastry usług backendowych, blue/green i canary

ChatGPT Apps
Poziom 16 , Lekcja 3
Dostępny

1. O czym jest ten wykład i dlaczego to ważne

Wyobraźmy sobie, że zostawiliście GiftGenius na etapie, w którym samotnie żyje na Vercel: jedna instancja MCP‑gateway (która jednocześnie wystawia MCP na zewnątrz i łączy się z waszymi usługami REST), jeden backend dla agentów, wszystko „jakoś działa”. To jeszcze znośne dla projektu hobbystycznego i pierwszych 100 użytkowników.

Ale gdy tylko OpenAI doda waszą App do Store i ona nagle trafi na stronę główną przed Bożym Narodzeniem, „jeden gateway na porcie 3000” zamieni się w bardzo smutną historię: kolejka wywołań tooli, time‑outy, błędy 500, spadek ocen w Store i maile od marketingu w stylu „dlaczego wszystko leżało w szczycie sprzedaży?”.

Naszym celem w tym wykładzie jest nauczyć się myśleć o GiftGenius (i każdym ChatGPT App) jak o systemie z wieloma identycznymi instancjami za load balancerem. Plus — zrozumieć zgrabne strategie wydań i klarowny schemat „jak się wycofać, jeśli coś pójdzie nie tak”.

2. Skalowanie horyzontalne i stateless‑design

Zacznijmy od podstawowej idei: jeśli wasz MCP Gateway lub wewnętrzny serwis backendowy przechowuje ważny stan w pamięci konkretnego procesu, praktycznie nie da się go normalnie skalować horyzontalnie.

Skalowanie pionowe vs horyzontalne

Najpierw uporządkujmy terminologię.

Skalowanie pionowe — to po prostu „dokładanie mięśni” jednemu serwerowi: więcej CPU, więcej RAM. Szybkie, czasem tanie na start, ale ma twardy sufit i czyni jedną instancję single point of failure: jeśli ten potwór padnie, padnie wszystko.

Skalowanie horyzontalne — to uruchamianie wielu egzemplarzy serwisu za load balancerem. Każda instancja jest względnie mała, nie trzyma krytycznego stanu w pamięci, a stan ląduje w zewnętrznych magazynach (Postgres, Redis, object storage). Można swobodnie dodawać i usuwać instancje pod obciążenie.

Dla MCP Gateway i serwisów backendowych (Gift REST API, Commerce REST API, Analytics Service / REST API itp.) skalowanie horyzontalne jest de facto obowiązkowe: ChatGPT może nagle skierować do was wielokrotnie większy ruch (sezon, promocja w Store, jakiś wiral na TikToku) i powinniście po prostu dodać instancje, a nie „modlić się, żeby jeden serwer wytrzymał”.

Czym jest serwis stateless w kontekście MCP Gateway i backendów

Żeby skalowanie horyzontalne działało, serwis musi być maksymalnie stateless.

Stateless w naszym kontekście znaczy:

  • serwis nie trzyma w pamięci unikalnego, długotrwałego stanu użytkownika, od którego zależy logika biznesowa;
  • każdy ważny stan trzymamy w zewnętrznej bazie, kolejce, cache’u, S3‑podobnym magazynie;
  • jeśli konkretna instancja padnie, inna może kontynuować obsługę użytkownika, po prostu „podbierając” kontekst z magazynu zewnętrznego.

Dla GiftGenius oznacza to, że:

  • historia doboru prezentów użytkownika, jego lajki/dislajki i koszyk leżą np. w Postgresie;
  • kolejki długotrwałych zadań (masowa generacja propozycji, wysyłka emaili) leżą u brokera typu Redis/Cloud Queue;
  • jeśli jest osobny serwis dla złożonych workflow agentów, to on przechowuje checkpointy i długą pamięć we własnym store, a nie w RAM jednego procesu.

Instancja MCP Gateway lub dowolnego serwisu backendowego staje się „krową, a nie domowym pupilkiem”: można ją bezlitośnie ubić i odtworzyć bez utraty danych biznesowych.

Mini‑przykład: przeniesienie stanu z pamięci do zewnętrznego magazynu

Załóżmy, że kiedyś zrobiliście bardzo prosty MCP‑tool add_to_cart, który przez gateway woła logikę wewnętrzną i ta trzyma koszyk w pamięci procesu (tak, w demach czasem tak się robi — i to jest OK, dopóki rozumiecie, że w produkcji tak nie wolno):

// ŹLE: koszyk w pamięci procesu serwisu backendowego
const inMemoryCarts = new Map<string, string[]>();

export async function addToCart(userId: string, sku: string) {
  const cart = inMemoryCarts.get(userId) ?? [];
  cart.push(sku);
  inMemoryCarts.set(userId, cart);
  return cart;
}

Skalowanie horyzontalne jest tu niemożliwe: jedno żądanie trafi na instancję A, inne — na instancję B i użytkownik będzie miał różne koszyki.

Właściwy wariant — wynieść koszyk do zewnętrznej bazy lub cache’a. Umownie (mocno uproszczone):

// DOBRZE: koszyk w zewnętrznym magazynie
import { db } from "./db";

export async function addToCart(userId: string, sku: string) {
  await db.cartItems.insert({ userId, sku }); // uproszczone
  const cart = await db.cartItems.findMany({ where: { userId } });
  return cart;
}

Teraz nie ma znaczenia, która instancja serwisu backendowego obsługuje żądanie przychodzące przez gateway: koszyk jest wspólny dla wszystkich.

3. Równoważenie obciążenia: jak ruch trafia do klastrów usług backendowych

Gdy tylko macie więcej niż jedną instancję serwisu, potrzebny jest ktoś, kto rozdziela żądania między nie. To jak dyspozytor zamówień w popularnej pizzerii: kurierów wielu, klientów wielu i bez logiki — chaos.

L4 vs L7 i dlaczego głównie interesuje nas L7

Load balancer może działać na różnych warstwach:

  • L4 (TCP/UDP) po prostu przekazuje bajty od klienta do jednego z backendów, bez rozumienia, jaki to protokół;
  • L7 (HTTP) rozumie, że ma do czynienia z żądaniem HTTP, umie zajrzeć w ścieżkę, nagłówki, ciasteczka, czasem nawet w body.

Dla architektury ChatGPT App z MCP Gateway i usługami REST prawie zawsze chcemy L7‑load balancer: wszystko komunikuje się po HTTP/SSE i chcemy umieć routować po ścieżce, domenie, nagłówkach (np. dla canary‑wydań) oraz robić health‑checki.

Health‑checki i wyłączanie „chorych” instancji z rotacji

Load balancer powinien okresowo sprawdzać, czy instancje żyją. Najprościej — mieć endpoint GET /health lub /readyz, który zwraca 200 OK, jeśli wszystko jest w porządku.

W serwisie Node/TypeScript, który działa jako MCP Gateway lub backend, health‑check może wyglądać tak:

// apps/gateway/src/http/health.ts
import { type Request, type Response } from "express";

export function healthHandler(req: Request, res: Response) {
  res.json({
    status: "ok",
    version: process.env.RELEASE_ID ?? "dev",
  });
}

Load balancer stuka co N sekund w /health. Jeśli odpowiedzi zaczynają wracać jako 5xx lub po time‑oucie, ta instancja jest wyłączana z rotacji i nowy ruch tam nie trafia.

Specyfika dla Streaming / SSE

MCP Gateway dość często działa przez SSE (Server‑Sent Events), zwłaszcza jeśli używacie streamingu wyników częściowych. Load balancer powinien:

  • obsługiwać długotrwałe połączenia HTTP;
  • umieć liczyć takie połączenia przy wyborze instancji (niektóre LB potrafią brać pod uwagę liczbę aktywnych połączeń, a nie tylko RPS).

To istotne, bo jeden „gadatliwy” wywołanie toola, które streamuje tekst 2 minuty, wisi jako aktywne połączenie. Jeśli takich połączeń jest zbyt dużo na jednej instancji, tę instancję trzeba tymczasowo „odciążyć” — nowe połączenia wysyłać na inne.

4. Klastry usług backendowych: dzielimy wg zadań, a nie wszystko do jednego worka

Logiczny kolejny krok — przestać myśleć o jednym „dużym serwisie backendowym” i podzielić system na kilka klastrów w zależności od charakteru obciążenia i krytyczności.

Przykładowa architektura GiftGenius wg klastrów

Wszystko zebrane w module 16 podpowiada nam taki schemat dla GiftGenius:

Klaster Co robi Charakter obciążenia Cechy skalowania
A: Gift REST API / lekkie narzędzia Wyszukiwanie produktów, formatowanie list, proste obliczenia Wysoki RPS, krótkie odpowiedzi (< 500 ms), małe zużycie CPU Skalujemy wg CPU/RPS, wiele małych instancji
B: Agents / Heavy Jobs REST‑serwis Wywołania LLM, złożone workflow, generowanie życzeń Niski RPS, długie odpowiedzi (10 s–2 min), IO‑heavy Skalujemy wg długości kolejki zadań, można używać workerów
C: Commerce REST API / ACP Checkout, integracja z dostawcą płatności, ACP Krytyczna niezawodność, twarde SLO Oddzielne wdrożenie, zmiany wolne i ostrożne

W istocie to realizacja wzorca bulkheads (grodzie): jeśli klaster B nagle zaczyna „palić CPU tokenami” przy generowaniu złożonych tekstów, klaster C z płatnościami dalej działa, bo ma własną pulę zasobów i własne skalowanie.

Jak to wygląda przez Gateway

MCP Gateway, opisany w pierwszym wykładzie modułu, widzi cały ruch MCP i routuje go do klastrów backendowych. Mniej więcej tak:

  • wywołania tooli list_gifts, suggest_gifts → klaster A (Gift REST API);
  • wywołania tooli generate_greeting_card albo złożone workflow agentów → klaster B (Agents REST‑serwis lub workery);
  • narzędzia create_order, confirm_payment → klaster C (Commerce REST API).

Za tym może stać jeden wspólny load balancer lub kilka balancerów (np. osobny L7‑LB przed commerce, by jeszcze mocniej izolować).

Można narysować ogólny obraz:

flowchart LR
    ChatGPT((ChatGPT))
    GW[MCP Gateway]
    LBA[LB Gift API Cluster A]
    LBB[LB Agents/Workers Cluster B]
    LBC[LB Commerce API Cluster C]

    A1[Gift REST API A-1]
    A2[Gift REST API A-2]
    B1[Agents Service B-1]
    B2[Agents Service B-2]
    C1[Commerce REST API C-1]
    C2[Commerce REST API C-2]

    ChatGPT --> GW
    GW -->|tools: gifts| LBA
    GW -->|agents workflows| LBB
    GW -->|commerce| LBC

    LBA --> A1
    LBA --> A2
    LBB --> B1
    LBB --> B2
    LBC --> C1
    LBC --> C2

Schemat jest lekko idealizowany, ale oddaje główną zasadę: różne typy obciążenia — różne klastry backendowe za jednym MCP Gateway.

5. Strategie wdrożeń: po co blue/green i canary

Przejdźmy teraz do tego, jak aktualizować to wszystko tak, by użytkownicy tego nie zauważyli, a wy mogli spać spokojnie w nocy.

Anty‑przykład: wdrożenie „na żywym produkcie”

Najprostsza i najgroźniejsza strategia: bierzecie działający klaster (np. klaster Gift REST API A), uruchamiacie nowy obraz na starym, podmieniacie kontenery albo restartujecie procesy.

Jakie tu są problemy:

  • gdy część instancji jest już nowa, a część stara, system może zachowywać się nieprzewidywalnie (zwłaszcza jeśli zmieniała się schema bazy);
  • jeśli coś poszło nie tak, rollback to nowe wdrożenie „jak było”, które może trwać minuty;
  • w momencie wdrożenia łatwo o krótki downtime, kiedy żadna instancja jeszcze nie wstała.

W Kubernetes i PaaS łagodzą to nieco rolling updates, ale idea jest ta sama: bez klarownej strategii macie dużo „szarej strefy”, gdzie różne wersje kodu jednocześnie obsługują ruch.

Blue/Green deploy: dwa środowiska i natychmiastowe przełączenie

Blue/Green — to podejście, w którym jednocześnie istnieją dwa niemal identyczne środowiska: Blue (bieżąca produkcja) i Green (nowa wersja).

Schemat procesu wygląda tak:

  1. Wdrażacie nową wersję (v2) w środowisku Green: to ten sam zestaw gateway + klastry backendowe, tylko na razie bez realnego ruchu.
  2. Przepuszczacie na Green wszystkie niezbędne testy: autotesty, smoke‑scenariusze, ręczne sprawdzenia przez ChatGPT Dev Mode.
  3. W momencie releasu przełączacie load balancer/routing tak, by 100% ruchu produkcyjnego szło do Green.
  4. Blue żyje obok jako „lotnisko zapasowe”. Jeśli coś pójdzie nie tak, przełączacie ruch z powrotem w kilka sekund.

Dla GiftGenius może to wyglądać tak: macie mcp-gateway-blue.example.com i mcp-gateway-green.example.com. ChatGPT App w produkcji „patrzy” na oficjalny MCP‑endpoint (gateway), a przy releasie zmieniacie konfigurację DNS/LB tak, aby nazwa domenowa mcp-gateway.example.com wskazywała już na green.

Plusy:

  • natychmiastowy przełącznik „tam‑z powrotem”;
  • każdy problem można leczyć już po rollbacku;
  • brak stanu „pół klastra nowe, pół klastra stare”.

Minusy:

Na czas releasu trzeba utrzymywać dwa pełne środowiska, czyli płacić za zasoby ×2. Dlatego taką strategię najczęściej stosuje się do krytycznych serwisów backendowych — np. klastra commerce C i samego MCP Gateway, gdzie checkoutu i punktu wejścia nie wolno psuć w żadnych okolicznościach.

Canary‑wydania: mała „kanarek” w kopalni

Canary to bardziej ekonomiczna opcja: nie podnosicie dwóch pełnych produkcji, tylko wdrażacie nową wersję stopniowo na niewielką część ruchu i uważnie ją obserwujecie.

Przykładowy scenariusz:

  1. Wdrażacie wersję v2 klastra Gift REST API A do tego samego puli lub do osobnej małej puli kanarkowej.
  2. Ustawiacie load balancer lub MCP Gateway tak, aby np. 1 % wywołań tooli związanych z prezentami szło na v2, a 99 % — na v1.
  3. Obserwujecie metryki: error rate, latency, specyficzne metryki biznesowe (konwersja, udane checkouty).
  4. Jeśli wszystko jest dobrze — stopniowo zwiększacie udział: 1 % → 5 % → 10 % → 50 % → 100 %. Jeśli źle — natychmiast się wycofujecie.

W kontekście ChatGPT Apps canary jest szczególnie użyteczne nie tylko dla kodu, lecz także dla eksperymentów z promptami: nowa wersja system‑promptu dla serwisu agentowego może radykalnie zmienić zachowanie, więc lepiej najpierw sprawdzić ją na niewielkiej próbce użytkowników.

Gateway albo LB mogą decydować, które żądanie jest „kanarkowe”, według różnych przesłanek:

  • losowo (np. 1 % wszystkich żądań);
  • po userId (część użytkowników trafia do eksperymentu na stałe);
  • po specjalnym nagłówku lub cookie (dla testów wewnętrznych).

Mały przykład logiki routingu w pseudo‑TypeScript (dla ilustracji idei w gateway):

// Pseudokod w Gateway: simple random canary 5%
function routeToGiftBackendCluster(ctx: { userId?: string | null }) {
  const rnd = Math.random();
  if (rnd < 0.05) {
    return "gift-api-v2"; // canary
  }
  return "gift-api-v1";   // stable
}

W prawdziwym życiu oczywiście nie zrobicie tego przez Math.random() w kodzie runtime, tylko wyniesiecie reguły do konfiguracji/feature‑flagów, ale logika jest podobna: część ruchu idzie do wersji canary serwisu backendowego, reszta — do stabilnej.

6. Rollback jako obowiązkowa część strategii

Dawno temu przyswoiłem dobrą zasadę: wycofanie musi być szybsze niż fix.

To znaczy, że jeśli po releasie posypią się błędy, a użytkownicy piszą „wszystko się sypie”, nie trzeba bohatersko naprawiać buga na produkcji. Trzeba wcisnąć duży czerwony przycisk „wycofaj”.

W kontekście platform takich jak Vercel (na których już stawialiśmy część Next.js GiftGenius) jest to bardzo naturalne: każde wdrożenie to niezmienny artefakt i Vercel pozwala szybko wrócić do poprzedniego.

Dla MCP Gateway i klastrów backendowych wdrożonych w Kubernetes lub innym orkiestratorze tę rolę spełnia kubectl rollout undo: wracacie do poprzedniego zestawu podów i obrazów.

Najważniejsze — logować i eksponować wersję, która aktualnie obsługuje ruch. Można np.:

  • dodawać version do /health i innych diagnostycznych endpointów (już to zrobiliśmy wyżej);
  • przekazywać identyfikator releasu przez nagłówki do logów (np. X-Release-Id).

Mini‑przykład: Next.js‑API‑route, który zwraca wersję builda do inspekcji ChatGPT App wewnątrz widgetu:

// apps/web/app/api/version/route.ts
export async function GET() {
  return Response.json({
    version: process.env.RELEASE_ID ?? "dev",
    builtAt: process.env.BUILT_AT ?? "unknown",
  });
}

Taki endpoint jest też przydatny do debugowania: możecie spytać instancję produkcyjną, jaka dokładnie wersja teraz działa i nie zgadywać „czy na pewno wszedł ostatni build?”.

7. Capacity planning: ile instancji potrzeba pod GiftGenius

Omówiliśmy już, jak bezpiecznie wdrażać nowe wersje (blue/green, canary) i szybko się wycofywać w razie problemów. Zostało praktyczne pytanie: ile w ogóle instancji i jakich klastrów trzymać w produkcji, żeby to wytrzymało realny ruch i nie zrujnowało was finansowo?

Bez przesady z formułami, ale odrobina ich się przyda. Skalowanie trzeba powiązać z obciążeniem i ekonomiką: ile żądań na dzień/sekundę, ile ciężkich wywołań LLM, ile to kosztuje w pieniądzach.

Dla prostoty myślcie rzędami wielkości:

  • przy 10k żądań dziennie do GiftGenius (około 0.1 RPS średnio) spokojnie przeżyjecie na jednej–dwóch instancjach MCP Gateway i paru instancjach Gift REST API/workerów agentów;
  • przy 100k żądań dziennie (12 RPS średnio, w pikach — więcej) warto już mieć 35 instancji gateway + klastra Gift REST API, oddzielny klaster B dla ciężkich agentów i wydzielony klaster commerce;
  • przy 1M żądań dziennie (dziesiątki RPS, szczytowe obciążenia w święta) na pewno przydadzą się klastry, wydzielone zasoby pod agentów LLM, agresywny cache i warstwa edge (o niej osobny wykład).

To nie są sztywne liczby, tylko sposób, by zmusić się do oceny rzędu obciążenia i myślenia z wyprzedzeniem: gdzie są wąskie gardła, jak będziecie skalować i ile to będzie kosztować.

Dla GiftGenius szczególnie ważne jest przygotowanie się na święta: Nowy Rok, Boże Narodzenie, Walentynki, Czarny Piątek. Obciążenie może wzrosnąć kilkukrotnie, a chcielibyście, by system to wytrzymał.

8. Praktyczny mini‑przykład: ewolucja wdrożenia GiftGenius

Aby wszystko zebrać w całość, narysujmy prostą ewolucję wdrożenia GiftGenius.
Tu kolejno zastosujemy wszystko, o czym mówiliśmy: stateless‑design gateway i serwisów backendowych, równoważenie obciążenia, osobne klastry i strategie wydań (blue/green, canary).

Poziom bazowy: jeden gateway + backend na Vercel/Kubernetes

W pewnym momencie kursu już to zrobiliście: jedna aplikacja Next.js z Apps SDK na Vercel, w której żyje i MCP‑endpoint, i prosta logika backendowa (Gift/Commerce) w jednym serwisie. Wszystko dość monolityczne.

Zalety są oczywiste: prosto, tanio, mało miejsc na błąd.

Minus jest jeden, ale krytyczny: to się nie skaluje pod poważny ruch i źle znosi aktualizacje.

Poziom 2: osobny MCP Gateway + kilka klastrów backendowych

Kolejny krok:

  • wynosicie MCP Gateway do osobnego serwisu (Node/Go/NGINX+Lua, bez znaczenia);
  • uruchamiacie kilka instancji Gift REST API (klaster A) i kilka workerów/serwisów dla agentów (klaster B);
  • dla commerce wydzielacie osobny serwis (klaster C), być może — na osobnej bazie/infrastrukturze.

Już tutaj włączamy klasyczne L7‑równoważenie, health‑checki i, jeśli to możliwe, skalowanie horyzontalne.

Poziom 3: strategie wydań

Na tym poziomie dodajecie:

  • Blue/Green dla klastra commerce C (i, jeśli chcecie, dla MCP Gateway), aby checkout i autoryzacja były maksymalnie stabilne;
  • Canary‑wydania dla klastrów Gift REST API i serwisu agentowego, aby spokojnie eksperymentować z nowymi wersjami tooli i agentów bez ryzyka zabicia całej produkcji.

Schematycznie:

flowchart LR
    ChatGPT((ChatGPT))
    GWBlue[Gateway Blue]
    GWGreen[Gateway Green]
    LB[Traffic Switch]

    subgraph Prod
      LB --> GWBlue
      LB -.canary,% .-> GWGreen
    end

    ChatGPT --> LB

W rzeczywistości może być trochę bardziej złożenie (osobny Blue/Green tylko dla commerce, canary tylko dla klastrów gift), ale idea jest jasna: zawsze wiecie, która wersja gdzie idzie, a dla ChatGPT wszystko wciąż wygląda jak jedna MCP‑brama wejściowa (gateway).

9. Kilka małych fragmentów kodu do wersjonowania i diagnostyki

Widzieliśmy już health‑endpoint i /api/version. Dodajmy jeszcze przykład, jak można logować wersję i klaster w handlerze MCP‑toola po stronie gateway, żeby potem łatwo „zestawiać” metryki.

Wyobraźmy sobie tool suggest_gifts, który jest zaimplementowany jako endpoint REST w Gift REST API i wywoływany przez gateway:

import { type McpToolHandler } from "@modelcontextprotocol/sdk";

export const suggestGifts: McpToolHandler<{
  occasion: string;
  budget: number;
}> = async ({ input, meta }) => {
  const releaseId = process.env.RELEASE_ID ?? "dev";
  const clusterId = process.env.CLUSTER_ID ?? "gift-api-A";

  console.log("[suggest_gifts]", {
    releaseId,
    clusterId,
    userId: meta.userId,
    occasion: input.occasion,
  });

  // tutaj MCP Gateway wg tabeli routingu wywołuje Gift REST API,
  // a sam tool pozostaje cienką nakładką nad wywołaniem REST
  return {
    content: [{ type: "text", text: "Gift ideas..." }],
  };
};

Tutaj:

  • czytamy RELEASE_ID i CLUSTER_ID z env;
  • zapisujemy je do logów ustrukturyzowanych;
  • później łatwo ich użyć do analizy: „na której wersji/klastrze sypie nam się więcej błędów?”.

Z punktu widzenia ChatGPT App to zupełnie przezroczyste, ale dla was jako deweloperów — ogromny plus, zwłaszcza w połączeniu z canary/blue‑green.

10. Typowe błędy przy skalowaniu i wdrażaniu ChatGPT App

Błąd nr 1: trzymanie stanu sesji/użytkownika w pamięci procesu gateway albo backendu.
Takie podejście zabija skalowanie horyzontalne: gdy tylko pojawia się druga instancja, stan „rozwarstwia się” między nimi. Szczególnie niebezpiecznie jest trzymać w pamięci koszyk, wyniki wyszukiwania czy postęp workflow. To wszystko powinno żyć w zewnętrznym magazynie — bazie, cache’u albo specjalistycznym store dla stanu agenta.

Błąd nr 2: myślenie, że „jednego mocnego serwera” wystarczy.
Skalowanie pionowe jest wygodne na start, ale kiepsko działa przy realnym wzroście: maszyna ma fizyczny limit, jeden proces staje się single point of failure, a ChatGPT może przynieść nieprzewidywalny pik ruchu. Dla MCP Gateway i klastrów backendowych prawie zawsze potrzebne są stateless‑design i kilka instancji za load balancerem.

Błąd nr 3: wdrażanie nowych wersji „na żywym produkcie” bez jasnej strategii.
Jeśli po prostu aktualizujecie kontenery/procesy w klastrze produkcyjnym, dostajecie stan pośredni, gdzie część ruchu idzie do starej wersji, a część — do nowej, a przy błędzie rollback zamienia się w „wdrażaj jeszcze raz”. Znacznie bezpieczniej utrzymywać albo dwa środowiska (blue/green), albo przynajmniej osobną wersję canary serwisu backendowego, do której trafia niewielka część ruchu.

Błąd nr 4: brak szybkiego planu rollbacku.
Zły scenariusz: release poszedł, metryki czerwone, użytkownicy narzekają, a wy dopiero zaczynacie myśleć, jak się wycofać. Dobry scenariusz: wcześniej przygotowana możliwość natychmiastowego wycofania (przełącznik blue/green, rollout undo, Vercel rollback), czytelne identyfikatory wersji w logach i health‑endpointach oraz twarda zasada „najpierw wycofaj, potem diagnozuj”.

Błąd nr 5: jeden wspólny klaster „do wszystkiego” bez podziału według typów obciążenia.
Jeśli generowanie tekstów z życzeniami (agenci LLM) i checkout żyją w jednym klastrze, dowolny problem po stronie modeli (opóźnienia, time‑outy, wzrost zużycia tokenów) może położyć też płatności. Podział na klastry według zadań (Gift REST API / lekkie narzędzia, serwis agents‑heavy, Commerce REST API) i osobne limity/zasoby dla każdego klastra to ważny krok ku odporności.

Błąd nr 6: brak powiązania między architekturą a ekonomią.
Łatwo popaść w „to podnieśmy jeszcze parę nodów”, zapominając, że każde wywołanie LLM i każda instancja kosztują. Bez choćby prostego capacity planningu (szacowania obciążeń i kosztów) można albo nie doskalować i przewrócić produkcję, albo przeskalować i zjeść marżę. Warto łączyć liczbę żądań, procent ciężkich operacji LLM i koszt hostingu z metrykami biznesowymi aplikacji.

Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION