我们使用Eureka实现了服务注册中心来服务注册与发现。为了方便统一配置文件的集中化管理我们使用ConfigServer。而服务间通过Ribbon或Feign实现服务的消费以及均衡负载。为了使服务集群更为健壮,使用Hystrix的熔断机制来避免在微服务架构中个别服务出现异常时引起的故障蔓延。

在以上架构设计中,我们的所有服务都注册到注册中心直接对外暴露使用,这样设计是否合理?(能不能加上一个权限和路由的管理功能?)或者说有没有更好的实现方式呢?

一、什么是Zuul?

为了解决上面这些问题,我们需要将权限控制等这样的东西从我们的服务单元中抽离出去,而最适合这些逻辑的地方就是处于对外访问最前端的地方,我们需要一个更强大一些的均衡负载器的服务网关

服务网关是微服务架构中一个不可或缺的部分。通过服务网关统一向外系统提供REST API的过程中,除了具备服务路由、均衡负载功能之外,它还具备了权限控制等功能。Spring Cloud Netflix中的Zuul就担任了这样的一个角色,为微服务架构提供了前门保护的作用,同时将权限控制这些较重的非业务逻辑内容迁移到服务路由层面,使得服务集群主体能够具备更高的可复用性和可测试性。

我们来看一下官方介绍:

下面简单画了一个zuul加入后的架构图

这样

不管是来自于客户端(PC或移动端)的请求,还是服务内部调用。一切对服务的请求都会经过Zuul这个网关,然后再由网关来实现 鉴权、动态路由等等操作。Zuul就是我们服务的统一入口。

二、快速入门

1.导入zuul依赖

  <dependency>      <groupId>org.springframework.cloudgroupId>      <artifactId>spring-cloud-starter-netflix-zuulartifactId>  dependency>

2.pom文件编写路由配置

server:  port: 10010 # 端口spring:  application:    name: api-gateway # 应用名称,会在Eureka中显示eureka:  client:    service-url:      defaultZone: http://127.0.0.1:8081/eurekazuul:  routes:    service-provider: # 这里是路由id,随意写      path: /service-provider/** # 这里是映射路径#      url: http://127.0.0.1:8001 # 映射路径对应的实际url地址      serviceId: service-provider # 指定服务名称
  • 如果不使用注册中心,我们可以直接通过url访问具体服务路径

  • 因为已经有了Eureka客户端,我们可以从Eureka获取服务的地址信息,因此映射时无需指定IP地址,而是通过服务名称来访问,而且Zuul已经集成了Ribbon的负载均衡功能。

3.启动类

@SpringBootApplication@EnableZuulProxy    //开启Zuul网关功能public class GatewayApp {    public static void main(String[] args) {        SpringApplication.run(GatewayApp.class,args);    }}

4.启动测试,会利用Ribbon进行负载均衡访问

日志中可以看到使用了负载均衡器

5.简化路由配置

在刚才的配置中,我们的规则是这样的:

  • zuul.routes..path=/xxx/**:来指定映射路径。是自定义的路由名。

  • zuul.routes..serviceId=service-provider:来指定服务名。

而大多数情况下,我们的路由名称往往和服务名会写成一样的。因此Zuul就提供了一种简化的配置语法:zuul.routes.=

比方说上面我们关于service-provider的配置可以简化为一条:

zuul:  routes:    service-provider: /service-provider/** # 这里是映射路径

6.默认路由配置

在使用Zuul的过程中,上面讲述的规则已经大大的简化了配置项。但是当服务较多时,配置也是比较繁琐的。因此Zuul就指定了默认的路由规则:

  • 默认情况下,一切服务的映射路径就是服务名本身。例如服务名为:service-provider,则默认的映射路径就 是:/service-provider/**

也就是说,刚才的映射规则我们完全不配置也是OK的。

7.路由前缀

zuul:  routes:    service-provider: /service-provider/**  prefix: /gateway
  • 我们通过zuul.prefix=/gateway来指定了路由的前缀,这样在发起请求时,路径就要以/gateway开头。

三、过滤器使用

Zuul作为网关的其中一个重要功能,就是实现请求的鉴权。而这个动作我们往往是通过Zuul提供的过滤器来实现的。

1.ZuulFilter

ZuulFilter是过滤器的顶级父类。看一下其中定义的4个最重要的方法:

public abstract ZuulFilter implements IZuulFilter{    abstract public String filterType();    abstract public int filterOrder();    boolean shouldFilter();// 来自IZuulFilter    Object run() throws ZuulException;// 来自IZuulFilter}

  • shouldFilter:返回一个Boolean值,判断该过滤器是否需要执行。返回true执行,返回false不执行。

  • run:过滤器的具体业务逻辑。

  • filterType:返回字符串,代表过滤器的类型。包含以下4种:

    • pre:请求在被路由之前执行

    • route:在路由请求时调用

    • post:在route和errror过滤器之后调用

    • error:处理请求时发生错误调用

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

2.过滤器执行生命周期

Zuul官网提供的请求生命周期图,清晰的表现了一个请求在各个过滤器的执行顺序。

正常流程:

  • 请求到达首先会经过pre类型过滤器,而后到达route类型,进行路由,请求就到达真正的服务提供者,执行请求,返回结果后,会到达post过滤器。而后返回响应。

异常流程:

  • 整个过程中,pre或者route过滤器出现异常,都会直接进入error过滤器,在error处理完毕后,会将请求交给post过滤器,最后返回给用户。

  • 如果是error过滤器自己出现异常,最终也会进入post过滤器,将最终结果返回给请求客户端。

  • 如果是post过滤器出现异常,会跳转到error过滤器,但是与pre和route不同的是,请求不会再到达post过滤器了。

使用场景

  • 请求鉴权:一般放在pre类型,如果发现没有访问权限,直接就拦截了

  • 异常处理:一般会在error类型和post类型过滤器中结合来处理。

  • 服务调用时长统计:pre和post结合使用。

3.自定义过滤器

接下来我们来自定义一个过滤器,模拟一个登录的校验。基本逻辑:如果请求中有access-token参数,则认为请求有效,放行。

@Componentpublic class LoginFilter extends ZuulFilter {    /**     * 过滤器类型,前置过滤器     *     * @return     */    public String filterType() {        return "pre";    }    /**     * 过滤器的执行顺序     *     * @return     */    public int filterOrder() {        return 1;    }    /**     * 该过滤器是否生效     *     * @return     */    public boolean shouldFilter() {        return true;    }    /**     * 登陆校验逻辑     *     * @return     * @throws ZuulException     */    public Object run() throws ZuulException {        // 获取zuul提供的上下文对象        RequestContext context = RequestContext.getCurrentContext();        // 从上下文对象中获取请求对象        HttpServletRequest request = context.getRequest();        // 获取token信息        String token = request.getParameter("access-token");        // 判断        if (StringUtils.isBlank(token)) {            // 过滤该请求,不对其进行路由            context.setSendZuulResponse(false);            // 设置响应状态码,401            context.setResponseStatusCode(HttpStatus.SC_UNAUTHORIZED);            // 设置响应信息            context.setResponseBody("{\"status\":\"401\", \"text\":\"request error!\"}");        }        // 校验通过,把登陆信息放入上下文信息,继续向后执行        context.set("token", token);        return null;    }}

测试,没有token参数,请求失败!

测试,有token参数,请求成功!

4.负载均衡和熔断

Zuul中默认就已经集成了Ribbon负载均衡和Hystix熔断机制。但是所有的超时策略都是走的默认值,比如熔断超时时间只有1S,很容易就触发了。因此建议我们手动进行配置:

zuul:  retryable: true   #是否开启重试功能   ribbon:  ConnectTimeout: 250 # 连接超时时间(ms)  ReadTimeout: 2000 # 通信超时时间(ms)  OkToRetryOnAllOperations: true # 是否对所有操作重试  MaxAutoRetriesNextServer: 2 # 同一服务不同实例的重试次数  MaxAutoRetries: 1 # 同一实例的重试次数hystrix:  command:    default:      execution:        isolation:          thread:            timeoutInMilliseconds: 6000 #设置hystrix的超时时间为6000ms

如果您觉得本文对你有帮助,欢迎老铁们帮忙点赞、关注、留言、分享你们的支持是我原创最大的动力

往期精选

SpringCloud配置中心的使用

SpringCloud-Eureka高可用搭建

SpringCloud-Ribbon负载均衡

SpringCloud-Feign远程调用

SpringCloud-Hystrix解决雪崩

Nacos入门案例

Mybatis动态SQL

默认网关出现乱码_SpringCloudZuul服务网关相关推荐

  1. 微服务之间调用经过网关吗_微服务网关入门

    一.什么是服务网关服务网关 = 路由转发 + 过滤器 1.路由转发:接收一切外界请求,转发到后端的微服务上去: 2.过滤器:在服务网关中可以完成一系列的横切功能,例如权限校验.限流以及监控等,这些都可 ...

  2. 什么是服务网关?为什么需要服务网关?如何选择服务网关?

    一.什么是服务网关 服务网关 = 路由转发 + 过滤器 1.路由转发:接收一切外界请求,转发到后端的微服务上去: 2.过滤器:在服务网关中可以完成一系列的横切功能,例如权限校验.限流以及监控等, 这些 ...

  3. Spring Cloud(六)服务网关 zuul 快速入门

    服务网关是微服务架构中一个不可或缺的部分.通过服务网关统一向外系统提供REST API的过程中,除了具备服务路由.均衡负载功能之外,它还具备了权限控制等功能.Spring Cloud Netflix中 ...

  4. 《深入理解 Spring Cloud 与微服务构建》第十一章 服务网关

    <深入理解 Spring Cloud 与微服务构建>第十一章 服务网关 文章目录 <深入理解 Spring Cloud 与微服务构建>第十一章 服务网关 一.服务网关简介 二. ...

  5. Spring Cloud版——电影售票系统七使用 Zuul 构建微服务网关

    2019独角兽企业重金招聘Python工程师标准>>> GitHub地址:https://github.com/leebingbin/SpringCloud.MovieTicketi ...

  6. Zuul微服务网关、容错与监控、Zuul路由端点、路由配置、Zuul上传文件、Zuul过滤器、Zuul异常处理、Zuul回退、Zuul聚合微服务

    一.为什么要使用微服务网关 二.Zuul 1.编写Zuul微服务网关 2.Zuul的Hystrix容错与监控 3.Zuul的路由端点 4.路由配置 1.自定义指定微服务的访问路径 2.忽略指定微服务 ...

  7. 微服务网关GateWay 过滤+路由+限流

    文章目录 1 微服务网关概述 2 微服务网关微服务搭建 3 微服务网关跨域 4 微服务网关过滤器 5 微服务网关限流 5.1 思路分析 5.2 令牌桶算法 5.3 网关限流代码实现 1 微服务网关概述 ...

  8. 你的微服务网关还只在用负载均衡吗?

    随着业务场景日益复杂,我们经常采用微服务架构来进行松耦合,但由于系统和服务的细分,导致系统结构变得非常复杂,微服务网关作为分散在各个业务系统微服务的API聚合点和统一接入点,需要担负整个流量管控的职责 ...

  9. 微服务架构-服务注册中心和服务网关(6.8) (转载)

    原文链接:微服务架构-服务注册中心和服务网关(6.8) 这篇文章还是基于SpringCloud开源框架体系来谈下对Eureka服务注册中心和Zuul服务网关在使用上的一些理解和说明.在使用微服务架构进 ...

最新文章

  1. EK算法网络流模板hdu1532
  2. 用深度神经网络搭建马赛克神器,高清无码效果感人
  3. vc连接数据库,对数据的基本操作
  4. html滑动直播,HTML5 canvas实现的静态循环滚动播放弹幕
  5. oracle安装清单过不去,oracle 11g(二)安装过程
  6. python中的time库安装步骤-python中time库的使用
  7. BZOJ3627 [JLOI2014]路径规划
  8. H - 拦截导弹 OpenJ_Bailian - 2945(dp动态规划)
  9. input眼睛显示 vue_2019前端面试题汇总(主要为Vue)
  10. ggplot2 多个柱状图比较_15. 再论ggplot2作图的图形元素组成
  11. Tomcat安装与卸载
  12. java multipy_用pytorch进行多变量线性回归
  13. 奥运五环(一键复制)
  14. java 仿易企秀_鲁班H5(开源可视化搭建系统, 可以理解为开源版本易企秀)核心实现原理解析...
  15. Kubernetes应用场景
  16. 阿里经济体大数据平台的建设与思考
  17. [node]nvs使用的注意事项
  18. JavaScript-IIFE
  19. OMCI协议二层功能的模型选择
  20. python+HTMLTable,生成html表格

热门文章

  1. 利用OLAMI在unity游戏中加入中文语音控制(一)
  2. wgs84坐标系转换工具_ArcGIS中不同坐标系之间的转换
  3. 罗永浩:因为要烧投资人的钱 所以没有勇气再做手机了
  4. 罗永浩从交个朋友拿走“天价”分手费?将进军AR行业:创业三部曲之三即将开拍...
  5. 华为nova 9 SE真机曝光:旗下首款一亿像素主摄 双环镜头吸睛
  6. 腾讯网易禁止未成年人本周六玩游戏
  7. 特斯拉:国内超级充电桩已超6000个
  8. 蛋壳公寓回应破产传闻:没有破产 也不会跑路
  9. 巴菲特将退休并把公司交给网红接管?被一封信恶搞...
  10. 估值150亿,账上还有近10亿现金,却减员500人,这家公司CEO的说法你认同吗?...