Spring Cloud Gateway + Консул конфигурации - PullRequest
0 голосов
/ 10 февраля 2019

Мы используем 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

Есть несколько проблем с конфигурацией, с которыми мы сталкиваемся, они перечислены ниже:

  • Перезаписать URL с префиксом / api / на соответствующий сервисный идентификатор, зарегистрированный на консуле : мы попытались настроить предикат, чтобы путь с префиксом api переписывалсяпуть и удалить API , но все равно это не работает.Таким образом, есть еще один сервис / hello-service / , зарегистрированный на консул-сервере, но мы хотим сделать вызов API с помощью / api / hello-service /
  • Перенаправить несопоставленный запрос в путь по умолчанию : Мы хотим перенаправить все несопоставленные запросы в пользовательский интерфейс.
  • Перенаправление HTTP на HTTPS на весеннем облачном шлюзе : мы хотим, чтобы все запросы, поступающие на весенний шлюз, были https
  • Пересылка HTTPS-запроса на HTTP-сервис. Идентификатор зарегистрирован зарегистрирован у консула: Службы, зарегистрированные в консуле, работают по протоколу HTTP, за исключением шлюза API, мы хотим иметь возможность отправлять HTTPS-запрос на HTTP-сервер, то есть завершать HTTPS только на API-шлюзе.

Любойбудет полезна помощь в решении вышеуказанной проблемы

Edit 1: После некоторой помощи от @spencergibb мы настроили весенний облачный шлюз с https.Но есть некоторые дополнительные проблемы, с которыми мы столкнулись

  • Если HTTPS включен как для шлюза API, так и для службы, мы получили ниже ошибку

javax.net.ssl.SSLException: время ожидания рукопожатия на io.netty.handler.ssl.SslHandler.handshake (...) (неизвестный источник) ~ [netty-handler-4.1.31.Final.jar: 4.1.31.

  • Если HTTPS включен только на шлюзе API, мы получили сообщение об ошибке ниже

    Произошла непредвиденная ошибка (тип = Не найдено, статус = 404).org.springframework.web.server.ResponseStatusException: 404 NOT_FOUND и получено

    для пути https://localhost:8443/api/hello-service/hello/message

    Невозможно подключиться

    дляпуть http://localhost:8080/hello-service/hello/message

Пожалуйста, найдите ссылку для примеров приложений

Инструкции:

  • Перейдите в каталог консул и запустите сервер консул с помощью команды ./consul agent -dev
  • запустите проект грейд-загрузчика api-gateway
  • запустите проект грейд-загрузчика rest-demo

Редактировать 2

Спасибо @spencergibb, Мы смогли успешно применить ssl на шлюзе и вызвать зарегистрированные службы по HTTP.Поскольку Spring Webflux с Netty не поддерживает прослушивание на двух портах , мы создали дополнительную привязку tcp-сервера к порту http на основе этого ответа .

Еще есть некоторыеПроблема, с которой мы сталкиваемся RewritePath для /api/ Правило

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

ниже - это полный след запроса

ОТЛАДКА 13-02-2019 03:32:01[FilteringWebHandler.java:86] VTC: Сортированные gatewayFilterFactories: [OrderedGatewayFilter averagedelegate=GatewayFilterAdapter enjdelegate=org.springframework.cloud.gateway.filter.AdaptCachedBodyGlobalFilter@257505ilter {252_fateate} {4800} -fateate_fateate_fateate_fateate_fate_fatef_fate_fate_fate_fate_fateg {}.org.springframework.cloud.gateway.filter.GatewayMetricsFilter@400caab4}, порядок = -2147473648}, OrderedGatewayFilter{delegate=GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.NettyWriteResponseFilter@36e2c50b}, порядок = -1},OrderedGatewayFilter {делегат = GatewayFilterAdapter {делегат = org.springframework.cloud.gateway.filter.ForwardPathFilter @ 66f0c66d}, order = 0},OrderedGatewayFilter averagedelegate=org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactory$$Lambda$360/1720581802@5821f2e6, order = 0}, OrderedGatewayFilter {Delegate = Delegway = Delegate = DelegwayFref.Reter.feter.Ruter.ref.terf.terf.terf.terf.terf.terf.terf.Reader.FatterFate.Web@ 27119239}, order = 10000}, OrderedGatewayFilter averagedelegate=GatewayFilterAdapter‹delegate=org.springframework.cloud.gateway.filter.LoadBalancerClientFilter@568a9d8f}, заказ = 10100}, OrderedGatewayAdapfile делегата {делегата} OrderedGatewayAdg,=org.springframework.cloud.gateway.filter.ForwardRoutingFilter@461a9938}, заказ = 2147483647}] TRACE 13-02-2019 03:32:01 [RouteToRequestUrlFilter.java:59] VTC: RouteToRequestUrlFilterначало TRACE 13-02-2019 03:32:02 [NettyWriteResponseFilter.java:68] VTC: NettyWriteResponseFilter начало TRACE 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 голосов
/ 15 февраля 2019

Потребовался ряд вещей

  1. отключить http2
  2. Отключить ssl-конфигурацию httpclient
  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
...