SpringCloud-microservice-Gateway gateway configuration
Spring Cloud Gateway official documentation: https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-starter
1. The role of Gateway
The gateway mainly has the following functions:
- Identity authentication and permission verification
- Service routing and load balancing
- request throttling
User access service process:
Initiate a request to the gateway —> the gateway finds the matching service for the request path —> the gateway checks or filters the request —> the gateway routes the request to the specified service —> the service returns a response to the gateway —> the gateway returns the service response to the client end
The same kind of gateway service in SpringCloud also has zuul, but zuul is implemented based on Servlet and belongs to blocking programming.
Gateway is based on WebFlux provided in Spring5, which belongs to responsive programming and has better performance.
2. Gateway quick start
1. Dependency and startup class
The Gateway service also uses the service registry at the end to achieve load balancing. Here, Ali's Nacos is selected.
<!-- Gateway 依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- Nacos 服务发现依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
Just need the above two dependencies, spring-cloud-starter-gateway contains spring-web related dependencies, you can start the service directly
The startup class does not require special configuration, examples are as follows:
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
2. yaml basic configuration
An example application.yml configuration file is as follows:
server:
port: 8088 # 服务端口
spring:
application:
name: gateway # 服务名称
cloud:
nacos:
server-addr: localhost:8848 # nacos 注册中心地址
gateway:
routes: # 服务路由列表
# - 表示列表,同级的 - 添加在同一列表内,id, uri, predicates 组成一个路由,是列表内的一个元素
- id: user-service-route # 路由 id,不可重复
# uri 为目标地址,有两个表示方法
# uri: http://localhost:8082 # 指定固定 ip,无负载均衡
uri: lb://user-service # 指定注册中心的服务名称,通过负载均衡发送请求
predicates: # 断言规则
- Path=/user/** # 匹配以 /user 为开头的请求路径,将其路由到 user-service
Now you can start the gateway service, provided you start Nacos first
After starting the gateway, the client can access the gateway, such as localhost:8088/user/1, the gateway will match the user-service route, and route the request to the user-service service obtained from the Nacos registration center
3. Routing assertion factory
Predicates are assertions, used to determine whether the current request matches the routing rules of the service
When there are multiple assertion rules, all of them must conform to the rules before the request will be routed and forwarded
In the above example, -Path is used, which means to judge the request path
Other commonly used assertion factories are as follows:
Screenshot from Dark Horse Programmer ppt↑
Gateway assertion factory official documentation: https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories
4. Load balancing strategy
The service route uri starts with lb to enable load balancing, and the load balancing strategy can be configured through Ribbon
service-name.ribbon.NFLoadBalancerRuleClassName Configure load balancing policy, where service-name is the service name in uri
The default policy is polling access
spring:
cloud:
gateway:
routes:
- id: user-service-route
uri: lb://user-service # lb 表示负载均衡,后跟服务名称
predicates:
- Path=/user/**
# 通过 Ribbon 配置某一服务的负载均衡策略
user-service: # 服务名称
ribbon:
# NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 随机访问策略
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # Nacos优先选择策略
5. Filter
1. Route filter
A route filter is a filter configured in a route and will only take effect for the current route
Just add the filters attribute in the routing configuration
Examples are as follows:
spring:
cloud:
gateway:
routes:
- id: user-service-route
uri: lb://user-service
predicates:
- Path=/user/**
filters: # 添加路由过滤器
- AddRequestHeader=from, gateway # 添加请求头 from=gateway
As used in the above example - AddRequestHeader is used to add request headers to the request
Similar common ones are:
- AddRequestHeader: Add request header
- RemoveRequestHeader: Remove the request header
- AddRequestParameter: Add query parameters
- RemoveRequestParameter: remove query parameters
- AddResponseHeader: Add response header
- RemoveRequestParameter: remove the response header
See more official documents of GatewayFilter Factories: https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories
2. defaultFilter filter
The default filter takes effect for all routes
Deploy spring.cloud.gateway.default-filters
Examples are as follows:
spring:
cloud:
gateway:
default-filters:
- AddRequestParameter=message, Hello # 添加请求参数 message=Hello
3. Global filter
Create a new class to implement the filter method in the GlobalFilter interface
And annotate @Component on the class to add the class to the Spring container
The exchange parameter in the filter method represents the context, where request, response, session and other information can be obtained
The chain parameter indicates the filter chain, which can be released
The following example implements a simple permission check, and checks whether the request header carries an attribute representing permission:
@Component
public class AuthorizeFilter implements GlobalFilter {
private static String adminAuth = "adminAuth";
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 获取请求头中的 Authorization 属性值
HttpHeaders headers = exchange.getRequest().getHeaders();
String authorization = headers.getFirst("Authorization");
if (!adminAuth.equals(authorization)) {
// 设置 401 响应状态码
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
// 完成响应,不再往后进行
return exchange.getResponse().setComplete();
}
// 放行
return chain.filter(exchange);
}
}
Annotating the @Order annotation on the global filter can set the priority of the filter, which is used to arrange the order of multiple filters
You can also implement the getOrder() method in the Ordered interface to achieve the same effect
//@Order(1) // 注解设置 order 为 1
@Component
public class MyFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return chain.filter(exchange);
}
@Override
public int getOrder() {
// 实现方法设置 order 为 1
return 1;
}
}
4. Filter execution order
Each filter has an int type order value
The execution order of the filter is sorted according to the order value, the smaller the order value, the higher the priority, and the earlier the execution
The order of the global filter is specified by itself, and the order of the routing filter and defaultFilter is incremented from 1 according to the declaration order
The order value of routing filter and defaultFilter is independent
When the order values of the three filters are the same, they have priority: route filter > defaultFilter > global filter
6. Cross-domain configuration
An example of yaml configuration is as follows:
spring:
cloud:
gateway:
globalcors: # 全局跨域处理
add-to-simple-url-handler-mapping: true # 解决 options 请求被拦截问题
cors-configurations:
'[/**]':
allowedOrigins: # 允许哪些网站的跨域请求
- "http://localhost:8080"
allowedMethods: # 允许的跨域请求方法
- "GET"
- "POST"
- "DELETE"
- "PUT"
- "OPTIONS"
allowedHeaders: "*" # 允许跨域请求中携带的请求头:全部
allowCredentials: true # 是否允许携带 cookie
maxAge: 360000 # 跨域检测的有效期