王敬林 ,朱韦桥
(1.中国铁道科学研究院 研究生部,北京 100081;2.北京经纬信息技术有限公司,北京 100081;3.中国铁道科学研究院集团有限公司 电子计算技术研究所,北京 100081)
铁路企业面对着繁杂的企业年金经办业务、巨额的年金基金管理和严格的投资监督等日常业务管理,传统的手工方式或完全依托账管人提供的信息系统进行管理,已无法满足业务发展需要,部分企业已经建设了相关企业年金信息系统,用于企业年金业务管理,由于设计理念和开发技术的限制,多采用单体架构进行系统的构建[1-2],但在运行过程中暴露了一些问题:
(1)企业年金政策性强、时效要求严格,铁路企业年金业务调整频繁,具有涉及人员广、业务操作复杂、专业性强等特点,年金系统需要根据业务规则的变化,进行及时迭代与更新,而传统的单体架构信息系统可维护性和可扩展性较差,面对微小的调整,整体系统都需要经历开发、测试、整体打包、停机、更新、部署、启动等实施过程,无法适应高频率更新升级的业务要求。
(2)年金信息系统涉及成员单位多、业务规则多、对口机构多且数据交互频繁,导致子系统和功能模块多,单体架构信息系统局部子系统或功能模块的故障,将导致整体系统崩溃,无法满足系统的高可用性。
(3)随着铁路云计算的发展,铁路企业已基本实现资源虚拟化、系统集群化的生产环境,单体架构信息系统面临运行瓶颈,同时,无法充分利用云计算可伸缩性、高扩展性的优势和特长[3]。
本文主要研究基于微服务架构构建的铁路企业年金信息系统(简称:微服务年金系统),解决单体年金信息系统的诸多问题。
铁路企业一般采用理事会受托管理模式,即铁路企业和职工作为委托人,委托企业年金理事会(受托人)管理企业年金基金。理事会下一般会设置专门经办机构(理事会办公室),负责企业年金理事会日常工作。由受托人选择一家同时具有账户管理、托管资质的机构作为账户管理人和托管人,由受托人选择若干家具有投资管理资质的机构作为投资管理人[2],企业年金各管理机构的职责分工与信息流传输如图1所示。
图1 企业年金管理机构职责分工及信息流传输示意图
铁路企业年金业务整体可分为计划层和成员层,其中,计划层包括产生和存续2个阶段,成员层包括产生、存续和终止3个阶段。计划层产生阶段主要包含计划建立相关流程;存续阶段主要包含计划监督、基金运作、投资监督和信息披露4部分。成员层产生阶段主要包含单位及职工的计划加入相关流程;存续阶段主要包含单位及职工的信息变更和年金缴费2部分;终止阶段主要包含计划退出流程。需求结构,如图2所示。
图2 铁路企业年金管理总体需求结构图
微服务架构是一系列小的、松耦合的分布式服务,这些服务围绕业务能力划分构建,具有组件化、通信协议轻量化、服务集中化、数据分散化的优点,能够使用不同的编程语言、不同的存储技术在云平台下独立部署[4-6]。
1.3.1 微服务拆分
领域驱动设计(DDD,Domain Driven Design)是一种以领域为核心的设计方法与理念。系统采用DDD理念,结合铁路企业年金管理业务,将企业年金业务领域拆分为:(1)核心域:成员领域;(2)支撑子域:年金计划子域,成员单位子域,缴费子域,支付子域等;(3)通用子域:消息子域,文件子域,流程子域,报表子域等。
使用场景走查的方法,确认领域模型满足领域中的业务场景和业务流程,根据每一个子域对应的边界上下文完成服务的拆分。业务服务主要包括:年金计划服务,成员单位服务,成员服务,年金缴费服务,年金支付服务等;公共服务包括:消息服务,文件服务,日志服务,流程服务等。
1.3.2 微服务年金系统总体架构
系统总体架构分为表现层、接口层、实体层、业务服务层、公共服务层、服务治理与监督、资源层等7个部分,如图3所示。
图3 微服务年金系统总体架构图
(1)表现层:使用前后端分离技术,对后台服务进行组合,完成与用户的交互。本系统中的年金日常业务管理和年金投资监督管理等页面功能,可以在后台服务接口确定的情况下进行前端的独立开发。
(2)接口层:将实体层、业务服务层、公共服务所覆盖的内容进行聚合,按照客户端的需求,为表现层提供符合展示要求的数据,封装成接口服务。如成员单位接口、成员接口、年金缴费接口、待遇支付接口、成交管理接口、投资转换接口等。接口提供在线数据交互和数据文件导入导出2种方式。
(3)实体层:微服务架构下的实体同时为业务服务和公共服务提供支持,在接口需要的情况下也可以直接调用。系统中,所有的数据均将封装为接口,方便对外提供统一的数据服务能力,包括计划信息、成员单位信息、成员信息、缴费信息、支付信息模型等。
(4)业务服务层:结合企业年金的实际业务,将实体和公共服务进行封装,为接口层提供支持。本层涵盖本系统的主要业务,包括年金计划服务、成员单位服务、成员服务、年金缴费服务、待遇支付信息服务等。
(5)公共服务:将微服务年金系统中多处用到的功能进行统一封装,以便更好地为业务服务层提供支持,包括消息服务、文件服务、日志服务、流程服务、缓存服务等。
(6)服务监督与治理:微服务架构下,对服务的安全、监控、预警十分重要。服务监督与治理贯穿公共服务层、业务服务层和接口层,主要提供服务注册、服务监控、服务授权、日志分析、熔断器等功能,实现对微服务的治理。
(7)资源层:主要是指系统操作的相关资源,包括数据库资源及各类文件资源,如计划信息库、成员单位信息库、成员信息库、缴费信息库、待遇支付信息库,以及相关的各类附件信息库(业务经办文件、指令等)。
Spring Cloud 是一系列框架有序集合,其标准化的、全站式的技术方案构成了一个生态圈,涵盖了众多微服务架构实现所需的核心组件,例如,服务网关、服务注册发现、配置中心、认证授权、容错限流、调用链监控、日志监控等[7-8]。本系统微服务架构实现主要使用的组件如图4所示。
图4 微服务年金系统技术实现图
(1)服务网关:客户端请求通过统一的服务网关接入后端服务。网关使用Zuul、Ribbon和Eureka 3个组件,实现智能路由和负载均衡的功能。智能路由就是依据请求策略将请求网关转发到认证授权服务,按照相应的权限分发到相应的服务实例,防止非法请求访问后端服务,同时,Zuul为后期规划的灰度测试创造了条件。
(2)服务注册发现:Eureka是一个基于REST的服务注册中心。在微服务架构中,服务需要集中化管理,因此,基础服务、公共服务和通用服务需要通过服务治理实现自动化注册和发现。服务注册中心是网关服务路由信息存储仓库,也是服务之间进行交互的媒介,发挥着服务注册和发现的作用。Eureka支持服务续约和服务下线,方便用户定位服务问题以及提供中间层服务器的故障转移。
(3)配置中心:Spring Cloud Config结合Git实现配置中心的搭建和配置信息的统一管理。配置服务通过注册中心注册到Eureka Server,企业年金服务可以通过注册中心发现配置服务,企业年金服务从而获取所需要的配置信息。
(4)认证授权:Spring Security、OAuth2和JWT实现微服务年金系统的认证授权。客户端请求通过网关路由到认证鉴权服务,获取用户登录信息和权限信息,客户端携带Token支持跨程序调用。微服务年金系统存在异构系统,利用JWT实现单点登录。
(5)容错限流:Hystrix实现微服务架构的服务可靠性,Hystrix服务延迟和容错库可用来隔离服务故障,确保系统稳健运行。各个服务独立部署,且服务与服务之间存在相互依赖关系,因此,服务访问失败的原因和场景非常复杂,容错限流服务可以实现服务隔离、服务降级和服务熔断,从而阻止联动故障的发生。
(6)调用链监控:Spring Cloud Sleuth结合Zipkin构建微服务的调用链监控,客户端每一个请求在调用过程需要多个服务,每个服务独立部署在不同物理机器和不同数据存储之间,调用链监控可以跟踪一个或多个事务,然后,拼接出服务运行的全链路。通过Zipkin可以查看跨多个事务的事务流。
(7)日志监控:日志监控通过ELK(Elastic Search、Logstash、Kibana)和Kafka实现日志收集与监控,分布在不同服务器的日志收集组件,通过消息中间件Kafka传递给Logstash,进行过滤分析后将数据存储在Elastic Search,通过Kibana查看所有的日志数据。
微服务年金系统采用前后端分离,前端使用Angular和Typescript开发,实现MVC划分和通道、路由等设计。前端应用部署在Nginx组合的服务器上,通过反向代理转发页面请求到后端服务器,同时Nginx实现前端的负载均衡[9]。
应用整体界面采用完全的响应式编程,使得数据驱动、局部刷新容易实现;采用Bootstrap兼容可扩展框架,通过页面栅格自适应各种分辨率的显示器,实现更好的用户体验。
通常,微服务架构的认证授权采用Spring Security、OAuth2和JWT的组合,该认证授权框架虽然具有一次获取Token可以多次使用的优势,即不需要每次都到认证授权服务去获取用户信息和权限信息,但是,如果用户权限发生改变,Token存储的信息不能及时变更,就会造成业务的漏洞,微服务年金系统通过引入缓存数据库(Redis)技术,用于存储Token信息,当用户权限更改时,将会自动删除存在Redis的Token,请求再次经过网关时,验证Token不存在,提示用户重新登录。
微服务年金系统授权认证过程,如图5所示。
(1)客户端发送请求到服务网关后,网关会根据请求路径过滤请求[9]。如果该路径是登录并获取Token操作的路径则直接放行,请求直接到达认证授权服务进行登录操作;
(2)进行JWT私钥加密,生成Token存储到Redis;
(3)返回给客户端。如果是其他请求,将会到Redis验证Token是否存在,若不存在,则返回客户端重新登录;若Token存在,则进行Token私钥解密校验:如果token被篡改或者失效,则直接拒绝访问并返回错误信息;如果验证成功,经过路由到达请求的年金业务服务,请求服务响应并返回数据。
图5 微服务年金系统授权认证过程图
微服务年金系统将数据和服务分开,保证服务的独立性。由于铁路企业数据要求集中管理,数据存储采用集中式的数据管理方式再实现数据的独立性[10-11]。系统针对每个业务服务划分专门的独立空间,从逻辑上与其他服务相隔离,如图6所示。跨企业年金业务的数据存储依据BASE思想,即基本可用(Basically Available)、软状态(Soft state)和最终一致性(Eventually consistent)的TCC模式实现分布式事务。
图6 微服务年金系统数据存储实现图
微服务年金系统已上线运行,应用效果显著。系统实现了铁路企业内部成员、年金资金、年金业务规则等基础数据统一管理,与相关系统数据交换和信息共享,信息流、资金流全程监控,为年金基金管理和投资监督提供了保障。企业年金政策调整、业务管理变化后,利用微服务架构的优势,系统具有横向扩展、快速更新升级的能力,为企业年金日常经办提供了时效保证,提高了用户体验。通过微服务架构改造的系统业务相对独立,服务集群部署,日志监控全面,运维定位迅速,为系统的高可用提供了技术支撑。
本文分析使用单体架构进行铁路企业年金系统构建的问题,介绍了微服务架构的概念和关键特性,并将微服务架构的理念引入到铁路企业年金信息化建设的系统设计中,实现了铁路企业年金业务流程贯通及全过程信息化管理,提高了系统的负载能力、可扩展性和独立性。
该系统需要进一步研究的内容有:
(1)虽然按照领域驱动设计进行了服务拆分,但是,随着日常业务的开展,服务拆分策略的合理性依然值得探讨,后续继续研究铁路企业年金业务特点,优化服务拆分;
(2)微服务年金系统服务可靠性的设计仍不够全面,服务访问的雪崩效应、服务失败应对策略、服务容错、服务隔离、服务限流、服务降级等问题没有完全解决,需要继续研究服务可靠性方案,进一步完善方案。