ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

带你快速搞懂微服务网关!

2021-04-12 18:32:50  阅读:265  来源: 互联网

标签:网关 zuul 请求 ctx 过滤器 搞懂 快速 public 路由


网关概念

网关(Gateway)又称网间连接器、协议转换器。网关在网络层以上实现网络互连,是复杂的网络互连设备,仅用于两个高层协议不同的网络互连。网关既可以用于广域网互连,也可以用于局域网互连。 网关是一种充当转换重任的计算机系统或设备。使用在不同的通信协议、数据格式或语言,甚至体系结构完全不同的两种系统之间,网关是一个翻译器。与网桥只是简单地传达信息不同,网关对收到的信息要重新打包,以适应目的系统的需求。微服务的中网关是用来处理外部请求分发到内部服务,用于控制外部流量的分发!

zuul网关简介

Zuul 是 Netflix OSS 中的一员,是一个基于 JVM 路由和服务端的负载均衡器。提供路由、监控、弹性、安全等方面的服务框架。Zuul 能够与 Eureka、Ribbon、Hystrix 等组件配合使用。

zuulzuul

zuul主要功能介绍

  1. 动态路由

动态地将客户端的请求路由到后端不同的服务,做一些逻辑处理,比如聚合多个服务的数据返回。

  1. 请求监控

可以对整个系统的请求进行监控,记录详细的请求响应日志,可以实时统计出当前系统的访问量以及监控状态。

  1. 认证鉴权

对每一个访问的请求做认证,拒绝非法请求,保护好后端的服务。

  1. 压力测试

压力测试是一项很重要的工作,像一些电商公司需要模拟更多真实的用户并发量来保证重大活动时系统的稳定。通过 Zuul 可以动态地将请求转发到后端服务的集群中,还可以识别测试流量和真实流量,从而做一些特殊处理。

  1. 灰度发布

灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度。

zuul原理

Zuul大部分功能都是通过过滤器来实现的。Zuul中定义了四种标准过滤器类型,这些过滤器类型对应于请求的典型生命周期。

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

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

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

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

zuul还提供了一类内置特殊的过滤器,

(1) StaticResponseFilter:StaticResponseFilter允许从Zuul本身生成响应,而不是将请求转发到源。

(2) SurgicalDebugFilter:SurgicalDebugFilter允许将特定请求路由到分隔的调试集群或主机。

(3) 继承ZuulFilter自定义过滤器

zuul自定义过滤器

下面主要介绍下ZuulFilter类、

public class AccessUserNameFilter extends ZuulFilter {  
    @Override  
    public Object run() {  
        RequestContext ctx = RequestContext.getCurrentContext();  
        HttpServletRequest request = ctx.getRequest();  
  
        System.out.println(String.format("%s AccessUserNameFilter request to %s", request.getMethod(), request.getRequestURL().toString()));  
  
        String username = request.getParameter("username");// 获取请求的参数  
        if(null != username && username.equals("chhliu")) {// 如果请求的参数不为空,且值为chhliu时,则通过  
            ctx.setSendZuulResponse(true);// 对该请求进行路由  
            ctx.setResponseStatusCode(200);  
            ctx.set("isSuccess", true);// 设值,让下一个Filter看到上一个Filter的状态  
            return null;  
        }else{  
            ctx.setSendZuulResponse(false);// 过滤该请求,不对其进行路由  
            ctx.setResponseStatusCode(401);// 返回错误码  
            ctx.setResponseBody("{\"result\":\"username is not correct!\"}");// 返回错误内容  
            ctx.set("isSuccess", false);  
            return null;  
        }  
    }  
 如果前一个过滤器的结果为true,则说明上一个过滤器成功了,需要进入当前的过滤,如果前一个过滤器的结果为false,则说明上一个过滤器没有成功,则无需进行下面的过滤动作了,直接跳过后面的所有过滤器并返回结果  
  
 @Override 
    public boolean shouldFilter() {  
        RequestContext ctx = RequestContext.getCurrentContext();  
        return (boolean) ctx.get("isSuccess");
    }  

优先级为0,数字越大,优先级越低
  
 @Override  
    public int filterOrder() {  
        return 0;  
    }  

 前置过滤器  
 @Override  
    public String filterType() {  
        return "pre";
    }  
}  

filterType:返回一个字符串代表过滤器的类型,在zuul中定义了四种不同生命周期的过滤器类型,具体如下:

pre:可以在请求被路由之前调用
route:在路由请求时候被调用
post:在route和error过滤器之后被调用
error:处理请求时发生错误时被调用

 

SpringCloud中zuul如何使用

  1. 项目配置

  • pom引入依赖

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
    </dependency>
  • @EnableZuulProxy注解

    @EnableZuulProxy
    @SpringBootApplication
    public class App {
        public static void main(String[] args) {
            SpringApplication.run(App.class, args);
        }
    }
  • 配置路由文件

    spring.application.name=zuul-test
    server.port=8080
    
    zuul.routes.test.path=/test/**
    zuul.routes.test.url=http://c.test.com
  1. 服务路由配置详解

  • 指定具体服务路由

    zuul.routes.access.path=/access-name/**

    上述代码将 access 服务的路由地址配置成了 access-name,也就是当需要访问 access中的接口时,我们可以通过 access-name/接口名 来进行。这其实就是将服务名称变成了我们自定义的名称。** 代表匹配多级接口。

  • 路由前缀

    有的时候我们会想在 API 前面配置一个统一的前缀,比如像 http://c.biancheng.net/access/login 这样登录接口,如果想将其变成 http://c.biancheng.net/rest/access/login,即在每个接口前面加一个 rest,此时我们就可以通过 Zuul 中的配置来实现:

      zuul.prefix=/rest
  • 本地跳转

    Zuul 的 API 路由还提供了本地跳转功能,通过 forward 就可以实现。

    zuul.routes.fsh-substitution.path=/api/**
      zuul.routes.fsh-substitution.url=forward:/local

    当我们想在访问 api/1 的时候会路由到本地的 local/1 上去,就可以参照上述代码实现。local 是本地接口需要我们自行添加,因此我们要建一个 Controller,代码如下所示。

    @RestController
    public class LocalController {
        @GetMapping("/local/{id}")
        public String local(@PathVariable String id) {
            return id;
        }
    }
  1. filter过滤器(参考zuul原理中filter使用)

    • 如何使用自定义过滤器
      
    Configuration
      public class FilterConfig {
          @Bean
          public AccessUserNameFilter accessFilter() {
              return new AccessUserNameFilter();
          }
      }
    如何禁用自定义过滤器
  • 有的场景下,我们需要禁用过滤器,此时可以采取下面的两种方式来实现:

    • 利用 shouldFilter 方法中的 return false 让过滤器不再执行
    • 通过配置方式来禁用过滤器,格式为“zuul. 过滤器的类名.过滤器类型 .disable=true”。如果我们需要禁用“使用过滤器”部分中的 AccessUserNameFilter,可以用下面的配置: zuul.AccessUserNameFilter.pre.disable=true

结束

因为zuul2.0连续跳票和zuul1的性能表现不是很理想,所以催生了spring团队开发了Gateway项目。下篇介绍Spring cloud gateway

欢迎关注公众号! 公众号回复:入群 ,扫码加入我们交流群

 

 

 

标签:网关,zuul,请求,ctx,过滤器,搞懂,快速,public,路由
来源: https://www.cnblogs.com/LemonTree-123/p/14649415.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有