SpringCloud |Part 5: Routing Gateway (Zuul)

1. Zuul background

    Different microservices generally have different network addresses, and external clients need to call multiple servers to complete a business requirement. The gateway is the middle layer between the client and the server, and all external requests will go through the gateway first.

2. Introduction to Zuul

    Zuul is Netflix's open source service gateway, which can be used with Eureka, Ribbon, Hystrix and other components. The core of Zuul is a series of filters that can accomplish the following functions.

  • Authentication and Security: Identify the authentication requirements for each resource and reject those that do not.
  • Review and Monitoring: Track meaningful data and statistics at the edge for a precise view of production.
  • Dynamic routing: Dynamically route requests to different backend clusters.
  • Stress test: Gradually increase traffic to the cluster to see performance.
  • Load distribution: Allocate the corresponding capacity for each load type, and discard requests that exceed the limit.
  • Static response handling: Partial responses are built directly at edge locations, avoiding their forwarding to internal clusters.
  • Multi-region resiliency: Request routing across AWS Regions aims to diversify ELB usage and bring the edge of the system closer to system users.

3. Preparations

    Create a new project on top of the original project.

Fourth, create a service-zuul project

    The 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.example</groupId>
	<artifactId>da-zuul-server</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>da-zuul-server</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.0.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
		<spring-cloud.version>Finchley.M8</spring-cloud.version>
	</properties>

	<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>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-netflix-eureka-client</artifactId>
            <version>RELEASE</version>
        </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>
		</dependencies>
	</dependencyManagement>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

	<repositories>
		<repository>
			<id>spring-milestones</id>
			<name>Spring Milestones</name>
			<url>https://repo.spring.io/milestone</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
	</repositories>


</project>

    Add the annotation @EnableZuulProxy to its entry applicaton class to enable the function of zuul:

@EnableZuulProxy
@SpringBootApplication
public class DaZuulServerApplication {

	public static void main(String[] args) {
		SpringApplication.run(DaZuulServerApplication.class, args);
	}
}

    Plus the configuration file application.yml plus the following configuration code:

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:1001/eureka/
server:
  port: 4001
spring:
  application:
    name: zuul-service
zuul:
  routes:
    api-1:
      path: /api-1/**
      serviceId: user-service
    api-1:
      path: /api-2/**
      serviceId: ribbon-service

    First specify the address of the service registry as http://localhost:1001/eureka/. The service name is service-zuul, and the service port is 4001; requests starting with /api-1/ are forwarded to the feign-service service; requests starting with /api-2/ are forwarded to the ribbon-service service; run this in turn six projects;

Open the browser to visit: http://localhost:4001/api-1/getHi?name=zhangsan; the browser displays:

Open the browser to visit: http://localhost:4001/api-2/getHi?name=zhangsan; the browser displays:

    zuul plays the role of routing

Five, service filtering

    Zuul is not only routing, but also filtering and doing some security verification. Modify the startup class.

@EnableZuulProxy
@EnableEurekaClient
@SpringBootApplication
public class DaZuulServerApplication {

	public static void main(String[] args) {
		SpringApplication.run(DaZuulServerApplication.class, args);
	}

	@Bean
	public MyFilter myFilter(){
		return new MyFilter();
	}
}

    The filter code is written as follows:

@Component
public class MyFilter extends ZuulFilter{

    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        RequestContext requestContext = new RequestContext().getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();
        Object token = request.getParameter("token");

        if (token ==null){
            try {
                requestContext.setSendZuulResponse(false);
                requestContext.setResponseStatusCode(401);
                requestContext.getResponse().getWriter().write("token is empty!");
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
        return null;
    }
}

    filterType: Returns a string representing the type of filter. Four filter types with different life cycles are defined in zuul.

  • pre: before routing
  • routing: when routing
  • post: after routing
  • error: send error call
  • filterOrder: the order of filtering
  • shouldFilter: Logical judgment can be written here, whether to filter, this article is true, and it will be filtered forever.
  • run: The specific logic of the filter. The availability is very complicated, including checking sql and nosql to determine whether the request has permission to access.

    At this time, visit: http://localhost:4001/api-1/getHi?name=zhangsan; the webpage displays:

    Visit http://localhost:4001/api-1/getHi?name=zhangsan&token=1 ; the webpage displays:

6. Source code download

    Zuul source code download: https://gitee.com/Clarences/Zuul-Server

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325034470&siteId=291194637