SpringCloud(Zuul) 阳光穿透心脏的1/2处 2021-11-14 15:08 442阅读 0赞 *主要收集、整理Zuul相关的知识点,并加以自己的实践理解* ### 目录结构 ### * 1 什么是API网关 * 2 什么是Zuul * 3 Zuul的核心 * 4 Zuul中默认实现的Filter * 5 搭建SpringCloud Zuul * * 5.1 maven依赖 * 5.2 启动类中开启Zuul服务 * 5.3 配置文件 * 5.4 自定义Filter * 5.5 Zuul的路由规则 * 5.6 忽略某个不想对外提供的服务 * 5.7 路由通配符含义 * 6 Zuul和Nginx哪家强 # 1 什么是API网关 # * 网关这种东西,是伴随着微服务风生水起的,微服务可以没有api网关,但是最好有,也并不是绝对的。因为有这个东西是合理的,没有的话,你的微服务会很难受。 * 首先网关最基础的作用就是对外包括ios、android、webapp、website、h5、微信小程序甚至是第三方提供一个统一服务接入入口。聚合内网众多微服务,为端上提供统一的api入口。对外统一使-用http协议,网关屏蔽了后端协议的差异性,后端可以专注于提供服务,无需考虑协议的转换。 * 其次,网关应该具备API防刷以及限流的功能。防刷可以保护你的API不会被恶意调用,限流可以保护你的后端不会被冲垮。网关应该还具备权鉴功能,是否具备对某个api的访问功能,应该做在api网关层会好很多。保护后端服务,提供完善的流控、服务降级、ACL、鉴权机制。 * 提供API管理平台,包括API的配置、沙箱测试、发布、修改、下线。 * 提供API层面的监控与报表,做到对业务自身的掌控,以及对用户行为等进行分析。为开放平台的持续完善提供基础服务。 * 它可以为不同类型的客户端定义不同的api: ![在这里插入图片描述][aHR0cHM6Ly9taWNyb3NlcnZpY2VzLmlvL2kvYmZmZS5wbmc] # 2 什么是Zuul # * Zuul是Spring Cloud全家桶中的微服务API网关。所有从设备或网站来的请求都会经过Zuul到达后端的Netflix应用程序。作为一个边界性质的应用程序,Zuul提供了动态路由、监控、弹性负载和安全功能。Zuul底层利用各种filter实现如下功能: 1) 认证和安全 识别每个需要认证的资源,拒绝不符合要求的请求。 2) 性能监测 在服务边界追踪并统计数据,提供精确的生产视图。 3) 动态路由 根据需要将请求动态路由到后端集群。 4) 压力测试 逐渐增加对集群的流量以了解其性能。 5) 负载卸载 预先为每种类型的请求分配容量,当请求超过容量时自动丢弃。 6) 静态资源处理 直接在边界返回某些响应。 # 3 Zuul的核心 # Filter是Zuul的核心,用来实现对外服务的控制。Filter的生命周期有4个,分别是“PRE”、“ROUTING”、“POST”、“ERROR”,整个生命周期可以用下图来表示。 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2hqbDAyMQ_size_16_color_FFFFFF_t_70] **Zuul大部分功能都是通过过滤器来实现的,这些过滤器类型对应于请求的典型生命周期。** * **PRE**: 这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。这个阶段后如果有自定义的过滤器,则会执行自定义的过滤器。 * **ROUTING**:这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服务的请求,并使用Apache HttpClient或Netfilx Ribbon请求微服务。 * **ERROR**:在其他阶段发生错误时执行该过滤器。 除了默认的过滤器类型,Zuul还允许我们创建自定义的过滤器类型。例如,我们可以定制一种STATIC类型的过滤器,直接在Zuul中生成响应,而不将请求转发到后端的微服务。 * **POST**:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。 # 4 Zuul中默认实现的Filter # <table> <thead> <tr> <th>类型</th> <th>顺序</th> <th>过滤器</th> <th>功能</th> </tr> </thead> <tbody> <tr> <td>pre</td> <td>-3</td> <td>ServletDetectionFilter</td> <td>标记处理Servlet的类型</td> </tr> <tr> <td>pre</td> <td>-2</td> <td>Servlet30WrapperFilter</td> <td>包装HttpServletRequest请求</td> </tr> <tr> <td>pre</td> <td>-1</td> <td>FormBodyWrapperFilter</td> <td>包装请求体</td> </tr> <tr> <td>route</td> <td>1</td> <td>DebugFilter</td> <td>标记调试标志</td> </tr> <tr> <td>route</td> <td>5</td> <td>PreDecorationFilter</td> <td>处理请求上下文供后续使用</td> </tr> <tr> <td>route</td> <td>10</td> <td>RibbonRoutingFilter</td> <td>serviceId请求转发</td> </tr> <tr> <td>route</td> <td>100</td> <td>SimpleHostRoutingFilter</td> <td>url请求转发</td> </tr> <tr> <td>route</td> <td>500</td> <td>SendForwardFilter</td> <td>forward请求转发</td> </tr> <tr> <td>post</td> <td>0</td> <td>SendErrorFilter</td> <td>处理有错误的请求响应</td> </tr> <tr> <td>post</td> <td>1000</td> <td>SendResponseFilter</td> <td>处理正常的请求响应</td> </tr> </tbody> </table> # 5 搭建SpringCloud Zuul # ## 5.1 maven依赖 ## <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> <version>2.1.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> <version>2.1.2.RELEASE</version> </dependency> ## 5.2 启动类中开启Zuul服务 ## package com.kinglong.springcloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.zuul.EnableZuulProxy; @SpringBootApplication @EnableZuulProxy//开启zuul public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ## 5.3 配置文件 ## server.port=8091 #服务名 spring.application.name=06-springcloud-api-gateway #自定义路由 zuul.routes.api-kinglong.path=/api-kinglong/** #负载均衡的服务名 zuul.routes.api-kinglong.service-id=05-springcloud-service-feign #eureka服务注册地址 eureka.client.service-url.defaultZone=http://eureka8085:8085/eureka/,http://eureka8086:8086/eureka/ 以上就可以直接启动了,这就是最简版的Zuul,他只是起到了对请求的转发作用。 ## 5.4 自定义Filter ## 实现自定义Filter,需要继承ZuulFilter的类,并覆盖其中的4个方法。 package com.kinglong.springcloud.filter; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.exception.ZuulException; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; /** * 自定义Filter * * @author haojinlong */ @Component //加了注解后可以让这个过滤器注入到spring中,变为一个bean public class AuthFilter extends ZuulFilter { /** * 返回值为过滤器的类型,过滤器的类型决定了过滤器在哪个生命周期执行, * pre标识在任意路由之前执行过滤器,其他值还有post,error,route和static,也可以自定义 * * @return */ @Override public String filterType() { return "pre"; } /** * 表示过滤器的执行顺序,当过滤器很多时,可以通过该方法返回值指定过滤器的执行顺序 * * @return */ @Override public int filterOrder() { return 0; } /** * 判断过滤器是否执行,true表示执行,false表示不执行 * * @return */ @Override public boolean shouldFilter() { return true; } /** * 具体逻辑 * 如果请求地址中携带了token参数,则认为是合法的请求,如果不是则为非法请求。当然还是要根据具体业务场景做相应的处理。 * 这里只是实验功能 * @return * @throws ZuulException */ @Override public Object run() throws ZuulException { RequestContext context = RequestContext.getCurrentContext(); HttpServletRequest request = context.getRequest(); String token = request.getParameter("token"); if(null == token){ context.setSendZuulResponse(false); context.setResponseStatusCode(401); context.addZuulResponseHeader("content-type", "text/html;charset=utf-8"); context.setResponseBody("无权限访问"); } return null; } } **有了第四步之后,再如第三步一样不带token访问就无法访问了,会被拦截出去。** ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2hqbDAyMQ_size_16_color_FFFFFF_t_70 1] ## 5.5 Zuul的路由规则 ## 配置文件中的两个路由配置其实是可以简写,合并成一个配置,如下: * 原先的路由配置 #自定义路由 zuul.routes.api-kinglong.path=/api-kinglong/** #负载均衡的服务名 zuul.routes.api-kinglong.service-id=05-springcloud-service-feign * 简写后的 zuul.routes.05-springcloud-service-feign=/api-kinglong/** ## 5.6 忽略某个不想对外提供的服务 ## 默认情况下,eureka上所有注册的服务都会被Zuul创建映射关系来进行路由,但是业务场景可能只需要让feign来集中提供服务,而那些底层的服务提供者的服务是不想对外开放的。这时就需要采用一些配置,使其忽略那些不想对外提供服务的路由 #忽略掉服务提供者,如果有多个,可以用逗号隔开即可 zuul.ignored-services=01-springcloud-service-provider 也可以更加精确地具体到某个接口 #忽略掉某个接口 zuul.ignored-patterns=/**/hello/** 还可以统一的为路由增加前缀 zuul.prefix=/myapi ## 5.7 路由通配符含义 ## <table> <thead> <tr> <th>通配符</th> <th>含义</th> <th>举例</th> <th>说明</th> </tr> </thead> <tbody> <tr> <td>?</td> <td>匹配任意单个字符</td> <td>/05-springcloud-service-feign</td> <td>匹配:/05-springcloud-service-feign/a,/05-springcloud-service-feign/b等</td> </tr> <tr> <td>*</td> <td>匹配任意数量的字符</td> <td>/05-springcloud-service-feign/*</td> <td>匹配:/05-springcloud-service-feign/aaaa,/05-springcloud-service-feign/bbbb等,但是不可以匹配:/05-springcloud-service-feign/bb/oo/hhh</td> </tr> <tr> <td>**</td> <td>匹配任意单个字符</td> <td>/05-springcloud-service-feign/**</td> <td>匹配:/05-springcloud-service-feign/a/r/ddd,/05-springcloud-service-feign/b/d/f等</td> </tr> </tbody> </table> # 6 Zuul和Nginx哪家强 # 有人已经做了相关测试 > [https://blog.csdn.net/zhangbijun1230/article/details/81660834][https_blog.csdn.net_zhangbijun1230_article_details_81660834] > (基于zuul1测试)最后的结论:因为zuul是java开发的,所以服务器硬件配置对性能影响很大,在8核32G的配置上,Zuul才跑赢了Nginx。 > [https://www.2cto.com/kf/201805/746203.html][https_www.2cto.com_kf_201805_746203.html] > (基于zuul2测试,zuul2采用的是netty开发)性能和nginx相差不大,基本一致。 Zuul的原始性能接近Nginx。事实上,在启动预热之后,显示测试结果更好一些。但Nginx看上去会稳定一下,Zuul出现了2次的请求错误。 如果你想使用Zuul的其他功能,或者希望通过它与其他的Netflix服务集成(比如Eureka),Zuul可以作为其他简单反向代理的替代品。 文献参考来源: > [https://blog.csdn.net/u011820505/article/details/79373594][https_blog.csdn.net_u011820505_article_details_79373594] > [https://microservices.io/patterns/apigateway.html][https_microservices.io_patterns_apigateway.html] > [https://blog.csdn.net/qq\_27384769/article/details/82991261][https_blog.csdn.net_qq_27384769_article_details_82991261] [aHR0cHM6Ly9taWNyb3NlcnZpY2VzLmlvL2kvYmZmZS5wbmc]: /images/20211114/bde2768136d14332b7d774f8b8744855.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2hqbDAyMQ_size_16_color_FFFFFF_t_70]: /images/20211114/9cb8effd491f44149c8ca206428d4da9.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2hqbDAyMQ_size_16_color_FFFFFF_t_70 1]: /images/20211114/b37260abf2bf49718eddc87a51ffa990.png [https_blog.csdn.net_zhangbijun1230_article_details_81660834]: https://blog.csdn.net/zhangbijun1230/article/details/81660834 [https_www.2cto.com_kf_201805_746203.html]: https://www.2cto.com/kf/201805/746203.html [https_blog.csdn.net_u011820505_article_details_79373594]: https://blog.csdn.net/u011820505/article/details/79373594 [https_microservices.io_patterns_apigateway.html]: https://microservices.io/patterns/apigateway.html [https_blog.csdn.net_qq_27384769_article_details_82991261]: https://blog.csdn.net/qq_27384769/article/details/82991261
相关 深入了解实践应用SpringCloudZuul过滤器(拦截器) 转载:[深入了解实践应用SpringCloudZuul过滤器(拦截器)][SpringCloudZuul] 之前我写过一篇文章[Spring Cloud Zuul(路由转发与 清疚/ 2022年12月11日 01:30/ 0 赞/ 217 阅读
相关 API网关服务SpringCloudZuul API网关服务SpringCloudZuul 文章目录 API网关服务SpringCloudZuul 快速入门 布满荆棘的人生/ 2022年05月08日 05:52/ 0 赞/ 285 阅读
还没有评论,来说两句吧...