Введение в Spring Cloud Gateway
Некоторое время назад была выпущена официальная версия Spring Boot 2. Spring Cloud Gateway основан на Spring Boot 2 и является новым проектом Spring Cloud. Этот проект предоставляет шлюз API, построенный поверх экосистемы Spring, в том числе: Spring 5 , Spring Boot 2 и Project Reactor. Spring Cloud Gateway стремится предоставить простой и эффективный способ отправки API и предоставить им сквозные проблемы, такие как: безопасность, мониторинг/метрики и отказоустойчивость. Текущая последняя версияv2.0.0.M8
, скоро будет официальная версия.
Особенности Spring Cloud Gateway:
- Java 8
- Spring Framework 5
- Spring Boot 2
- динамическая маршрутизация
- Сопоставление маршрутов, встроенное в сопоставления Spring Handler
- Сопоставление маршрутов на основе HTTP-запросов (путь, метод, заголовок, хост и т. д.)
- Фильтры применяются к совпадающим маршрутам
- Фильтры могут изменять нисходящие HTTP-запросы и HTTP-ответы (добавлять/удалять заголовки, добавлять/удалять параметры, переписывать путь, устанавливать путь, Hystrix и т. д.)
- Управляется API или конфигурацией
- Поддержка маршрутизации конфигурации Spring Cloud DiscoveryClient, используемой в сочетании с обнаружением и регистрацией службы.
vs Netflix Zuul
Zuul основан на сервлете 2.5 (с использованием 3.x) и использует блокирующий API. Он не поддерживает никаких постоянных соединений, таких как веб-сокеты. Принимая во внимание, что Gateway построен на Spring Framework 5, Project Reactor и Spring Boot 2 и использует неблокирующий API. Поддерживаются веб-сокеты, и, поскольку они тесно интегрированы со Spring, это упростит разработку.
Начало работы с Spring Cloud Gateway
Недавно автор изучал исходный код Spring Cloud Gateway, и писал статьи по анализу исходного кода для реализации большинства функций, но ведь официальная версия не выпущена, данная статья является вводной практикой, показывающей несколько часто используемых функций , с нетерпением жду выхода последней официальной версии .
В примере запускаются две службы: Gateway-Server и user-Server. Смоделированный сценарий заключается в том, что клиент запрашивает внутреннюю службу, а шлюз предоставляет унифицированную запись для внутренней службы. Все серверные службы зарегистрированы в сервисе обнаружения Consul (можно собрать и zk, и Eureka, я больше привык использовать consul). Шлюз перенаправляет на определенные серверные службы посредством балансировки нагрузки.
Сервис пользователя
Пользовательский сервис регистрируется в Consul и предоставляет интерфейс/test
.
полагаться
Требуемые зависимости следующие:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
конфигурационный файл
spring:
application:
name: user-service
cloud:
consul:
host: 192.168.1.204
port: 8500
discovery:
ip-address: ${HOST_ADDRESS:localhost}
port: ${SERVER_PORT:${server.port}}
healthCheckPath: /health
healthCheckInterval: 15s
instance-id: user-${server.port}
service-name: user
server:
port: 8005
management:
security:
enabled: false
открытый интерфейс
@SpringBootApplication
@RestController
@EnableDiscoveryClient
public class GatewayUserApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayUserApplication.class, args);
}
@GetMapping("/test")
public String test() {
return "ok";
}
}
незащищенный/test
интерфейс, возврат ок.
Служба шлюза
Служба шлюза предоставляет такие функции, как различные конфигурации маршрутов, фабрики утверждений маршрутов и фабрики фильтров.
полагаться
Зависимости, которые необходимо импортировать:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
</dependency>
//依赖于webflux,必须引入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gateway-core</artifactId>
</dependency>
//服务发现组件,排除web依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
<version>2.0.0.M6</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</exclusion>
</exclusions>
</dependency>
//kotlin依赖
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>${kotlin.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
<version>${kotlin.version}</version>
<optional>true</optional>
</dependency>
Зависимости, связанные с kotlin, представлены, как указано выше, и здесь необходимо поддерживать конфигурацию маршрутизации kotlin. Использование Spring Cloud Gateway должно исключать конфигурацию, связанную с Интернетом, и вводится ссылка на webflux, которая будет проверяться при запуске приложения и должна быть введена.
Фабрика утверждений маршрута
Существуют различные типы фабрик утверждения маршрута, в зависимости от времени запроса, хоста, пути, метода и т. д. Ниже определено соответствие утверждения маршрута на основе пути.
@Bean
public RouterFunction<ServerResponse> testFunRouterFunction() {
RouterFunction<ServerResponse> route = RouterFunctions.route(
RequestPredicates.path("/testfun"),
request -> ServerResponse.ok().body(BodyInserters.fromObject("hello")));
return route;
}
Когда запрошенный путь/testfun
, код состояния ok возвращается напрямую, а тело ответаhello
нить.
завод фильтров
Шлюзам часто необходимо фильтровать запросы маршрутизации и выполнять некоторые операции, такие как построение заголовков после аутентификации.Существует много типов фильтрации, таких как добавление заголовков запроса, добавление параметров запроса, добавление заголовков ответа, автоматических выключателей и других функций.
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder, ThrottleGatewayFilterFactory throttle) {
//@formatter:off
return builder.routes()
.route(r -> r.path("/image/webp")
.filters(f ->
f.addResponseHeader("X-AnotherHeader", "baz"))
.uri("http://httpbin.org:80")
)
.build();
//@formatter:on
}
Как и выше, когда путь запроса/image/webp
, перенаправить запрос наhttp://httpbin.org:80
и отфильтровать ответ, добавив заголовок ответаX-AnotherHeader: baz
.
пользовательская маршрутизация
Вышеупомянутые два подраздела относятся к пользовательской маршрутизации API, которую также можно определить с помощью конфигурации:
spring:
cloud:
gateway:
locator:
enabled: true
default-filters:
- AddResponseHeader=X-Response-Default-Foo, Default-Bar
routes:
# =====================================
- id: default_path_to_http
uri: blueskykong.com
order: 10000
predicates:
- Path=/**
Приведенная выше конфигурация определяет маршруты и фильтры. Глобальный фильтр добавляет заголовки ко всем ответамX-Response-Default-Foo: Default-Bar
. Идентификатор определяется какdefault_path_to_http
Маршрут, но приоритет относительно низкий, когда запрос не может быть сопоставлен, он будет перенаправлен наblueskykong.com
.
kotlin пользовательская маршрутизация
Spring Cloud Gateway может использовать kotlin для настройки маршрутизации:
@Configuration
class AdditionalRoutes {
@Bean
fun additionalRouteLocator(builder: RouteLocatorBuilder): RouteLocator = builder.routes {
route(id = "test-kotlin") {
path("/image/png")
filters {
addResponseHeader("X-TestHeader", "foobar")
}
uri("http://httpbin.org:80")
}
}
}
Когда запрошенный путь/image/png
, будут отправленыhttp://httpbin.org:80
, и установите фильтр, добавив в его заголовок ответаX-TestHeader: foobar
голова.
компонент обнаружения службы
В сочетании с регистрацией службы в компоненте обнаружения он перенаправляется на конкретный экземпляр службы через serviceId. Соответствующие зависимости были введены в предыдущей конфигурации.
@Bean
public RouteDefinitionLocator discoveryClientRouteDefinitionLocator(DiscoveryClient discoveryClient) {
return new DiscoveryClientRouteDefinitionLocator(discoveryClient);
}
будетDiscoveryClient
вводить вDiscoveryClientRouteDefinitionLocator
В конструкторе о локаторе определения маршрута анализ исходного кода будет объяснен позже, и здесь он не будет расширен.
spring:
cloud:
gateway:
locator:
enabled: true
default-filters:
- AddResponseHeader=X-Response-Default-Foo, Default-Bar
routes:
# =====================================
- id: service_to_user
uri: lb://user
order: 8000
predicates:
- Path=/user/**
filters:
- StripPrefix=1
Указанная выше конфигурация включенаDiscoveryClient
Реализация локатора. Маршруты определены, все пути запросов начинаются с/user
Запрос в начале будет переадресован наuser
service и примените фильтр к пути, усекая первый префикс пути. то есть доступ/user/test
Фактический запрос преобразуется вlb://user/test
.
websocket
Вы также можете настроить маршрутизацию шлюза для веб-сокетов:
spring:
cloud:
gateway:
default-filters:
- AddResponseHeader=X-Response-Default-Foo, Default-Bar
routes:
- id: websocket_test
uri: ws://localhost:9000
order: 9000
predicates:
- Path=/echo
Запустить ws-серверwscat --listen 9000
, запустите шлюз (порт шлюза 9090) и подключитесь к клиентуwscat --connect ws://localhost:9090/echo
.
Клиентский доступ
Для функций, реализованных выше, читатели могут загрузить исходный код, чтобы попробовать его. Здесь автор показывает только результаты обращения к пользовательским сервисам:
Шлюз успешно сбалансировал нагрузку на пользовательский сервер и вернулся в порядке. Заголовок ответа содержит заголовок глобальных настроек фильтраX-Response-Default-Foo: Default-Bar
Суммировать
В этой статье мы рассмотрели некоторые функции и компоненты, принадлежащие Spring Cloud Gateway. Этот новый API предоставляет готовые инструменты для поддержки шлюзов и прокси. С нетерпением ждем официальной версии Spring Cloud Gateway 2.0.
Адрес источника
GitHub.com/Доступный ETS2012/S…