Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring cloud: Ribbon and HTTPS

We want to use HTTPS for our microservices communication based on Feign and Ribbon. The services are based on spring boot and tomcat is correctly setup. The instances are registered with the HTTPS URL and securePort enabled on Eureka. However, when we call another microservice via Feign then the underlying Ribbon doesn't recognizes the protocol and falls back to HTTP. I could solve that problem by adding the protocol to the FeignClient annotation like this:

    @FeignClient("https://users")

But it seem that the Zuul proxy and the Hystrix/Turbine which are also using Ribbon internally have the same HTTP fallback problem. Is there any way to configure Ribbon centrally to use HTTPS as default or use the securePort setting of the registred eureka instance?

Eureka instance configuration:

eureka.instance.hostname=localhost
eureka.instance.securePort = ${server.port}
eureka.instance.securePortEnabled = true  
eureka.instance.nonSecurePortEnabled = false 
eureka.instance.metadataMap.hostname = ${eureka.instance.hostname}
eureka.instance.metadataMap.securePort = ${server.port}
eureka.instance.homePageUrl = https://${eureka.instance.hostname}:${server.port}/
eureka.instance.statusPageUrl = https://${eureka.instance.hostname}:${server.port}/admin/info

With these settings it looks in Eureka like the service runs on HTTPS. The Zuul proxy runs fine, but uses the HTTP URL to call the service. You have to enable SSL in Spring Boots embedded Tomcat by providing a server certificate in a keystore:

server.ssl.key-store=server.jks
server.ssl.key-store-password=<pw>
server.ssl.keyStoreType=jks
server.ssl.keyAlias=tomcat
server.ssl.key-password=<pw> 

Tomcat than only runs on HTTPS and the HTTP port is blocked, but than I get: localhost:8081 failed to respond because a HTTP URL is used to call the service. By setting ribbon.IsSecure=true the users service url is correctly generated, but the Ribbon loadbalancer fails to lookup the users service in Eureka: Load balancer does not have available server for client: users. I aslo tried to set users.ribbon.IsSecure=true in the zuul proxy only, but still get the same error.

Caused by: com.netflix.client.ClientException: Load balancer does not have available server for client: user
at com.netflix.loadbalancer.LoadBalancerContext.getServerFromLoadBalancer(LoadBalancerContext.java:468)
at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:184)
at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:180)
at rx.Observable$1.call(Observable.java:145)
at rx.Observable$1.call(Observable.java:137)
at rx.Observable$1.call(Observable.java:145)
at rx.Observable$1.call(Observable.java:137)
at rx.Observable.unsafeSubscribe(Observable.java:7304)
at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber$1.call(OperatorRetryWithPredicate.java:112)
at rx.schedulers.TrampolineScheduler$InnerCurrentThreadScheduler.enqueue(TrampolineScheduler.java:81)
at rx.schedulers.TrampolineScheduler$InnerCurrentThreadScheduler.schedule(TrampolineScheduler.java:59)
at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber.onNext(OperatorRetryWithPredicate.java:77)
at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber.onNext(OperatorRetryWithPredicate.java:45)
at rx.internal.util.ScalarSynchronousObservable$1.call(ScalarSynchronousObservable.java:41)
at rx.internal.util.ScalarSynchronousObservable$1.call(ScalarSynchronousObservable.java:30)
at rx.Observable$1.call(Observable.java:145)
at rx.Observable$1.call(Observable.java:137)
at rx.Observable$1.call(Observable.java:145)
at rx.Observable$1.call(Observable.java:137)
at rx.Observable$1.call(Observable.java:145)
at rx.Observable$1.call(Observable.java:137)
at rx.Observable.subscribe(Observable.java:7393)
at rx.observables.BlockingObservable.blockForSingle(BlockingObservable.java:441)
at rx.observables.BlockingObservable.single(BlockingObservable.java:340)
at com.netflix.client.AbstractLoadBalancerAwareClient.executeWithLoadBalancer(AbstractLoadBalancerAwareClient.java:102)
at com.netflix.client.AbstractLoadBalancerAwareClient.executeWithLoadBalancer(AbstractLoadBalancerAwareClient.java:81)
at org.springframework.cloud.netflix.zuul.filters.route.RibbonCommand.forward(RibbonCommand.java:129)
at org.springframework.cloud.netflix.zuul.filters.route.RibbonCommand.run(RibbonCommand.java:103)
at org.springframework.cloud.netflix.zuul.filters.route.RibbonCommand.run(RibbonCommand.java:1)
at com.netflix.hystrix.HystrixCommand$1.call(HystrixCommand.java:298)
like image 260
Daniel Sass Avatar asked Jun 03 '15 14:06

Daniel Sass


People also ask

Is ribbon supported by spring Cloud?

0, Spring Cloud Netflix now supports customizing Ribbon clients by setting properties to be compatible with the Ribbon documentation.

What is ribbon in spring Cloud?

Ribbon primarily provides client-side load balancing algorithms. Apart from the client-side load balancing algorithms, Ribbon provides also other features: Service Discovery Integration – Ribbon load balancers provide service discovery in dynamic environments like a cloud.

Is Netflix ribbon deprecated?

Spring Cloud Netflix Ribbon has been deprecated and is not included in the 2020.0. 0 release train. Spring Cloud LoadBalancer is the suggested alternative.

Does Zuul use ribbon?

Internally, Zuul uses Netflix Ribbon to look up for all instances of the service from the service discovery (Eureka Server).

How do I set up a Spring Cloud ribbon client?

See the Spring Cloud Project page for details on setting up your build system with the current Spring Cloud Release Train. You can configure some bits of a Ribbon client by using external properties in <client>.ribbon.*, which is similar to using the Netflix APIs natively, except that you can use Spring Boot configuration files.

Does Spring Cloud Netflix support customizing ribbon clients?

Starting with version 1.2.0, Spring Cloud Netflix now supports customizing Ribbon clients by setting properties to be compatible with the Ribbon documentation. This lets you change behavior at start up time in different environments. <clientName>.ribbon.NFLoadBalancerClassName: Should implement ILoadBalancer

How to configure ribbon client side load balancer in Spring Boot?

Spring boot has very nice way of configuring ribbon client side load balancer with minimal effort. It provides the following features Multiple protocol (HTTP, TCP, UDP) support in an asynchronous and reactive model To get ribbon binaries, go to maven central. Here is an example to add dependency in Maven: 4. Netflix ribbon example 4.1.

What is Spring Cloud used for?

Spring Cloud. Spring Cloud provides tools for developers to quickly build some of the common patterns in distributed systems (e.g. configuration management, service discovery, circuit breakers, intelligent routing, micro-proxy, control bus, one-time tokens, global locks, leadership election, distributed sessions, cluster state).


Video Answer


1 Answers

We solved the zuul proxy problem now by setting

ribbon.IsSecure=true
eureka.instance.secureVirtualHostName=${spring.application.name}

so that all services are also in the secure virtual hosts pool in com.netflix.discovery.shared.Applications. That helps the discovery process to find the instances in eureka.

However, the Hystrix dashboard has still a similar problem

like image 178
Daniel Sass Avatar answered Oct 20 '22 05:10

Daniel Sass