我们希望在基于Feign和Ribbon的微服务通信中使用HTTPS。这些服务基于spring引导,tomcat已正确设置。这些实例在Eureka上使用HTTPS URL和启用了securePort进行注册。然而,当我们通过Feign调用另一个微服务时,底层的Ribbon无法识别该协议并退回到HTTP。我可以通过像这样将协议添加到FeignClient注释来解决这个问题:
@FeignClient("https://users")
但似乎Zuul代理和Hystrix/Turbine也在内部使用Ribbon有相同的HTTP回退问题。是否有任何方法可以将Ribbon集中配置为默认使用HTTPS或使用注册的eureka实例的securePort设置?
Eureka实例配置:
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
有了这些设置,它在Eureka中看起来就像服务运行在HTTPS上。Zuul代理运行良好,但使用HTTP URL调用服务。您必须在Spring Boots嵌入式Tomcat中启用SSL,方法是在密钥库中提供服务器证书:
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只在HTTPS上运行,HTTP端口被阻塞,但我得到:localhost:8081 failed to respond
,因为使用HTTP URL来调用服务。通过设置ribbon.IsSecure=true
,可以正确生成用户服务url,但是Ribbon loadbalancer无法查找到Eureka: Load balancer does not have available server for client: users
中的用户服务。我也试图在zuul代理中设置users.ribbon.IsSecure=true
,但仍然得到相同的错误。
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)
我们现在通过设置
解决了zuul代理问题ribbon.IsSecure=true
eureka.instance.secureVirtualHostName=${spring.application.name}
使所有服务也在com.netflix.discovery.shared.Applications
的安全虚拟主机池中。这有助于发现过程找到eureka中的实例。
然而,Hystrix仪表盘仍然有类似的问题
我有同样的问题,试图配置Zuul代理使用Ribbon连接到运行在https上的微服务:RibbonRoutingFilter正在查看requestURI并在执行run方法时创建RestClient。我配置了Eureka在http上运行。它是在Eureka上注册的底层https微服务,不能被Ribbon访问。
http与简单的zuul路由设置完美地工作。
在添加isSecure:true之后,也可能存在握手不成功的可能性,遇到过一次,我通过添加如下所示的Truststore来解决这个问题
-Djavax.net.ssl.trustStore ="//位置。JKS文件"和-Djavax.net.ssl.keyStorePassword ="有效password".
这个帮助我修复了HTTPS握手问题