微服务API 网关的设计及应用
廖俊杰,陶智勇
(武汉邮电科学研究院,湖北武汉430074)
摘
要:随着微服务架构的广泛传播与应用,微服务网关的重要性得以逐渐显现出来,所有的客户端和消费端都通过统一的网关接
入微服务。为此,定制化的设计实现了一个基于Zuul 的微服务API 网关,并基于此API 网关构建了一个企业知识管理的微服务系统。企业知识管理系统的微服务化,业务服务经由统一API 网关封装,解决了系统权限控制代码冗余、结构复杂、模块高耦合、标准不一等问题,为系统的低耦合、高扩展、易维护提供了稳妥的解决方案。
关键词:微服务架构;API 网关;Spring Cloud Zuul;知识管理系统中图分类号:TP311.5
文献标志码:A
文章编号:1003-7241(2019)08-0085-04
Research and Implementation of Microservice API Gateway
LIAO Jun -jie,TAO Zhi -yong
(Wuhan Research Institute of Posts and Telecommunications,Wuhan 430074China )
Abstract:With the wide spread and application of the micro-service architecture,the importance of the micro-service gateway gradu-ally emerges.All clients and consumers access the micro-service through a unified gateway.To this end,the customized design implements a Zuul-based microservice API gateway,and based on this API gateway,builds an enterprise knowl-edge management microservice system.The micro-service of the enterprise knowledge management system and the busi-ness service are encapsulated by the unified API gateway,which solves the problems of system authority control code re-dundancy,complex structure,high module coupling,and different standards.It provides a stable solution for low coupling,high expansion and easy maintenance of the system.
Key words:microservice architecture;API gateway;Spring Cloud Zuul;knowledge management system
收稿日期:2018-07-20
1引言
微服务架构系统中,需要一个API 网关来承担系统门面的工作,以过滤和调度来自外部的访问请求[1]。微服务网关具备路由、均衡负载、鉴权过滤等核心功能,并能整合服务治理、请求转发熔断机制、服务聚合等功能来优化系统[2]。本文实现的服务网关向客户端统一提供REST API 接口,便于各系统的集成,为整个微服务架构系统的入口提供可靠保护,同时将多个子服务应用的权限控制统一转移到微服务网关,降低校验逻辑的分散冗余,把非业务逻辑内容迁移到服务路由,简化了通用逻辑模块的复用,便于开发和维护,对系统进行极大的优化,并降低了开发和运维成本[3]。
2Spring Cloud Zuul 关键技术
Zuul 是一个开源的微服务网关模块,由Netflix 设计,它的底层是基于Java 虚拟机的路由器和服务器端负载均衡器来实现的。在实际工程中往往配合服务注册中心Eureka,负载均衡器Ribbon 以及断路器Hystrix 等组件同时使用[4]。Zuul 的底层设计决定了其拥有路由和过滤器的性质。Zuul 引入了Ribbon 模块,二者整合后共同实现服务器端的负载均衡。一系列过滤器组合构成了Zuul 核心,利用其核心,Zuul 可以实现以下功能[5]:
(1)验证:每接收到一个访问请求后,对比资源的验证条件,然后根据条件进行拒绝或者通过访问。
(2)审查及监控:边缘区域上统计数据,这些数据有利于得出更为精准的生产状态总结。
(3)动态路由:动态的自动建立和更新路由表,根据实际情况将请求正确的转发到后端。
85
Techniques of Automation &Applications
(4)压力测试:按一定规模增加集群的并发访问量,并以此估计系统性能。
(5)负载分配:根据需求为不同负载类型提供确定的容量,所有请求都必须在值,否则该请求将会被弃用。
(6)主动流量管理:从路径、客户端IP 地址和用户这几个方面来主动配置限流,也可以多类型结合。
(7)静态响应处理:部分响应发生在边缘位置上,可以有效避免转发至系统后端服务集群。
Zuul 的核心是由多个过滤器组合而成,这是一个多功能的过滤器框架,通过过滤器完成了路由、反向代理、ddos 预防以及日志等功能[6]。
3Zuul 微服务API 网关的实现
需要对Zuul 进行定制化的二次开发与配置来实现微服务API 网关的服务路由、负载均衡、请求过滤等必要或者扩展功能。系统整合Zuul 网关后,简略架构图如下(图1)所示:
图1微服务系统整合Zuul 网关图Zuul 网关将作为所有请求进入后台的入口,服务细节也均被包装了,客户端只需要和网关进行交互,网关通过Ribbon 实现服务的负载均衡调用,各内部服务通过Feign 实现服务间的相互调用。下面是Zuul 微服务网关的实现过程。
3.1构建网关
首先需要构建起最基本的API 网关服务,这里用一
个Spring Boot 工程来搭建Zuul 微服务网关,然后在刚搭建的项目pom.xml 文件里添加Zuul 依赖spring-cloud-starter-zuul [7]。引用如下:
在这个引用的模块中,除了包含Spring Cloud Zuul 的必要核心依赖zuul-core,还带有以下几个重要的网关所需依赖:
(1)spring-cloud-starter-hystrix:提供熔断机制,在微服务做转发时提供保护功能,主要方式是使用线程隔离和断路器,防止某个微服务的故障导致级联服务也出现故障,有效的阻止了系统服务的雪崩效应。
(2)spring-cloud-starter-ribbon:可提供多种负载均衡策略,为路由转发提供负载均衡功能,还提供了请求重试的功能。
(3)spring-cloud-starter-actuator:提供常规微服务管理端点,集成了服务的自省和监控功能,可以利用/health 请求检查应用的工作状况,Spring Cloud 中的服务治理中心常用该端点返回所注册服务应用的健康状态。可以利用/routes端点可以返回当前的所有路由规则。
引入依赖后,还需在网关服务应用工程的启动类加上@EnableZuulProxy 注解,整合Zuul 的代理功能,该类代码添加了ZuulProxyConfiguration 注解。再跟踪这个注解的类,发现该类注入了与实现负载均衡功能相关的DiscoveryClient 以及RibbonCommandFactoryConfig-uration,该类同时也注入了一系列的过滤器,有一些比较常用,比如PreDecorationFilter、RibbonRoutingFilter、Simple-HostRoutingFilter 等。
最后要在配置文件applicationp.properties 中配置Zuul 网关服务模块的应用名、服务端口、服务注册中心地
址(也可以给出配置中心的地址,将除应用名之外的配置信息放在搭建好的配置中心)等基本信息,例如:
spring.application.name=api-gateway server.port=5556
以上便可利用Zuul 实现一个基础的API 网关服务。
3.2服务路由配置
在成功搭建一个基础API 网关服务后,我们需要为
其增加请求路由的功能。首先要提到的是一种传统的路由配置方式。传统路由配置方式没有Eureka 和Consul 的服务治理框架的帮助,不能依赖于服务发现机制。具体做法是在配置文件中指定每个路由表达式与服务实例的映射关系来实现API 网关对外部请求的路由。这种方式在实际中分为单实例和多实例配置,单实例是zuul.routes. 一对 86 这里采用更好的解决方案,用面向服务的方式来进行路由配置,Spring Cloud Zuul可以通过与服务注册中心(Eureka、Consul)的整合,借用其服务发现和治理功能来自动维护服务实例。面向服务的路由的核心是,用路由的路径直接映射到一个具体的服务名,这里类似传统配置方式的多实例配置,但是这里的具体url是交给服务注册中心的发现机制自动更新、自动配置的,不再需要手动维护listOfServers。 具体搭建时,要在网关服务工程的pom.xml文件中添加spring-cloud-starter-eureka依赖来整合服务注册中心,并在配置文件中指定注册中心位置和设置服务路由,即可成功完成服务路由的配置。至此,API网关服务添加了服务路由的功能,实现了服务实例列表的自动维护。 3.3负载均衡控制 在3.1中,我们提到了Zuul自身引入ribbon依赖,这个模块是API网关实现负载均衡能力的基础。由于采用了服务路由的配置方式,ribbon可以根据传入的服务名(serviceId)使用自己模块的getServer方法,很方便的获取到具体的服务实例,API网关可以通过路由映射表很容易的获得所有的service的地址和位置,这给负载均衡的实现提供了很大的便利[9]。 Zuul经过以下几个主要步骤实现负载均衡。接收到请求后,Zuul会拦截对应请求,根据请求前缀对比服务路由,然后转发到对应的服务上,一个服务可以对应多个客户端实例,它们有相同且唯一的serverId。因为在服务注册中心上,同一个serverId可以对应注册多个客户端实例服务,即同一个服务项目在不同的端口或者IP地址上同时运行。Zuul做转发的时候会结合eureka-server起到负载均衡的效果,Zuul为内部网络提供了网关的功能,作为一个代理服务器来被系统使用,Zuul在这里提供了服务端负载均衡的功能,它会反向代理所有注册到服务注册中心上的服务[10]。 Ribbon是Zuul网关所使用的负载均衡器,但是网关注重的是承担并发的工作,在高并发的情况下,可以分散各服务器的压力,也可以感知后台服务实例的实时变化来确定使用不同的分发策略[11]。它提供了7种负载均衡策略,Ribbon源码中为负载均衡策略IRule接口7种具体的实现,可以通过网关模块的配置文件选择均衡策略。例如: service-A.ribbon.NFLoadBalancerRuleClassName= com.netflix.loadbalancer.RandomRule 为A服务指定的访问策略是随机访问。也可以定义方法实现IRule接口,使用自己业务逻辑所需要的定制化负载均衡策略。 3.4请求过滤 在3.2中完成网关服务路由的功能后,客户端请求就已经可以经由网关入口访问到具体微服务应用后台提供的接口了。但是,这样的服务路由缺少了权限控制,系统接口直接对外暴露,客户端请求不经过滤就能得到后台资源,系统的安全性能无法得到保障[12]。这里需要实现请求的安全验证以及权限控制功能。显然,Zuul网关作为客户端请求的唯一入口,可以更方便的实现这些过滤功能,而且过滤器也是Zuul的一个核心功能。 在Zuul中,定义的过滤器都有四个必要的特征:过滤类型、执行顺序、执行条件和具体操作。这几个特征在Zuul的源码里体现为ZuulFilter抽象类中独有的四个抽象方法:String filterType(),int filterOrder(),boolean shouldFilter(),Object run()。 我们将具体的校验逻辑写在run()的实现类中,并根据实际要求配置实现其它三个方法。在过滤器配置完成后,再在微服务网关的应用主类中为过滤器创建Bean,网关服务启动时就可以同时启动这个过滤器了。例如:@Bean public AccessFilter accessFilter(){ return new AccessFilter(); } 该AccessFilter是一个继承了ZuulFilter的过滤器。这就是实现一个基本请求过滤功能的步骤。在实际项目中,Zuul网关的请求过滤多用来处理权限校验、签名校验、请求限流等需求,搭建项目时,会在run()方法中整合其他专用jar包来完成复杂的逻辑,比如鉴权逻辑,可以引入OAuth、JWT等模块代码来完成。 4微服务API网关的应用 为解决大型企业各种知识内容的存储及查找,内部员工的信息分享、团队交流等问题,利用微服务架构搭建一个企业知识管理平台。 87 Techniques of Automation&Applications通过合理的组织信息,使得各部门和各级员工高效利用企业知识资源。微服务API网关模块,是整个知识管理系统的统一请求访问入口,包装了内部系统的所有应用服务信息。整个微服务应用总体架构设计如图2所示。 图2微服务应用系统总体架构图 4.1微服务划分 确定微服务边界是系统构建的重要步骤,企业知识管理系统中,将业务系统划分为后台管理模块、资源共享模块、员工交流模块和基础服务模块,根据划分,四个模块各自对应一个微服务模块。 后台管理服务,用于管理员的操作。管理员后台界面操作,对用户、角色、组织机构的权限进行设定。通过赋予角色权限,用户再绑定角色的方式实现用户的权限的控制,以此构建知识的权限体系,知识库的开放级别由用户角色级别决定,用来保证知识的安全。后台管理服务在完成审批功能时,还需调用基础服务模块的工作流引擎,用来对用户上传的资源进行各级相关管理员的审核。 资源共享服务,主要用于用户上传分享资源和下载资源的操作。用户在登陆个人账号后,以文章帖子的形式描述上传的资源,同时可以添加不同格式的附件。该模块提供全站搜索功能,用户输入关键字搜索所需资源,得到的结果会经过用户角色的权限过滤。 员工交流服务,提供企业内部交流平台,包括问吧和团队建设模块。问吧模块用户可以进行资源求助或者问题解答,以这种方式补充知识库中缺少的一些经验性知识。团队建设为内部提供活动发布、公告通知、投票活动等平台,助力企业的团队建设工作。 基础服务,为整个系统提供各种公共的服务包括工作流引擎服务、文档插件服务、报表工具服务,邮件短信服务等。工作流引擎服务作用于资源审核,文档插件服务提供了在线编辑预览文件的功能,报表工具可以完成一些统计报表的生成及导入导出,邮件短信服务用来提供注册安全验证,以及其他的系统通知。 各业务服务模块都由统一API网关进行封装对外提供服务。 5结束语 API网关为微服务系统提供了统一入口,起到了客户端和后台微服务应用之间的桥接作用,是微服务架构系统的重要部分[12]。本文研究且实现了基于Spring Cloud Zuul的微服务API网关,在客户端请求经过网关时,进行统一的路由转发、负载均衡以及请求过滤处理,极大的优化了系统架构。微服务API网关在企业知识管理系统中的应用,有效的解决了外部调用情况下系统的安全防护问题,同时预处理、负载均衡技术的使用提高了系统性能,也为平台的运维提供了便利。 参考文献: [1]洪华军,吴建波,冷文浩.一种基于微服务架构的业务系统设计与实现[J].计算机与数字工程,2018,46(1):149-154. [2]赵毅,张涛.恒丰银行分布式核心系统-API网关技术原型落地实践[J].中国金融电脑,2017(4):48-55. [3]朱荣鑫.基于微服务架构的游戏商城服务端的设计与实现[D].南京:南京大学,2017. [4]王方旭.基于Spring Cloud实现业务系统微服务化的设计与实现[J].电子技术与软件工程,2018(8):60-61. [5]蒋勇.基于微服务架构的基础设施设计[J].软件,2016, 37(5):93-97. [6]杜华雄.基于云平台的任务管理系统的设计与实现[D].沈阳:沈阳工业大学,2017. [7]马雄.基于微服务架构的系统设计与开发[D].南京:南京邮电大学,2017. [8]张晶,黄小锋,李春阳.微服务框架的设计与实现[J].计算机系统应用,2017,26(6):259-262. [9]郭正敏.基于SOA架构的分布式服务化治理方案的研究[D].南京:南京邮电大学,2016. [10]简玮侠.高可用服务发现架构的设计和实现[J].信息与电脑(理论版),2015(22):75-76. [11]黄垂碧.应用层网关攻击检测和性能优化策略研究 [D].合肥:中国科学技术大学,2014. [12]李春阳,刘迪,崔蔚,李晓珍,李春岐.基于微服务架构 的统一应用开发平台[J].计算机系统应用,2017,26(4):43-48. 作者简介:廖俊杰(1993-),男,在读硕士,研究方向:互联网技术。88 Techniques of Automation&Applications