Spring

 View Only

 How do I get spring-cloud-gateway to work with PCF internal routes?

Philipp Westrich's profile image
Philipp Westrich posted Feb 27, 2020 10:05 AM

We are currently using spring-cloud-gateway as our application gateway for a micro-service application deployed in PCF. However, we have some problems getting it to work when using container-networking with PCF's apps.internal routes. The main issue is that load balancing does not work.

 

We have found that the gateway will not loadbalance when pointing it against a PCF internal route. We have deployed three instances of a dummy backend service and routed our requests to this service through the spring-cloud-gateway. The configuration looks like this:

spring: cloud: gateway: routes: - id: dummyservice uri: http://dummyservice.apps.internal predicates: - Path=/dummyservice/** filters: - RewritePath=/dummyservice/(?<segment>.*), /$\{segment}

All requests to the dummy service arrive at a single instance. Other instances do not receive any requests. This problem does not occur when using an external route.

 

Is there some configuration that must be set in order for the gateway to correctly work with internal routes?

 

We use Spring Boot version 2.2.4 with Spring Cloud Version Hoxton.SR1. PCF Api version is 2.142.0.

Daniel Mikusa's profile image
Daniel Mikusa

OK, so when you use the internal domain, traffic is routing directly between two app instance. It's not going through Gorouter, so you lose the load balancing that is provided by Gorouter.

 

Without Gorouter the only load balancing you get is at the DNS layer. When you resolve `dummyservice.apps.internal`, the response should be round-robined.

 

Ex:

vcap@c1a47cdf-f581-49c4-771c-250d:~$ host speed-test.apps.internal speed-test.apps.internal has address 10.248.39.92 speed-test.apps.internal has address 10.252.251.126 speed-test.apps.internal has address 10.253.200.126 vcap@c1a47cdf-f581-49c4-771c-250d:~$ host speed-test.apps.internal speed-test.apps.internal has address 10.252.251.126 speed-test.apps.internal has address 10.248.39.92 speed-test.apps.internal has address 10.253.200.126 vcap@c1a47cdf-f581-49c4-771c-250d:~$ host speed-test.apps.internal speed-test.apps.internal has address 10.252.251.126 speed-test.apps.internal has address 10.253.200.126 speed-test.apps.internal has address 10.248.39.92

See how the .92 address rotates through the response.

 

This could be a problem though if your app is caching DNS or if your app is caching connections to a backend service. I believe that the Java buildpack will disable caching by default (check your staging output, it emits a message saying when it disables this). If you can confirm that DNS caching has been disabled in the JVM, then the other culprit could be that connection reuse is happening.

 

Many apps will keep HTTP connections open and use them multiple times for different requests. This saves the overhead of making a new TCP connection & establishing a new TLS session (when HTTPS is used). The problem is that this is going to be a connection to a specific backend, and that won't change until the connection is dropped. This could lead to unbalanced traffic loads to your backend apps.

 

To work around this, you need to have a smart client that can load balance. Check out the LoadBalancerClientFilter or ReactiveLoadBalancerClientFilter

in SCG. I believe that should do what you want.