1. Zuul profile
API gateway provides a unified access for services in microservices architecture. Clients access related services through API gateway. The DEFINITION of an API gateway is similar to the facade pattern in design pattern, which is equivalent to the facade in the entire microservices architecture through which all client access is routed and filtered. It realizes the functions of request routing, load balancing, check filtering, service fault tolerance, service aggregation and so on.
2. Create the Spring Cloud Zuul project
2.1 Adding related dependencies to poM
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-cloud-demo</artifactId>
<groupId>com.hxmec</groupId>
<version>1.0 the SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-zuul</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
</dependencies>
</project>
Copy the code
2.2 Adding a Configuration File
The bootstrap.yml configuration is as follows
server:
port: 9200
spring:
application:
name: zuul-proxy
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8888/eureka/
Copy the code
Application. Yml configuration is as follows:
zuul:
routes: Configure a route for the service
eureka-client-provider:
path: /provider/**
eureka-client-consumer:
path: /consumer/**
Copy the code
2.3 Creating the startup class ZuulApplication
The startup class code is as follows:
@EnableZuulProxy
@EnableDiscoveryClient
@SpringBootApplication
public class ZuulApplication {
public static void main(String[] args) { SpringApplication.run(ZuulApplication.class, args); }}Copy the code
2.4 Start the program and test it
Start the spring-Cloud-Eureka-Server, spring-Cloud-Eureka-client-provider, Spring-Cloud-Eureka-client-consumer and gateway Zuul projects created in the paper before.
The test address is as follows:
- http://localhost:9200/provider/demo/hello
- http://localhost:9200/consumer/test/callHello
3. Common functions of Zuul
3.1 Configuring Routing Rules
We can configure routing rules by modifying the configuration in application.yml, where we route requests matching /provider/** to the Eureka-client-provider service. Requests matching /consumer/** are routed to eureka-client-consumer.Copy the code
The configuration is as follows:
zuul:
# Disable default route configuration
ignored-services: eureka-client-provider,eureka-client-consumer
routes: Configure a route for the service
eureka-client-provider:
path: /provider/**
eureka-client-consumer:
path: /consumer/**
Copy the code
Visit http://localhost:9200/provider/demo/hello routing to eureka – the client – the provider; Visit http://localhost:9200/consumer/test/callHello can route to the same eureka – the client – the consumer.
3.2 Configuring access Prefixes
Configuration is as follows
zuul:
Configure the unified access prefix
prefix: /zuul
routes: Configure a route for the service
eureka-client-provider:
path: /provider/**
eureka-client-consumer:
path: /consumer/**
Copy the code
All requests unified prefix need plus/zuul visit http://localhost:9200/zuul/provider/demo/hello routing to eureka – the client – the provider;
3.3 Header Filtering and Redirection Adding a Host
- By default, Zuul filters out some sensitive headers when requesting routes. The following configuration prevents loss of cookies and Authorization during routing:
zuul:
sensitive-headers: Cookie,Set-Cookie,Authorization # configure filter sensitive request headers. Set this parameter to null
Copy the code
- Zuul does not set the initial host header when requesting a route.
zuul:
add-host-header: true # Redirection set to true will add the host header
Copy the code
3.4 Viewing Routing Information
You can use the SpringBoot Actuator to view routing information in Zuul.
- Add dependencies to pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Copy the code
- Added enabling the endpoint configuration of viewing routes
# Endpoint of the route
management:
endpoints:
web:
exposure:
include: 'routes'
Copy the code
- Simply visit http://localhost:9200/actuator/routes to see by routing information
- By visiting http://localhost:9200/actuator/routes/details to check the detailed routing information
4. The filter
Routing and filtering are two core functions of Zuul. Routing is responsible for forwarding external requests to specific service instances and is the basis of unified access, while filtering is responsible for additional processing of the request process and is the basis of request verification and filtering and service aggregation.
4.1 Filter Types
Zuul filters have the following types:
- Pre: performs functions such as permission verification and log printing before the request is routed to the target service.
- Routing: Performed when the request is routed to the target service, which is where the original HTTP request is built and sent using Apache HttpClient or Netflix Ribbon;
- Post: After the request is routed to the target service, such as adding header information to the response of the target service, collecting statistics, etc.
- Error: The request is executed when an error occurs at another stage.
4.2 Filter life cycle
The Filter has four life cycles, namely “PRE”, “ROUTING”, “POST”, and “ERROR”. The whole life cycle can be shown in the following figure
Zuul implements most of its functionality through filters that correspond to the typical lifecycle of a request.
- PRE: This filter is invoked before the request is routed. We can use this filter to authenticate, select requested microservices in the cluster, log debugging information, and so on.
- ROUTING: This filter routes the request to the microservice. This filter is used to build requests sent to microservices and request microservices using Apache HttpClient or Netfilx Ribbon.
- POST: This filter is executed after routing to the microservice. Such filters can be used to add standard HTTP headers to responses, collect statistics and metrics, send responses from microservices to clients, and so on.
- ERROR: This filter is executed when errors occur in other phases.
4.3 Customizing Filters
In Zuul Gateway, we need to define a class that inherits the ZuulFilter abstract class and implements the four corresponding abstract methods.
In the following example, we define a custom AccessTokenFilter to verify that the request has accessToken parameters:
@Component
@Slf4j
public class AccessTokenFilter extends ZuulFilter {
/** * Filter type pre means intercept before request *@return* /
@Override
public String filterType(a) {
return "pre";
}
/** * Filter execution order. When a request has multiple filters at one stage, you need to execute * in sequence based on the return value of this method@return* /
@Override
public int filterOrder(a) {
return 0;
}
/** * Check whether the filter takes effect *@return* /
@Override
public boolean shouldFilter(a) {
return true;
}
@Override
public Object run(a) throws ZuulException {
// Get the context
RequestContext currentContext = RequestContext.getCurrentContext();
HttpServletRequest request = currentContext.getRequest();
String accessToken = request.getParameter("accessToken");
if (StringUtils.isEmpty(accessToken)) {
//setSendZuulResponse(false) causes Zuul to filter the request without routing it
currentContext.setSendZuulResponse(false);
// Set the error code returned
currentContext.setResponseStatusCode(401);
currentContext.setResponseBody("AccessToken is null");
return null;
}
log.info("Get AccessToken as {}",accessToken);
// Otherwise, execute the service logic.....
return null; }}Copy the code
Verify that the Zuul service is valid after being restarted
In the filter code implemented above, we implement our custom filter by inheriting the ZuulFilter abstract class and rewriting the following four methods. The four methods define:
- FilterType () : The type of filter that determines in which lifecycle of the request the filter is executed. This is defined as pre, which means that the request will be executed before it is routed.
- FilterOrder () : filter execution order. When requests have multiple filters in a phase, they need to be executed sequentially based on the value returned by this method. The value is specified by a number. A larger number indicates a lower priority.
- ShouldFilter () : Check whether this filter needs to be executed. Here we return true directly, so the filter will apply to all requests. In practice, we can use this function to specify the effective range of the filter.
- Run () : specifies the logic of the filter. . Here we through currentContext setSendZuulResponse (false) make Zuul filtering the request, does not carry on the route, Then through currentContext. SetResponseStatusCode (401) set up the return error code, of course we can also further optimize our return, Such as through currentContext. SetResponseBody (body) to return to the body content editing, etc.
4.4 Core Filter
Some default filters are provided in Zuul
type | The order | The filter | function |
---|---|---|---|
pre | – 3 | ServletDetectionFilter | The tag handles the type of Servlet |
pre | 2 – | Servlet30WrapperFilter | Wrap the HttpServletRequest request |
pre | – 1 | FormBodyWrapperFilter | Wrapping request body |
pre | 5 | PreDecorationFilter | The current request is preprocessed for subsequent operations. |
pre | 1 | DebugFilter | Debugging flag |
route | 10 | RibbonRoutingFilter | ServiceId Forwards the request |
route | 500 | SendForwardFilter | Forward request forwarding |
route | 100 | SimpleHostRoutingFilter | Url Request forwarding |
post | 900 | LocationRewriteFilter | Rewrite the Location header to Zuul’s URL |
post | 0 | SendErrorFilter | Handle request responses with errors |
post | 1000 | SendResponseFilter | Process normal request responses |
4.5 Ribbon and Hystrix support
Zuul already has load balancing and service fault tolerance capabilities because it integrates the Ribbon and Hystrix. You can configure Zuul with the Ribbon and Hystrix.
- You can use the Hystrix configuration to set the timeout period for HystrixCommand execution during route forwarding:
hystrix:
command: # used to control HystrixCommand behavior
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 1000 HystrixCommand: HystrixCommand: HystrixCommand: HystrixCommand: HystrixCommand: HystrixCommand
Copy the code
- You can use the Ribbon configuration to set the timeout for connection requests and processing in routing forwarding:
ribbon: # global configuration
ConnectTimeout: 1000 Service request connection timeout (ms)
ReadTimeout: 3000 Service request processing timeout (ms)
Copy the code
4.6 Using Zuul to Limit Traffic
Add dependencies:
<dependency>
<groupId>com.marcosbarbero.cloud</groupId>
<artifactId>spring-cloud-zuul-ratelimit</artifactId>
<version>${latest-version}</version>
</dependency>
Copy the code
Redis is used as the data store in this article. Other storage references are: github.com/marcosbarbe…
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
Copy the code
Spring-cloud-zuul-ratelimit is an extension of the distributed traffic limiting policy that zuul and Spring-cloud-Zuul-ratelimit integrate to provide distributed traffic limiting policy. You only need to configure a few lines in YML to enable the application to support traffic limiting:
ratelimit:
enabled: true
repository: REDIS Use redis for storage, always capitalize!
policies:
eureka-client-provider: # limit traffic for the above service
limit: 100 # How many requests per second
quota: 20 #quota specifies the total time allowed per request.
refreshInterval: 60 # Time to refresh the time window, default (seconds)
type:
- ORIGIN URL by request path, ORIGIN by client IP address, USER by login USER name, including anonymous USER
Copy the code
Ratelimit supports the following flow limiting granularity:
- Service granularity (default, traffic limiting for the current service module)
- User granularity (see summary at the end of this article for details
- ORIGIN granularity (ORIGIN requested by the user as granularity control)
- Interface granularity (request the address of the interface as granularity control)
- The above granularity is freely combined and can support a variety of situations
- If that’s not enough, customize the RateLimitKeyGenerator implementation.
Supported storage modes:
- InMemoryRateLimiter – Uses ConcurrentHashMap as the data store
- ConsulRateLimiter – Use Consul for data storage
- RedisRateLimiter – Uses Redis as the data store
- SpringDataRateLimiter – Uses the database as the data store
5. Test project address
Github.com/ty197287300…