• 微服务实战微服务网关Zuul入门与实战


    网关的作用

    微服务架构中,服务实例的地址可能经常会发生变化,所以我们不能直接将服务的地址暴露出来。如果每一个微服务都直接暴露接口,会导致一系列的问题,比如调用过于复杂,涉及到账户、权限不能统一处理等。另外基于高内聚低耦合的设计准则来讲,我们也应该将内部系统和外部系统做切割。

    因此,这时就需要有一个独立的组件来处理外部的请求,这个组件就是服务网关。服务网关就是为了简化前端的调用逻辑,通常情况下也会实现相关的认证逻辑,根据外部不同的请求响应不同的数据,从而简化内外部系统之间调用的复杂度。
    在这里插入图片描述
    服务网关负责服务请求路由、组合及协议转换。客户端的所有请求都首先经过服务网关,然后由它将请求路由到合适的微服务。服务网关经常会通过调用多个微服务并合并结果来处理一个请求,它可以在系统外部与内部响应之间友好的转换。

    本文将先着重介绍Zuul组件。

    Spring Cloud 网关组件Zuul介绍

    Zuul 是 Netflix 公司开源的产品,被称为第一代网关,也是 Spring Cloud 前几个版本默认使用的一款提供动态路由微服务网关组件。Zuul 接收所有外来请求,并将请求转发到对应的后端服务。作为一个前置服务,Zuul 旨在实现动态路由,监控,弹性和安全性等功能。

    Zuul 提供了不同类型的 filter 用于处理请求,这些 filter 可以让我们实现以下功能:

    1. 权限控制和安全性:可以识别认证需要的信息和拒绝不满足条件的请求。
    2. 监控:与边缘位置追踪有意义的数据和统计结果,从而带来精确的生产视图。
    3. 动态路由:根据需要动态地路由请求到后台的不同集群。
    4. 压力测试:逐渐增加指向集群的流量,以了解性能。
    5. 负载均衡:为每一种负载类型分配对应容量,并弃用超出限定值的请求
    6. 静态资源处理:直接在 zuul 处理静态资源的响应,从而避免其转发到内部集群。

    Zuul网关实战

    之前的介绍中,我们启动了注册中心registry,dms服务,和app服务,请求时,直接调用了app服务的接口,app服务又调用了dms服务:

    在这里插入图片描述

    加上网关服务之后,就会变成如下:
    在这里插入图片描述

    接下来,我们创建zuul服务:

    1、创建服务

    创建子模块zuul,pom.xml引入eureka-client 和zuul的依赖

    
                org.springframework.boot
                spring-boot-starter-web
            
    
            
                org.springframework.cloud
                spring-cloud-starter-netflix-eureka-client
            
    
            
            
                org.springframework.cloud
                spring-cloud-starter-openfeign
            
    
            
            
                org.springframework.cloud
                spring-cloud-starter-netflix-zuul
            
            
                javax.servlet
                javax.servlet-api
                3.1.0
            
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    2、创建配置文件

    server:
      port: 8004
    spring:
      application:
        name: zuul
    
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:8001/eureka/
    feign:
      hystrix:
        enabled: true
    zuul:
      routes:
        app: #活动
          path: /app/** #配置请求URL的请求规则
          serviceId: app #指定Eureka注册中心中的服务id
        dms: #活动
          path: /dms/** #配置请求URL的请求规则
          serviceId: dms #指定Eureka注册中心中的服务id
    logging:
      pattern:
        console: '%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{15} - %msg%n'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    3、创建Zuul过滤器

    /**
     * @Author:公众号:程序员965
     * @create 2022-06-30
     **/
    @Component
    public class MyZuulFilter extends ZuulFilter {
    
    //    pre :可以在请求被路由之前调用
    //    route :在路由请求时候被调用
    //    post :在route和error过滤器之后被调用
    //    error :处理请求时发生错误时被调用
        @Override
        public String filterType() {
            return "pre";// 前置过滤器
        }
    
        //通过int值来定义过滤器的执行顺序,优先级为0,数字越大,优先级越低
        @Override
        public int filterOrder() {
            return 0;
        }
    
        //返回一个boolean类型来判断该过滤器是否要执行,所以通过此函数可实现过滤器的开关
        @Override
        public boolean shouldFilter() {
            return true;//此处为true,说明需要过滤
        }
    
        //过滤器的具体逻辑。
        @Override
        public Object run() throws ZuulException {
            // 获取上下文
            RequestContext currentContext = RequestContext.getCurrentContext();
            HttpServletRequest request = currentContext.getRequest();
            String accessToken = request.getParameter("accessToken");
            if (StringUtils.isEmpty(accessToken)) {
                //setSendZuulResponse(false)令zuul过滤该请求,不进行路由
                currentContext.setSendZuulResponse(false);
                //设置返回的错误码
                currentContext.setResponseStatusCode(401);
                currentContext.setResponseBody("AccessToken is null");
                return null;
            }
            System.out.println("获取到AccessToken为:"+accessToken);
            // 否则正常执行业务逻辑.....
            return null;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    4、编写启动类

    注意增加@EnableZuulProxy注解

    /**
     * @Author:公众号:程序员965
     * @create 2022-06-30
     **/
    @EnableZuulProxy
    @EnableEurekaClient
    @SpringBootApplication
    public class ZuulApplication {
        public static void main(String[] args) {
            SpringApplication.run(ZuulApplication.class, args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    5、启动验证

    这个时候,我们将直接请求app的接口地址,改成网关zuul的地址和端口:http://localhost:8004/app/index

    在这里插入图片描述

    可以看到,请求中没有token访问授权认证失败!

    总结

    总结下网关的作用:

    1. 简化客户端调用的复杂度,统一处理外部请求。
    2. 数据的裁剪和聚合,根据不同的接口需求,对数据加工后对外提供接口
    3. 多平台的支持,对不同的客户端提供不同的网关支持。
    4. 遗留系统的微服务化改造,可以作为新老系统的中转组件。
    5. 统一处理调用过程中的安全、权限问题。

    先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

  • 相关阅读:
    十五、SQL Limit(干货版)
    CSS详细汇总
    springboot3接入nacos
    Leetcode-141环形链表
    QML代码生成
    [开源预告]开源用两千元做的水下机器人方案
    模型量化:轻量化你的深度学习模型
    文心一言 VS 讯飞星火 VS chatgpt (92)-- 算法导论8.3 5题
    【数据结构】二叉树--顺序结构及实现 (堆)
    【计算机视觉 | 目标检测】arxiv 计算机视觉关于目标检测的学术速递(8 月 25 日论文合集)
  • 原文地址:https://blog.csdn.net/m0_67391683/article/details/126066534