基于微服务架构社会化发行系统设计与实现

2021-04-24 13:05
网络安全技术与应用 2021年4期
关键词:调用网关日志

(辽宁高速通智慧出行有限责任公司 辽宁 110000)

在拆除省界收费站背景下,辽宁高速基于国家政策,辽宁高速统一管理的优势,提出ETC 聚合发行的构想,并积极推动建设ETC 生态圈。截至2019 年6 月,辽宁省汽车保有量为800 多万辆,ETC 用户仅有240 万左右,因此ETC 占有比只有20%多。根据政策要求,在2019 年年底力争全省新增ETC 用户420 万,各市汽车ETC 安装率在80%以上,通行高速公路车辆ETC 使用率在90%以上。这意味着短时间要完成过去几年甚至十几年的发行量,可以想象任务之艰巨。传统ETC 发行主要在省级发行方的专业服务网点或银行代理网点进行,发行渠道单一、效率低、体验差、不利于大规模发展用户。在ETC聚合发行的构想下,一方面增加线下网点,另一方面重点拓展网上渠道充分发挥互联网渠道优势[1]。

随着ETC 业务大力推广,各大支付机构、银行等相继争抢ETC在线发行市场。支付宝、微信、京东、360、中移动、各大银行等多种渠道开展发行业务,因此ETC 在线发行系统势必会出现接入方式多样化、系统请求高并发、个性化业务拓展、系统快速响应等特点。而传统ETC 发行系统多采用单体架构模式实现,单体架构将前端页面、业务逻辑处理和数据处理等统一编码在单个应用下。在ETC 发展初期由于业务需求单一、业务办理少,采用单体架构在代码开发、测试、部署、维护等流程中相对比较简单高效。但是随着ETC 业务不断发展,需求逐渐增多,代码结构会变得越来越庞大,后期对代码的整体理解和实施维护方面的困难也会增强[2]。再者,单体架构在单一进程当中运行,如果遇到系统维护升级等情况也会导致系统其他功能不可用,从而影响系统的可靠度。因此,单体架构应用具有业务拓展困难、技术选择单一、代码耦合度高、维护困难、可靠度低等缺点。

2014 年学者 Martin Fowler 正式提出微服务架构的概念。微服务架构是一种架构模式,是指根据业务需求将系统拆分为多个微小服务,服务独立部署在不同的进程中,不同服务通过一些轻量级交互机制来通信,例如RPC、HTTP 等。服务可独立扩展伸缩,每个服务定义了明确的边界,不同的服务可以采用不同的编程语言来实现,由独立的团队来维护[3]。

针对目前ETC 在线发行业务场景和单体架构的缺陷,本文将分析微服务架构体系优缺点、以及如何基于SpringCloud 微服务技术实现具有前后端分离、高并发、高可读、可扩展、可独立开发部署等特点的微服务架构系统。

1 微服务架构优势与不足

1.1 微服务优点

单体结构系统根据功能拆分为多个微小的服务,每个服务可单独开发、编译、部署等,相比单体架构微服务具有以下优势[4]。

(1)降低复杂度

传统单体架构将所有功能模块堆积在同一应用下,而微服务架构根据业务功能将服务拆解成多个单体应用,不同应用可以专注不同的功能实现,因此微服务结构清晰、功能单一、编码简单明了。每个微服务可独立开发测试维护,模块之间互不影响,降低模块间耦合度的同时也提高了代码的可读和可维护性。

(2)可独立部署

由于微服务拆分为多个独立的应用,因此微服务可以独立部署在单个服务器容器下,并运行在独立的进程中。当业务迭代时只需开发部署相关服务即可,降低测试工作量避免了大量回归测试,同时也降低了服务发布的风险。

(3)容错

在微服务架构下,当某一组件发生故障时,故障会被隔离在单个服务中。通过限流、熔断等方式降低错误导致的危害,保障核心业务正常运行。

(4)可扩展

微服务扩展性可从两个方面分析,即开发可扩展和部署可扩展。开发可扩展是指有新增完整业务需求时,可单独开辟新的服务模块,在不影响现有服务的情况下,通过独立模块的编码开发、测试、部署、完成业务需求。部署可扩展是指当系统访问量过大时,可通过添加负载服务器,解决系统响应慢的问题。单体架构也可以实现服务的横向扩展,但由于单体应用包含系统所有的功能,而某些功能访问频次并不高,如添加负载会导致资源的浪费。而微服务可通过监控每个服务的请求量,根据实际情况扩展不同的服务,合理使用服务器资源。

1.2 微服务不足

任何事务的出现都具有两面性,微服务虽然有很多优势,但同时也有以下几点缺陷[5]。

增加运维成本和开支成本:由于微服务架构是由多个微小服务组成,需要在多台服务器部署且每个服务会负载集群,因此服务器开支成本较高。如果微服务某个模块出现异常,往往需要排查整个请求链路执行情况,而单体架构只需在本服务器根据日志分析即可,在这个过程中无形增加了运维成本。

问题追踪难度增加:微服务请求调用链会经过多个不同的服务,如一次请求出现问题,需分析请求到达服务的状态和执行结果,从而增加追踪问题的复杂度。

内容重复:对部分业务,流程大致相同时,如果不能很方便将代码封装,就可能导致在多个服务中有些重复性的代码。除此之外还有日志重复,一个调用链可能要调用多个服务,在追踪问题时,每个服务都要对参数和响应进行记录,这样就导致相同日志内容重复出现在多个地方。

2 ETC 社会化发行业务功能

传统ETC 设备申请需客户携带身份证原件、驾驶证原件、自驾办理车辆前往附近ETC 营业厅进行办理。然而营业厅办理会给用户带来很多不便,如遇到客户资料不全、附近没有营业厅网点、办理人员太多等情况都可能导致用户办理中断。随着省界收费站拆除和ETC 大力推广,传统办理模式已不能满足当前需求。为应对ETC 业务的不断扩张、减少客户出行、节省用户时间,从而提出ETC 社会化在线发行需求。客户借助APP 客户端或微信小程序在线提交客户身份证、车辆行驶证、银行卡、邮寄地址等信息申请ETC 设备,后台审核用户订单信息,如客户信息填写正确,业务人员将ETC 设备邮寄给客户。客户收到未激活的设备,通过APP 客户端或微信小程序等自助在线激活设备。根据需求分析可分为如下几个功能:

2.1 H5 新办ETC 订单

H5 新办模式主要对接银联、工行、建行、农行、邮储、中行、农信社等银行接入方。各接入方客户端APP 通过调用ETC 社会化发行接口拉起新办H5页面,首页展示新办相关协议,用户勾选同意后,点击下一步,跳转到车辆信息页。此页需上传用户行驶本正反面,填写车牌号车牌颜色。点击下一步,调用后台接口校验车牌是否在黑名单以及是否已发行。校验通过后进入开户人信息页,此页填写开户人姓名、身份证信息。点击下一步,后台服务将姓名、身份证号等关键信息传递给银行,进行一次签约校验,银行校验用户信息是否填写正确。校验通过后,银行给用户发送短信验证码,页面跳转到下一页,用户输入校验码。点击下一步,后台将用户手机号、验证码等信息上送给银行,进行二次签约校验。校验通过后,后台服务将订单提交到内部发行核心系统,完成新办订单提交。

2.2 原生新办ETC 订单

我们知道H5 新办模式只需接入方调用后台接口拉起H5 页面,并提供一次签约和二次签约接口相关接口即可。虽然H5 模式方便商户接入,但是H5页面风格固定并不能满足其他商户页面个性化需求。而原生新办模式是指社会化发行系统只提供用户车辆信息提交、身份信息提交、校验车辆是否在黑名单、校验车辆是否已发行、订单提交等接口服务,前端页面由各接入方自行实现。接入方可自行选择通过安卓或IOS 系统原生APP、微信或支付宝小程序来实现前端页面,这样可以满足不同商户页面个性化需求。

2.3 ETC 设备激活

新办订单出库后,用户收到的设备(ETC 卡OBU 标签)是未激活状态。用户需通过微信小程序、APP 等渠道自助激活设备。其中设备激活分为标签激活和卡激活两部分。系统主要提供写标签车辆信息、写标签系统信息、写标签结果确认、卡片个人化、卡片系统化等服务。

2.4 特殊业务办理

用户在使用过程中遇到特殊情况,如损坏标签、损坏ETC 卡或变更车辆信息等情况时,可在线办理标签更换、ETC 卡更换、车辆信息变更、卡注销、标签二次激活等相关特殊业务。

2.5 支付功能

在ETC 大力推广的背景下,虽然很多渠道的ETC 设备是免费领取的,但并不意味着所有渠道免费或者永久免费。如需用户支付标签费用,系统提供微信、支付宝、银联等多种付款渠道。

3 微服务架构设计

3.1 微服务拆分

微服务是指根据业务功能合理拆分为多个可独立部署维护的子服务。微服务的拆分方案是决定系统是否具备高内聚、松耦合、可扩展、高可读等特性的关键所在。

从ETC 社会化发行业务功能章节分析可将服务拆分为新办订单、设备激活、特殊业务、支付服务等模块,每个模块完成各自领域内业务互不干扰。鉴于新办订单、激活、特殊业务等需调用内部核心发行系统完成,为减少冗余代码提高代码复用率,提取出第三方发行模块。第三方发行模块调用核心发行系统服务并对内部服务提供接口,如此提高代码复用率的同时使以上三个模块更专注于业务逻辑处理。同理,可提取出第三方支付服务。由于微服务不会开放所有的功能,增加用户鉴权服务可保护数据服务安全。系统拆分如表1 所示。

表1 系统拆分表

3.2 架构总体设计

(1)技术选型

ETC 社会化发行采用的是前后端分离可独立部署维护的微服务系统架构。后台提供REST 风格接口,既支持各接入方系统直接调用,又支持接入方客户端嵌入H5 页面进行调用。前端采用VUE 框架,VUE 是一个轻量级MVVM 即数据双向绑定架构模式,可减少开发人员频繁操作DOM 文档,方便开发人员专注于业务逻辑处理。目前微服务架构主流的技术有Dubbo 和SpringCloud。Dubbo 是一款开源的轻量级、高性能Java RPC 远程调用框架,其提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动发现和注册。SpringCloud 是一个完整的微服务解决方案,其提供注册中心、配置中心、网关、链路追踪、Fegin 远程调用、断路器、消息总线等一系列组件。经过对比,Dubbo 是一款轻量级RPC 框架,而SpringCloud 是专注于微服务领域的具有全套解决方案的框架。本文采用SpringCloud 技术来实现ETC 社会化发行微服务后台。

(2)架构设计

从微服务技术角度分析以下三个服务必不可少。网关服务:网关服务是微服务架构的统一入口,其核心功能是路由转发与过滤器。路由转发类似于Nginx 反向代理,可根据路由规则将请求转发到对应微服务。注册中心:注册中心记录了微服务和服务地址之间的映射关系,承担服务注册与发现功能。配置中心:配置中心就是把项目中各种配置、各种参数、各种开关,全部都放到一个集中的地方进行统一管理,并提供一套标准的接口。当各个服务需要获取配置的时候,就来配置中心的接口拉取。当配置中心中的各种参数有更新的时候,也能通知到各个服务及时同步最新的信息,使之动态更新。

通过ETC 社会化发行业务功能、服务拆分、技术选型等分析,确定了微服务总体架构。可将系统架构分为应用层、接入层、平台服务层、数据层、基础支撑层。系统架构图如图1 所示。

应用层:直接面向用户可视化操作的H5 页面或各接入方客户端应用。

接入层:接入层是指微服务的统一入口,接收客户端所有请求,并根据地址与服务路由规则将请求转发到对应微服务。网关服务不仅有路由转发功能,还包括服务鉴权、系统限流等功能。

平台服务层:平台服务层指从业务功能与SpringCloud 微服务技术体系角度拆分的具体服务。从业务服务分为新办订单、特殊业务、设备激活、用户鉴权等。从微服务组件分为注册中心、配置中心、基于Hystrix 断路器组件、基于Ribbon 的负载均衡组件、基于Sleuth 链路追踪组件、SpringBoot Admin 微服务监控服务等。

数据层:主要指Mongo 数据库实例、Redis 缓存等。

基础支撑层:包括服务器、网络设备、等支撑系统的物理组件。

图1 系统架构图

4 微服务架构实现

4.1 服务注册与发现

随着业务的发展,系统功能越来越复杂,微服务数量也不断增加。并且服务的集群规模、服务位置、服务命名等都可能发生变化。传统模式下服务调用方需要单独维护服务提供方地址,这样不仅增加了维护的复杂度而且当服务提供方地址变更或者新增负载服务后调用方也不能动态感知。为解决此类问题,微服务架构体系提出服务治理概念,用于解决微服务的注册与发现问题。

Eureka 是SpringCloud 微服务体系中专为服务治理构建的组件。Eureka 服务治理主要包括服务注册中心、服务提供者、服务消费者三个要素。注册中心是Eureka 提供的服务端,主要用于提供服务注册与发现功能。服务提供者提供具体服务的应用,将自身服务注册到注册中心,供消费者发现,其中主要功能包括服务注册、服务同步、服务续约等。服务消费者从注册中心拉取服务列表,消费者根据需求调用具体服务,其中主要功能包括获取服务、服务调用、服务下线等[6]。Eureka 各元素之间通信关系如图2 所示。基于本系统架构,API 网关、各业务服务以及微服务组件等都会通过Eureka 进行服务注册与发现,Eureka 维护消费端以及服务端的绑定关系。例如消费端API网关服务通过注册中心查找定位具体的服务端服务。

4.2 服务路由

Spring Cloud Ribbon 是一个基于Http 和TCP 的客服端负载均衡工具,它是基于Netflix Ribbon 实现的。它不像服务注册中心、配置中心、API 网关那样独立部署,但是它几乎存在于每个微服务的基础设施中,SpringCloud 微服务体系中Zuul 和Fegin 等组件就是基于Ribbon 来实现路由转发或者客户端调用。Ribbon 有很多负载均衡算法,最简单算法来自著名的 Round Robin 算法,即轮询法[7]。其思想是根据服务实例组成的集合,按照顺序依次循环调用,另外还有加权轮询[8]、最小连接数算法等[9]。

图2 Eureka 各元素通讯图

4.3 微服务网关

微服务是由很多服务组合而成的系统,每个服务都需要鉴权、限流、权限校验等功能。如果每个服务都对外暴露接口,各自实现鉴权、限流等逻辑。这样不仅会生成代码冗余,而且造成客户端调用地址多,维护很不方便。更好的解决方案是提供API 网关,API 网关作为微服务统一入口,类似Nginx 反向代理,将客户端所有请求路由到服务端进行处理。当然网关不是单纯转发功能,还可针对流量进行扩展,比如鉴权、限流、权限校验、签名验签、日志等。通过引入网关,客户端无须关心后台调用哪些服务,只需要与网关进行交互。网关引入带来方便的同时也伴随着安全隐患,如果网关服务不稳定、响应效率低等都可能导致服务不可用。ETC 社会化发行系统采用网关作为系统的唯一入口,实现了请求响应日志信息统一打印,借助网关过滤器实现了请求信息签名验签、用户鉴权等功能,有效解耦业务功能与非业务功能代码。

本文采用SpringCloud Zuul 组件实现微服务网关服务,Zuul 不仅具有动态路由功能,还可通过过滤器组件自定义实现微服务安全认证、签名验签等功能。动态路由与负载均衡:当客户端请求进入网关服务,Zuul 根据微服务实例名与路径匹配关系,自动将请求转发到服务端。Zuul 路由转发通过Ribbon 组件实现,Ribbon 根据自定义配置将请求动态负载到微服务,从而实现微服务高并发。安全认证:由于Http 请求是无状态的,服务端无法区分安全访问和非法访问。客户端请求服务提供的接口时,他们访问的权限往往需要有一定限制,系统不会将所有接口对外开放。然后Zuul 组件默认路由并没有校验权限,为此需要借助zuul 组件另外核心功能过滤器ZuulFilter 来实现请求拦截。在过滤器中实现权限校验逻辑,校验通过才能请求微服务[10]。

4.4 服务容错

在微服务架构中,系统拆分成了多个微小服务,各微服务之间通过服务注册与发现的方式互相依赖。由于每个服务运行在不同的进程,通过远程调用方式互相通讯,这样很可能出现网络延迟或者被调用服务本身故障,因此导致调用方的对外服务也出现延迟,若此时调用方请求不断增加,最后调用方可能出现无法响应而形成任务积压,线程资源无法释放,最终导致自身服务的瘫痪,甚至出现故障蔓延导致整个服务不可用。为了解决这样的问题,因此产生了断路器等一系列的服务保护机制。

针对上述问题,在Spring Cloud Hystrix 中实现了断路器、线程隔离等服务保护功能。它是基于Netflix 的开源框架 Hystrix 实现的,该框架目标在于通过控制那些访问远程系统、服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。Hystrix 具备了服务降级、服务熔断、线程隔离、请求缓存、请求合并及服务监控等强大功能[6]。例如网关服务通过Ribbon 路由到各级服务,Ribbon 默认实现了断路器功能,当下级服务出现异常时能快速响应,避免大量请求堆积到网关从而导致整个服务不可用。

4.5 微服务高并发以及高可用

根据辽宁省ETC 发行需求可知,在2019 年下半年要完成过去几年甚至十几年ETC 发行量的2-3 倍。可想而知,系统在这段时间要承担大量的请求数,因此系统要具备高并发以及高可用等特点。高并发是系统并行处理大量请求的能力,主要体现在系统快速响应、高吞吐量、高并发用户量等指标。高可用是指系统是否具备稳定运行的能力,比如某服务异常不可用时是否有备份提供服务,主要解决服务单点故障问题。

系统高并发可从垂直扩展和水平扩展方面出发。垂直扩展:一提高单机硬件处理能力,比如增加系统内存、增加系统内核数等。二提高微服务快速响应能力。使用缓存将系统常用的用户信息、商户信息等基础数据、以及更新频次多查询慢的统计数据放置在JVM 内存中,减少频繁的数据库查询以及频繁的IO 操作。使用线程池减少频繁创建线程所占用的资源和时间,比如数据库连接线程池。优化查询语句,数据查询在业务处理占比很高,通过优化查询语句以及表结构添加索引等手段,可有效解决系统响应慢的问题。水平扩展,垂直扩展可提高单体服务的处理能力,但单机服务器处理能力有限面对高并发请求往往会出现请求丢失、内存溢出、连接超时等情况。微服务特点是通过分析,将业务量大、频繁使用的业务模块进行水平扩展。水平扩展是将微服务整体部署在新服务器下,可根据需求部署多台服务,可精准定位减少资源浪费并且有效解决系统高并发问题。

系统高可用是指系统是否具备稳定的运行能力,如网关服务、注册中心、业务服务等部署在单节点服务器,当请求量超出瓶颈时可能会出现单点故障。在服务注册与发现段落,我们知道注册中心Eureka可集群部署,实现服务同步,从而达到互为备份的目的。在服务路由段落分析,每个微服务可添加负载服务器,Ribbo 可通过负载策略将请求转发到“活着”的微服务下,从而解决单点故障问题。网关服务作为微服务入口,请求方来自用户,可通过F5、Nginx 反向代理等实现网关集群部署等,或者通过keepalive 地址漂移技术实现网关热备,以达到网关高可用。

4.6 微服务调用关系

微服务特点是服务多、调用关系复杂,每一次请求链路会经过多个服务,所以微服务之间调用关系是否能清晰表达十分重要。通过服务拆分设计与架构总体设计分析以及SpringCloud 微服务技术特点,得到本系统数据流向图如图3 所示。

图3 数据流向图

5 微服务架构其他技术

5.1 统一日志处理ELK

从第1 章分析我们知道微服务架构有复杂度低、独立部署、高容错、可扩展等优势,同时也有运维开支成本高、问题追踪复杂、内容重复等不足。其中问题追踪复杂和内容重复等都与日志打印方式息息相关。每次请求链路会经过多个服务且每个服务有多台负载服务器,如果服务出现异常维护人员需要通过查找链路经过的所有服务日志来定位问题,因此追踪问题变得异常复杂。针对现有问题,如果微服务日志统一收集在一个服务器且能通过唯一标识搜索每次请求链路上所有日志,这样不仅能减少开发人员定位问题难度还能减少重复日志打印。

ELK Stack 是软件集合Elasticsearch、Logstash、Kibana 的简称,由这三个软件及其相关的组件可以打造大规模日志实时处理系统。其中,Elasticsearch 是一个基于 Lucene 的、支持全文索引的分布式存储和索引引擎,主要负责将日志索引并存储起来,方便业务方检索查询。Logstash 是一个日志收集、过滤、转发的中间件,主要负责将各条业务线的各类日志统一收集、过滤后,转发给 Elasticsearch 进行下一步处理。Kibana 是一个可视化工具,主要负责查询 Elasticsearch的数据并以可视化的方式展现给业务方,比如各类饼图、直方图、区域图等。ELK 的出现提供了微服务日志统一收集存储,并且提供可视化界面减少开发人员日志查询工作量。结合微服务链路追踪技术,将请求链路唯一标识存储于Elasticsearch,通过该唯一标识可将链路日志一次查出。高并发情况下微服务同步日志打印存储会大大影响程序执行效率。本文结合Logback 日志组件、Redis 消息队列、ELK 软件来实现微服务日志异步统一收集存储[11]。ELK 日志处理流程如下图4 所示。

图4 ELK 日志处理流程

5.2 微服务监控Adimin

微服务系统由多个模块组成,且每个模块可部署在多台服务器,这样解决单点故障的同时提高系统高并发。在生产服务运行当中,系统可能会出现很多问题,比如内存溢出、磁盘空间不足、系统响应超时、服务异常退出等问题。由于微服务的系统部署或者网络调用关系非常复杂,人工发现问题变的越来越复杂,因此微服务监控扮演着重要的角色。

SpringBoot Admin 是一个管理和监控SpringBoot 应用程序的开源软件,是在SpringBoot Actuator[12]接口基础上进行UI 美化封装的监控工具。与注册中心Eureka 结合使用可监控微服务服务的健康状况,例如服务器内存和磁盘空间使用情况、JVM 和内存指标、在线修改日志打印级别、请求链路响应时间、服务上线或下线状态变更通知等。

5.3 单元测试与在线文档Swagger

传统接口文档需开发人员根据接口规范编辑纸质文档。由于接口每次升级改造都需同步修改纸质文档,因此可能会出现多个版本文档,也可能导致最新的文档与实际接口不一致,所以给开发人员带来额外的工作量。Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 Restful 风格的 Web 服务。Swagger 提供在线API 接口文档,开发者可通过浏览器在线查看接口规范并且可在线单元测试。

6 结语

在拆除省界收费站的背景下,ETC 发行业务得到大力推广,传统办理模式远远不能满足当前业务需求。本文通过对比单体架构和微服务架构优缺点,决定采用微服务架构来设计并实现社会化发行系统。社会化发行系统采用前后端分离技术。前端使用VUE 框架实现H5页面,为各商户接入提供方便快捷的解决方案。微服务后台采用SpringCloud 技术体系,其具备独立开发部署、松耦合、弹性扩张、高并发等特点。面对不同接入方需求,本系统即提供通用H5 页面又提供REST 风格微服务接口。因此不仅能快速响应不同的需求,而且能适配需求的弹性扩展。由于社会化发行系统并发能力以及扩展能力增强,可支持业务不断增加、扩展发行渠道。随着本系统的上线部署,客户可随时随地在不同渠道在线办理ETC 发行业务,不仅有效解决了网点少、距离远、排队等待等问题,还大大提高了ETC 发行效率,在2019 年下半年发行430 万套ETC 设备,高效完成辽宁省ETC 发行任务。

猜你喜欢
调用网关日志
一名老党员的工作日志
扶贫日志
核电项目物项调用管理的应用研究
信号系统网关设备的优化
雅皮的心情日志
游学日志
基于系统调用的恶意软件检测技术研究
LTE Small Cell网关及虚拟网关技术研究
应对气候变化需要打通“网关”
一种实时高效的伺服控制网关设计