云服务下的最佳拍档
2019-10-21金琦邱元阳刘宗凡倪俊杰杨磊
金琦 邱元阳 刘宗凡 倪俊杰 杨磊
编者按:随着互联网、云计算的高速发展,人们对数据信息化服务依赖程度越来越深。以往的单体应用架构和面向服务化应用的架构逐渐不能满足业务的需求。而微服务这种分布式架构的兴起,是云计算应用快速发展的必然产物,也将是未来整个软件应用架构向灵活多变、低耦合、高扩展性、动态伸缩发展的方向之一。与此同时,以Docker为代表的容器虚拟化技术将极大减少微服务应用实现大规模部署、落地的成本。
在上一期的文章中,我们介绍了Docker的概念、基本使用方法、基本使用体验,可能有的读者尝试过搭建Docker环境,拉取把程序和环境合在一起的镜像来运行容器,开发环境、测试环境、业务使用环境就能非常方便地保持一致。甚至你会想到既然使用容器技术能带来这么多方便.是否能把更多的学校业务进行容器化,这样的想法很好,现在我们耳熟能详的“微服务”就是将一个大系统拆分拆解为多个容器,将每一个微服务单独部署在云平台的一个容器中,把多个接口用常用HTTP API进行封装,对外提供一个简单明了的接口,实现多个个体应用服务部署上的独立和统一,从而使服务有更高的可靠性。
第一代显示技术CRT
金琦:经过一个周期的教育信息化建设,当前教育信息化又衍生和积累了一些新现象和新问题.教育信息化发展呈现出智能化、开放化,个性化与社交化等特征。“智慧校园”逐渐取代“数字校园”,而云服务是智慧校园的主要技术载体。在云服务模式中,各类资源和应用以不同的形式动态地、碎片化地、按需地提供给师生及管理者,实现对教学.学习、管理的无缝服务,从而使学校从庞杂的信息化系统建设中解放出来,更多地关注教学和学习本身。云服务具有低成本部署、高效资源应用、受客户端访问等特征,可大大降低学校信息化建设的门槛。《教育信息化2.0行动计划》明确提出,“充分利用云计算、大数据、人工智能等新技术,构建全方位、全过程、全天候的支撑体系,助力教育教学、管理和服务的改革发展”。
邱元阳:云服务是目前各行业包括教育行业广泛应用的一种信息化服务模式。它采用虚拟化技术调配资源(网络,服务器、存储、应用和服务等),允许用户根据需求通过网络申请资源,而这些资源以最小化的管理和交互成本来快速供应和释放。云服务主要分为三种服务模式(如图1),这个分法主要是从用户体验的角度出发的。
(1)基础设施即服务(laaS.Infrastructure as aService),是指用户通过网络可以获得计算机基础设施的服务。目前主要通过虚拟化技术采用模块化建设,对计算、存储、网络、安全等基础IT设施进行资源池化,通过统一的云平台管理系统实现自动化、智能化、集中化的业务编排和调度管理。目前对学校来说,关心的是由各类大数据采集器、传感器、网络设备等构成能够识别学生不同诉求并提供个性化学习模式的物联网环境。
(2)平台即服务(PaaS,Platform as a Service).是指把软件开发的平台作为一种可以获得的服务,交给用户使用。主要实现平台核心组件,包括设备管理,通信协议互联、流媒体处理、安全管理、移动服务管理等。目前对学校来说,关心的是为师生建立起统一的便捷的资源获取途径及资源平台。
(3)软件即服务(saaS,Software as a Service),是指用户不需要购买并安装软件,直接使用服务商云端提供的软件,只需管理自己的业务数据就可以了。对学校来说,关心的是覆盖校园各类管理、教务教学、个性学习和评测、云盘和云桌面等功能,能够随时随地为学生、教师、家长、公众等不同用户提供全方位、个性化的全流程应用与服务。
刘宗凡:上面讲的云服务体系架构从用户体验角度的确容易理解,因为从这个角度而言,它们之间关系是独立的,毕竟它们面对不同类型的用户。另外,我们也可以从技术角度理解,就这个角度而言.它们并不是简单的继承关系(PaaS基于Iaa.而SaaS基于PaaS).因为首先SaaS可以是基于PaaS或者直接部署于laaS之上,其次PaaS可以构建于laaS之上,也可以直接构建在物理资源之上。有了Docker的加入,PaaS将有更大的发挥空间,甚至在云计算的基础领域部分取代laaS。目前的laaS只是取代了传统的服务器,其环境和应用的部署与传统相比差异很小,只是在运维上有很大的改变。PaaS这种开关式的环境搭建显然比laaS要方便很多,符合技术发展的趋势。如果只是为部署一般应用,PaaS就可以胜任,但laaS大行其道的原因就是,每个应用方都有不同的需求,而有些独特的需求在公有云模板化的运行环境中无法支撑.这样超出模板外的需求可用Web API来实现,如果对资源有需求则用单独的laaS来实现,这样就可以覆盖多数需求。
在PaaS层中,以前都是服务商提供应用开发框架和部署工具,大多数PaaS解决方案都用容器来定义应用单元,隔离和管理应用运行。但是,在一个传统的PaaS中,应用容器是被平台控制的,对用户是不可见的。一個叫DotCloud的PaaS服务商认识到用户对底层的容器技术更感兴趣,于是在2013年将其容器技术开源,这就是后来的Docker,将应用容器的控制权从平台服务商交到用户手中,是一个明智的选择。现在应用容器可以被用做一个可插拔的应用交付和运维单元,这样应用方的信息化建设就可以不再被锁定到一个平台上了。在Docker的体系中,关键的有两个——Docker Register和Docker Engine,前者负责构建和分发应用镜像,后者负责构建容器。这样的组合方式.符合云服务中的软件即服务(SaaS)理念,用户可以在各自的数据中心内建立私有的Docker Register,形成属于自己的私有集群,以应对大规模的应用扩展需求。Docker很像一个集装箱,通过LXC技术先进行整合镜像,再集中汇总进行分发。特点体现在,具有标准的镜像结构既实现了对不同资源实行不同存储的功能,也能满足大规模的托管服务,对于有主机集群的云服务平台,通过分解应用构建。发布等方式实现对云计算技术的开发,在实现云服务平台的构建的同时,还可以进行优化和自动化维护环境,使得工作效率能够得到有效提升,在降低成本的同时,满足了接下来我们要重点讨论的微服务架构所需要的资源。
什么是微服务架构
金琦:以前教育行业的软件架构多为单体架构,信息化业务单一,系统构建并不复杂,所有的代码、数据库、业务文件都部署在一台机器上,即使碰到类似阅卷、选课并发访问量大的情况.应对也就是对硬件软件进行改造(如增加缓存,把应用服务和数据服务进行分离、单机改为集群),这依然是单体架构的思想。但随着学校信息化的进一步发展,对软件的依赖也逐渐加深,需要信息化部门为学校加速业务处理效率和提高数据挖掘能力的时候,通常就会遇到“信息孤岛”,即学校的业务数据沉淀在应用内部,无法被其他应用有效使用。应用程序孤岛效应主要集中在业务和数据的两个方面。业务模块只能在应用程序的边界内使用,无法突破边界提供外部的调用。数据也同样被应用程序看作是程序的一部分,数据的产生、读取、写入,定义解释都强依赖于应用程序的代码,甚至于脱离应用程序代码,数据就会变成一堆无法读懂的垃圾数据。此时的学校信息化服务就逐渐成为业务信息流动的阻碍,进而成为学校业务进一步发展的阻碍.但是此时的学校又没有足够的资源去突破“孤岛”。
倪俊杰:其实业界对单体系统并不是没有解决方案,而且解决方案很早就提出来了,就是SOA(面向服务架构),其大致的意思就是在不破坏应用程序独立性的前提下,由应用程序把功能以服务的形式暴露,提供给外部通过标准协议进行调用,实现需求方各个应用之间的交互和协作,达到打破应用“孤岛”效应的效果。但SOA事实上是针对大型企业的特点,如遵从企业服务总线对项目模块化,而非学校比较需要的服务模块化,所以从部分学校的SOA实践来看,其实施效果并不理想。主要的原因在于不同应用的服务之间协作涉及到大量和各自业务相关的数据操作,各应用缺乏统一业务处理流程,难以统一。所以从学校的角度来看,为了实现SOA需要对应用进行大量的定制化开发,实施难度和代价都比较高:平台升级需要重新构建、编译、打包部署,学校应用整个服务层是有多少个服务实例就必须要有多少个配套的虚拟机工作才能把这套系统支撑起来,总体看运维成本也比较高,制约了SOA在学校的推广和落地的速度。但是通过应用之间的联通来打破“孤岛效应”,实现学校应用之间的高效协作,是提高学校业务运转效率的一种正确的方式。我们不能简单地说一种架构比另一种架构更好,这主要取决于正在构建的应用程序的目的。SOA更适合需要与许多其他应用程序集成的大型复杂企业应用程序环境。也就是说,小型应用程序不适合SOA架构,因为它们不需要消息中间件组件。而微服务架构可以为开发人员提供更大的控制权,所以更适合于学校这样可以较小和良好地分割并有基于Web系统和移动应用的使用场景,所以SOA和微服务这两种不同类型的体系结构是根据不同的场景需求来选择的。
邱元阳:关于微服务.本刊2017年第7期《弱水三千,只需一脑壳足矣——容器与微服务》一文做了简单且形象的类比说明,接下来我们对微服务做个深入阐述,微服务可以看作是SOA服务化的升级版,微服务是一种架构风格.其概念源于Martin Fowler在2014年写的—篇博文Micro services,他提出微服务是一种架构风格,提倡将应用系统按照一定的原则将大系统拆分成一系列小型服务,每个服务只需要专注于单一的业务功能即可,并且服务之间可以互相独立运行,采用轻量级HTTP API进行通信,来满足业务和用户的需求。其强调服务的独立性、无状态、功能职责单一化,强调通过多个微服务的组合实现复杂业务,强调通过服务的替换和升级实现对企业业务的敏捷支持。通过将服务细分,微服务有望解决SOA过程中的“大”和“笨重”的问题,真正实王见IT对业务支持的“随需而动”。
在传统经典分层架构模式下(如表现层、业务层、数据层),业务虽然在逻辑划分上有模块和组件,但常作为一个整体进行编译、打包、部署、运维,因此在物理部署层面依然是一个“单块”。围绕这种架构模式,我们可以看到很多常用的IDE集成开发环境和编程框架(如eclipse、spring等),它们为开发者提供便捷的开发、调试、测试、部署等体验,让开发者可以通过工具、框架快速生成应用原型而不必将大量精力花在服务分解和分布式设计上。但是伴随着业务和功能的累积扩张,应用体积也随机迅速扩大,单块架构难以适应这种快速变化的需求,并且面临开发效率低、交付周期长、技术转型难等一系列的挑战。
微服务架构则是从架构层面出发,将应用系统按照一定的边界分解成一系列的独立微服务(如图2),每个微服务与传统应用中的逻辑模块或组件相当.但是可以独立地进行编译、部署、运行,具有独立部署、复杂度可控、技术选型灵活和高扩展性的特征。微服务的主要优点有:职责单一,每个服务只做一件事情,并通过定义良好的接口清晰表述服务边界:业务粒度微小,由于体积小、复杂度低,每个微服务可由一个小规模开发团队完全掌控,易于保持高可維护性和开发效率:隔离性好,每个微服务都可以独立部署,互相隔离,互不影响,一个服务停机不会影响其他服务:管理容易,每个服务可以独立地进行开发部署,可以针对业务特点使用不同的开发语言,系统不会长期限制在某个技术上:微服务的系统架构还让微服务与微服务之间在结构上“松耦合”,而在功能上则表现为一个统一的整体。这种所谓的“统一的整体”表现出来的是统一风格的界面、统一的权限管理、统一的安全策略、统一的上线过程、统一的日志和审计方法、统一的调度方式、统一的访问入口等。
当然.像任何其他技术一样,微服务架构也存在不足,主要表现在:
(1)通信成本高。在单体应用中的一个函数或进程调用在微服务架构下可能变成了一个HTTP远程调用,网络延迟会带来更长的耗时.造成更高的通信成本。
(2)数据一致性问题。在单体应用中数据通常存储在一个数据库中,保证数据的—致性很容易,而在微服务架构下,通常不同的微服务有不同的数据库,但往往一个操作可能会涉及多个微服务的互相调用,当服务很多时整个调用链路变长,调用失败的风险高,在这种分布式架构下更难保证数据的一致性和可靠性。
(3)部署复杂。微服务化后服务实例变多,造成更多需要部署、配置和监控的部分,此外,一个应用的改变可能会波及多个服务.扩展和监控难度更大。微服务架构在容器云中的实践
金琦:将业务系统组件化和服务化的“微服务技术”,为系统建设者提供了一个更好的选择,让系统建设者更专注于解决业务问题本身。通过前面的讨论,我们已经了解了单体应用、SOA和微服务应用的优点和缺点。在实际的业务场景中,我们应该怎么去规划和构建属于学校自己的微服务呢?
杨磊:对于“微服务”的概念以及特点相信大家已经有一定的了解了,其实单从概念来说.是比较容易理解的。那应该如何把一个单体应用拆分成多个微服务呢?下面我以“课堂考勤办公业务”为例,通过对该单体应用的拆分,一起来了解一下微服务体系应该有哪些构成。
首先,我们从学校集成门户界面中访问课堂考勤办公业务,可以将这个业务拆分成三个独立的子微服务:学校排课微服务.学生选课微服务、数据中心微服务。
(1)学校排课微服务。包含根据时间点全校所有教学班排课的XML表,建立对应排课Javabean对象,然后利用JDK自带的JAXB解析包,可以方便地将该XML表解析转换成排课对象,并对外暴露接口/courseschedule,提供排课列表Json数据。
(2)学生选课微服务。该模块依赖数据中心微服务,完成学生选课功能,并公布选课情况接口/report/t class_selection/{class_selection}。
(3)数据中心微服务。公布教师信息接口/report/teacherlD/{teacherlD}和公布学生信息接口/report/studentlD/{studentlD}。
其次.我们结合开发框架Spring cloud来阐述一下“微服务”在技术层面的实现和架构。Spring Cloud是一系列框架、组件的有序集合,拥有功能完善的、轻量级的微服务实现组件,如服务发现治理、服务容错、服务网关、服务配置,负载均衡、消息总线、服务跟踪等方面均有经过实践检验的成熟组件。系统采用Eureka做服务注册与发现,Zuul做路由API网关,Ribbon做负载均衡,Hystrix做服务熔断,Spring Cloud Config做统一管理微服务配置。
这样,微服务的基础组件就都有了,结合上一步拆分出的微服务,可做出如图3所示的架构图。
从图3中可以看到一所学校有诸如“学校排课…数据中心”等多个业务,拆分多个模块后,就会出现多样的问题,而springCloud提供了一整套的解决方案,从而可以统一管理各服务中心的配置,并且在运行期间可以动态修改配置文件。
CAS解决学校的师生在多个微服务之间切换时,需要重复登录的问题完成统一认证。
ZUUL网关根据URL转发请求到不同的微服务。例如,教师用户请求访问课堂考勤微服务接口,网关再把所有请求转发到具体的学校排课。学生选课、数据中心相关微服务中,其中的映射关系如下:
Eureka专门给各种服务提供注册登记,配置服务注册中心的URL地址。一个微服务就是一个节点,是一个完整的应用程序,并且可独立运行部署。系统除了前面和业务相关的微服务外,还有API网关节点、配置中心Config—Server节点,Turbine的Hystrix监控节点等。这些节点都是以Eureka客户端形式注册在Eureka服务端,然后各个节点间采用轻量级Feign组件就可以实现相互调用通信了,同时也实现了对各种服务可用性的监控。
Ribbon是支持负载均衡,默认的负载均衡策略是轮询,我们也可以根据自己实际的需求自定义负载均衡策略。
Hystrix通过添加延迟容忍和容错逻辑,帮助控制这些分布式服务之间的交互。Hystrix通过隔离服务之间的访问点、停止级联失败和提供回退选项来实现这一点,这些都可以提高系统的整体弹性。
金琦:我们做了服务的拆分,也完成了单个微服务的技术实现,为了让微服务可以为学生和教师提供服务,需要将完成的微服务进行部署上线。针对微服务的部署,有什么最佳的实践呢?
刘宗凡:基于微服务的思想是可以不用容器技术的.但由于微服务应用由数十甚至上百个服务组成,服务使用不同的语言和框架编写。每个服务都是一个迷你应用,有自己特定的部署.资源、扩展和监视要求。例如,需要根据服务的需求为每个服务运行一定数量的实例。此外.必须为每个服务实例提供相应的CPU、内存和I/O资源。更有挑战性的是.尽管如此复杂.部署服务也必须要快速、可靠和具有成本效益。所以我们只是利用容器化技术简化微服务创建、集成、部署、运维的整个流程,推动微服务在云端的大规模实践,下面以一个容器云平台为例,说明各个流程的实践(如图4)。
(1)在容器云平台,用户可以很方便地创建微服务项目,并在项目中与代码仓库进行关联,轻松选择代码项目进行构建。每当开发人员提交代码时,系统可以自动将存于代码仓库的微服务程序快速构建成新的容器镜像,经过持续集成自动化验证后转化为随时可以部署的容器镜像.用户可以将这个微服务一键部署到容器云平台上。
(2)在镜像仓库支持加入平台以外的任意镜像源.如可以加入Docker官方和社区的优质镜像,用户可以根据自己的业务需要.像搭积木一样自由组合、复用各种容器化微服务,轻松集成应用。例如,用户需要一个通用的tomcat網站服务或者MySQL数据库,可以直接在镜像中选择适合的数据库服务镜像,并与其业务连接起来。可以一次部署多个镜像并为每个镜像的容器设定CPU和内存占用。从配置部署到启动只需要几分钟。
(3)平台支持升级回滚。平台部署有完整的版本管理,每次升级会生成一个部署版本,可以随意选择一个旧版本进行回滚,部署出现异常时可以指定版本恢复。
我们用Docker容器快速编排所有节点,其中这三个示例的微服务节点都要启动三个实例以作负载均衡。系统运行在阿里云服务器上,不同节点采用不同的端口,如学校排课微服务microservice-classschedules-report提供面向用户接口/report/classscheduleslD/{classscheduleslD},供用户查询学校最新的排课数据。同时访问Turbine聚合节点,可以监控多个微服务运行状态。
后记
虽然微服务架构带来了诸多优势,但构建、部署、维护分布式的微服务系统并不容易。而容器所提供的轻量级的、面向应用的虚拟化运行环境为微服务提供了理想的载体。同样,基于容器技术的云服务将极大地简化容器化微服务创建、集成、部署、运维的整个流程,从而推动微服务在云端的大规模实践。
构建复杂的应用确实非常困难,而微服务架构模式可以使构建复杂应用变得简单化。微服务架构的诞生和容器技术的流行几乎是同时发生的,是互联网时代倒逼传统技术和架构而产生的变革,基于容器技术的PaaS平台给开发者提供了一个部署和管理微服务的简单方法,它把所有这些问题都打包内置解决了。