SpringCloud Distributed Microservice Cloud Architecture Part 5: Routing Gateway (zuul)(Finchley version)
In the micro-service architecture, several basic service governance components are needed, including service registration and discovery, service consumption, load balancing, circuit breaker, intelligent routing, configuration management, etc. Understanding the springcloud architecture can be added as follows: 3536227259, these basic components work together to form a simple micro-service system.A simple microservice system is shown below:
Note: A service and B service can be invoked from each other, and the configuration service is registered with the service registry.
In Spring Cloud micro-service systems, a common way of load balancing is that client requests go through load balancing (zuul, Ngnix) first, then to the service gateway (zuul cluster), and then to the specific services registered uniformly to the highly available service registry cluster, where all the configuration files of the services are managed by the configuration services (described in the next article), and the services are configured.Configuration files are placed in the git repository to allow developers to change the configuration at any time.
1. Introduction to Zuul
Zuul's main functions are routing forwarding and filtering.Routing functionality is part of a microservice, such as /api/user forwarding to user service and/api/shop forwarding to shop service.The Zuul default combines with Ribbon to achieve load balancing.
zuul has the following functions:
- Authentication
- Insights
- Stress Testing
- Canary Testing
- Dynamic Routing
- Service Migration
- Load Shedding
- Security
- Static Response handling
- Active/Active traffic management
2. Preparations
Continue with the project in the previous section.On the original project, create a new project.
3. Create service-zuul Project
Its pom.xml file is as follows:
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.forezp</groupId> <artifactId>service-zuul</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>service-zuul</name> <description>Demo project for Spring Boot</description> <parent> <groupId>com.forezp</groupId> <artifactId>sc-f-chapter5</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency> </dependencies> </project>
Turn on zuul's functionality by adding the comment @EnableZuulProxy to its entry applicaton class:
@SpringBootApplication @EnableZuulProxy @EnableEurekaClient @EnableDiscoveryClient public class ServiceZuulApplication { public static void main(String[] args) { SpringApplication.run( ServiceZuulApplication.class, args ); } }
Add the configuration file application.yml with the following configuration code:
eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/ server: port: 8769 spring: application: name: service-zuul zuul: routes: api-a: path: /api-a/** serviceId: service-ribbon api-b: path: /api-b/** serviceId: service-feign
First, the address of the service registry is specified as http://localhost:8761/eureka/, the port of the service is 8769, and the service name is service-zuul; requests starting with/api-a/are forwarded to the service-ribbon service; requests starting with/api-b/are forwarded to the service-feign service;
Run these five projects in turn; open your browser to access: http://localhost:8769/api-a/hi?name=forezp ; browser display:
hi forezp,i am from port:8762
Open browser to access: http://localhost:8769/api-b/hi?name=forezp ; browser display:
hi forezp,i am from port:8762
This indicates that zuul plays a routing role
IV. Service Filtering
zuul is not only a route, but also filters and does some security validation.Continue to renovate the project;
@Component public class MyFilter extends ZuulFilter { private static Logger log = LoggerFactory.getLogger(MyFilter.class); @Override public String filterType() { return "pre"; } @Override public int filterOrder() { return 0; } @Override public boolean shouldFilter() { return true; } @Override public Object run() { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); log.info(String.format("%s >>> %s", request.getMethod(), request.getRequestURL().toString())); Object accessToken = request.getParameter("token"); if(accessToken == null) { log.warn("token is empty"); ctx.setSendZuulResponse(false); ctx.setResponseStatusCode(401); try { ctx.getResponse().getWriter().write("token is empty"); }catch (Exception e){} return null; } log.info("ok"); return null; } }
FiltererType: Returns a string representing the type of filter, and defines four different filter types for the life cycle in zuul, as follows:
- pre: before routing
- Routing: when routing
- post: after routing
- error: send wrong call
- filterOrder: Order of filtering
- shouldFilter: Here you can write a logical judgment, whether to filter or not, this article true, always filter.
- run: The specific logic of the filter.It can be complex to use, including checking sql, nosql to determine whether the request has access or not.
Visit: http://localhost:8769/api-a/hi?name=forezp ; Web page display:
token is empty
Visit http://localhost:8769/api-a/hi?name=forezp&token=22 ;
Web page display:
hi forezp,i am from port:8762