Anomalyzero
Anomalyzero

Reputation: 125

Spring Cloud Gateway: Does not route request, eventually encounter 413 request entity too large

I am trying to set up a simple Spring Cloud Gateway example.

I have 2 docker containers running locally that will respond with AAA and ZZZ when the following endpoint is hit

http://localhost:2000/restmessage
http://localhost:2001/restmessage

I'm trying to make a simple Gateway that will route to one of these services. Eventually there will be actual logic to make this decision, but for now I just want to see something work and have hardcoded to the first instance.

Here is my GlobalFilter

@Component
public class MacFilter implements GlobalFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerWebExchange modifiedExchange = exchange.mutate()
                .request(rq -> rq.uri(
                        UriComponentsBuilder.fromUri(exchange.getRequest().getURI())
                        .host("localhost")
                        .port(2000)
                        .build()
                        .toUri()
                ))
                .build();

//        ServerWebExchangeUtils.setAlreadyRouted(modifiedExchange);


        return chain.filter(modifiedExchange);
    }
}

And properties

spring.cloud.gateway.routes[0].id=routezero
spring.cloud.gateway.routes[0].uri=http://localhost:8081
spring.cloud.gateway.routes[0].predicates[0]=Path=/restmessage

This Filter runs every time I hit the gateway with restmessage (http://localhost:8080/restmessage). But if the commented setAlreadyRouted method is commented out, it hits it hundreds of times. Eventually the curl command fails with a 413 REQUEST ENTITY TOO LARGE. By watching the logs of the docker services, I can tell they are never hit.

$ curl localhost:8080/restmessage -i
HTTP/1.1 413 Request Entity Too Large
content-length: 0

If I uncomment the setAlreadyRouted method, it no longers calls hundreds of times and the request comes back immediately, but the response is empty and the docker containers are again never called.

$ curl localhost:8081/restmessage -i
HTTP/1.1 200 OK
content-length: 0

I've also tried this with a FilterFactory and a RouteLocator Bean but they all demonstrate the same behavior.

I've been crawling all over the documentation, but everything I can find seems to indicate that this should be working. Can anybody help me out?

Upvotes: 2

Views: 2706

Answers (2)

Jonck van der Kogel
Jonck van der Kogel

Reputation: 3293

What you want to do is define the routes to your backend services. In you current setup you are creating a route to a service running on port 8081 and as far as I can read in your description there is no service running on that port.

So in other words, if you have a 2 identical services, one running on localhost:2000 and the other on localhost:2001, you are going to want 2 routes, one for the one service and one for the other. Of course since the services expose identical endpoints you are going to need something by which to distinguish to which service you want to route. For example this can be done by adding a header to your request.

A sample setup could be something like this. In your application.yaml (so not in your application.properties, it can also be done in a properties file but yaml is better suited for this purpose), put something like this:

spring:
  application:
    name: gateway-service
  cloud:
    gateway:
      routes:
        - id: 2000service
          uri: http://localhost:2000
          predicates:
            - Path=/restmessage
            - Header=route, service-one
        - id: 2001service
          uri: https://localhost:2001
          predicates:
            - Path=/restmessage
            - Header=route, service-two

You can get rid of your GlobalFilter and of the properties that you defined. Now start up your application:

mvn spring-boot:run

Then do a curl to your service (assuming here your gateway runs on port 8080):

curl http://localhost:8080/restmessage -H "route: service-one"

You should now see your request being routed towards your service running on port 2000.

Hope this helps!

Upvotes: 1

Joseph-z
Joseph-z

Reputation: 29

maybe a discovery center, such as eureka, will solve your problem.

  • first, register docker server to eureka;
  • then, give spring cloud gateway a eureka configuration;
  • finally, set @EnableDiscoveryClient at your spring cloud gateway application class.

also, this issue's posts could help you much: https://github.com/spring-cloud/spring-cloud-gateway/issues/383

Upvotes: 0

Related Questions