企业应用在云计算时代下的技术转型

一、云计算的历史和现状

现在无论是互联网企业还是传统的IT企业,亦或是传统行业中的企业,都在或大规模地实践,或小规模地尝试,或准备实施云计算。它们中的一些企业,比如国内的 BAT、国外的 Google、Facebook。它们自己都有大规模的服务器集群,所以很早就开始大规模地应用虚拟化以提高对计算资源的使用效率,同时也在开始使用容器技术。在05、06年的时候,Intel 和 AMD 的处理器开始提供对虚拟化技术的硬件支持,从而使得 x86 处理器开始对虚拟化技术提供良好的支持。同时,KVM 和 Xen 等技术的成熟奠定了软件方面的基础。很快地,在2006年8月份,亚马逊发布了 EC2 的试用版本,公有云计算服务开始起步。在 2007 年,Google 向 Linux 贡献了 cgroups。在此之前,Google 内部已经大规模地使用了容器技术。在 2010 年,OpenStack 的第一个版本 Austin 发布。开源 IaaS 开始起步,企业的私有云有了很好的技术基础。在2013年12月,Docker 技术发布,从此容器技术开始极速发展,一发而不可收拾。

云计算技术最大的意义是提高了计算资源的使用效率,使得大规模的服务器集群成为一个可被灵活共享的资源池。云计算使得应用对计算资源、文件存储资源、数据库资源的使用更透明、灵活、高效,从而大幅降低了企业的运营成本。同时,公有云服务使得各种新的创业项目能迅速落地实现,找到运行的环境,并为其将来可能的快速发展提供几乎无限的资源支持。

二、云计算时代的企业应用

互联网应用的特点是规模大、变化快。老牌的互联网公司,因为其大规模的服务器集群,即便提高一个百分点的资源利用率,也会节省巨大的成本。所以这些企业拥抱云计算是自然而然的事。而一个新兴的互联网创业团队,难以大规模地部署自有的服务器,也难以维持完整的运营团队,公有云便是他们的首选,而且公有云也为他们的迅速成长提供了可能。所以小规模的互联网企业也会拥抱云计算。

对于传统行业来说,云计算的到来创造了一些新形式服务,新形式的企业。例如 SalesForce,用 SaaS 的形式提供 CRM 应用。使它的用户可以用更低的成本使用优质的服务。

然而 SaaS 本质是一种公有服务,但并不是所有的企业应用都适合公有服务。部署在企业内部更安全、更快速,尤其是对于那些有大量企业应用相互集成的场景。同时,很多企业应用往往是一整套的服务,其中涉及很多的产品,全面地向公有服务方向转型其实就是设计一系列全新的产品。同时这么做也有如何让客户接受的问题。所以企业应用向 SaaS 转型的问题就不是一个单纯的技术问题,而是上升到了整个公司战略方向的问题,超出了本文的范畴,所以不在继续讨论。

1. 云计算给企业应用带来的好处

云计算的一大益处是通过弹性计算降低了硬件的使用成本,而弹性计算的本质是按需使用计算资源。所以,企业应用想要借力云计算就必须能让自己运行在云计算平台上,同时应用要具有足够的灵活性,从而可以按需使用计算资源。云计算以及其相关的技术能够给企业应用带来以下好处:

  • 虚拟化和容器化技术使资源使用更高效
  • 容器化技术使部署流程标准化、规范化
  • 容器化和分布式技术使实践微服务成为可能
  • 容器化技术使得自动化的扩容缩容更容易

虚拟化和容器化技术使资源使用更高效

云计算这些年的快速发展的一个标志是虚拟化技术,尤其是容器技术的快速发展,这些技术的发展成熟也为企业应用的架构演进提供了成熟的技术基础。

在一台服务器上,理论上你可以运行很多的进程,这些进程可以是不同的语言编写的程序,Java、C、Python、Nodejs 等等,可以使不同端口提供各种不同的服务。但是在实际应用中,这样的部署方式会极大地提高系统的复杂度,提高出错的概率。即便是相同的语言,例如 Java,不同的程序会需要不同的运行时版本。可能会依赖不同的系统组件,这些组件之间可能会相互冲突。不同程序之间会抢占系统资源,相互影响,甚至导致程序崩溃。这些问题都会导致系统复杂度提高,可用性和可维护性降低。

通过应用虚拟化和容器化技术,一台服务器的资源可以被分割为彼此相对隔离的小份,不同的应用可以在这些细分的资源中相对独立的运行。不同应用可以配置自己不同的环境而不相互冲突。不同应用对资源的使用也可进行隔离,从而避免了资源抢占导致的各种问题。

在这方面,虚拟化和容器化是一对互补的技术,粗粒度的、对安全性和隔离性要求更高的应用可以使用虚拟机这样的虚拟化技术。但是过多的虚拟机会浪费,因为虚拟机的资源是高度隔离而不易共享的,同时虚拟层的引入也会导致效率的降低。而容器化可以更细粒度,同时更高效、更轻量化地分割计算资源,使一台服务器或虚拟机可以更有效率地运行更多的服务。

容器化技术使部署流程标准化、规范化

Java 的一个口号是一次编译到处运行,但是这个目标并没有真正实现。原因在于 Java 编译出来的 artifact 本身并不能直接运行,还是依赖于第三方的类库和框架、JVM 和操作系统等等。这些组成部分的差异会导致运行结果的不同。这些不同直接导致的一个后果就是在开发环境没问题的程序跑在测试或生产环境就有可能出问题。再者,因为应用开发出来之后还需要涉及到如何编译、打包、部署等一系列的工作。如果开发人员去做这些工作,无疑要花精力去熟悉部署和运行的环境,而且按照以往的开发模式,不同的公司,甚至不同的产品在这些方面都是不同的,并没有一个统一的流程。

而 Docker 的出现解决了这两个主要问题。Docker 的镜像,不仅包含了其所运行的程序,还包含了一切程序运行所需的环境,依赖的类库框架、运行时环境,以及操作系统(Docker 镜像中的操作系统并不是真正的操作系统,但是非常近似)。就如同集装箱一样,运输方便,开箱即用。同时,Docker 的出现使得开发人员可以按照一种标准的方式编译、打包、部署应用,避免了差异化带来的学习成本和工作成本。开发人员从一个项目迁移到另一个项目所需的学习时间也比以往更少,技术经验得到了最大化的复用。

此外,软件的分发也可以使用 Docker 镜像为单元。

对于互联网公司来说,其复杂的开发运维环境所带来的问题正是 Docker 所擅长所解决的。而对于企业应用来说,虽然开发运维环境不像互联网应用那样复杂,但是 Docker 同样可以在其各个环节简化工作量,提高工作效率。

容器化和分布式技术使实践微服务成为可能

微服务架构的流行是容器化和分布式技术发展成熟的必然结果。微服务的架构思想早已有之,只是在服务的粒度上有所不同罢了,其它并没有什么本质上的差别。但是,微服务架构会提升技术上的实现复杂度。容器和分布式技术的发展和成熟为微服务的普及扫清了技术障碍。

容器化技术使得自动化的扩容缩容更容易

按需使用计算资源的一个表现就是产品易于扩容缩容。一个服务器端应用的扩容缩容分两种情况:一是应用层的扩容缩容,二是数据层的扩容缩容。这两者不同的地方在于无状态的服务和有状态的服务在实现扩容缩容方面的不同方法。举例说明,缓存和关系型数据库是常见的有状态的服务,因为数据本身就是状态。(因为数据层的更多的是面对扩容,所以这里就不在太缩容了)使缓存可扩容的方法是使用一致性哈希算法,关系型数据库则通常要使用中间层的方法是分库分表对应用层来说是透明的。因为对于企业应用来说,数据层承受的压力通常远小于互联网应用,所以一般不涉及数据层的扩容问题。下面更多的谈应用层的扩容缩容。

扩容缩容的首要前提是应用的无状态化。即不要随意在每个节点中的内存或磁盘上存储可反映业务整体的数据。例如,以登陆系统的用户数据。这些数据应该存放在数据层。在 NoSQL 技术普及之后,应用的状态可以存放在 Redis 这样的数据库中。

扩容缩容的简单示例:
  1. 监测计算资源的使用情况 监测宿主机和容器内部的资源使用率,当现有的宿主机的资源使用率达到一定程度之后便触发扩容事件,当多台宿主机的计算资源的使用降低到可将其整合到一台宿主机的时候便触发缩容事件。对容器资源的检查可使用 Google 开源的 cAdvisor 来实现。
  2. 创建或删除服务器 当扩容缩容事件发生时,调度节点可执行响应的 API 创建和删除服务器(OpenStack 和 Amazon AWS 均有 API 用于创建、删除服务器)
  3. 部署容器计算层、监控组件等基础服务 在新节点上部署 Mesos Slave 等基础服务
  4. 在新节点上部署新的服务节点 服务节点应当向服务注册中心注册自己的信息

注:调度节点应当运行在每个宿主机上,并通过 Master 选择算法选择一台作为 Active 的调度节点。以保证高可用

2. 实践云计算

实践云计算绝对不仅仅是把应用运行在 AWS 这样的云计算平台上就可以的。一个应用能否被称为是云计算的主要看一下几点:

  1. 可用性的高低:整个系统并不会因为个别节点的软件或硬件的故障而无法正常提供功能,甚至当一个机房出现问题之后,整个系统也能快速恢复或者持续的提供服务。
  2. 伸缩性的高低:系统中的每个功能是否都可以根据请求量的增加和降低,通过增加和减少集群规模而扩容或缩容。
  3. 部署速度的快慢:系统需要多长时间部署一个新的功能,或修改已有的功能。

如何实践云计算

无状态化

只有无状态的应用才容易具有较高的可用性和可伸缩性。无状态的应用可以部署多个节点,请求可被随意地路由在这些节点上而不用担心请求失败;扩容缩容可以简化为增减节点。那什么是无状态?简单来说就是不会在本地存储空间,如内存和磁盘上记录长期存在的业务数据,例如已登录的用户。

无状态化设计只适用于应用层,对于数据层来说,实现无状态化是不可能,因为其本身的功能就是承载各种数据。但这里我们不去讨论数据层的设计。

分布式化

将整个系统安装功能划分为多个独立运行的功能模块,彼此之间通过远程调用和消息队列的方式相互通信,共同协作。这样独立部署运行的独立功能模块使得模块彼此之间的资源程度可以降低,可用性和伸缩性的设计可以按照更细的粒度进行,部署的速度也会更快。

容器化

独立运行的功能模块必须按照一定的形式包装,这种包装要实现一定程度的资源隔离,同时有统一的、被广泛接受的格式,可以在多种不同的平台上运行。在这方面,以 Docker 为代表的容器技术无疑是这方面的翘楚。同时,Docker 生态圈中的技术,如 Mesos、Kubernetes 等等已经在可用性、伸缩性等方面提供了完善的基础。不使用 Docker 使得可用性、伸缩性等方面的设计需要投入更多,无法利用现有成果。

当然,这里并不是说所有的功能都要封装在 Docker 这样的容器技术中,任何技术都是有适用范围的,容器技术也不例外。通常来说,像数据库这样的功能不适合用容器封装,因为它们的可变性不高。

技术要点和演化路径

上面提到的关于企业应用如何实践云计算的几点只是大的方向。方向最终需要具体的技术才能落地,所以下面谈谈几个比较重要的技术,以及渐进式的实施过程。下面提到的这些过程并不是按照其顺序瀑布式地进行,而应当按照敏捷开发的方式迭代地进行。

模块化设计和模块拆分

模块化设计和模块拆分不是什么高深的技术,但却是企业应用向云计算演进中重要的一步,因为冗余庞大的应用是不可能适应云计算这样灵活易变的环境。一个产品从一开始就应当关注模块设计,软件设计者要时刻不忘问自己软件产品是否需要划分出一个新模块、模块接口是什么样的、模块的职责是什么、模块之间的依赖应该如何。这些问题的答案要清晰并且要和实际的业务需求能够吻合。我相信一个成熟有经验的架构师在设计一个新的产品时是可以很好地贯彻模块化的设计思想。

难点往往在于处理已有项目上。因为企业应用和互联网应用在用户使用方式上的不同,全新设计一个新的产品以替代老产品往往会遇到更大的阻力,所以往往需要在已有的产品的基础上做工作。

对已有产品进行模块上的调整或重新划分是第一步。首先已有产品在模块化上处于混乱的状态的话,那架构师、开发人员和产品人员要在一起工作,制定出理想的模块划分。这个划分一定是要有清晰的层级关系,在业务和技术上都是合理的。在这一阶段,云计算所需要考虑的各种高可用、伸缩性等设计不用过多考虑。这些问题都是在后面的 PaaS 化是需要重点考虑的问题。

这时划分出来的模块可能会与现有的设计有较大的出入(或者因为现有设计的混乱导致有较大出入),所以一次性地将已有的产品按照新的模块划分进行调整是不现实的。可行的重构方法是将现有的产品自上而下地、逐个模块地按照新的模块设计进行重构。原因很简单,越底层的模块被依赖的越多,牵一发而动全身,所以难以自下而上地重构。当靠下的模块被重构之后,其上的模块不可避免的也需要一些调整。所以模块重构是一个反复迭代的工作。

如果有条件重写产品,则可以选择自下而上的方式。

在这一阶段,新拆分出来的模块可以通过本地调用其它模块的接口,也可通过跨进程调用的方式,后者的好处是可以在物理上分割模块,使得一定程度上倒逼了模块化的设计,但是增加了技术上的复杂度。

分布式化

分布式化并不是目的,而是一种必然的结果。如果一个产品是一个巨大的单体应用,那为了适应云计算环境,为了更高的可用性、可维护性和可伸缩性,那分布式便是必然的结果。或者按照流行的说法就是微服务的架构。

但是分布式会带来更高的技术难度,所以不可一蹴而就,而是要循序渐进。原来的模块会被提取出来作为一个独立的服务运行。整个应用先被一分为二,然后在分成三个。。。逐渐的把整个应用拆分为多个服务。

在应用容器化之间,每个服务可以按照独立的进程方式运行。或者虽然运行在一个进程内但却是通过远程调用的方式在一起工作。

在远程调用技术方面,成熟的选择有很多。可以选择基于 HTTP 协议的 REST API、基于 TCP 的 RPC 技术,以及消息队列等技术,很多框架也整个了分布式调用的功能,如阿里巴巴开源的服务治理框架 Dubbo、国外的 Actor 框架 Akka、Apache Camel 等等。所以说在技术上,分布式调用已经有非常多成熟的选择了(但是不要选择共享数据库)。

分布式化可分为两个阶段:

  1. 静态分布式化:服务之间是远程调用关系,但是服务是静止的,服务的地址不会发生改变。
  2. 动态分布式化:服务会因为扩容缩容、故障等等原因改变其运行着的实例的地址和数量,服务调用者在调用服务之前需要查找服务的具体地址。

在企业应用实现容器化和 PaaS 化之前,动态的分布式调用几乎是不可能实现的。所以产品的演化应该循序渐进,先演化为静态分布式化,在进一步发展。

在实践分布式化的时候,有两点经验需要注意:

  1. 远程调用透明化:在实现分布式化的过程中有一点实践经验需要考虑,那就是远程调用要对业务功能透明化,即业务代码在调用一个远程服务时看不出与调用本地方法有何不同。一个服务究竟是被远程调用还是本地调用体现在配置上。代码之间的调用是通过接口实现,背后的具体的栈是根据配置生成的。
  2. API 的文档化:不同于本地调用,分布式调用更加容易出错。如果缺乏准确的文档描述,那会给开发带来很多困难。在使用 REST API 时,常用的文档工具有 RAML 和 Swagger。RPC 调用,例如 Thrift,会有专门的 IDL 用于描述接口。
模块容器化(Docker)

在分布式化之后,要做的是把独立运行的服务封装在容器之内。这么做的目的主要有三:

  1. 资源隔离和限制
  2. 构建标准化
  3. 为 PaaS 做基础

在这一歩的时候,服务只是以 Docker 作为运行的单元,每个服务并不会对应多个节点,没有负载均衡、服务注册查找路由等问题。服务之间可以通过 Docker link 找到彼此。整体应用可以通过 Docker compose 这样的技术实现。

PaaS 平台化

在公有云方面,PaaS 一直没有真正的发展起来。但是在各大互联网巨头内部,云计算平台建设早就开始了。在 Docker 出现之后,云计算平台的最后一块砖终于是填补上了。虽然各大公司并没有称自己的云计算平台是 PaaS,但是起到的作用是相同的。那就是将巨大的计算资源对应用透明化。应用本身不用关心它所依赖的服务在哪里,怎么运行,只需知道名称、版本、协议等即可,云平台会负责将请求路由到正确的服务上。缓存和数据库平台对应用也是透明的,应用用于巨量的存储资源。故障恢复、扩容缩容、监控、日志等功能也都是也都是云平台所提供的。这其实就是平台及服务。

对于走向云计算的企业应用来说,虽然规模上远不如互联网巨头那样以千万台服务器记的集群规模,但是麻雀虽小,五脏俱全。云计算平台所需提供的基本功能只是在规模上有所不同罢了,因此在实现难度上依旧很高。好在2013年底 Docker 的出现改变了这一切。Docker 的出现使得 PaaS 在技术上有了新的方向。此后,一系列围绕 Docker 出现的技术构建了一个完整的生态圈。这个生态圈中的 Mesos(包括 Marathon)、Kubernetes、CoreOS 等技术的出现极大地降低了实现云平台的难度,使得中小规模的企业也可以构建自己的应用平台。

以 Mesos 为例,Mesos 提供了一个计算资源管理分配的平台,通过提供 API,使得其它技术可以使用整个集群中的计算资源而不用关心具体的服务器信息。Marathon 在 Mesos 之上为长时间运行的应用提供了调度功能。并通过与 Zookeeper 和 HAProxy 集成提供了服务发现和负载均衡的功能。

Kubernetes 则提供了一站式的解决方案,其设计源于 Google 内部使用 Borg 系统。因为 Mesos 的设计更偏向于底层,所以 Mesos 和 Kubernetes 并不冲突,可以共用。

同时 OpenStack 社区和 Docker、Mesos 与 Kubernetes 等社区正在积极协同工作,以使这些技术可以更好地协同工作在一起。

Mesos、Kubernetes 这样的技术并不能完全解决 PaaS 的所有问题。比如日志、监控等功能仍需通过引入其它技术实现。同时,将 Mesos 或 Kubernetes 整合进产品也需要很多工作。另一方面,它们所提供的功能也不可能完全符合企业的要求。好在,Spring 这样的传统开源社区也在行动。Spring 退出了 Spring Cloud 项目,通过整合 Netflix OSS 和 Consul 这样优秀的开源解决方案,从而使得应用程序本身能更加适应在云计算环境中的工作。

IaaS 平台化

在实现了以上几部之后,接下来产品就能更好地适应云计算平台,利用其提供的各种功能,构建面向云的企业应用。企业应用在构建了自己的 PaaS 平台之后,对上可以为各个企业应用提供高可用、伸缩性、服务治理、负载均衡等等的功能,对下可以通过 API 与 OpenStack、Amazon AWS 这样的 IaaS 平台整合。当然,这个阶段的企业应用还是可以按照传统的方式部署安装。

以整合 Amazon AWS 为例,通过 VPC 可以是产品与客户的内部网络整合,RDS、S3 等服务可以被用作更可靠的数据服务,Glacier 可以被用作数据备份,等等。通过 Amazon AWS 提供的 API,可以为新的客户提供快速的部署,低廉、灵活的使用成本。

三、总结

一个传统行业的软件企业的产品往往会有多种。每种产品如果都自己在云计算方面投入大量的研发力量自然是一种重复浪费。其实传统软件企业一般也有平台技术团队,但这些团队只是面对传统的软件部署和使用方式,提供的服务也只是操作系统一级的产品。但是面对云计算时代,操作系统只是提供计算资源的 IaaS 中的一小部分,应用不应当去关心具体的资源,而是向云操作系统提供资源使用的申请。现在大型企业,包括传统企业也都在搭建自己的私有云。中小企业则在逐步地使用公有云服务。如果传统软件企业不能为自己的应用提供一个适应云计算时代的 PaaS 平台,那便无法适应已经开始的企业 IT 架构的变化。

因此,传统软件企业应当意识到这一点,及早做出改变,是自己的产品能更好地适应新的时代。

转载于:https://my.oschina.net/lifany/blog/542309

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值