(D) Spring Cloud tutorial --Zuul (F version)

Reference: Fang Zhipeng column

In the micro-service architecture, service management requires several basic components, including registration and service discovery, service consumption, load balancing, circuit breakers, intelligent routing, configuration management, mutual cooperation of these basic components, jointly set up a simple micro-service system. A simple micro service system below:

 Note: A and B services are services that can be invoked from each other, plotting the time forgotten. And configure the service is registered with the service registry. In Spring Cloud micro-services system, a common load balancing methods, the client request first passes through load balancing (zuul, Ngnix), and then reach the service gateway (zuul cluster), and then to a specific service. , Unified registration services to highly available cluster service registry, all configuration files by the configuration service management services (under article describes), configure service profiles on the git repository to facilitate developers to change the configuration at any time.

Introduction 1. Zuul

Zuul main function is to route forwarding and filters. Routing function is part of the micro-services, such as / api / user is forwarded to the service to the user, / api / shop to shop forwarded to the service. zuul default and Ribbon combination to achieve a load balancing feature.

zuul has the following features:

  • Authentication
  • Insights
  • Stress Testing
  • Canary Testing
  • Dynamic Routing
  • Service Migration
  • Load Shedding
  • Security
  • Static Response handling
  • Active/Active traffic management

Continue to use on a project. In the original project, create a new project.

2. Create a service-zuul project

Its pom.xml file 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.zang</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.zang</groupId>
        <artifactId>sc-f-zuul</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>

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


</project>

在其入口applicaton类加上注解@EnableZuulProxy,开启zuul的功能:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@SpringBootApplication
@EnableZuulProxy
@EnableEurekaClient
@EnableDiscoveryClient
public class ServiceZuulApplication {

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

3. Zuul路由配置

配置文件application.yml加上以下的配置代码:

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

首先指定服务注册中心的地址为http://localhost:8761/eureka/,服务的端口为8769,服务名为service-zuul;以/api-a/ 开头的请求都转发给service-ribbon服务;以/api-b/开头的请求都转发给service-feign服务;

依次运行这五个工程;打开浏览器访问http://localhost:8769/api-a/hi?name=zang,显示如下:

 访问http://localhost:8769/api-a/hi?name=zang,显示如下:

 这说明Zuul起到了路由的作用。

4. Zuul服务过滤

Zuul不仅只是路由,并且还能过滤,做一些安全验证。继续改造工程;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

@Component
public class ArgFilter extends ZuulFilter {

    private static Logger log = LoggerFactory.getLogger(ZuulFilter.class);

    @Override
    public String filterType() {
        // 前置过滤器
        return "pre";
    }

    @Override
    public int filterOrder() {
        // 优先级为0,数字越大,优先级越低
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        // 是否执行该过滤器,此处为true,说明需要过滤
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        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;
    }
}

通过继承ZuulFilter然后覆写上面的4个方法,就可以实现一个简单的过滤器,下面是相关注意点进行说明:

  • filterType:返回一个字符串代表过滤器的类型,在zuul中定义了四种不同生命周期的过滤器类型,具体如下:
    • pre:路由之前
    • routing:路由之时
    • post: 路由之后
    • error:发送错误调用
  • filterOrder:过滤的顺序
  • shouldFilter:这里可以写逻辑判断,是否要过滤,本文true,永远过滤。
  • run:过滤器的具体逻辑。可用很复杂,包括查sql,nosql去判断该请求到底有没有权限访问。

这时访问:http://localhost:8769/api-a/hi?name=zang;网页显示:

访问 http://localhost:8769/api-a/hi?name=zang&token=1 ; 网页显示:

 

Guess you like

Origin www.cnblogs.com/zjfjava/p/12239447.html