Spring 云:功能区和 HTTPS

Spring cloud: Ribbon and HTTPS

我们希望使用 HTTPS 进行基于 Feign 和 Ribbon 的微服务通信。这些服务基于 spring 引导并且 tomcat 已正确设置。这些实例在 Eureka 上启用了 HTTPS URL 和 securePort 注册。但是,当我们通过 Feign 调用另一个微服务时,底层 Ribbon 无法识别该协议并回退到 HTTP。我可以通过将协议添加到 FeignClient 注释来解决这个问题,如下所示:

    @FeignClient("https://users")

但Zuul代理和内部同样使用Ribbon的Hystrix/Turbine似乎也有同样的HTTP回退问题。有什么方法可以集中配置功能区以默认使用 HTTPS 或使用已注册 eureka 实例的 securePort 设置?

尤里卡实例配置:

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 embedded 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 负载均衡器无法在 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.call(LoadBalancerCommand.java:184)
at com.netflix.loadbalancer.reactive.LoadBalancerCommand.call(LoadBalancerCommand.java:180)
at rx.Observable.call(Observable.java:145)
at rx.Observable.call(Observable.java:137)
at rx.Observable.call(Observable.java:145)
at rx.Observable.call(Observable.java:137)
at rx.Observable.unsafeSubscribe(Observable.java:7304)
at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber.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.call(ScalarSynchronousObservable.java:41)
at rx.internal.util.ScalarSynchronousObservable.call(ScalarSynchronousObservable.java:30)
at rx.Observable.call(Observable.java:145)
at rx.Observable.call(Observable.java:137)
at rx.Observable.call(Observable.java:145)
at rx.Observable.call(Observable.java:137)
at rx.Observable.call(Observable.java:145)
at rx.Observable.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.call(HystrixCommand.java:298)

我在尝试配置 Zuul 代理以使用 Ribbon 连接到 https 上的微服务时遇到同样的问题 运行ning:RibbonRoutingFilter 正在查看 requestURI 并在执行 运行 方法时创建 RestClient。不过,我在 http 上将 Eureka 配置为 运行。是注册在Eureka上的底层https微服务无法被Ribbon访问

http 与简单的 zuul 路由设置完美结合。

我们现在通过设置

解决了zuul代理问题
ribbon.IsSecure=true
eureka.instance.secureVirtualHostName=${spring.application.name}

这样所有服务也都在 com.netflix.discovery.shared.Applications 的安全虚拟主机池中。这有助于发现过程在尤里卡中找到实例。

但是Hystrix dashboard还是有类似的问题

在添加 isSecure:true 之后也可能存在握手不成功的可能性,遇到过一次,我通过添加如下所示的 Truststore 解决了这个问题

-Djavax.net.ssl.trustStore="//location of.JKS file " and -Djavax.net.ssl.keyStorePassword="valid password".

他们帮我解决了 HTTPS 握手问题