前言
本文章是根据潘志伟老师在上海Dubbo沙龙的演讲稿进行整理,意在为大家展示最真实、最一手的沙龙技术干货。
1、作者介绍
潘志伟(微信号panzw008),现任上海融之家首席架构师,十余年互联网架构经验 ,精通Microservice Architecture ,Hadoop拥有亿级用户平台架构经验 万级并发的API网关经验。
2、上海融之家
上海融之家金融信息服务有限公司作为消费金融领域领先的信息技术服务提供商,打造了国内第一款互联网贷款搜索平台,在短短2年内,用户数从0发展到3000W+,累计撮合借款金额近150亿。
面对如此快速的发展,原有的技术架构很难支撑越来越复杂的业务场景,在系统可用性以及稳定性方面以及快速迭代方面,都给融之家技术团队带来了很大的压力。因此,如何针对当前需求,选择合适的技术架构,保证架构平滑演进。融之家技术团队从2015年截止到目前累计经历了4次演进(单体应用、多实例部署、半微服务、微服务),让平台能更懂用户,更理解用户的需求,把合适的人匹配到合适的产品。
一、单体应用
创业初期,融之家初始创业团队在进行架构选型时,主要围绕以下2点进行考虑:
1、研发资源有限,研发人力有限、技术水平有限,需要选择一个易维护、简单、方便部署的技术架构;
2、产品需要快速研发上线,并能够满足快速迭代要求;
基于以上2点的考虑,创业期平台架构和部署方式非常简单,采用最通用的Spring MVC+mybatis+MySQL架构,使用一台ECS和一台RDS部署线上环境。
这种基础架构为业务快速上线奠定了坚实的基础,App上线后的效果远超我们当初的预期,业务进入快速增长期,但简单平台架构是也带来了很多问题。
二、多实例部署
由于业务高速增长,迭代需求非常频发,但是人力资源有限,根本不可能停下来重新梳理架构,但是又必须解决目前平台架构发版后暂停服务等问题,我们选择了在维护现有系统的基础上增加多实例部署的方式来解决业务问题。
引入Nginx做反向代理,用户Session信息写入Redis,通过Redis实现多实例之间的session共享。多实例部署方式帮助我们暂时解决了问题,这种架构方式也持续了很长时间。在这段时间内我们的技术主要是做功能的迭代,更新频率非常高。值得庆幸的是付出后有很大的回报,用户量增加非常快,交易量也有很大的提升。但随之而来的新问题又出现了,由于业务之间的共享都是依赖DB,导致平台里面存在大量重复的代码,代码之间耦合非常严重,线上的Bug频发、测试回归量巨大,每次迭代上线都没有办法完成回归。
三、“半”微服务
针对线上的频发的故障以及越来越复杂的业务需求,技术团队开始考虑重构系统,考虑引入微服务,微服务的降低系统复杂度、可独立部署、容错,可扩展的优点深深吸引了我们。希望通过服务的方式来隔离不同的业务,业务之间的依赖通过接口方式执行。在微服务框架的选型中,我们比对了Dubbo和Spring Cloud,经过技术内部多次讨论最后选型Dubbo 2.5.3版本。经过重构后的业务系统如下:
四、微服务
服务化后解决了代码耦合问题,也提升了线上产品稳定性。但是每个人编写的代码风格不一致,SQL水平不一致,有些人甚至在服务层做了多表联合查询,这给后续的分库分表埋下了隐患。为了统一代码风格,加速系统的重构,技术团队结合业务现在以及同行的经验,开发了一套微服务代码工具。
同时,重新梳理了微服务组件名称以及调用的流程。接口聚合层统一命名为back层,并处理协议转化(http->Dubbo),原子服务层统一命名为basic层,每个原子服务单独连接一台数据库。
对于每个业务进行重新梳理以及服务边界划分,引入HBase、Hive、ES、HDFS等存储模引擎做数据存储,重构后的业务结构图更清晰。
五、经验分享
1、预发布环境和生产环境兼容
目前业界比较通用的开发流程为开发环境、测试环境、预发布环境、生产环境。开发环境由开发人员维护,测试环境则有测试人员维护、预发布和生产环境则有运维人员维护。但是如果预发布环境和生产环境完全一致则浪费太多机器,但是预发布环境又是缺一不可的。因此引入group分组的概念,把需要验证的basic服务和预发布的back层所引入的服务配置在同一个组,则有效的解决了预发布和生产环境一致的问题。
2、服务权限控制
平台规模越来越大,参与开发的人员也越来越多,此刻权限问题尤其重要。对于用户层面的权限控制在back层面已经完成,但是对于内部核心服务之间的RPC调用也需要权限控制的需求。但是目前Dubbo对于权限这款的控制相对比较弱,通过了解业务方的需求后,基于Filter机制实现了一套RPC调用的权限认证。
支持如下授权:
按Application授权
根据IP地址授权
基于时间范围授权
基于方法名授权
非授权业务方试图调用服务则会触发告警
3、线程隔离
为了做到千人千面的推荐场景,在我们的App“借钱”列表中会调用后台几十个服务,而且会根据用户的行为实时调整排序逻辑。我们对于聚合后的响应时间也有明确约定要求<=1秒。为满足业务方 需求,重新梳理了业务调用逻辑以及依赖关系,改掉了之前串行调用方式,把能并行调用的服务的全部并行调用。设置ExecutorService来并行化调用,通过future来获取结果,同时设置了future.get 的超时时间。
然后由于依赖的后台服务过多,有些服务响应不及时,在高并发的场景下业务聚合层(back)的tomcat线程池爆满,拖垮整个服务,引起平台雪崩。技术团队引入Hystrix利用线程池隔离的方式来规避因某个服务响应慢而拖垮整个平台。为了降低现在代码改动量,基于hystrix做了自定义annotation,只要使用自定义的注解并设置响应的参数即可完成线程池的隔离。
4、熔断机制
我们希望能在配置中心手动触发熔断以及达到熔断触发值后能立即熔断且主动报警,如果直接使用hystrix提供的@HystrixCommand注解不能实现手动触发机制。对于熔断的一些指标如错误率、时间窗口、主动告警等做了个性化设置。基于上述的需求通过注解方式实现了@JdqHystrixCommand注解。只需要在需要熔断的方式上增加一句注解即可。
5、Mock平台
在开发、测试过程中经常出现这样的场景,前后端接口协议已经定义,但是后端依赖的很多服务,其中部分服务还没有提供,为了不影响开发进度,需要mock一些数据。测试人员需要模拟一次支付成功、注册失败、5秒延时返回结果,服务异常等等场景。需要能方便模拟,而且不需要研发人员修改任何代码。基于Dubbo的Filter机制实现了一套Mock平台,JDQMockFilter会在Consumer端以及Provider端执行。JDQMockFilter拿到请求后会先调用Mock平台查询是否有Mock服务。
6、监控
服务拆分后出现大量的服务组件,必须要时刻了微服务运行状态, Dubbo自带的简易监控中心不能满足我们监控需求。所以基于Dubbo的MonitorService自研了一套监控平台,实时收集微服务运行期间所产生的成功率、失败率、平均耗时、最大耗时、并发量、数据传输排行等。对于服务的下线,耗时过长都会触发报警。
7、服务框架预览
经过4次的架构演变,平台的稳定性、吞吐量、并发量都有非常大的提升,整个RPC框架也重新定义了,增加了权限平台,mock平台,监控平台。
六、总结
微服务架构可以更好的进行业务解耦,具备更好的扩展性以及独立性,可以提高研发团队间的并行化研发速度,提升效率、提高模块复用性,具备高可用、高并发特性。但微服务架构对服务治理的能力要求比较高,维护成本也会比单体应用高。Dubbo 出生于阿里系,是阿里巴巴服务化治理的核心框架,并被广泛应用于中国各互联网公司;只需要通过 Spring 配置的方式即可完成服务化,对于应用无入侵。我们借助Dubbo完成了微服务重构,目前用户数以及接口调用量都在不断提升。
欢迎大家关注阿里中间件微信公众号,所有中间件活动预告和回顾(含PPT和演讲稿)都会发布在此公众号,而且每周都会分享最前沿的技术干货,最in的程序圈子,你还不加入?开源社区由您创造!