1. The role of Gateway
1. Permission control: As the entrance to microservices, the gateway needs to verify whether the user is qualified to request, and if not, intercept it.
2. Routing and load balancing: All requests must first go through the gateway, but the gateway does not process business, but forwards the request to a certain microservice according to certain rules. This process is called routing. Of course, when there are multiple target services for routing, load balancing is also required.
3. Current limiting: When the request traffic is too high, the gateway will release the request at the speed that the downstream microservices can accept to avoid excessive service pressure.
2. Usage steps
1. Dependencies and configuration
<!--网关-->
<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>
server:
port: 10010 # 网关端口
spring:
application:
name: gateway # 服务名称
cloud:
nacos:
server-addr: localhost:8848 # nacos地址
gateway:
routes: # 网关路由配置
- id: user-service # 路由id,自定义,只要唯一即可
# uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
- Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求
We will proxy all requests that comply with the Path rules to the address specified by the uri parameter.
In the above example, we proxy requests starting with /user/** to lb://userservice, where lb is the load balancer (LoadBalance), and pulls the service list based on the service name to achieve load balancing.
Restart the gateway. When accessing http://localhost:10010/user/1, the /user/** rule is met and the request is forwarded to uri: http://userservice/user/1
If there are multiple predicates, the rules must be satisfied at the same time. There are examples below.
1. Route id: the unique identifier of the route
2. Route target (uri): the target address of the route, http represents a fixed address, lb represents load balancing based on the service name
3. Route assertions (predicates): rules for judging routes
4. Route filtering Filters: Process requests or responses
2. Routing assertion
The assertion rules we write in the configuration file are just strings. These strings will be read and processed by the Predicate Factory and turned into conditions for routing judgment.
For example, Path=/user/** is matched according to the path. This rule is composed of
org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory class to handle, there are more than a dozen assertion factories like this in Spring Cloud Gateway
name | illustrate | Example |
After | It is a request after a certain point in time |
- After=2037-01-20T17:42:47.789-07:00[America/Denver] |
Before | It is a request before a certain point in time | - Before=2031-04-13T15:14:47.433+08:00[Asia/Shanghai] |
Between | It is a request before a certain two points in time. | - Between=2037-01-20T17:42:47.789-07:00[America/Denver], 2037-01-21T17:42:47.789-07:00[America/Denver] |
Cookie | The request must contain certain cookies | - Cookie=chocolate, ch.p |
Header | The request must contain certain headers | - Header=X-Request-Id, d+ |
Host | The request must be to access a certain host (domain name) | - Host=**.somehost.org, **.anotherhost.org |
Method | The request method must be the specified method | - Method=GET,POST |
Path | The request path must comply with the specified rules | - Path=/red/{segment},/blue/** |
Query | The request parameters must contain the specified parameters | - Query=name, Jack or - Query=name |
RemoteAddr | The requester's IP must be in the specified range | - RemoteAddr=192.168.1.1/24 |
Weight | Weight processing |
Generally, we only need to master Path and add examples from official documents to cope with various work scenarios.
predicates:
- Path=/order/**
- After=2031-04-13T15:14:47.433+08:00[Asia/Shanghai]
For details, see -> Gateway Service Gateway Assertion Factory_928-y’s Blog-CSDN Blog
3. Filter factory
GatewayFilter is a filter provided in the gateway, which can process requests entering the gateway and responses returned by microservices.
name | illustrate |
AddRequestHeader | Add a request header to the current request |
RemoveRequestHeader | Remove a request header from the request |
AddResponseHeader | Add a response header to the response structure |
RemoveResponseHeader | Removes a response header from the response result |
RequestRateLimiter | Limit requested traffic |
Let's take AddRequestHeader as an example:
Requirement: Add a request header to all requests entering userservice: sign=xn2001.com is eternal
You only need to modify the application.yml file of the gateway service and add route filtering.
spring:
cloud:
gateway:
routes: # 网关路由配置
- id: user-service # 路由id,自定义,只要唯一即可
# uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
- Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求
filters:
- AddRequestHeader=sign, xn2001.com is eternal # 添加请求头
How to verify, we modify an interface in userservice
@GetMapping("/{id}")
public User queryById(@PathVariable("id") Long id, @RequestHeader(value = "sign", required = false) String sign) {
log.warn(sign);
return userService.queryById(id);
}
Restart both services and visit: http://localhost:10010/user/1
You can see that the console prints out this request header.
The gateway provides 31 types of filter factories introduced above, but the function of each filter is fixed. If we want to intercept requests, we can't do it by doing our own business logic.
4. Global filter
The function of the global filter is also to process all requests and microservice responses entering the gateway, which is the same as the function of GatewayFilter. The difference is that the logic of GlobalFilter can be written to customize the rules; while the logic of GatewayFilter is defined through configuration, and the processing logic is fixed.
Requirements: Define global filters, intercept requests, and determine whether the request parameters meet the following conditions
Whether there is authorization in the parameter and
whether the parameter value is admin.
If both are satisfied, the authorization will be allowed, otherwise it will be intercepted.
@Component
public class AuthorizeFilter implements GlobalFilter, Ordered {
// 测试:http://localhost:9007//hello/feifn?authorization=admin
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 获取第一个 authorization 参数
String authorization = exchange.getRequest().getQueryParams().getFirst("authorization");
if ("admin".equals(authorization)){
// 放行
return chain.filter(exchange);
}
// 设置拦截状态码信息
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
// 设置拦截
return exchange.getResponse().setComplete();
}
// 设置过滤器优先级,值越低优先级越高
// 也可以使用 @Order 注解
@Override
public int getOrder() {
return 0;
}
}
5. Filter order
Requests entering the gateway will encounter three types of filters: DefaultFilter, current route filter, and GlobalFilter;
After routing is requested, the three are merged into a filter chain (set), and each filter is executed in sequence after sorting.
Sorting rules
1. Each filter must specify an order value of type int. The smaller the order value, the higher the priority and the higher the execution order.
2. GlobalFilter implements the Ordered interface or uses the @Order annotation to specify the order value, which we specify ourselves.
3. The order of routing filters and defaultFilter is specified by Spring. The default is to increase from 1 in the order of declaration.
4. When the order values of the filters are the same, they will be executed in the order of defaultFilter > routing filter > GlobalFilter.
For a detailed explanation, see Filter_928-y’s blog-CSDN blog
6. Cross-domain issues
Students who don’t understand cross-domain issues can learn more about it on Baidu; it is more convenient to solve cross-domain issues in Gateway.
spring:
cloud:
gateway:
globalcors: # 全局的跨域处理
add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
corsConfigurations:
'[/**]':
allowedOrigins: # 允许哪些网站的跨域请求 allowedOrigins: “*” 允许所有网站
- "http://localhost:8090"
allowedMethods: # 允许的跨域ajax的请求方式
- "GET"
- "POST"
- "DELETE"
- "PUT"
- "OPTIONS"
allowedHeaders: "*" # 允许在请求中携带的头信息
allowCredentials: true # 是否允许携带cookie
maxAge: 360000 # 这次跨域检测的有效期