1 网关的简介

1.1 网关API(接口) Gateway(网关)

    网关的概念:相当于客户端请求统一请求到网关服务器上,再由网关服务器进行转发请求到实际的服务器地址上,  
    类似于Nginx。  

    网关的作用:网关可以拦截客户端所有请求,对该请求进行权限控制、负载均衡、日志管理、接口调用监控等  

    网关和过滤器的区别:过滤器适合于单个tomcat服务器进行拦截请求,网关是拦截整个微服务所有请求。  

    网关分为内网网关和外网网关  

    Nginx和Zuul网关的区别:  

        1. Zuul和Nginx都可以实现负载均衡、反向代理、过滤请求、实现网关效果  
        2. 不同点  
            (1)Nginx采用C语言编写,Zuul采用java语言编写,Zuul的负载均衡实现是采用Ribbon + eureka实现本地负载均衡  

            (2)Nginx负载均衡实现采用服务器端实现负载均衡  

            (3)Nginx比Zuul功能更加强大,因为Nginx整合一些脚本语言(Nginx + Lua)  

            (4)Nginx适合于服务器端负载均衡  

            (5)Zuul适合服务中实现网关,而且使用技术是java  

        最好建议nginx + zuul实现网关
            nginx作用实现反向代理  
            zuul对微服务实现网关拦截  

1.2 接口在什么背景下产生的

    在面向服务架构和微服务背景下差生,目的是为了解耦。  

1.3 接口分类

  • 开放接口—–其他机构合作伙伴进行调用(必须在外网访问),如微信公众号开发,需要通过appid + appsocket 生成accessToken 进行通信。对接支付宝开发、微信开发;目的可以授权,遵循OAuth2.0协议方式

  • 内部接口

    一般只能在局域网中进行访问,服务调用之间关系都在同一个微服务系统中  
        目的:保证安全问题  

1.3.1 设计一套项目接口需要考虑的点

        接口权限(开放接口|内部接口)  
        考虑幂等性  
        安全性(https)防止串改数据(验证签名)
        使用网关拦截  
        接口实现黑名单和白名单、接口使用http协议 + json格式,符合restful风格,目的是为了跨平台。  
        考虑高并发对接口服务实现保护服务降级、熔断、隔离之类  
        最后使用统一的API管理平台  

2 搭建一个Zuul网关系统

2.1 zuul网关搭建示意图

2.2 创建zuul网关项目,在parent中添加一下依赖

     <!-- 导入springcloud整合zuul启动器 -->
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
    </dependency>   

2.3 创建application.yml文件

            server:
              port: 80

            spring:
              application:
                name: zuul-server
            eureka:
              client:
                service-url:
                  # 注册中心地址
                  defaultZone: http://localhost:8100/eureka
                  # 是否注册到注册中心,默认是开启
                register-with-eureka: true
                # 是否开启检索服务,默认是开启
                fetch-registry: true

            zuul:
              routes:
                # 自定义的转发服务规则
                app-a:
                  # 当客户端请求 127.0.0.1:80/app-member开头的路径时,都会转发到会员服务
                  path: /app-member/**
                  # 会员服务的别名
                  serviceId: app-test-member
                # 自定义的转发服务规则
                app-b:
                  # 当客户端请求 127.0.0.1:80/app-order开头的路径时,都会转发到订单服务
                  path: /app-order/**
                  # 订单服务的别名
                  serviceId: app-test-order    

2.3.1 创建zuul启动类

            /**
             * @author fyzn12
             * @version 1.0
             * @date 2020/7/29 15:03
             * @EnableEurekaClient:开启网关代理
             * @description:TODO
             */
            @SpringBootApplication
            @EnableZuulProxy
            @EnableEurekaClient
            public class AppZuul {

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

2.4 按一下顺讯启动各个服务 eureka服务–>zuul服务–>会员服务–>订单服务

2.5 访问订单服务的原始接口路径如下图所示

2.6 访问zuul服务中配置文件中设定的跳转路径如下图所示

3 配置一个拦截器,模拟用户登录判断

3.1 创建一个类继承ZuulFilter

        /**
         * @author fyzn12
         * @version 1.0
         * @date 2020/7/29 15:53
         * @description:编写一个拦截器,拦截所有请求,判断用户是否登录
         */
        @Component
        public class TokenFilter extends ZuulFilter {
            /**
             * @description:过滤器的类型,如 pre  :表示在请求之前执行
            */
            @Override
            public String filterType() {
                return "pre";
            }
         /**
          * @description:过滤器的执行顺序,当一个请求在同一阶段存在多个过滤器的时候,多个过滤器执行操作
         */
            @Override
            public int filterOrder() {
                return 1;
            }
            /**
             * @description:判断过滤器是否生效,return true表示生效
            */
            @Override
            public boolean shouldFilter() {
                return true;
            }
            /**
             * @description:编写过滤器拦截业务代码
            */
            @Override
            public Object run() throws ZuulException {
                System.out.println("测试Zuul------------******************************************");
                //拦截所有的服务接口,判断服务接口上是否有传递userToken
                // 1. 获取上下文 使用zuul自带的一个zuul.context.RequestContext;
                RequestContext context = RequestContext.getCurrentContext();
                // 2. 获取request
                HttpServletRequest request = context.getRequest();
                // 3. 获取token的时候从请求头中获取
                String userToken = request.getParameter("userToken");
                if (StringUtils.isEmpty(userToken)){
                    // 用户尚未登录,不能访问一下路径application.yml文件中配置的路径
                    context.setSendZuulResponse(false);
                    context.setResponseBody("466555454545655");
                    context.setResponseStatusCode(401);
                    //返回一个错误提示
                    return null;
                }
                //正常情况下可以执行
                return null;
            }
        }  

3.1.1 对该类重写的方法在注释中已经表明,下面对filterType的一些简单介绍

        pre:这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。  

        routing:这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服务的请求,并使用Apache HttpClient或Netfilx Ribbon请求微服务。  

        POST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。  

        ERROR:在其他阶段发生错误时执行该过滤器。  

它们各自的含义与功能总结如下。

  • filterType:该函数需要返回一个字符串来代表过滤器的类型,而这个类型就是在HTTP请求过程中定义的各个阶段。在Zuul中默认定义了4种不同生命周期的过滤器类型,具体如下所示。
    * pre: 可以在请求被路由之前调用。
    * rouing:在路由请求时被调用。
    * post:在routing和error过滤器之后被调用。
    * error: 处理请求时发生错误时被调用。

  • fil terOrder: 通过int值来定义过滤器的执行顺序,数值越小优先级越高。

  • shouldFil ter: 返回一个boolean值来判断该过滤器是否要执行。我们可以通过此方法来指定过滤器的有效范围。

  • run: 过滤器的具体逻辑。在该函数中,我们可以实现自定义的过滤逻辑,来确定是否要拦截当前的请求,不对其进行后续的路由,或是在请求路由返回结果之后,对处理结果做一些加工等。

4 使用Nginx搭建一个Zuul网关集群

搭建的结构构造图如下

4.1 关键文件的配置步骤

  1. 找到电脑文件路径C:\Windows\System32\drivers\etc下的hosts文件
  2. 用记事本打开文件
  1. 修改nignx.conf文件

4.2 在Zuul项目配置文件中添加如下配置

            # 开启所有监控中心接口
            management:
              endpoints:
                web:
                  exposure:
                    exclude: "*"  

4.3 启动eureka服务的前提下启动两个zuul项目,端口号分别为81、82

4.4 使用nginx设置的域名访问订单服务http://www.fyzn12.com/app-order/orderToMember?name=张三&userToken=1

4.5 总结:通过nginx搭建zuul网关集群时,默认是按照轮训的算法去实现。对此Zuul的一些简单基础学习到此结束,后续会把在学习过程中觉得深入的点做一下笔记