• Spring-Cloud-Netflix-Zuul网关


    Spring-Cloud-Netflix-Zuul网关

    API网关

    1. API网关,顾名思义,是统一管理API的一个网络关口、通道,是整个微服务平台所有请求的唯一入口
    2. 所有的客户端和消费端都通过统一的网关接入微服务,在网关层处理所有的非业务功能
      有网关和没有网关:
    1. 没有:没有网关的时候, 用户可以随意访问一台微服务
    2. 有:有了网关后, 请求必须得要先经过网关, 确定这个请求是否合法,如果合法, zuul会对其做出判断 , 转发到指定的微服务,也会自动帮助做负责均衡

    Zuul概述

    1. Zuul是Netflix出品的一个基于JVM路由和服务端的负载均衡器(网关)
    2. Zuul包含了对请求的路由和过滤两个最主要的功能:
    1. 路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础
    2. 过滤器功能则负责对请求的处理过程进行干预,是实现请求校验、服务聚合等功能的基础
    1. Zuul也作为一个客户端注册进Eureka
      将Zuul自身注册为Eureka服务治理下的应用
      同时从Eureka中获得其他微服务的消息,也即以后的访问微服务都是通过Zuul跳转后获得。

    Zuul使用

    1. 在工程当中创建一个网关微服务

    在这里插入图片描述

    2. 导入zuul相关依赖

    在这里插入图片描述

    <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>
        </dependencies>
    

    3.创建启动类,在启动类上添加@EnableZuulProxy

    在这里插入图片描述

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

    4 .创建application/yml

    在这里插入图片描述

    server:
      port: 8001
    eureka:
      client:
        serviceUrl:
          #eureka服务端提供的注册地址 参考服务端配置的这个路径
          defaultZone: http://eureka:3000/eureka,http://eureka1:3001/eureka,http://eureka2:3000/eureka2
      instance:
        instance-id: zull-0 #此实例注册到eureka服务端的唯一的实例ID
        prefer-ip-address: true #是否显示IP地址
        #eureka客户需要多长时间发送心跳给eureka服务器,表明它仍然活着,默认为30 秒 (与下面配置的单位都是秒)
        leaseRenewalIntervalInSeconds: 1
        #Eureka服务器在接收到实例的最后一次发出的心跳后,需要等待多久才可以将此实例删除,默认为90秒
        leaseExpirationDurationInSeconds: 3
    
    spring:
      application:
        name: client-zuul #此实例注册到eureka服务端的name
    
    1. 启动 根据zull的端口号+服务名称 访问
      在这里插入图片描述

    zuul配置路由

    1. 在zuul的配置文件当中添加如下配置
      在这里插入图片描述
    zuul:
      routes:
        goods: #自己定义的名称  商品服务
          serviceId: client-goods
          path: /goods/**   #/* 是一级   /** 是多级
        order: #订单服务
          serviceId: client-order
          path: /order/**
    

    配置完成后,再访问地址http://localhost:8003/goods/getGoods.do
    在这里插入图片描述

    1. 禁用通过微服务的名称直接调用
      在这里插入图片描述
      在这里插入图片描述
    2. prefix 前缀: 访问网关时需要加上prefix
      在这里插入图片描述
      访问时:http://localhost:8001/api/goods/getGoods.do
      在这里插入图片描述

    过滤器

    过滤器(filter)是zuul的核心组件 zuul大部分功能都是通过过滤器来实现的

    zuul中定义了4种标准过滤器类型:

    1. PRE
      这种过滤器在请求被路由之前调用。 可利用这种过滤器实现身份验证、在 集群中选择请求的微服务、记录调试信息等。
    2. ROUTING
      这种过滤器将请求路由到微服务。 这种过滤器用于构建发送给微服 务的请求,并使用 Apache HttpCIient或 Netfilx
    3. POST:
      这种过滤器在路由到微服务以后执行。
      这种过滤器可用来为响应添加标准 的 HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等
    4. ERROR:
      在其他阶段发生错误时执行该过滤器。

    自定义过滤器: 写一个类继承 ZuulFilter类
    在这里插入图片描述

    @Component
    public class zfilter extends ZuulFilter {
        /*返回过滤器的类型*/
        @Override
        public String filterType() {
            return FilterConstants.PRE_TYPE; //前置过滤器
        }
        /*返回指定过滤器的执行顺序 越小越靠前*/
        @Override
        public int filterOrder() {
            //+1 在此过滤器之后执行
            return FilterConstants.PRE_DECORATION_FILTER_ORDER+1;
        }
        /*判断该过滤器是否要执行, true表示执行, false表示不执行。*/
        @Override
        public boolean shouldFilter() {
            return true;
        }
        /*过滤器的具体逻辑*/
        @Override
        public Object run() throws ZuulException {
            RequestContext ctx = RequestContext.getCurrentContext();
            HttpServletRequest request = ctx.getRequest();
            String remoteAddr = request.getRemoteAddr();
            System.out.println("访问者IP:"+remoteAddr+"访问地址:"+request.getRequestURI());
            //可以通过strip-prefix: true/false确定是否要移除前缀
            System.out.println("路由后的地址:"+ctx.get(FilterConstants.REQUEST_URI_KEY));
            return null;
        }
    }
    
    

    zuul容错与回退

    zuul默认是整合了hystrix和ribbon的, 提供降级回退,当服务访问不通的时候,会调用自己提供的方法,是服务级别的

    实现步骤:

    1. 编写一个类,实现FallbackProvider
      在这里插入图片描述
    @Component
    public class ZuulFallBackProvider implements FallbackProvider {
        //制定为哪个微服务提供回退(这里写微服务名 写*代表所有微服务)
        @Override
        public String getRoute() {
            return "*";
        }
    
        //此方法需要返回一个ClientHttpResponse对象
        // ClientHttpResponse是一个接口,具体的回退逻辑要实现此接口
        @Override
        public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
            //这里可以判断根据不同的异常来做不同的处理, 也可以不判断
            //完了之后调用response方法并根据异常类型传入HttpStatus
            if (cause instanceof HystrixTimeoutException) {
                return response(HttpStatus.GATEWAY_TIMEOUT);
            } else {
                return response(HttpStatus.INTERNAL_SERVER_ERROR);
            }
        }
    
        private ClientHttpResponse response(final HttpStatus status) {
            //这里返回一个ClientHttpResponse对象 并实现其中的方法,关于回退逻辑的详细,便在下面的方法中
            return new ClientHttpResponse() {
                @Override
                public HttpStatus getStatusCode() throws IOException {
                    //返回一个HttpStatus对象 这个对象是个枚举对象, 里面包含了一个status code 和reasonPhrase信息
                    return status;
                }
                @Override
                public int getRawStatusCode() throws IOException {
                    //返回status的code  比如 404,500等
                    return status.value();
                }
                @Override
                public String getStatusText() throws IOException {
                    //返回一个HttpStatus对象的reasonPhrase信息
                    return status.getReasonPhrase();
                }
                @Override
                public void close() {
                    //close的时候调用的方法, 讲白了就是当降级信息全部响应完了之后调用的方法
                    System.out.println("close调用");
                }
                @Override
                public InputStream getBody() throws IOException {
                    //把降级信息响应回前端
                    return new ByteArrayInputStream("系统繁忙,请稍后再试".getBytes());
                }
                @Override
                public HttpHeaders getHeaders() {
                    //需要对响应报头设置的话可以在此设置
                    HttpHeaders headers = new HttpHeaders();
                    headers.setContentType(MediaType.APPLICATION_JSON);
                    return headers;
                }
            };
        }
    }
    

    zuul集群

    新创建创建两个zuul服务
    修改8001的zullsever代理的配置
    在这里插入图片描述
    8002的zuul服务端:
    在这里插入图片描述
    8003的zull服务
    在这里插入图片描述

    开启所有的服务:
    在这里插入图片描述
    在这里插入图片描述
    访问goods服务:
    http://localhost:8002/api/goods/getGoods.do
    在这里插入图片描述

  • 相关阅读:
    网页爬虫小记:两种方式的爬取网站内容
    AOP中使用Aspectj对接口访问权限进行访问控制
    Spring Boot应用总结更新
    SpringBoot集成mybatis配置
    经验收集
    关于阿拉伯文开发的一点经验
    关于IDataReader.GetSchemaTable的一些事情
    removing vmware debugger from visual studio
    SQL Server 2008 R2 附加数据库 “尝试打开或创建物理文件 拒绝访问”的解决办法
    Visual Studio 2013 ReportViewer Control
  • 原文地址:https://www.cnblogs.com/joker-dj/p/12675516.html
Copyright © 2020-2023  润新知