Spring Cloud Gateway
brief introduction
Spring Cloud Gateway is a gateway service developed on the spring official website based on Spring 5.0, Spring Boot 2.0, Project Reactor and other technologies.
Main functions of gateway:
- Spring Cloud Gateway provides the basic functions of the gateway based on the Filter chain: security, monitoring / embedding point, current limiting, etc. ***
- Spring Cloud Gateway provides a simple, effective and unified API routing management method for microservice architecture.
3.Spring Cloud Gateway is a solution to replace Netflix Zuul.
4. The core of the Spring Cloud Gateway component is a series of filters, Through these filters, the requests sent by the client can be forwarded (routed) to the corresponding microservices. Spring Cloud Gateway is a firewall and agent added at the forefront of the whole microservice, hiding the IP port information of the microservice node, so as to strengthen security protection. Spring Cloud Gateway itself is also a microservice and needs to be registered with Eureka service registry.
**
**The core functions of the gateway are: * * filtering and routing (forwarding client requests to various microservices)
Schema after adding GetWay
Whether it is a request from the client (PC or mobile terminal) or an internal call of the service, all requests for the service can pass through the Gateway, and then the Gateway can realize authentication, dynamic routing and other operations. The Gateway is the unified entrance of our service
Introduction to core concepts
- The composition of route information: it consists of an ID, a destination URL, a group of assertion factories and a group of filters. If the route assertion is true, it indicates that the request URL matches the configured route.
- The input type of the assertion function in Spring Cloud Gateway is ServerWebExchange in Spring 5.0 framework. The assertion function of Spring Cloud Gateway allows developers to define and match any information from Http Request, such as request header and parameters.
- Filter is a standard Spring WebFilter. There are two types of filters in Spring Cloud Gateway: Gateway Filter and Global Filter. The filter will modify requests and responses.
quick get start
Step analysis
1. New construction
2. Write startup class
3. Write configuration
4. Write routing rules
5. Start test
1. Import jar package for new project
<dependencies> <!--gateway relevant--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <!--eureka relevant--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies>
2. Write startup class
package com.pjh; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class GateWayApplication { public static void main(String[] args) { SpringApplication.run(GateWayApplication.class); } }
3. Write configuration
server: port: 10010 #port spring: application: name: gateway-service #Service name registered to eureka eureka: client: service-url: defaultZone: http://Localhost: address and port of 10086 / Eureka #eureka registry instance: prefer-ip-address: true
4. Write routing rules
server: port: 10010 spring: application: name: api-gateway cloud: gateway: routes: # Routing id, which can be any - id: user-service-route # Service address of agent uri: http://127.0.0.1:8088 # Route assertion: can match mapping path predicates: - Path=/user/** eureka: client: service-url: defaultZone: http://127.0.0.1:10086/eureka instance: prefer-ip-address: true
5. Start test
The user service method was successfully called to query the database
Service oriented routing
What is service oriented routing
In the routing rule just now, the service address of the path is written to death. If a service has multiple instances, you should go to Eureka registry to find the list of all instances corresponding to the service according to the service name, and then conduct dynamic routing
Modify the configuration file, and obtain it through the configuration name
server: port: 10010 spring: application: name: api-gateway cloud: gateway: routes: # Routing id, which can be any - id: user-service-route #lb means to obtain specific services from eureka uri: lb://producer-service #http://127.0.0.1:8088 #Route assertion, you can configure the mapping path predicates: #Add request path prefix - Path=/user/** eureka: client: service-url: defaultZone: http://127.0.0.1:10086/eureka instance: prefer-ip-address: true
test
explain
When the protocol used in the routing configuration is lb (take uri: LB: / / producer service as an example), gateway will use LoadBalance and user service to resolve to the actual host and port through eureka for ribbon load balancing
Routing prefix
Function and purpose of routing prefix:
**
Objectives:
You can add or remove a prefix to the address requested to the gateway service
**
analysis:
Address of service provider: http://127.0.0.1:9091/user/8
- Add prefix: add a prefix path to the request address and then use it as the service address of the agent;
http://127.0.0.1:10010/8 --> http://127.0.0.1:9091/user/8 Add prefix path / user
- Remove prefix: remove some prefix paths from the path in the request address, and then serve as the service address of the agent;
http://127.0.0.1:10010/api/user/8 --> http://127.0.0.1:9091/user/8 Remove prefix path / api
effect:
If the request address of the client is inconsistent with the service address of the microservice, you can add and remove the path prefix by configuring the path filter.
add prefix
Concept:
Add a prefix path to the request address and then serve as the service address of the agent;
example
For example, in the browser, you enter http://127.0.0.1:10010/8
If you set the auto prefix content to / user
The gateway will automatically add * * / user when calling the micro service**
That is, the address becomes: http://127.0.0.1:9091/user/8
Profile configuration
server: port: 10010 spring: application: name: api-gateway cloud: gateway: routes: # Routing id, which can be any - id: user-service-route #lb means to obtain specific services from eureka uri: lb://producer-service #http://127.0.0.1:8088 #Route assertion, you can configure the mapping path predicates: #Add the request path prefix. The prefix added automatically cannot be included here. Otherwise, the assertion fails - Path=/** filters: - PrefixPath=/user eureka: client: service-url: defaultZone: http://127.0.0.1:10086/eureka instance: prefer-ip-address: true
Remove prefix
concept
Remove some prefix paths from the path in the request address, and then use it as the service address of the agent
Example:
For example, the address you visit in the browser is: http://127.0.0.1:10010/api/user/8
Set the address of the gateway calling the microservice after removing a prefix as http://127.0.0.1:9091/user/8
**
Take the example above as an example
**
The number of prefixes to be removed from the route is specified by StripPrefix=1. For example, the path / api/user/1 will be proxied to / user/1, that is:
StripPrefix=1 http://localhost:10010/api/user/8 -->http://localhost:9091/user/8 StripPrefix=2 http://localhost:10010/api/user/8 -->http://localhost:9091/8
Profile configuration
server: port: 10010 spring: application: name: api-gateway cloud: gateway: routes: # Routing id, which can be any - id: user-service-route #lb means to obtain specific services from eureka uri: lb://producer-service #http://127.0.0.1:8088 #Route assertion, you can configure the mapping path predicates: #Remove prefix - Path=/api/user / * * the request path here should be set to the path before removing the prefix - Path=/** filters: #Here, 1 means filtering one prefix, and 2 means filtering two prefixes - StripPrefix=1 eureka: client: service-url: defaultZone: http://127.0.0.1:10086/eureka instance: prefer-ip-address: true
filter
brief introduction
One of the important functions of Gateway is to realize the authentication of request. This action is often implemented through the filter provided by the Gateway. The functions in the previous routing prefix chapter are also implemented using filters. The Gateway has dozens of built-in filters, and the common built-in filters are:
Configure global default filters
These built-in filters can be similar to the usage in the section using route prefix, or they can be configured not only for a route; Instead, it can take effect for all routes, that is, configure the default filter:
Understand the following:
server: port: 10010 spring: application: name: api-gateway cloud: gateway: routes: # Routing id, which can be any - id: user-service-route #lb means to obtain specific services from eureka uri: lb://producer-service #http://127.0.0.1:8088 #Route assertion, you can configure the mapping path predicates: #Add the request path prefix. The prefix added automatically cannot be included here. Otherwise, the assertion fails #Remove prefix - Path=/api/user / * * the request path here should be set to the path before removing the prefix - Path=/** filters: - PrefixPath=/user #Here, 1 means filtering one prefix, and 2 means filtering two prefixes #- StripPrefix=1 default-filters: # The response header filter sets the header attribute name of the output response as X-Response-Default-MyName and the value as test; #If there are multiple parameters, override one line to set different parameters - AddResponseHeader=X-Response-Default-MyName, test eureka: client: service-url: defaultZone: http://127.0.0.1:10086/eureka instance: prefer-ip-address: true
After configuration, use the developer tool to find an additional key value pair in the response header:
Filter type:
In terms of Gateway implementation, there are two kinds of filters;
1. Local filter:
Through spring cloud. gateway. routes. Filters are configured for specific routes and only work for the current route
On; The built-in filter can be configured or customized according to the built-in filter. If you configure spring cloud. gateway. Default filters are global filters that take effect for all routes; But these filters
The GatewayFilterFactory interface should be implemented in the implementation of.
2. Global filter:
It does not need to be configured in the configuration file and acts on all routes; Just implement the GlobalFilter interface
Execution lifecycle
Basic introduction
The Filter life cycle of Spring Cloud Gateway is similar to that of Spring MVC. There are two interceptors: "pre" and "post". "Pre" and "post" are called separately before and after the request is executed.
The pre and post here can be implemented before and after the filter method is executed by the gateway filterchain of the filter.
Usage scenario
Common application scenarios are as follows:
**Authentication request: * * generally, before the GatewayFilterChain executes the filter method, if it is found that there is no access permission, it will directly return null.
**Exception handling: * * generally, after the GatewayFilterChain executes the filter method, the exception is recorded and returned.
Statistics of service call duration: the gateway filterchain performs statistics according to the time before and after the filter method is executed.
Custom filter
Custom local filter
Objectives:
Write and configure a custom local filter according to the default filter, which can obtain the requested parameter value through the parameter name in the configuration file
**
analysis:
Requirements: in the filter (MyParamGatewayFilterFactory) http://localhost:10010/api/user/8?name=itcast The value of the parameter name in is obtained and output to the console; And the parameter name is variable, that is, it may not always be name; You can configure the parameter name when configuring the filter.
Implementation steps:
- Configure filters;
- Write filter;
- test
1. Configure filter;
server: port: 10010 spring: application: name: api-gateway cloud: gateway: routes: # Routing id, which can be any - id: user-service-route #lb means to obtain specific services from eureka uri: lb://producer-service #http://127.0.0.1:8088 #Route assertion, you can configure the mapping path predicates: #Add the request path prefix. The prefix added automatically cannot be included here. Otherwise, the assertion fails #Remove prefix - Path=/api/user / * * the request path here should be set to the path before removing the prefix - Path=/** filters: - PrefixPath=/user #FilterTest here is the first half of the configured filter class name FilterTestGatewayFilterFactory - FilterTest=age #Here, 1 means filtering one prefix, and 2 means filtering two prefixes #- StripPrefix=1 default-filters: # The response header filter sets the header attribute name of the output response as X-Response-Default-MyName and the value as test; #If there are multiple parameters, override one line to set different parameters - AddResponseHeader=X-Response-Default-MyName, test eureka: client: service-url: defaultZone: http://127.0.0.1:10086/eureka instance: prefer-ip-address: true
2. Write filter;
package com.pjh.Filter; import org.springframework.cloud.gateway.filter.GatewayFilter; import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.stereotype.Component; import javax.print.DocFlavor; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @Component/*Add bean annotation*/ public class FilterTestGatewayFilterFactory extends AbstractGatewayFilterFactory<FilterTestGatewayFilterFactory.Config> { /*Construction method*/ public FilterTestGatewayFilterFactory(){ super(Config.class); } /*Specify the corresponding parameter name*/ static final String PARAM_NAME = "param"; @Override public GatewayFilter apply(Config config) { return (exchange, chain) -> { ServerHttpRequest request = exchange.getRequest(); if (request.getQueryParams().containsKey(config.param)){ request.getQueryParams().get(config.param) .forEach(value -> System.out.printf("----------Local filter-----%s = %s-----", config.param, value)); } return chain.filter(exchange); }; } @Override public List<String> shortcutFieldOrder() { return Arrays.asList(PARAM_NAME); } public static class Config{ /*Corresponds to the parameters specified when configuring the filter*/ private String param; public String getParam() { return param; } public void setParam(String param) { this.param = param; } } }
3. Test
Custom global filter
Objectives:
Define a global filter to check whether the request carries the token parameter
**
analysis:
Requirements:
Write a global filter and check whether the request address carries the token parameter in the filter. If the value of the token parameter exists, it will be released; If the parameter value of token is empty or does not exist, the returned status code is set to: unauthorized and will not be executed again.
Implementation steps:
- Write global filter;
- test
1. Write global filter;
package com.pjh.Filter; import org.apache.commons.lang.StringUtils; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; @Component public class MyGlobalFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { System.out.println("Executing global filter"); String token = exchange.getRequest().getQueryParams().getFirst("token"); //Judge whether it is empty if (StringUtils.isBlank(token)){ /*Set the status code to unauthorized*/ exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); return exchange.getResponse().setComplete(); } return chain.filter(exchange); } @Override public int getOrder() { /*When there are multiple filters, the smaller the value, the earlier the execution*/ return 1; } }
2. Test
When there is no token parameter
With token parameter
**
Load balancing and fusing
By default, Ribbon load balancing and Hystrix fuse mechanism have been integrated in the Gateway. However, all timeout policies are the default values. For example, the fuse timeout is only 1S, which is easy to trigger. Therefore, manual configuration is recommended
server: port: 10010 spring: application: name: api-gateway cloud: gateway: routes: # Routing id, which can be any - id: user-service-route #lb means to obtain specific services from eureka uri: lb://producer-service #http://127.0.0.1:8088 #Route assertion, you can configure the mapping path predicates: #Add the request path prefix. The prefix added automatically cannot be included here. Otherwise, the assertion fails #Remove prefix - Path=/api/user / * * the request path here should be set to the path before removing the prefix - Path=/** filters: - PrefixPath=/user #FilterTest here is the first half of the configured filter class name FilterTestGatewayFilterFactory #- FilterTest=age #Here, 1 means filtering one prefix, and 2 means filtering two prefixes #- StripPrefix=1 default-filters: # The response header filter sets the header attribute name of the output response as X-Response-Default-MyName and the value as test; #If there are multiple parameters, override one line to set different parameters - AddResponseHeader=X-Response-Default-MyName, test hystrix: command: default: execution: isolation: thread: timeoutInMilliseconds=2000 ribbon.: ConnectTimeout: 1000 # Connection timeout duration ReadTimeout: 2000 # Data communication timeout duration MaxAutoRetries: 0 # Number of retries for the current server MaxAutoRetriesNextServer: 0 # How many service retries OkToRetryOnAllOperations: false # Do you want to retry all request methods eureka: client: service-url: defaultZone: http://127.0.0.1:10086/eureka instance: prefer-ip-address: true
Gateway cross domain configuration
General gateway is the unified entrance of all microservices, and cross domain problems will inevitably occur when calling
What is cross domain
In js request access, if the access address is inconsistent with the domain name, ip or port number of the current server, it is called cross domain request. If it is not solved, the return result of the corresponding address cannot be obtained.
For example, from http://localhost:9090 js access in http://localhost:9000 Because the ports are different, the data is also a cross domain request.
If there is a cross domain problem when accessing the Spring Cloud Gateway server; You can configure the gateway server to determine which services can be requested across domains; The specific configuration is as follows:
spring: cloud: gateway: globalcors: corsConfigurations: '[/**]': #allowedOrigins: * # This way of writing or the following can be used, * means all allowedOrigins: - "http://docs.spring.io" allowedMethods: - GET
The above configuration indicates that it is allowed to http://docs.spring.io Get service data by get request. allowedOrigins specifies the server address allowed to access, such as: http://localhost:10000 It is also possible. " [/ * *] 'indicates the address of all requests to access the gateway server
Specific instructions on the official website: https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.1.1.RELEASE/multi/mul
ti__cors_configuration.html
Gateway high availability
Start multiple Gateway services and automatically register with Eureka to form a cluster. In case of internal service access, access the Gateway and automatic load balancing. No problem.
However, the Gateway is more external access, such as PC terminal, mobile terminal, etc. They can't load balance through Eureka, so what should I do?
At this time, other service gateways can be used to proxy the Gateway. For example: Nginx
Difference between Gateway and Feign
As the entrance of the whole traffic, the Gateway accepts all requests, such as PC, mobile terminal, etc., and sends different requests to different micro service processing modules. Its role is regarded as nginx. In most cases, it is used for permission definition and service terminal traffic control
Fegin exposes some service interfaces of the current microservices and is mainly used for service calls between microservices