The gateway (second generation) of spring cloud ecology will replace Zuul (first generation) in the future. Gateway is built based on Netty (network communication framework, which can realize high-performance server and client), Reactor and WebFlux (Web Framework Based on Reactive)
Benefits of spring cloud gateway
- Strong performance: zuul1 is the first generation gateway 1.6 times of X
Reference: https://www.imooc.com/article/285068 - Powerful: built in many practical tools, such as forwarding, monitoring, current limiting, etc
- Elegant design: easy to expand
Disadvantages of spring cloud gateway
- Relying on Netty and Webflux, rather than Servlet Programming Model, has a certain adaptation cost
- You cannot work under a Servlet container or build a war package
- Springboot1. Is not supported x
1, Write spring cloud gateway
1.1. Create project
1.2. In POM Adding dependencies to XML
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.5.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.itmuch</groupId> <artifactId>gateway</artifactId> <version>0.0.1-SNAPSHOT</version> <name>gateway</name> <description>Applet gateway</description> <properties> <java.version>1.8</java.version> <spring-cloud.version>Greenwich.SR1</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- use Zipkin After that, Sleuth No, because Zipkin Already included Sleuth --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zipkin</artifactId> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.5.0</version> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>0.9.0.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
1.3. In application Add attributes to YML
server: port: 8040 spring: application: name: gateway zipkin: base-url: http://localhost:9411/ sleuth: sampler: #The sampling rate is 0.1 (10%) by default. If it is set to 1.0, it means that all data will be reported to Zipkin probability: 1.0 cloud: nacos: discovery: server-addr: localhost:8848 gateway: discovery: locator: # Let the gateway find other microservices through the service discovery component enabled: true routes: # - id: user_route # uri: lb://user-center # predicates: # - Path=/users/** # - id: content_route # uri: lb://content-center # predicates: # - Path=/shares/**,/admin/** #Custom routing predicate factory - id: after_route uri: lb://content-center predicates: #The time format must be in accordance with the following format, refer to (Note: idea The code set must be changed to utf8)TimeBetweenRoutePredicateFactory#main - TimeBetween=9 a.m:00, 10 pm:00 filters: #For the custom filter factory class PreLogGatewayFilterFactory, arbitrarily pass two parameters a and B, a = config getName(),b=config.getValue() - PreLog=a,b management: endpoints: web: exposure: include: '*' endpoint: health: show-details: always logging: level: org.springframework.cloud.gateway: trace
1.4 test run
Access content center / shares/1
Original path http://localhost:8010
Now use the gateway gateway path http://localhost:8040 , the gateway forwards successfully and implements the reverse proxy
Forwarding rule: accessing ${gateway_url} / {microservice x} / * * will be forwarded to the / * * path of microservice X
II. Core concepts of spring cloud gateway
- Route: the basic element of spring cloud gateway, which can be simply understood as a forwarding rule. Contains: ID, target URL, predict collection and Filter collection
- Predicate: Java util. function. Predict: spring cloud gateway uses predict to realize the matching conditions of routes
- Filter: modify requests and responses
2.1 routing predicate factory
reference resources: https://www.imooc.com/article/290804
2.2. Custom routing predicate factory
Implementation requirements: set the time period of network access, beyond which it is inaccessible
2.2.1. In application Add attributes to YML
spring: application: name: gateway zipkin: base-url: http://localhost:9411/ discoveryClientEnabled: false sleuth: sampler: # The sampling rate is 0.1 (10%) by default probability: 1.0 cloud: nacos: discovery: server-addr: localhost:8848 gateway: discovery: locator: # Let the gateway find other microservices through the service discovery component enabled: true routes: #Custom routing predicate factory - id: after_route uri: lb://content-center predicates: #The time format must be in accordance with the following format, refer to (Note: idea The code set must be changed to utf8)TimeBetweenRoutePredicateFactory#main - TimeBetween=9 a.m:00, 5 pm:00
Appendix: method of modifying coding bit utf8 in IDEA
2.2.2. Create configuration class
package com.itmuch.gateway; import lombok.Data; import java.time.LocalTime; @Data public class TimeBeweenConfig { private LocalTime start; private LocalTime end; }
2.2.3. Create a user-defined project class
package com.itmuch.gateway; import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.time.format.FormatStyle; import java.util.Arrays; import java.util.List; import java.util.function.Predicate; @Component public class TimeBetweenRoutePredicateFactory extends AbstractRoutePredicateFactory<TimeBeweenConfig> { public TimeBetweenRoutePredicateFactory() { super(TimeBeweenConfig.class); } /** * The core method of routing predicate factory * @param config * @return */ @Override public Predicate<ServerWebExchange> apply(TimeBeweenConfig config) { LocalTime start = config.getStart(); LocalTime end = config.getEnd(); return exchange -> { LocalTime now = LocalTime.now(); return now.isAfter(start) && now.isBefore(end); }; } /** * Controls the mapping relationship between the configuration class timebeenconfig and the configuration file application#predictions * @return */ @Override public List<String> shortcutFieldOrder() { //The two properties start and end of the TimeBetween Config class correspond to the 9:00 and 17:00 parameters of TimeBetween in the application respectively return Arrays.asList("start", "end"); } //Test the time format of the output spring cloud gateway public static void main(String[] args) { DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT); System.out.println(formatter.format(LocalTime.now())); } }
2.2.4 test run results
The current time is 6:49 PM, and the gateway can be accessed from 9:00 am to 5:00 pm, so the access result should be 404
2.3 filter factory
reference resources: https://www.imooc.com/article/290816
2.4. Custom filter factory
Filter life cycle
- Pre: before the Gateway forwards the request
- Post: after the Gateway forwards the request
2.5. Prepare filter factory
Requirement: log when entering the factory
2.5.1,application. Add filter attribute to YML
spring: application: name: gateway zipkin: base-url: http://localhost:9411/ discoveryClientEnabled: false sleuth: sampler: # The sampling rate is 0.1 (10%) by default probability: 1.0 cloud: nacos: discovery: server-addr: localhost:8848 gateway: discovery: locator: # Let the gateway find other microservices through the service discovery component enabled: true routes: #Custom routing predicate factory - id: after_route uri: lb://content-center predicates: #The time format must be in accordance with the following format, refer to (Note: idea The code set must be changed to utf8)TimeBetweenRoutePredicateFactory#main - TimeBetween=9 a.m:00, 10 pm:00 filters: #For the custom filter factory class PreLogGatewayFilterFactory, arbitrarily pass two parameters a and B, a = config getName(),b=config.getValue() - PreLog=a,b
2.5.2. Create a custom filter factory class PreLogGatewayFilterFactory
It is important to note that the custom filter factory class must end with GatewayFilterFactory
package com.itmuch.gateway; import lombok.extern.slf4j.Slf4j; import org.springframework.cloud.gateway.filter.GatewayFilter; import org.springframework.cloud.gateway.filter.factory.AbstractNameValueGatewayFilterFactory; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; @Slf4j @Component public class PreLogGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory { @Override public GatewayFilter apply(NameValueConfig config) { return ((exchange, chain) -> { //Get the values of the two parameters configured in the application, config getName()=a; config.getValue()=b log.info("The request came in...{},{}", config.getName(), config.getValue()); ServerHttpRequest modifiedRequest = exchange.getRequest() .mutate() .build(); ServerWebExchange modifiedExchange = exchange.mutate() .request(modifiedRequest) .build(); return chain.filter(modifiedExchange); }); } }
2.5.3 test run results
visit http://localhost:8040/shares/2
2.6. Global filter
reference resources: https://www.imooc.com/article/290821
3, Monitoring spring cloud gateway
reference resources: https://www.imooc.com/article/290828
3, Summary of debugging and troubleshooting skills
reference resources: https://www.imooc.com/article/290824
4, Gateway current limiting
reference resources: https://www.imooc.com/article/290828
Special announcement: this series of tutorials (spring cloud Alibaba) refer to the online video courses provided by zimuke.com. Students in need can search and learn by themselves