Spring cloud gateway

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:

    @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ę?

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.

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.

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

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.

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.

0

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

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'.

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.

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?

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.

1 użytkowników online, w tym zalogowanych: 0, gości: 1