Zuul路由管理实践

Zuul Routing Management in Practice

Posted by     "杨波" on Tuesday, July 10, 2018

TOC

介绍

网关的核心功能之一是路由转发,为此,网关需要获取并维护一张路由表,这个路由表简单可以理解为一个服务名<>服务地址的映射表,有了这张路由表,网关就可以根据请求路径或者HTTP头中的服务信息,将请求转发到对应的目标服务地址。

Zuul[附录1]是Netflix开源的微服务网关,在Netflix经过大规模生产级验证,最新的数据表明Netflix每天有近千亿级流量要经过Zuul网关。另外,Zuul也是Spring Cloud全家桶的核心组件。本文介绍Zuul网关路由管理的一些常用方案,可供准备在生产环境使用Zuul的企业参考。

方案一,基于Eureka自发现

eureka discovery

这个也是Netflix的做法,Zuul网关借助Eureka[附录2]服务注册中心获取路由表,简述步骤如下:

  1. 内部微服务(前端聚合服务或者后台基础服务)启动时,自动注册到Eureka服务注册中心,并定期向注册中心报心跳,表明自己的存活状态。例如,上图中,svcx在Eureka上有一组对应的ip:port对,表示svc服务对应的存活服务实例地址列表。
  2. Zuul网关集成Ribbon[附录3]客户端,Ribbon能够从Eureka上自动发现并定期获取服务的实例地址信息,并进行本地缓存。
  3. 当Zuul网关接收到外部请求,它根据某种规则从请求中获取服务名,例如,假设第一级path就是服务名,那么api.xxx.com/svcx中的svcx就是服务名。解析获取服务名后,Zuul将服务名传给Ribbon,Ribbon通过查找缓存的路由表获取服务实例地址列表,再根据某种路由策略(例如,随机或者RoundRobin等),选择一个目标实例地址发起调用。

该方法相对简单,部署Eureka服务注册中心即可实现。同时也比较灵活,内部服务可以自注册自发现,研发人员可以自助完成服务上下线,更贴合DevOps研发模式,不太需要运维配合介入。

该方案的问题是,目前很多企业内部还有很多历史遗留服务,这些服务基本上还是基于传统域名进行管理的,如果升级到Eureka的自注册自发现方式,迁移和改造成本不小。

方案二,基于服务治理中心和域名做法

dns discovery

对于内部遗留系统较多,服务主要基于传统域名方式管理,暂时还不具备条件采用上述第一种方案的企业,可以采用基于服务治理中心+域名的做法,如上图所示。

该方案需要开发一套服务治理中心,用来集中管理路由等服务元数据信息,同时企业内部需要DNS域名服务支持。采用该方案的流程简述如下:

  1. 研发人员通过运维申请部署服务所需的机器,ip和内部域名等相关信息,完成服务开发和部署,通过内部域名测试服务正常。
  2. 研发人员通过服务治理中心注册服务,提供相应的服务名和域名信息,也提供一些额外的元数据信息,如该服务对哪些网关可见(即要通过哪些网关将该服务暴露出去),该服务目前是否在生产环境可访问(是否已经过QA流程升级到生产环境)。
  3. Zuul网关定期从服务治理中心拉取服务路由表(注意,这里只需要拉取对该网关可见的路由表,例如无线网关只拉取对无线网关可见的服务,不需要拉取全部路由表),并缓存在本地内存。
  4. 当Zuul网关接收到外部请求,它根据某种规则从请求中解析出服务名,再通过查询内存中的路由表找到目标服务的内部域名,最后对目标域名发起调用。通过域名调用时,底层HTTP客户端会自动通过DNS服务解析并获取对应的ip地址。注意,在实际场景中,这里解析到的ip一般是一个vip,真实的服务实例一般躲在一个内部的负载均衡器LB(例如F5+nginx)后面,这个vip指向LB,LB会对后台服务做负载均衡和转发。

该方案复杂度适中,内部的域名和负载均衡系统一般由运维支持,服务治理中心的研发门槛和成本不高,基本上就是一个简单的数据库应用。该方案的灵活性和自动化程度没有第一种方案好,需要一些人工配置,但是可以在运维和服务治理中心层面按需增加一些治理环节,可治理性会更好一点。

方案三,基于配置中心Apollo和域名做法

discovery apollo

对于一些初创公司,刚开始什么都缺的情况下,最简单的路由管理的方式就是直接把路由配置在Zuul网关的本地配置文件中。但是这种做法很不灵活,每次修改路由都需要重启网关集群。所有建议可以部署一套配置中心,例如Apollo,把路由信息简单配置在Apollo配置中心中,然后让网关定期从Apollo获取路由配置并做本地缓存,该方案如上图所示。

Apollo支持XML格式的配置,下面是一个路由配置案例:

<zuul_route>
  <svc_route>
    <name>svc1</name>
    <endpoint>192.168.100.1:8080</endpoint>
    <endpoint>192.168.100.2:8080</endpoint>
    <endpoint>192.168.100.3:8080</endpoint>      
  </svc_route>
  <svc_route>
    <name>svc2</name>
    <endpoint>192.168.101.1:8080</endpoint>
    <endpoint>192.168.101.2:8080</endpoint>
    <endpoint>192.168.101.3:8080</endpoint>      
  </svc_route>
</zuul_route>

结论

  1. 路由转发是网关的核心功能,为此网关需要维护和管理一张路由表,常见做法有基于Eureka自发现,基于服务治理中心和域名,或者最简单的基于配置中心。
  2. 波波在极客时间的课程《微服务架构和实践160讲》,马上上线第三模块《微服务网关Zuul架构和实践》,会对Zuul网关的架构、源码和生产实践等内容进行深度剖析,欢迎关注。

附录

  1. Zuul
  2. Eureka
  3. Ribbon

comments powered by Disqus