Spring Cloud Gateway + Consul配置

时间:2019-02-10 05:12:28

标签: spring spring-cloud spring-cloud-gateway

我们先使用Spring Cloud Gateway将多个微服务与领事作为服务发现。有几种使用不同语言开发的微服务。

请为该应用找到 build.gradle

buildscript {
    ext {
        springBootVersion = '2.1.2.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

group = 'com.demo'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

repositories {
    mavenCentral()
    maven { url 'https://repo.spring.io/milestone' }
}

ext {
    set('springCloudVersion', 'Greenwich.RELEASE')
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    implementation 'org.springframework.cloud:spring-cloud-starter-consul-config'
    implementation 'org.springframework.cloud:spring-cloud-starter-consul-discovery'
    implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
    implementation 'org.springframework.boot:spring-boot-starter-security'
    // https://mvnrepository.com/artifact/io.netty/netty-tcnative-boringssl-static
    compile group: 'io.netty', name: 'netty-tcnative-boringssl-static', version: '2.0.20.Final'
    runtimeOnly 'org.springframework.boot:spring-boot-devtools'
    compileOnly 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    }
}

下面是API网关配置的示例
application.yaml

server:
  port: 10000
  http:
    port: 9000
  # enable HTTP2
  http2:
    enabled: true
  # enable compression
  compression:
    enabled: true
    mime-types: text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json
  ssl:
    enabled: true
    key-store: /var/.conf/self-signed.p12
    key-store-type: PKCS12
    key-store-password: "something"
    key-alias: athenasowl
    trust-store: /var/.conf/self-signe.p12
    trust-store-password: "something"
spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          predicates:
          - Path="'/api/' + serviceId + '/**'"
          filters:
          - RewritePath="'/api/' + serviceId + '/(?<remaining>.*)'", "serviceId + '/${remaining}'"
management:
  security:
    enabled: false
  server:
    port: 10001
    ssl:
      enabled: false
  endpoint:
    gateway:
      enabled: true
  endpoints:
    web:
      exposure:
        include: "*"
    health:
      sensitive: false
logging:
  level:
    root: DEBUG
    org:
      springframework:
        web: INFO
  pattern:
    console: "%-5level %d{dd-MM-yyyy HH:mm:ss,SSS} [%F:%L] VTC : %msg%n"
    file: "%-5level %d{dd-MM-yyyy HH:mm:ss,SSS} [%F:%L] VTC : %msg%n"
  file: /tmp/log_files/apigateway.log
security:
  basic:
    enabled: false

我们面临一些配置问题,它们在下面列出:

  • 将/ api /前缀的URL重写为在领事上注册的相应serviceId :我们试图配置谓词以使路径以 api 前缀em> 重写路径并删除 api ,但仍然无法正常工作。因此,在领事服务器上注册了另一个服务 / hello-service / ,但是我们要使用 / api / hello-service /
  • 将不匹配的请求重定向到默认路径 :我们希望将所有不匹配的请求重定向到UI。
  • 在Spring Cloud Gateway上将HTTP重定向到HTTPS :我们要强制所有到Spring网关的请求都为https
  • 将HTTPS请求转发到在consul中注册的HTTP serviceId :在consul中注册的服务均在HTTP上,但API网关除外,我们希望能够将HTTPS请求发送至HTTP后端,即仅在API网关处终止HTTPS。

任何解决上述问题的帮助都很好

修改1: 在@spencergibb提供帮助后,我们使用https设置了spring cloud网关。但是,我们还面临其他一些问题

  • 如果同时在API网关和服务上均启用HTTPS,我们将收到以下错误消息
  

javax.net.ssl.SSLException:握手超时   io.netty.handler.ssl.SslHandler.handshake(...)(未知来源)   〜[netty-handler-4.1.31.Final.jar:4.1.31。

  • 如果仅在API网关上启用HTTPS,我们将收到以下错误消息

      

    发生意外错误(类型=未找到,状态= 404)。   org.springframework.web.server.ResponseStatusException:404 NOT_FOUND   并收到

    对于路径https://localhost:8443/api/hello-service/hello/message

      

    无法连接

    对于路径http://localhost:8080/hello-service/hello/message

请找到sample applications

的链接

说明:

  • 导航到领事目录并使用命令./consul agent -dev启动领事服务器
  • 运行api-gateway春季启动gradle项目
  • 运行rest-demo spring boot gradle项目

编辑2

谢谢@spencergibb,我们能够在网关上成功应用ssl并通过HTTP调用注册的服务。从Spring Webflux with Netty does not support listening on two ports开始,我们基于this answer创建了一个附加到http端口的附加tcp服务器。

对于RewritePath规则,/api/仍然面临着一些问题

  predicates:
    - name: Path
      args:
        pattern: "'/api/'+serviceId.toLowerCase()+'/**'"
  filters:
    - name: RewritePath
      args:
        regexp: "'/api/' + serviceId.toLowerCase() + '/(?<remaining>.*)'"
        replacement: "'/${remaining}'"

下面是请求的完整跟踪

  

DEBUG 13-02-2019 03:32:01 [FilteringWebHandler.java:86] VTC:已排序   gatewayFilterFactories:   [OrderedGatewayFilter{delegate=GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.AdaptCachedBodyGlobalFilter@257505fd},   order = -2147482648},   OrderedGatewayFilter{delegate=GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.GatewayMetricsFilter@400caab4},   order = -2147473648},   OrderedGatewayFilter{delegate=GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.NettyWriteResponseFilter@36e2c50b}},   order = -1},   OrderedGatewayFilter {delegate = GatewayFilterAdapter {delegate=org.springframework.cloud.gateway.filter.ForwardPathFilter@66f0c66d},order = 0},   OrderedGatewayFilter{delegate=org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactory$$Lambda$360/1720581802@5821f2e6,   order = 0},   OrderedGatewayFilter{delegate=GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter@27119239},   order = 10000},   OrderedGatewayFilter{delegate=GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.LoadBalancerClientFilter@568a9d8f},   order = 10100},   OrderedGatewayFilter{delegate=GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.WebsocketRoutingFilter@6ba77da3},   order = 2147483646},   OrderedGatewayFilter{delegate=GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.NettyRoutingFilter@73c24516},   order = 2147483647},   OrderedGatewayFilter{delegate=GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.ForwardRoutingFilter@461a9938},   order = 2147483647}] TRACE 13-02-2019 03:32:01   [RouteToRequestUrlFilter.java:59] VTC:RouteToRequestUrlFilter开始   跟踪13-02-2019 03:32:02 [NettyWriteResponseFilter.java:68] VTC:   NettyWriteResponseFilter start跟踪13-02-2019 03:32:02   [GatewayMetricsFilter.java:101] VTC:正在停止计时器   带有标签的“ gateway.requests”   [tag(结果= CLIENT_ERROR),标签(routeId = rewrite_response_upper),标签(routeUri = http://httpbin.org:80),tag(status=NOT_FOUN

1 个答案:

答案 0 :(得分:2)

需要一些东西

  1. 禁用http2
  2. 禁用httpclient的ssl配置
  3. 更新locator谓词和过滤器以使用详细配置。

这是application.yml的结果部分

server:
  port: 8443
  http:
    port: 8080
  servlet:
  # enable HTTP2
#  http2:
#    enabled: true
  # enable compression

# ... removed for brevity

spring:
  application:
    name: api-gateway
  cloud:
    consul:
      enabled: true
    gateway:
#      httpclient:
#        ssl:
#          handshake-timeout-millis: 10000
#          close-notify-flush-timeout-millis: 3000
#          close-notify-read-timeout-millis: 0
#      routes:
      # - id: ui_path_route
      #   predicates:
      #   - Path="'/**'"
      #   filters:
      #   - RewritePath="'/**'", "/ui"
      discovery:
        instanceId: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}
        locator:
          enabled: true
          predicates:
          - name: Path
            args:
              pattern: "'/api/' + serviceId + '/**'"
          filters:
          - name: RewritePath
            args:
              regexp: "'/api/' + serviceId + '/(?<remaining>.*)'"
              replacement: "'/${remaining}'"
#... removed for brevity