Spring cloud gateway

Spring cloud gateway
anckor
  • Rejestracja:ponad 5 lat
  • Ostatnio:3 dni
  • Postów:309
0

Potrzebuję zrealizować taki scenariusz: Uderzam do gateway'a, on uderza do service 1 i zwraca wynik. Jednak w przypadku, gdy service 1 zwróci 4xx, lub 5xx chcę automatycznie zrobić fallback. Myślałem, że da się to zrealizować w Spring cloud gateway, ale albo się nie da albo ja jestem ślepy. W każdym tutorialu jest coś na wzór:

Kopiuj
    @Bean
    public RouteLocator myRoutes(RouteLocatorBuilder builder) {
        return builder.routes()
                .route(p -> p
                        .path("/employee/message")
                        .filters(f ->
                                f.hystrix(config -> config
                                        .setName("countries-service")
                                        .setFallbackUri("forward:/countriesfallback"))
                        )
                        .uri("http://localhost:8081")
                )
                .build();
    }

I tutaj jest prawie okej, bo jak /employee/message się wywali, to poleci fallback na /countriesfallback, ale do usługi, która jest w tym samym projekcie co gateway. Niestety nie działa opcja wpisania: forward:/http://service3/countriesfallback. W takiej sytuacji muszę tworzyć usługę /countriesfallback, która WebClientem strzela mi do service3. Bez sensu. Da się jakoś to zrobić w cloud gateway, albo ktoś zna inną wartą uwagi bibliotekę?

Charles_Ray
  • Rejestracja:około 17 lat
  • Ostatnio:około 5 godzin
  • Postów:1875
0

Nie za bardzo rozumiem co ma gateway do fallbacka. Fallback jesteś w stanie zaimplementować używając instrukcji warunkowej if. Gateway jako pattern w ogole służy do czegoś innego.

Jeśli już szukasz jakichś gotowych mechanizmów, które są trochę bardziej inteligentne, to Resillience4j.


”Engineering is easy. People are hard.” Bill Coughran
edytowany 1x, ostatnio: Charles_Ray
anckor
  • Rejestracja:ponad 5 lat
  • Ostatnio:3 dni
  • Postów:309
0

Nie za bardzo rozumiem co ma gateway do fallbacka.

To ma, że jak serwis do którego kieruje żądanie nie działa to wtedy chce zrobić fallback na inny serwis.

Fallback jesteś w stanie zaimplementować używając instrukcji warunkowej if.

Ale w jaki sposób w tym fragmencie, który wkleiłem dodać instrukcję if? Te routy w spring gatewayu definiujesz za pomocą beanów i spring potem już sam sobie go rozkłada na czynniki pierwsze.

Jeśli już szukasz jakichś gotowych mechanizmów, które są trochę bardziej inteligentne, to Resillience4j.

Patrzałem. Resillience4j nie ma api gatewaya.

edytowany 1x, ostatnio: anckor
Charles_Ray
  • Rejestracja:około 17 lat
  • Ostatnio:około 5 godzin
  • Postów:1875
0

Podbijam, że fallback to kwestia komunikacja usługa-usługa w ogólności, wzorzec Gateway rozwiązuje inny problem.

Nie wiem jak to rozwiązać stricte w Spring Gateway, może musisz jakoś manualnie sobie te routę ogarnąć. Przeczytaj dokumentację. Jeszcze raz - aby zaimplementować fallback czy circuit breaker, nie potrzebujesz żadnego gatewaya


”Engineering is easy. People are hard.” Bill Coughran
edytowany 1x, ostatnio: Charles_Ray
anckor
  • Rejestracja:ponad 5 lat
  • Ostatnio:3 dni
  • Postów:309
0

W takim razie może źle się wyraziłem. Potrzebuję gateway'a żeby przekazać request do serwisu. Z tym, że z gatewaya może pójść albo do service-A albo do service-B. I ja chcę, żeby zawsze szedł do service-A, a jak on zwróci 4xx lub 5xx, to chcę strzelić do service-B. I to mam na myśli mówiąc fallback.

Charles_Ray
  • Rejestracja:około 17 lat
  • Ostatnio:około 5 godzin
  • Postów:1875
0

Dobra chyba rozumiem, ale to jest dziwne trochę. Idąc za https://roytuts.com/how-to-implement-circuit-breaker-pattern-using-hystrix-in-spring-cloud-gateway/ musisz sztucznie wystawić w tym komponencie gatewaya kontroler, który zostanie zawołany jako fallback i w tym kontrolerze klientem HTTP wołasz ten swój serwis.

Ma to sens o tyle, że fallback zawsze powinien się udać (stad wołana jest lokalna klasa), niestety u Ciebie nie ma takiej pewności. Nie rozumiem tego patentu ze sztucznym wystawianiem kontrolera, powinno się po prostu wskazać metodę do wywołania, ale może czegoś nie rozumiem.


”Engineering is easy. People are hard.” Bill Coughran
edytowany 1x, ostatnio: Charles_Ray
anckor
  • Rejestracja:ponad 5 lat
  • Ostatnio:3 dni
  • Postów:309
0

I właśnie o tym piszę, że wg mnie jest to trochę bez sensu. Teoretycznie da się jeszcze tak:

Kopiuj
spring:
  cloud:
    gateway:
      routes:
      - id: ingredients
        uri: lb://ingredients
        predicates:
        - Path=//ingredients/**
        filters:
        - name: Hystrix
          args:
            name: fetchIngredients
            fallbackUri: forward:/fallback
      - id: ingredients-fallback
        uri: http://localhost:9994
        predicates:
        - Path=/fallback

Wtedy nie musisz mieć endpointu /fallback w swojej aplikacji, tylko taki enpoint masz w zewnętrznej wystawionej na http://localhost:9994. Teoretycznie jest tak jak chce, tylko, że nie ma tu nigdzie miejsca na to, żeby zrobić warunek 'route tylko przy 4xx/5xx'.

edytowany 1x, ostatnio: anckor
Charles_Ray
  • Rejestracja:około 17 lat
  • Ostatnio:około 5 godzin
  • Postów:1875
0

Hmm no ale Spring jakoś przetwarza ten plik i tworzy sobie rejestr route. Nie da rady tam wstawić swojej routy, która sobie skonfigurujesz w kodzie? Spring zwykle bardzo dobrze wspierał customy, tym się reklamuje, że jest mega rozszerzalny :)

https://cloud.spring.io/spring-cloud-gateway/reference/html/#configuration

EDIT: w sumie to co chcesz zrobić jest antypatternem, bo Gateway powinien być głupi :) pomyśl sobie, co się stanie jak będziesz miał 100 usług i zaczniesz w Gatewayu kodować właśnie takie logiki fallbacków - dziesiątki zespołów będą orać kod tego gatewaya i ich wdrożenia będą zależne od wdrożenia tego komponentu. To jest średniowieczne podejście, jakie stosowało się przy szynach integracyjnych, przy mikroserwisach robi się odwrotnie (decentralizacja i autonomia). Zamiast koordynować, postaw na orkiestrację - zdeleguj obsługę żądania do usługi i w niej zakoduj logikę fallbacka. To wydaje mi się najlepsze rozwiązanie.


”Engineering is easy. People are hard.” Bill Coughran
edytowany 6x, ostatnio: Charles_Ray
anckor
Pewnie masz racje z tym antypatternem, z tym, że to co robię to prawdopodobnie rozwiązanie przejściowe (do roku czasu) i obejmie tylko 2 mikroserwisy. Więc nie będzie tu grzebania w tym przez rzesze ludzi. A i w sumie chyba już znalazłem to co chcę, dzięki.
Charles_Ray
Polecam się, powodzenia
anckor
  • Rejestracja:ponad 5 lat
  • Ostatnio:3 dni
  • Postów:309
0

Mam jeszcze 1 pytanie. Jak to wygląda w kwestii utrzymania kontraktu API między gateway'em, a serwisami? Bo jeżeli mam API wystawione w serwisie nr1, to tak samo muszę je mieć spisane w gateway'u żeby wiedzieć gdzie przekazywać żądania. I wtedy każda zmiana API w serwisie nr1 niesie za sobą konieczność zmiany w gateway'u. Tak się zawsze robi czy jest jakaś możliwość żeby nie utrzymywać tego samego kodu w dwóch różnych miejscach?

Charles_Ray
  • Rejestracja:około 17 lat
  • Ostatnio:około 5 godzin
  • Postów:1875
1

No widzisz - wracamy do pytania po co Ci ten gateway :) nie każdy endpoint wystawiasz publicznie na gateway, to rzeczywiście byłaby nadmiarowa robota i wystawienie bebechow na świat.

https://microservices.io/patterns/apigateway.html

Przykład: wystawiam na świat metodę API publishArticle, która jest routowana do odpowiedniego serwisu. Co się dzieje dalej, jakie inne usługi są zaangażowane w proces, jest przezroczyste dla gatewaya.

Zespoły mogą w jakiś sposób zgłaszać endpointy, które chcą wystawić na API np. dopisując się pliku konfiguracyjnego lub poprzez jakiś inny mechanizm.


”Engineering is easy. People are hard.” Bill Coughran
edytowany 1x, ostatnio: Charles_Ray

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.