金融行业微服务架构解析
引言:
对于微服务,每个人都有自己的理解,与互联网企业的大量落地相比,微服务在传统金融行业还没有普及,这首先是传统金融行业线上系统需求更新和版本迭代没有互联网公司那么频繁;其次是技术能力约束了新技术的落地;再者传统金融行业对系统可用性和稳定性的要求非常高。
如何理解微服务架构?微服务能够给金融行业带来什么?金融行业微服务架构如何选型?这些都需要我们对微服务架构进行深入的剖析。
目录:
一、什么是微服务
二、主流微服务框架
三、微服务架构关键技术
微服务架构定义
微服务的定义源于 2014 年 3 月 Martin Fowler 所写的一篇文章“Microservices”,微服务的四个特性定义抽象为“小、独、轻、松”。
微服务的感性认识
转型之前:
紧耦合组件
慢的部署周期,等待集成测试
转型之后:
松耦合组件
自动化部署,无需等待独立组件
微服务优势
可伸缩性:服务的承载能力在设计之初并不能完全符合后来业务发展的要求,随着业务量增大,服务要通过服务器集群方式进行扩展,各个微服务的扩展数量也是按需求扩展,承载量大的微服务扩展节点多,承载量小的微服务扩展节点少,从而实现资源有效配置。
降低风险:准备好部署各个阶段的工件,包括:构建工件,测试脚本,配置文件和部署清单文件。
a) 从负载均衡列表中移除掉“金丝雀”服务器。
b) 升级“金丝雀”应用(排掉原有流量并进行部署)。
c) 对应用进行自动化测试。
d) 将“金丝雀”服务器重新添加到负载均衡列表中(连通性和健康检查)。
e) 如果“金丝雀”在线使用测试成功,升级剩余的其他服务器。(否则就回滚)
弹性系统:在理想的设计中,一旦某一非核心微服务启动失败,其他微服务仍然可用,用户在没有使用到异常模块所提供的服务时,对这一异常完全无感知,大大增强了用户体验。
敏捷:开发成本降低,响应速度加快。各个开发团队的人员不必耗费大量时间了解整个服务端架构,主要通过了解某个微服务的金融业务需求和技术体系即可参与开发,从而降低了学习成本以及改动代码带来的风险,代码审查流程的简化也相应地加快了开发响应速度。
灵活:不要求所有的微服务都使用同一种技术和平台来实现。
微服务架构带来的问题
依赖服务变更很难跟踪,其他团队的服务接口文档过期怎么办?依赖的服务没有准备好,如何验证我开发的功能。
部分模块重复构建,跨团队、跨系统、跨语言会有很多的重复建设。
微服务放大了分布式架构的系列问题,如分布式事务怎么处理?依赖服务不稳定怎么办?
运维复杂度陡增,如:部署物数量多、监控进程多导致整体运维复杂度提升。
这些解决方案折腾到最后就会明白,原来我们要有一个微服务应用平台才能整体性的解决这些问题。
微服务架构适用场景
微服务架构并不是万能的,有它适合采用的系统,这些系统包括:
对于业务流程较为复杂,且业务会逐渐变得更加复杂的系统,单体应用将十分庞大,后期难以修改和维护,应考虑使用微服务架构。
为了满足业务需求,项目中引入了众多的技术栈,中间件,单体应用会给开发者带来很大的困扰,应考虑将应用拆分成多个独立部署的采用最优技术栈实施的微服务。
高并发的,有高可用和弹性伸缩需求的系统,往往是那些面向庞大数量互联网用户的平台类、交易类系统,应考虑利用微服务架构便于横向扩展和弹性伸缩的特性。
单体应用版本发布成本高,而单个微服务的变更和发布都很容易,那些有高频率版本发布需求的系统,应使用微服务架构。
没有数据实时强一致要求,可接受数据最终一致的系统,可使用微服务架构。
在银行系统中:
OA、HR、绩效等管理类系统并不需要微服务架构;
信贷、CRM等管理类应用如果体积庞大(几十万行代码以上),要使用微服务改造;
中间业务、核心账务、网银由于系统压力大,可以采用微服务架构。
微服务架构在互联网金融方面的应用
第三方支付包括以支付宝、财付通、盛付通为代表的互联网支付企业,也包括快钱、汇付天下为代表的金融型支付企业。
P2P小额信贷是一种个人对个人的直接信贷模式。
大数据金融是指集合海量非结构化数据,通过对其进行实时分析,可以为互联网金融机构提供客户全方位信息。
众筹融资指用团购+预购的形式,向网友募集项目资金的模式。众筹利用互联网传播的特性,让小企业、艺术家或个人对公众展示他们的创意,争取大家的关注和支持,进而获得所需要的资金援助。
所谓信息化金融机构,是指通过采用信息技术,对传统运营流程进行改造活重构,实现经营、管理全面电子化的银行、证券和保险等金融机构。
互联网金融门户是指利用互联网进行金融产品的销售以及为金融产品销售提供第三方服务的平台。它的核心就是“搜索+比价”的模式。
业界开源微服务框架方案比较
综合来看,SpringCloud是首选。为什么选择SpringCloud?
不只是解决微服务的某一个问题,而是一个解决微服务架构实施的综合性解决框架;
整合了诸多被广泛实践和证明过的框架作为实施的基础部件,又在该体系基础上创建了一些非常优秀的边缘组件 ;
大量的兼容性测试,保证了更好的稳定性;
极高的社区活跃度;
SpringCloud之于其他微服务框架就好比是:品牌机 VS DIY电脑
微服务平台技术图谱
微服务技术桟:
API Doc: Swagger UI
API Mock: Swagger Mock API
AOP基础框架:Spring framework
微服务容器:Spring Boot
服务发布:Spring Web MVC
服务注册中心:Spring Cloud - Eureka
服务路由:Spring Cloud – Ribbon
服务调用:Spring Cloud – Feign
服务熔断器:Spring Cloud – Hystrix
安全认证:Spring Cloud - Security
服务配置中心:Apollo , Spring Cloud – Config
服务监控:Spring Boot Admin
关键技术架构与设计
我们从这9个方面来解析微服务关键技术架构与设计。
1、前端UI框架
兼容性
Vue是流行的前端框架,其对浏览器的兼容性较好,主流的操作系统和浏览器都支持。
vue响应式双向数据绑定实现自动同步
vue.js采用数据劫持结合发布者-订阅者的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时,发布消息给订阅者,触发相应的监听回调。
具体的来讲,Vue.js通过Directives指令去对DOM做封装,当数据发生变化,会通知指令去修改对应的DOM,数据驱动DOM的变化。vue.js还会对操作做一些监听(DOM Listener),当我们修改视图的时候,vue.js监听到这些变化,从而改变数据。这样就形成了数据的双向绑定。
2、微服务容器
微服务运行的容器环境
我们来看一下微服务运行容器,要做可靠高效的微服务架构应用,实际上我们需要做的事情还是非常多的。如果没有一个统一的微服务容器,这些能力在每个微服务组件中都需要建设一遍,而且会五花八门,也很难集成到一起。
微服务容器:负载均衡
微服务容器的基础服务能力之一就是支持负载均衡。
通常所说的负载均衡都指的是服务端负载均衡,其中分为硬件负载均衡和软件负载均衡。硬件负载均衡主要通过在服务器节点之间安装专门用于负载均衡的设备,比如F5等;而软件负载均衡则是通过在服务器上安装一些具有负载均衡功能或模块的软件来完成请求分发工作,比如Nigix等。
客户端负载均衡和服务器负载均衡最大的不同点在于上面所提到的服务清单所存储的位置。在客户端负载均衡中,所有客户端节点都维护着自己要访问的服务端清单,而这些服务端的清单来自于服务注册中心,建议使用Spring Cloud Netflix 的Ribbon组件。
微服务容器:服务熔断、容错、升降级、限流
微服务容器的基础服务能力之二就是服务熔断、容错、升降级、限流,在系统出现异常时提供故障恢复能力。
3、注册中心
服务注册与发现
一般情况,系统内微服务的调用都通过这种客户端负载均衡的模式进行,否则就需要有很多的负载均衡进程。跨业务系统的服务调用,也可以采用这种去中心化的路由方式。当然采用SOA的模式,由中心化的服务网管来管理系统间的调用也是另一种选择,要结合企业的IT现状和需求来决定。
4、配置中心
集中配置管理
微服务分布式环境下,一个系统拆分为很多个微服务,一定要告别投产或运维手工修改配置的方式。需要采用集中配置管理的方式来提升运维的效率。
配置文件主要有运行前的静态配置和运行期的动态配置两种。静态配置通常是在编译部署包之前设置好。动态配置则是系统运行过程中需要调整的系统变量或者业务参数。
要想做到集中的配置管理,那么需要注意以下几点:
配置与介质分离,这个就需要通过制定规范的方式来控制。千万别把配置放在Jar包里。
配置的方式要统一,格式、读写方式、变更热更新的模式尽量统一,要采用统一的配置框架
运行时需要有个配置中心来统一管理业务系统中的配置信息,这个就需要平台来提供配置中心服务和配置管理门户。
配置修改同步交互
配置修改后通过推送或者定时拉取的方式更新并缓存到应用程序所在的微服务容器中供应用程序使用。
高可用运行架构设计
配置中心有两种部署模式
高可用模式,见上图,支撑大规模微服务访问时根据负载情况可以对“配置查询同步服务”进行横向扩展
ALL-IN-ONE模式,配置变更服务、配置查询服务合并为一个进程。适合支撑少量系统的场景使用。
配置中心可以支持高可用模式部署,满足金融行业的要求。
5、监控中心
基于Skywalking定制实现
SkyWalking主要就是通过收集各种格式的数据进行存储,然后展示。所以我们需要关注的是 SkyWalking Collecter、SkyWalking UI 和 存储设备。
APM探针
JavaAgent 是JDK 1.5 以后引入的,也可以叫做Java代理。
JavaAgent 是运行在 main方法之前的拦截器,它内定的方法名叫 premain ,也就是说先执行 premain 方法然后再执行 main 方法。
使用agent技术构建一个独立于应用程序的代理程序(即为Agent),用来协助监测、运行甚至替换其他JVM上的程序。使用它可以实现虚拟机级别的AOP功能。
APM全链路运行监控
调用链跟踪分析:把同一TraceID的Span收集起来,按时间排序就是timeline。把ParentID串起来就是调用栈。
实时分析:对单条日志直接分析,不做汇总,重组。得到当前QPS,延迟。
离线分析:按TraceID汇总,通过Span的ID和ParentID还原调用关系,分析链路形态。
6、日志中心
日志中心架构
日志分析是运维工程师解决系统故障,发现问题的主要手段。日志主要包括系统日志、应用程序日志和安全日志。系统运维和开发人员可以通过日志了解服务器软硬件信息、检查配置过程中的错误及错误发生的原因。经常分析日志可以了解服务器的负荷,性能安全性,从而及时采取措施纠正错误。
通常,日志被分散的储存在不同的设备上。如果你管理数十上百台服务器,你还在使用依次登录每台机器的传统方法查阅日志,即繁琐又效率低下。为此,我们使用集中化的日志管理,将所有服务器上的日志收集汇总。
集中化管理日志后,日志的统计和检索又成为一件比较麻烦的事情,这时实时日志分析ELK平台能够完美的解决上述的问题,ELK由ElasticSearch、Logstash和Kiabana三个开源工具组成。
规范日志与流水,问题追根溯源
作为一个微服务应用平台除了提供支撑开发和运行的技术组件和框架之外,还应该提供一些运维友好的经验总结,我们推荐的日志与流水实现如下:
先来看日志,平台应提供的日志主要有三种,系统日志,引擎日志还有跟踪日志。有了这些日志,在出问题的时候能够帮助我们获取一些关键信息进行问题定位。
要想做到出了问题能够追根溯源,那么右边的这些流水号的设计也是非常重要的,日志与各种流水号配合,能够让我们快速定位问题发生的具体时间地点以及相关信息,能够快速还原业务交易全链路。对这些日志与流水的细节处理,对于系统运维问题定位有非常大的帮助,没有这些有用的日志内容,ELK日志收集套件搭建的再漂亮,收一堆垃圾日志也是没用的。
通常开源框架只是提供个框架有开发人员自由发挥,而设计一个平台则一定要考虑直接提供统一规范的基础能力。
7、API Gateway
基于Spring Cloud Netflix的Zuul组件定制实现
异步非阻塞模式启动的线程很少,基本上一个CPU core上只需启一个处理线程,它使用的线程资源就很少,上下文切换(Context Switch)开销也少。非阻塞模式可以接受的连接数大大增加,可以简单理解为请求来了只需要进队列,这个队列的容量可以设得很大,只要不超时,队列中的请求都会被依次处理。
API Gateway逻辑架构
API网关就像整个系统的门面一样,所有的外部访问都经过它实现调度、过滤、请求路由、负载均衡、校验等等。
API Gateway 功能
API网关上还可以实现更多更复杂的功能。
8、IAM(Identity and Access Management)
IAM架构
IAM为企业提供统一的账号管理视角,对所有基于账号的管理、认证、授权、审计进行集中的统一管理,提高了账号管理的安全,帮助系统管理员提高了工作效率,降低了管理负担,同时改善了普通用户在不同资源中登录认证的重复繁琐过程,为日常工作提供了更高的安全性。
统一用户中心
IAM可以为企业所有的资源使用人员如普通用户、系统管理人员、驻场代维人员、合作伙伴、临时工作人员等定义主账号,按照公司的组织方式对人员进行管理。通过一对一的主账号管理模式,可以在该平台实现对所有资源使用人员进行集中定义、集中维护等生命周期管理。
统一认证与鉴权
安全认证方面,我们基于Spring Security结合Auth2再加上JWT(Json web token)做安全令牌,实现统一的安全认证与鉴权,使得微服务之间能够按需隔离和安全互通。认证鉴权一定是个公共的服务,而不是多个系统各自建设。
9、微服务管理
服务管理机制
服务提供者:
服务注册
在服务注册时,需要确认下eureka.client.register-with-eureka=true参数是否正确,默认为true,若设置为false将不会启动注册操作。
服务同步
由于服务注册中心之间因互相注册为服务,当服务提供者发送注册请求到一个服务注册中心,它会将该请求转发给集群中相连的其他注册中心,从而实现注册中心之间的服务同步。
服务续约
eureka.instance.lease-renewal-interval-in-seconds参数用于定义服务续约任务的调用间隔时间默认30秒。
eureka.instance.lease-exptration-duration-in-seconds参数用于定义服务失效时间,默认为90秒。
服务消费者:
获取服务
当我们启动服务消费者时候,它会发送一个REST请求给服务注册中心,来获取上面注册的服务清单。为了性能考虑,Eureka Server会维护一份只读的服务清单来返回给客户端,同时该缓存清单会每隔30秒更新一次。
服务调用
服务消费者在获取服务清单后,通过服务名可以获得具体提供服务的实例名和该实例的元数据。因为有这些服务实例的详细信息,所以客户端可以根据自己的需要决定具体调用哪个实例。
单服务异常导致雪崩
采用微服务架构后,服务之间会有错综复杂的依赖关系,例如,一个前端请求一般会依赖于多个后端服务。
在微服务架构中,存在着那么多的服务单元,若一个单元出现故障,就很容易因依赖关系而引发故障的蔓延,最终导致整个系统的瘫痪,造成所谓的雪崩效应,这样的架构较传统架构更加不稳定。
自我保护
当网络分区故障发生时,微服务与Eureka Server之间无法正常通信,而微服务本身是正常运行的,此时不应该移除这个微服务,所以引入了自我保护机制。
服务注册到Eureka Server之后,会维护一个心跳连接,告诉Eureka Server自己还活着。Eureka Server在运行期间,会统计心跳失败的比例在15分钟之内是否低于85%,如果出现低于的情况,Eureka Server会将当前的实例注册信息保护起来,让这些实例不会过期,尽可能保护这些注册信息。
服务容错处理
资源隔离:包括线程池隔离和信号量隔离,限制调用分布式服务的资源使用,某一个调用的服务出现问题不会影响其他服务调用
降级机制:超时降级、资源不足时(线程或信号量)降级,降级后可以配合降级接口返回托底数据。
熔断:当失败率达到阀值自动触发降级(如因网络故障/超时造成的失败率高),熔断器触发的快速失败会进行快速恢复。
缓存:提供了请求缓存、请求合并实现。
精选提问:
问1:服务下线之后,eureka默认有30秒的心跳,怎么做到优雅下线呢?
答:spring-boot-starter-actuator中提供了/shutdown的方式优雅下线。
问2:微服务中事物的一致性怎么保证?
答:事务一致性保证:可靠事件模式、补偿模式、TCC。
问3:hystrix不更新了,有别的替换组件吗?
答:hystrix不更新,可以选择Resilience4j和Sentinel。
问4:服务提供者a 往eureka注册了服务,不希望 B 能看到这个服务。能做到吗?
答:应用注册到Eureka可以进行分组,服务消费端可以指定访问目标应用的其中一个组内的实例。
问5:IAM的授权是全局的还是只是账户管理系统的,全局的怎么实现资源和资源组的统一管理?
答:IAM提供统一账户管理,授权对企业来说是全局的。资源指的是应用功能权限的话,可以集中管理或者应用自治,按需选择。
问6:微服务是否适合高并发实时数据的处理?
答:微服务是一种架构风格,具体里面的应用可以是实时交易类、数据分析类,并没有限制。
问7:微服务与大数据、分布式的关系,微服务对环境的要求是什么,单机是否可以部署微服务?
答:微服务是一种架构风格,通常采用分布式部署。如果是做demo部署到单机没问题。
问8:hystrix或sentinel能否做到对应用集群整体的流控/熔断控制啊?
答:整体的熔断一般手工做。比如通过负载均衡下线。流控hystrix貌似不管。建议流控在网关上做。
推荐阅读
关于EAWorld:微服务,DevOps,数据治理,移动架构原创技术分享。长按二维码关注!
普元金融出品金融技术系列课程——《金融技术四讲》。7月5日起,每周五直播图文微课堂,连续四周,不容错过。也希望给其他行业有所启发。