Spring云:功能区和HTTPS

时间:2015-06-03 14:24:39

标签: spring spring-boot spring-cloud

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

    @FeignClient("https://users")

但似乎Zuul代理和Hystrix / Turbine也在内部使用Ribbon具有相同的HTTP回退问题。是否有任何方法可以集中配置功能区以将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负载均衡器无法在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)

3 个答案:

答案 0 :(得分:5)

我们现在通过设置

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

以便所有服务也位于com.netflix.discovery.shared.Applications中的安全虚拟主机池中。这有助于发现过程在eureka中找到实例。

但是,Hystrix仪表板仍有类似的问题

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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

<块引用>

-Djavax.net.ssl.trustStore="//.JKS 文件的位置" 和 -Djavax.net.ssl.keyStorePassword="有效密码"。

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