Java 春云,Zuul https

Java 春云,Zuul https,java,spring,https,cloud,netflix-zuul,spring-cloud,spring-cloud-netflix,netflix-ribbon,Java,Spring,Https,Cloud,Netflix Zuul,Spring Cloud,Spring Cloud Netflix,Netflix Ribbon,我的网关应用程序(使用zuul)中的https服务有问题 代理http服务时效果很好,但代理https服务时我遇到了问题 我有例外 java.lang.IllegalStateException: Could not create URI object: Expected scheme-specific part at index 6: https: at org.springframework.web.util.HierarchicalUriComponents.toUr

我的网关应用程序(使用zuul)中的https服务有问题 代理http服务时效果很好,但代理https服务时我遇到了问题 我有例外

java.lang.IllegalStateException: Could not create URI object: Expected scheme-specific part at index 6: https:
           at org.springframework.web.util.HierarchicalUriComponents.toUri(HierarchicalUriComponents.java:430) ~[spring-web-4.2.6.RELEASE.jar:4.2.6.RELEASE]
           at org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration$OverrideRestClient.reconstructURIWithServer(RibbonClientConfiguration.java:184) ~[spring-cloud-netflix-core-1
           at com.netflix.client.AbstractLoadBalancerAwareClient$1.call(AbstractLoadBalancerAwareClient.java:106) ~[ribbon-loadbalancer-2.1.5.jar:2.1.5]
           at com.netflix.loadbalancer.reactive.LoadBalancerCommand$3$1.call(LoadBalancerCommand.java:303) ~[ribbon-loadbalancer-2.1.5.jar:2.1.5]
           at com.netflix.loadbalancer.reactive.LoadBalancerCommand$3$1.call(LoadBalancerCommand.java:287) ~[ribbon-loadbalancer-2.1.5.jar:2.1.5]
           at rx.internal.util.ScalarSynchronousObservable$4.call(ScalarSynchronousObservable.java:223) ~[rxjava-1.1.5.jar:1.1.5]
           at rx.internal.util.ScalarSynchronousObservable$4.call(ScalarSynchronousObservable.java:220) ~[rxjava-1.1.5.jar:1.1.5]
           at rx.Observable.unsafeSubscribe(Observable.java:8460) ~[rxjava-1.1.5.jar:1.1.5]
           ... 150 common frames omitted
    aused by: java.net.URISyntaxException: Expected scheme-specific part at index 6: https:
           at java.net.URI$Parser.fail(URI.java:2848) ~[na:1.8.0_92]
           at java.net.URI$Parser.failExpecting(URI.java:2854) ~[na:1.8.0_92]
           at java.net.URI$Parser.parse(URI.java:3057) ~[na:1.8.0_92]
           at java.net.URI.<init>(URI.java:673) ~[na:1.8.0_92]
尤里卡:

 instance:
    hostname: localhost
  client:
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
  server:
    enableSelfPreservation: false
我的客户端配置

spring:
  application:
    name: mille-test2
  cloud:
    config:
      discovery:
        enabled: true
        serviceId: mille-config-server
eureka:
  client:
    healthcheck:
      enabled: true  
server:
  port: 50000
  ssl:
    key-store: classpath:my.jks
    key-store-password: secret
    key-password: secret 

eureka:
  client:
    enabled: true
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
  instance:
    nonSecurePortEnabled: false
    securePortEnabled: true
    securePort: ${server.port}    
    instanceId: ${spring.application.name}:${spring.application.instance_id:${random.value}}
    statusPageUrl: https://${eureka.hostname}:${server.port}/info
    healthCheckUrl: https://${eureka.hostname}:${server.port}/health
    homePageUrl: https://${eureka.instance.hostname}:${server.port}/
    secureVirtualHostName: ${spring.application.name}
    metadataMap:
       hostname: ${eureka.instance.hostname}
       securePort: ${server.port}  

有什么问题吗?

不确定您是否能够解决此问题,但我遇到了同样的问题。但是,只有当Zuul试图通过https(如您所指出的)将请求代理给服务端点“root”时,才会出现这种情况

例如,使用上面的Zuul配置-点击端点
/test
可能会导致该异常,但是点击任何其他代理到
mille-test2
服务(未映射到根目录)的端点可能会工作
test/something
。至少对我来说是这样。因此,作为一项临时工作,我只是创建了扩展根的不同端点,例如
/test/new
。笨拙,是的,但可行


我现在正在使用SpringCloudBrixton.SR4

我在Brixton.SR6的调试器中跟踪了这个问题

  • 在调用将服务器实际添加到uri的超类方法之前,假LoadBalancer.ReconstructureWithServer(…)调用RibbonUtils.UpdateToHttpSifRequired(…)
  • 传入的uri为“”,这是传入url完全匹配zuul映射并使用服务发现获取服务器/端口时的正常情况
  • updateToHttpsIfNeeded()添加“https”,并通过build(true)调用UriComponentsBuilder以创建HierarchycalUriComponents的实例
  • 然后在该实例上调用toUri(),由于传入build()的是true,因此该实例遵循encode==true路径并调用新的URI(toString())(第415行)。toString()返回“https:”,因为我们已经设置了方案,但没有设置服务器或端口
  • URI根本不喜欢这样,并在索引6处抛出java.net.URISyntaxException:Expected scheme-specific部分:https:
至于解决这个问题,也许在URI中设置服务器和端口之前,FaignLoadBalancer不应该确保https?或者,RibbonUtils.updateToHttpsIfNeeded在调用toUri()之前,应该在UriComponentsBuilder中设置服务器和端口-它具有服务器实例

这就解释了为什么只有安全连接才会发生这种情况。当在映射中使用精确的url匹配时,我还没有找到任何解决方法,除了恢复到Brixton.SR5,这很好,因为对build()的调用没有传递true标志,因此不会调用new URI()。嗯

编辑:另请参见

spring:
  application:
    name: mille-test2
  cloud:
    config:
      discovery:
        enabled: true
        serviceId: mille-config-server
eureka:
  client:
    healthcheck:
      enabled: true  
server:
  port: 50000
  ssl:
    key-store: classpath:my.jks
    key-store-password: secret
    key-password: secret 

eureka:
  client:
    enabled: true
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
  instance:
    nonSecurePortEnabled: false
    securePortEnabled: true
    securePort: ${server.port}    
    instanceId: ${spring.application.name}:${spring.application.instance_id:${random.value}}
    statusPageUrl: https://${eureka.hostname}:${server.port}/info
    healthCheckUrl: https://${eureka.hostname}:${server.port}/health
    homePageUrl: https://${eureka.instance.hostname}:${server.port}/
    secureVirtualHostName: ${spring.application.name}
    metadataMap:
       hostname: ${eureka.instance.hostname}
       securePort: ${server.port}