zoukankan      html  css  js  c++  java
  • SpringCloud学习(五):Zuul 路由过滤/网关

    菜鸟学渣接触spring cloud 系列...

    公司也上微服务了,再不学习下就凉了,所以来踩坑吧...

    版本:

      spring-boot:  2.0

      spring-cloud: Finchley.SR1

    已有项目:

      [eureka-server]              # 注册中心   port 8761

      [eureka-client-one]       #  微服务1    port 8501

      [eureka-client-two]       #  微服务2    port 8502

      [eureka-client-turbine] #  断路监控   port 8503

    能上图绝不BB

      

      添加网关后,所有微服务API都通过ZUUL访问,zuul根据url分发到各个微服务实例

      spring-cloud-gateway是Spring自己撸的网关,和netflx-zuul性质一样,后面也去学习一下.

    一、Zuul网关  [eureka-client-zuul]

      新建项目[eureka-client-zuul]

      引入依赖  spring-cloud-starter-netflix-zuul

    <?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.renzku</groupId>
        <artifactId>eureka-client-zuul</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>jar</packaging>
    
        <name>eureka-client-zuul</name>
        <description>Demo project for Spring Boot</description>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.4.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.SR1</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>
        </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>
    
    
    </project>
    pom.xml

      配置文件  application.yml

    server:
      port: 8601
    
    spring:
      application:
        name: eureka-client-zuul
    
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8761/eureka/
    
    # 动态路由后面研究
    # 默认引入eureka后不手动配置,会自动为每个服务都创建一个默认路由规则: 访问路径的前缀为serviceId配置的服务名称,这里修改下
    zuul:
      routes:
        clientOne:
          path: /client-one/**
          serviceId: eureka-client-one
        clientTwo:
          path: /client-two/**
          serviceId: eureka-client-two
    #      url: http://localhost:8502/

      启动类  EurekaClientZuulApplication.java

    @SpringBootApplication
    @EnableEurekaClient
    @EnableZuulProxy
    public class EurekaClientZuulApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(EurekaClientZuulApplication.class, args);
        }
    
    
    }

      目录结构

      

      

      访问 http://localhost:8601/client-one 和 http://localhost:8601/client-two

      zuul根据url分别访问了微服务[eureka-client-one]和[eureka-client-two]

      

    二、ZuulFilter过滤

      过滤器有4中:

        pre: 该类型的filters在Request routing到源web-service之前执行。用来实现Authentication、选择源服务地址等
        routing:该类型的filters用于把Request routing到源web-service,源web-service是实现业务逻辑的服务。这里使用HttpClient请求web-service。
        post:该类型的filters在ROUTING返回Response后执行。用来实现对Response结果进行修改,收集统计数据以及把Response传输会客户端。  
        error:上面三个过程中任何一个出现错误都交由ERROR类型的filters进行处理。

      顺序:

      

                        来源: https://blog.csdn.net/tianyaleixiaowu/article/details/77893822

      ‘pre' 过滤器  ZuulRequestFilter.java

    public class ZuulRequestFilter extends ZuulFilter {
    
        public int filterOrder() {
            // filter 顺序
            return 5 - 1;
        }
    
        public String filterType() {
        // filter 类型
    return "pre"; } @Override public boolean shouldFilter() {
        // filter 是否生效,这里一般根据请求头中的header灵活设置
    return true; } public Object run() { RequestContext ctx = getCurrentContext(); // 添加个头信息 转发到其他微服务的请求头中会带上 “requestFilterParam” ctx.addZuulRequestHeader("requestFilterParam", "here is RequestFilter!"); return null; } }

      'post'过滤器   ZuulResponseFilter.java

    public class ZuulResponseFilter extends ZuulFilter {
        public String filterType() {
            return "post";
        }
    
        public int filterOrder() {
            return 999;
        }
    
        public boolean shouldFilter() {
            return true;
        }
    
        public Object run() {
            RequestContext context = RequestContext.getCurrentContext();
            HttpServletResponse servletResponse = context.getResponse();
            // 添加个头信息   最后返回数据的头信息header中会带上  “responseFilterParam”
            servletResponse.addHeader("responseFilterParam", "here is ResponseFilter!");
            return null;
        }
    }

      启动类加入Filter使生效

    @SpringBootApplication
    @EnableEurekaClient
    @EnableZuulProxy
    public class EurekaClientZuulApplication {
    
        @Bean
        public ZuulRequestFilter requestFilter(){
            return new ZuulRequestFilter();
        }
    
        @Bean
        public ZuulResponseFilter responseFilter(){
            return new ZuulResponseFilter();
        }
    
        public static void main(String[] args) {
            SpringApplication.run(EurekaClientZuulApplication.class, args);
        }
    }

      

      测试 ZuulRequestFilter 和 ZuulResponseFilter:

      [eureka-client-one]中添加个Rest API: “/zuul/test"

    @RestController
    public class HelloWorld {
    
        @RequestMapping("/")
        @HystrixCommand(fallbackMethod =  "someBoom")
        public String home(){
            int a = 0, c = 1;
            int d = c/a;  // 抛出异常触发
            return "hello world";
        }
    
        public String someBoom(){
            return "wokao, 魂淡";
        }
    
        @RequestMapping("/zuul/test")
        public String zuulTest(@RequestHeader String requestFilterParam){
            return "requestFilterParam: " + requestFilterParam + " .--client one";
        }
    }

      通过网关访问  http://localhost:8601/client-one/zuul/test

      可以看到 2个过滤器都生效了..

      

    三、Zuul 断路器

      如果某个微服务炸了,zuul可以实现断路器的功能

      从依赖来看,是基于hystrix

      

      新增fallback类   MyZuulFallbackProvider.java  

    /**
     * 默认回退
     */
    public class MyZuulFallbackProvider implements FallbackProvider{
        /**
         * 为那个微服务提供回退: *
    ull为 所有
         * @return 这里不是eureka的serviceId,而是zuul.routes下的值,比如为[eureka-client-one]断路,则return "clientOne"
         */
        @Override
        public String getRoute() {
            return null;
        }
    
        @Override
        public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
            return new ClientHttpResponse() {
                @Override
                public HttpStatus getStatusCode() throws IOException {
                    return HttpStatus.OK;
                }
    
                @Override
                public int getRawStatusCode() throws IOException {
                    return 200;
                }
    
                @Override
                public String getStatusText() throws IOException {
                    return "OK";
                }
    
                @Override
                public void close() {
    
                }
    
                @Override
                public InputStream getBody() throws IOException {
                    return new ByteArrayInputStream("zuul fallback".getBytes());   // 回退信息
                }
    
                @Override
                public HttpHeaders getHeaders() {
                    HttpHeaders headers = new HttpHeaders();
                    headers.setContentType(MediaType.APPLICATION_JSON);
                    return headers;
                }
            };
        }
    }

      启动类加入使其生效

    @SpringBootApplication
    @EnableEurekaClient
    @EnableZuulProxy
    public class EurekaClientZuulApplication {
    
        @Bean
        public ZuulRequestFilter requestFilter(){
            return new ZuulRequestFilter();
        }
    
        @Bean
        public ZuulResponseFilter responseFilter(){
            return new ZuulResponseFilter();
        }
    
        @Bean
        public FallbackProvider fallbackProvider(){
            return new MyZuulFallbackProvider();
        }
    
        public static void main(String[] args) {
            SpringApplication.run(EurekaClientZuulApplication.class, args);
        }
    }

      现在把[eureka-client-one]关闭,zuul路由访问必定报错,触发fallback

      访问   http://localhost:8601/client-one/zuul/test

      

  • 相关阅读:
    Windows Server 2012配置开机启动项
    Windows Server 2019 SSH Server
    NOIP2017 senior A 模拟赛 7.7 T1 棋盘
    Noip 2015 senior 复赛 Day2 子串
    Noip 2015 senior复赛 题解
    Noip 2014 senior Day2 解方程(equation)
    Noip 2014 senior Day2 寻找道路(road)
    Noip 2014 senior Day2 无线网络发射器选址(wireless)
    Noip2014senior复赛 飞扬的小鸟
    Noip 2014 senior 复赛 联合权值(link)
  • 原文地址:https://www.cnblogs.com/renzku/p/9614864.html
Copyright © 2011-2022 走看看