基于容器云的微服务架构实践
【编者按】微服务架构的诞生和容器技术的流行,几乎是同时发生的,这并非偶然,而是互联网时代倒逼传统技术和架构而产生的变革,而以Docker 为代表的容器技术则为微服务理念提供了匹配的实现机制,本文作者从什么是微服务切入,详细的介绍了微服务架构的优势,最后从自身实践出发,给出了微服务架构的云端实践。
以下为原文:
近年来,微服务架构及容器技术备受关注,在各类文章、演讲、博客中频频亮相,成为业界最热门的话题。在时尚的词汇和热情满满的讨论背后,人们开始严肃的重新思考互联网时代服务的架构以及应用开发、运维的方法。微服务以一种全新的架构设计模式,牵动了互联网应用从设计到运维整个流程方法论的变革。而以Docker为代表的容器技术则为微服务理念提供了匹配的实现机制,进而实质性的改变了新一代应用开发和发布的方式。
什么是微服务架构?
微服务架构(Microservices Architecture)是一种架构风格(Architectural Style)和设计模式,提倡将应用分割成一系列细小的服务,每个服务专注于单一业务功能,运行于独立的进程中,服务之间边界清晰,采用轻量级通信机制(如HTTP/REST)相互沟通、配合来实现完整的应用,满足业务和用户的需求。
微服务作为架构模式的变革,其诞生绝非偶然。它是当传统服务架构在互联网时代遭遇挑战时,人们对于架构模式,开发和运维方法论的一种反思。所以,在深入探讨微服务架构之前,我们先回顾一下更为普遍的传统服务架构。
传统“单块架构”:
在过去的10多年中,甚至是微服务日趋流行的当下,绝大多数应用采用的仍是我们更为熟悉的传统架构,称之为“单块架构(Monolithic Architecture)”模式。此类架构系统通常以技术分层,例如最常见的“分层架构”中的表现层、业务逻辑层、数据层。而业务逻辑则可根据更具体的业务职责、功能进行模块化,形成逻辑组件。这里需要提一下的是,“分层架构”虽然有逻辑上的模块和组件,但在物理部署架构层面仍是一个“单块”,通常作为一个整体编译、打包、部署、运维。“单块架构”便是从物理部署角度,对于包括“分层架构”在内的应用架构模式的一种定义。
“分层架构”是软件架构体系中的经典模式,也是长时间来应用架构实际上的标准。而单块架构也有其一定优势,体现为:
- 便于开发:大量常用的集成开发环境(IDE)和编程框架(如Rails,Django)都是围绕传统架构下单块应用设计的。这些工具为开发者提供了方便和熟悉的开发、调试体验。
- 便于测试:由于整个应用包含在一个进程中,在常用工具的配合下应用可以很容易在开发、测试环境中启动。然后采用UI自动化工具(如Selenium)便可简单实现End-to-End测试。
- 便于部署:多数编程语言和框架都有特定的应用打包格式。部署只需将单一软件包复制到运行环境。而这一过程也可通过现有工具实现自动化。
由于这些优点,在项目初期,单块架构有一定的吸引力。开发者可以通过工具、框架快速生成应用原型,而不必花大量精力在服务分解和分布式架构设计上。但随着业务的扩张和功能的累积,原本简单的应用体积会迅速变大,此时单块架构很难适应快速变更的需求,由于架构层面的局限性,这类应用会面临多重挑战。
- 开发效率低:随着应用复杂度的增加,越来越少开发人员对应用能有全局性的深度理解。新功能开发和缺陷修复难度呈几何性增加。代码修改的正确性无法保障。而庞大的代码库需要更庞大的开发团队来维护,无形中又增添了管理、沟通和协调的成本。另外,新加入的团队成员需要花费大量的时间和精力来熟悉一个复杂的代码库。
- 交付周期长:在单一进程的单块架构下,任何微小的改动都需要重新编译、集成、测试和部署整个应用。随着应用体积的增大,交付流程和反馈周期都会相应变长,应用发布的代价也随之增加。于是应用交付周期变缓,交付间隙积累的代码变动增加,从而对于下次交付产生更大的压力,形成恶性循环。
- 技术转型难:单一进程、单块架构意味着中心化的技术选型。比如,应用的不同逻辑组建通常需要采用相对统一的编程语言、框架和技术栈。这些在项目初始阶段便已定型。之后,即便是应用中全新的逻辑组件,也很难采用不同的技术栈。而当应用达到一定规模后,全局化的技术栈更新会面临很高的风险。所以,单块架构应用一旦定型,就很难再享受行业技术变更、发展所带来的红利。
由于这些结构性、系统性问题的存在,单块架构下的应用越来越难适应互联网时代快速变更的市场需求。微服务便是从架构层面出发,推动传统应用开发、运维方式的变革,从而帮助企业快速响应市场需求、快速迭代、快速交付,在互联网时代保持竞争力。
微服务架构的优势:
在微服务架构下,我们将原本单一的应用按照功能边界分解成一系列独立、专注的微服务。每个微服务对应传统应用中的一个组件,但是可以独立编译、部署和扩展。相对单块架构,微服务具备以下优势。
- 复杂度可控:在将应用分解的同时,规避了原本复杂度无止境的积累。每一个微服务专注于单一功能,并通过定义良好的接口清晰表述服务边界。由于体积小、复杂度低,每个微服务可由一个小规模开发团队完全掌控,易于保持高可维护性和开发效率。
- 独立部署:由于微服务具备独立的运行进程,所以每个微服务也可以独立部署。当某个微服务发生变更时无需编译、部署整个应用。由微服务组成的应用相当于具备一系列可并行的发布流程,使得发布更加高效,同时降低对生产环境所造成的风险,最终缩短应用交付周期。
- 技术选型灵活:微服务架构下,技术选型是去中心化的。每个团队可以根据自身服务的需求和行业发展的现状,自由选择最适合的技术栈。由于每个微服务相对简单,当需要对技术栈进行升级时所面临的风险较低,甚至完全重构一个微服务也是可行的。
- 容错:当某一组建发生故障时,在单一进程的传统架构下,故障很有可能在进程内扩散,形成应用全局性的不可用。在微服务架构下,故障会被隔离在单个服务中。若设计良好,其他服务可通过重试、平稳退化等机制实现应用层面的容错。
- 扩展:单块架构应用也可以实现横向扩展,就是将整个应用完整的复制到不同的节点。当应用的不同组件在扩展需求上存在差异时,微服务架构便体现出其灵活性,因为每个服务可以根据实际需求独立进行扩展。
微服务架构的云端实践:
虽然微服务架构带来了诸多优势,但必须承认,构建,部署,维护分布式的微服务系统并不容易。而容器所提供的轻量级、面向应用的虚拟化运行环境为微服务提供了理想的载体。同样,基于容器技术的云服务将极大的简化容器化微服务创建、集成、部署、运维的整个流程,从而推动微服务在云端的大规模实践。以下将以灵雀云为例,来说明各个流程的实践:
1. 创建: 灵雀云的镜像构建和持续集成服务帮助用户将独立、可复用的微服务打包,转化为随时可以部署的容器镜像。假设用户的微服务程序,存储于GitHub等代码托管服务中,用户可以将这个代码仓库构建成容器镜像,并保存在镜像仓库中,用户可以将这个微服务一键部署到我们的容器云平台。同时,灵雀云提供了持续集成的功能,用户可以选择是否性使用。每当微服务的代码有变化时,就构建一个新的容器镜像,以便以后部署使用。
2. 集成: 该平台不仅在平台的镜像仓库中汇集了大量来自Docker官方和社区的优质镜像,也支持平台以外的任意镜像源。用户可以自由组合、复用数以万计的容器化微服务,像搭积木一样轻松集成应用。比如,用户需要一个通用的MySQL数据库服务,他无需构建镜像,可以直接在 镜像社区 中选择适合的数据库服务镜像,并与其微服务链接起来。
3. 部署: 微服务由于组件数量众多,云端部署成为实践上的一个难点。灵雀云以容器为应用发布的载体,用户不必指定传统部署方式中繁琐的步骤,只需提供容器镜像和简单的容器配置,平台会将整个部署流程自动化。另外,该平台还与docker-compose兼容,实现对于由多个微服务容器组成的完整应用的一键部署。
4. 运维: 微服务由于独立进程众多,部署后的运维、管理成为实践上的另一个难点。灵雀云完全屏蔽底层云主机和基础架构运维,让用户专注于应用。同时,通过容器编排、自动修复、自动扩展、监控日志等高级应用生命周期服务,实现容器化微服务的智能托管,进一步帮助用户降低运维成本和难度。
5. 网络: 微服务架构下各组件之间的沟通、协调对网络有较高要求,尤其在云端实践中,各个微服务组件的物理位置是动态的,且不受应用控制。灵雀云提供完整的容器网络解决方案,支持负载均衡、服务发现、跨主机关联,以及应用安全内网来确保微服务对内、对外网络的可用性及安全性。
- 首先,要实现服务的高可用性,负载均衡器是必不可少的,灵雀云支持基于传输层和应用层的负载均衡,以满足用户不同需求。
- 负载均衡也可以实现服务发现,云端部署服务时,各个组件部署的物理位置是有可能发生变化的。在灵雀云,当用户创建一个微服务的时候,不论这个服务是停止状态还是运行状态,我们都会为服务创建负载均衡器和一个域名,这样其他服务就可以通过这个域名访问该服务。即使服务中的容器实例被迁移,系统也会在它重新启动后,将它挂载回原来的负载均衡器。
- 跨主机关联,是指微服务的容器实例会被部署在不同的云主机上,但会被关联到该服务的负载均衡器上,以服务来自内网或外网的请求。
- 内部服务地址,对于很多微服务应用来说,这是个很重要的功能,比如在一个应用中,一个微服务需要访问一个 cache服务器(比如memcached),但是出于安全的考虑,不希望外部请求访问到这个cache服务器,就可以使用灵雀云的内部服务地址。系统同样会创建负载均衡,以及域名,但是这个域名只供该用户的其他服务访问,外部应用,或其他用户服务是无法访问的。
- 专属 IP是灵雀云最近新增的一个功能,有些用户由于特殊需求,不希望和其他用户共享IP,就可以申请一个专属IP,并绑定在自己的应用上,以获得更好的隔离性。
6. 存储: 微服务提倡多元化持久性(Polyglot Persistence),应用内的每个微服务可根据实际需求选择最合适的数据服务。微服务一般分两类,无状态服务和有状态服务,无状态服务比如应用服务器,他们通常是不保存数据的,方便横向的扩展。有状态服务需要存储数据,比如数据库服务,缓存服务。Docker的特性,决定了容器本身的数据并不是持久化的,需要通过挂载Volume来实现数据的存储。灵雀云将持久性云存储抽象成数据卷,可以直接挂载在容器上,并在容器重启、迁移中自动重新挂载。可支持任意容器化数据服务,供微服务应用集成。同时,支持对微服务数据的备份,恢复,和下载,可以利用备份随时恢复数据。
微服务架构的诞生和容器技术的流行,几乎是同时发生的,这并不是偶然。这是互联网时代倒逼传统技术和架构而产生的变革,最前线的开发者和他们所在的互联网企业最先感受到了这场变革。灵雀云希望与开发者一起共同引领这场变革,帮助互联网企业真正专注于自身的核心业务,并在技术和架构上保持领先。
作者简介:
陈恺,2015年正式加盟 灵雀云 ,任首席技术官。携其十数年大规模、企业级分布式系统/云平台研发经验,打造基于容器技术、面向开发者的云计算平台。加入云雀科技之前,2004年在微软从事Windows操作系统内核(Kernel)的研发,2010年出任微软云平台Windows Azure首席架构师/软件开发部经理,专注于云计算/分布式系统的研发,组建、带领团队开发Azure最核心的中控系统(Fabric Controller),管理并支撑整个云平台后端,承载千万级规模应用。