【摘要】
我所在的公司是国内主要的房地产企业之一,由于近几年房地产业务以及信息技术的飞速发展 ,公司信息化项目的管理难度以及成本也随着项目数量的增加而逐渐升高。为提高信息化项目的成功率,2017年8月,公司启动了PMO项目管理平台V1.0的开发,并于2017年11月成功投产。但经过一段时间的运行,单体架构的1.0版本系统无法适配业务的高速迭代,模块间很容易互相影响,版本发布成本非常高。因此,2018年1月,公司任命我为该项目的系统架构师兼开发负责人,负责项目的架构评审、改造设计及实现。本文结合作者的实践,以PMO项目管理平台为例,讨论微服务架构及其应用,包括微服务的基本概念及特点,如何从单块架构迁移到微服务架构,以及在实现微服务架构的过程中遇到的问题及其解决方案等等。
【正文】
项目背景
我所在的公司是国内主要的房地产企业之一,也是一家世界500强企业。众所周知,信息化是企业发展过程中的必经之路,为企业的节能提效做出了巨大的贡献。由于近几年房地产业务以及信息技术的飞速发展,公司内部的信息化建设也逐渐成型,信息化项目也越来越多,相应的管理成本和管理难度也随之升高。为了让信息化技术更好地服务于业务,推动业务的高效发展,提高信息化项目的成功率和贯彻落实公司的战略方针,2017年8月,公司成立PMO(Project Management Office),启动了PMO项目管理平台V1.0的开发,并于2017年11月成功投产。
PMO项目管理平台主要用于公司内部信息化建设项目的项目管理,主要包括项目管理(信息化项目从立项申请到项目上线运维的全生命周期管理)、产品线管理(部门内部针对业务线划分成具体的产品线,主要用于产品线内部的周报、创新等方面的管理)、资源池管理(资源池,即约定人员单价协议,按实际投入人天进行结算的外包厂商;主要包括资源池厂商的配置、协议管理、日报管理、考勤管理等)、供应商管理(信息化项目的供应商CURD、资质评审、人员管理等)、付款管理(应付未付、预测付款、历史付款、付款审批等)、任务管理(站内信以及审批待办的统一管理)以及系统管理(权限管理、基础档案管理、日志管理、系统参数管理等)等功能。
由于V1.0版本开发过程中存在明显的赶工现象,模块间的解耦设计没有做到位,模块间的变动很容易互相影响,整体修改成本比较大,每次模块内的功能改动都必须仔细评估对其他模块的影响,同时也给系统留下很大的缺陷隐患。另一方面,随着时间的推移,系统中的项目数越来越多,规模越来越大,系统的并发业务量也越来越大,开发人员进行代码维护也更加困难,代码冲突时常发生,项目构建时间也越来越长,一个微不足道的bug,就可能导致整个系统无法提供正常服务,业务对于系统的可靠性、高并发的支持等要求也越来越高。而且,单块架构的V1.0版本无法通过scale-out的方式进行动态扩展,无法满足业务的高速迭代需求。2018年1月,公司任命我为该项目的系统架构师兼开发负责人,主持项目的架构评审,改造设计及实现。根据项目的当前情况以及业务需求,经过研发团队的探讨,我决定采用微服务架构来对项目进行改造。
微服务的定义和特点
微服务,顾名思义,就是将原应用程序拆分成一个个细粒度的服务,服务单独部署,服务之间通过标准的API接口进行相互通信。与单块架构相比较,微服务架构具有以下特点:
(1)通过服务实现组件化。由于单个微服务实现简单,能够聚焦于一个指定的业务功能或业务需求,每个服务对外提供统一的轻量级REST接口,实现组件化。
(2)功能明确,易于理解。微服务能够被一个开发人员理解、修改和维护,这样小团队能够更关注自己的工作成果,便于管理。
(3)围绕业务功能构件开发团队。根据康威定律:设计系统的组织,其产生的设计和架构等价于组织间的沟通结构,所以如果采用微服务架构,需要围绕业务功能来构件开发团队,这样更符合企业的分工与组织结构,便于管理,避免出现一个开发团队负责维护多个系统服务的情况。
(4)支持多种开发语言与多种平台。不同的微服务能使用不同的语言进行开发,运行在不同的操作系统平台上,服务之间通过标准的REST接口和统一的轻量级JSON数据格式进行交互与协作。
(5)离散化数据管理。在微服务架构中,无法创建或维护统一的数据模型或结构,全局数据模型将在不同的系统之间有所区别,需要进行数据模型的离散化管理。
(6)基础设施自动化。微服务强调以灵活的方式集成自动部署,通过CI持续集成工具实现基础设施自动化,所以一般微服务都离不开DevOps。
微服务架构实践
在决定采用微服务架构之后,第一要务就是进行服务拆分。但是在推进的过程中我才发现,系统前期由于赶工,并没有采用前后端分离的方式,这样将无法实现服务的拆分以及分离部署。所以,我做的第一件事就是召集所有前端和后台开发人员对前后端交互页面进行梳理、改造,保证所有的后台接口都是符合Restful,所有的前端页面与后台接口交互时都采用ajax+json进行。经过一个多星期,结合Nginx的反向代理和SpringBoot的RestController,项目终于实现的前后端分离部署以及模块的服务化改造,为进行下一步的服务划分提供了基础。
第二步是进行服务的初步划分。说到服务划分,这是一个持续演化的过程,一般不建议直接在原系统的服务进行一刀切,一步到位。因为一般情况下,项目的技术团队比较缺乏微服务的实践经验,还需要一定的时间去适应一套新的技术架构。
为了快速积累项目团队微服务经验,我选择了一个最简单的供应商管理模块来实现微服务,并新建了一个单独的Git分支,进行独立的代码管理,而不是在原有系统分支上进行克隆改造,避免受到原有代码的影响。
第三步是以终为始,构建一个独立的敏捷微服务团队。高效的微服务团队需要是一个全栈的团队,跨职能的团队,应该包含整个项目周期的所有技能,前后端开发、UI设计、测试、构建部署、上线与运维都是必须技能。也就是说,微服务团队除了熟练的业务逻辑开发之外,还需要有DevOps能力、服务的快速构建、良好的团队文化等等。所以在这一步,我从其他团队中调配了一名熟悉DevOps工程师过来,搭建Jenkins,集成Gitlab,Sonarqube,实现代码的自检、应用的自动化构建和自动化部署。另外,也从原有开发团队抽出相应的前后端开发人员、UI以及测试人员,建立一个独立于原系统的开发团队,即实现了一个团队维护两套系统到两个团队维护两个系统的转变。
第四步是技术栈选型。由于原项目使用的是SpringMVC架构,最终我选择Spring Cloud服务框架,服务框架的选择也决定了后续的运行时支撑服务选型、服务监控选型、以及服务容错选型等等。
运行时支撑服务选型方面,服务注册中心选择使用Eureka,Eureka 在 Netflix 经过大规模生产验证,支持跨数据中心,客户端配合 Ribbon 可以实现灵活的客户端软负载;服务网关选择的是Zuul,Zuul 在 Netflix 经过大规模生产验证,支持灵活的动态过滤器脚本机制;配置中心则选用Springcloud自带的Spring Cloud Config,基本可以满足当前规模的服务治理。
服务监控方面,主要包括日志监控,调用链监控,Metrics 监控,健康检查和告警通知等产品。日志监控采用ELK(Elasticsearch+Logstash+Kibana),调用链监控采用国内比较流行的CAT。
服务容错方面,采用Hystrix。因为Hystrix针对 Java 技术栈,把熔断、隔离、限流和降级等能力封装成组件,任何依赖调用(数据库,服务,缓存)都可以封装在 Hystrix Command 之内,封装后自动具备容错能力。Hystrix 起源于 Netflix 的弹性工程项目,经过 Netflix 大规模生产验证,目前是容错组件的社区标准。
第五步是开始大刀阔斧地进行改造实现。首先针对原来的供应商管理模块进行分析整理,抽取一些可以复用的设计,达到资源的最大利用。由于供应商管理模块相对比较独立,与其他模块的耦合依赖较少,所以对原系统的改造也比较少。最终,经过两个星期的改造,供应商管理模块的所有功能成功迁移到微服务架构中。
小结
完成了第一个微服务的迁移之后,我利用Nginx进行灰度发布,不断地进行迭代演化,逐渐提高微服务的整体占比,最终,PMO项目管理平台V2.0于2018年5月份成功完成了微服务架构的迁移,原系统的所有服务都有序地整合到对应的微服务中,整个团队也成功实现了微服务转型。
持续演化的方式不但保证了系统的可用性,还提高了系统整体的可扩展性,安全性和可修改性,最大程度上保证了业务的正常运行。虽然项目的开发过程遇到了很多问题,但是在整个微服务团队的齐心协力之下,问题都得到很好的解决,达到了项目的预期目标,得到了领导和同事的一致好评。我也将在后续的工作实践中不断地学习,提高自身素质和能力,带领技术团队为公司提供更高质量的技术服务,为业务保驾护航。