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

      

  • 相关阅读:
    HTML5 Canvas 颜色填充学习
    PHP中使用函数array_merge()合并数组
    div border-radius
    php中数组可以不写下标
    ab apache Benchmarking中链接的写法 记得加上/
    div border-radius画圆
    Why should i use url.openStream instead of of url.getContent?
    Using Java SecurityManager to grant/deny access to system functions
    In Java, what is the default location for newly created files?
    三种纯CSS实现三角形的方法
  • 原文地址:https://www.cnblogs.com/renzku/p/9614864.html
Copyright © 2011-2022 走看看