• Getway网关管理ZUUL


    1.ZUUL微服务网关

    微服务架构体系中,通常一个业务系统会有很多的微服务,比如:OrderService、ProductService、UserService...,为了让调用更简单,一般会在这些服务前端再封装一层,类似下面这样:

    image.png

    这样做,当然能跑起来,但是维护量大,以后各个微服务增加了新方法,都需要在网关层手动增加相应的方法封装,而spring cloud 中的zuul很好的解决了这一问题,示意图如下:

    image.png

    Zuul做为网关层,自身也是一个微服务,跟其它服务Service-1,Service-2, ... Service-N一样,都注册在eureka server上,可以相互发现,zuul能感知到哪些服务在线,同时通过配置路由规则(后面会给出示例),可以将请求自动转发到指定的后端微服务上,对于一些公用的预处理(比如:权限认证,token合法性校验,灰度验证时部分流量引导之类),可以放在所谓的过滤器(ZuulFilter)里处理,这样后端服务以后新增了服务,zuul层几乎不用修改。

    2.代码实现:

    代码的机构图如下:

    image.png

    pom.xml:

    <?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</groupId>
        <artifactId>stu-zuul</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>jar</packaging>
    
        <name>stu-zuul</name>
        <description>Demo project for Spring Boot</description>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.3.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.RELEASE</spring-cloud.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-ribbon</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-test</artifactId>
                <scope>test</scope>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka</artifactId>
                <version>1.3.1.RELEASE</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-feign</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-hystrix</artifactId>
            </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>
    
    

    启动类:

    StuZuulApplication:

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
    
    //启动类加上注解@EnableZuulProxy
    //它默认加上了@EnableCircuitBreaker和@EnableDiscoveryClient
    @SpringBootApplication
    @EnableZuulProxy
    public class StuZuulApplication {
        public static void main(String[] args) {
            SpringApplication.run(StuZuulApplication.class, args);
        }
    }
    

    熔断器:

    这个地方我用的springboot版本比较高,网上大部分是之前的版本的熔断器的配置,如果产生冲突可以看下是否有哦依赖版本冲突的问题:

    MyFallbackProvider

    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.nio.charset.Charset;
    import com.netflix.hystrix.exception.HystrixTimeoutException;
    import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
    import org.springframework.http.HttpHeaders;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.MediaType;
    import org.springframework.http.client.ClientHttpResponse;
    import org.springframework.stereotype.Component;
    
    @Component
    public class MyFallbackProvider implements FallbackProvider {
      @Override
      public String getRoute() {
        // 表明是为哪个微服务提供回退,*表示为所有微服务提供回退
        return "*";
      }
    
      @Override
      public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
        return null;
      }
    
      public ClientHttpResponse fallbackResponse(Throwable cause) {
        if (cause instanceof HystrixTimeoutException) {
          return response(HttpStatus.GATEWAY_TIMEOUT);
        } else {
          return this.fallbackResponse();
        }
      }
      public ClientHttpResponse fallbackResponse() {
        return this.response(HttpStatus.INTERNAL_SERVER_ERROR);
      }
      private ClientHttpResponse response(final HttpStatus status) {
        return new ClientHttpResponse() {
          @Override
          public HttpStatus getStatusCode() throws IOException {
            return status;
          }
          @Override
          public int getRawStatusCode() throws IOException {
            return status.value();
          }
          @Override
          public String getStatusText() throws IOException {
            return status.getReasonPhrase();
          }
          @Override
          public void close() {
          }
          @Override
          public InputStream getBody() throws IOException {
            return new ByteArrayInputStream("服务不可用,请稍后再试。".getBytes());
          }
          @Override
          public HttpHeaders getHeaders() {
            // headers设定
            HttpHeaders headers = new HttpHeaders();
            MediaType mt = new MediaType("application", "json", Charset.forName("UTF-8"));
            headers.setContentType(mt);
            return headers;
          }
        };
      }
    }
    

    bootstrap.yml:

    server:
      port: 8040
    spring:
      application:
        name: stu-zuul
    eureka:
      client:
        service-url:
          defaultZone: http://user:password123@localhost:8761/eureka
      instance:
          prefer-ip-address: true
          instance-id: ${spring.application.name}:${spring.cloud.client.ipAddress}:${spring.application.instance_id:${server.port}}
          hostname: localhost
          ip-address: localhost
    hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 60000
    ribbon:
      NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule #配置规则 轮询
      ConnectTimeout: 3000
      ReadTimeout: 60000
    zuul:
      routes:
        api-a:
          path: /api-provider/**
          service-id: stu-provide
          sensitive-headers:
        api-b:
          path: /api-consumer/**
          service-id: stu-consumer,stu-consumer-feign-hytrix
    

    上面已经讲到注解了@EnableZuulProxy后,它默认加上了@EnableCircuitBreaker和@EnableDiscoveryClient,

    另外他是整合了ribbon的,不需要加额外的注解,但是可以配置相关的负载均衡的规则,下面的配置需要额外注意:

    zuul:
      routes:
      #配置服务提供者的前缀,替代服务注册名,访问的时候就为http://localhost:8040/api-provider/**
        api-a:
          path: /api-provider/**
          service-id: stu-provide
          sensitive-headers:
        #配置消费者的前缀,替代服务注册名,访问的时候就为http://localhost:8040/api-consumer/**
        api-b:
          path: /api-consumer/**
          service-id: stu-consumer,stu-consumer-feign-hytrix
    

    启动后进行访问,会得到相关提供者的信息.
    附上代码地址:https://github.com/fengcharly/springCloud-ribbon-turbine.git

  • 相关阅读:
    elemen-ui表格多选,分页保持勾选状态的实现
    element-ui中的change事件传递多个参数的方法
    vue中访问不存在路由默认跳转404页面实现方法
    IntelliJ IDEA 汉化包
    vue 移动端项目用手机预览调试
    vue 中使用 rem
    vue中配置axios.js文件,发送请求
    vue中axios的使用
    爬楼梯
    不同路径
  • 原文地址:https://www.cnblogs.com/charlypage/p/9344693.html
Copyright © 2020-2023  润新知