zoukankan      html  css  js  c++  java
  • 构建高性能微服务架构

    传统架构之痛

    当前的时代称为互联网的时代,互联网应用的特点往往是,新型的应用迅速出现颠覆旧的商业模式,一旦商业模式稍有起色便会有大量的厂商蜂拥而至,使得蓝海变成红海,经过短时间的残酷竞争,热度往往持续较短时间后,大量厂商退出市场,仅仅前二名到三名能够存活下来,最终这一波浪潮被下一波取代。我们回想视频网站,团购网站,社交网站,微博,打车,直播等,全都呈现这种模式。

    所以互联网市场只有一招,天下武功,唯快不破。

    当一种商业模式出现的时候,为了迅速切入市场,占领商业献祭,快速验证商业模式,往往软件的设计会采取传统的单体架构。

    传统的单体架构往往分三层,最下面一层是数据库,中间是应用程序层,所有的商业逻辑都会在这一层,最上面是页面。

    如果商业模式比较成功,则应用会添加新的功能,一种方式是全部添加到原有的商业逻辑中,另一种方式是开发一个全新的三层结构来支撑新的功能。

    由于是单体结构,一方面应用层里面的功能越来越多,如图中一个功能变为三个功能,将来可能三十个功能,另一方面很多代码和逻辑都不能复用,如图中功能 2,每个应用都有,这种功能常见的有认证模块,消息的编码和解码模块等。

    这种单体结构会带来三方面灵活性比较差。

    第一,时间灵活性:应用快速迭代,缩短客户需求到产品上线的时间。

    互联网应用的需求随时改变,因而应用开发的迭代速度要求会比较快,传统的软件可能半年或者一年发布一个功能,而互联网应用则可能每周都发布新的功能。而且互联网产品会时常搞活动,比如双十一,每次活动不可能提前很长时间策划,从而给开发充分的产品周期。

    然而单体结构的应用如果有了 30 个模块,每个模块由两到三个人负责,则修改的成本会非常的大,从开发人员看来,整个架构牵一发动全身,每次修改必须要做好良好的前期设计,并且让整个团队评审,如果新的需求要改多个模块,则代码的管理和合并就成为很大的问题。

    而且无论测试,联调,上线,扩展,缩减,升级,回滚都需要重新搭建环境,需要配置软件,需要进行回归测试,运维人员需要反复的部署环境,而且无法保证环境的一致性,任何一个环境配置的小问题,都有可能导致软件使用有问题。

    第二,空间灵活性:应用弹性伸缩,应对业务量突然增长后较短时间恢复。

    互联网应用往往是针对终端用户的,终端用户的行为往往不如企业用户那样容易预测,终端用户可能因为促销,过节等因素导致访问量的迅速的增长,当访问遭遇峰值的时候,我们希望应用可以快速扩展。

    然而对于单体架构,应用扩展的过程如万丈高楼平地起,一层一层慢慢盖。

    如果部署在物理机上面,则还需要采购新的物理设备,如果有虚拟化平台,则需要申请新的虚拟机,并且配置好网络和存储。然而仅仅一个空的虚拟机是没有用的,上面什么环境都没有,接下来需要安装应用环境,比如 Tomcat, Apache 等,然后就是将应用,页面配置到应用环境中,还没有结束,新启动的是一个独立的系统,还需要将这个系统加入到当前的系统中,才能一起承担访问量,例如加入到负载均衡器的配置里面。这样每部署一套都需要从头来一遍,实在是运维人员的噩梦。

    第三,管理灵活性:易部署,易迁移,服务发现,依赖管理,自动修复,负载均衡。

    现在很多互联网应用都需要多地,多机房部署,有时候会从一个机房迁移到另一个机房,如果每次变动都如上面一样从底层到顶层都做一遍,成本比较大,时间比较长。

    当一个应用依赖于另一个应用,被依赖的应该宕机之后,修复需要手动进行,从底层到顶层配置一遍,而且修复好的系统往往 IP 地址也变了,则依赖于此应用的所有应用都需要修改配置。

    微服务化之路

    要解决上面所述的三个问题,对应的有三个步骤。

    第一步,去状态化,从而实现程序的可扩展。

    单体架构的程序往往很多数据是保存在内存里面的,或者是本地文件系统的,例如用户访问的 session 数据,例如用户上传的照片。所谓的去状态化,就是使得应用程序仅仅运行商业逻辑,而将数据的保存全部交给外部的存储服务。内存里面的数据可以放在缓存 redis 里面,结构化数据放在统一的数据库服务里面,文件存放在对象存储里面。这样应用程序就变成了一个只有商业逻辑的应用,可以随时扩展。

    这里面有一个问题就是应用程序的状态外置化了,放在统一的缓存,数据库,对象存储里面了,可是应用程序宕机了是没有问题了,再启动一个就可以,如果缓存,数据库,对象存储宕机了,数据不也是没有了么?

    其实主流的开源的缓存 Redis,数据库 MySQL,对象存储 swift 等,他们设计的时候就是考虑了高可用和容灾的情况的,所以数据存储的工作就应该让专业的模块来做这件事情,而应用程序应该关注在商业逻辑的实现,从而加速开发的速度。当然这些存储模块的维护则是另外的专业人士在做的,这部分人士是缓存的专家,数据库的专家,对象存储的专家,不需要懂商业逻辑。

    第二步,容器化,可编排。

    与传统 IaaS 架构不同,容器提供的不仅仅是基础资源,而是将操作系统,应用运行环境以及代码打包成一个不可修改的镜像进行交付,容器的机制可以保证无论在哪里,什么时候运行,都能保持环境的一致性,也就是 Docker 所宣称的“Build, Ship, and Run Any App, Anywhere(一次构建,随处运行)”。

    容器特别适合部署无状态的服务,上一步的无状态化,给容器化奠定了良好的基础。

    一个服务往往会包含多个组件,因而会封装成为多个容器,容器之间会有相互的依赖,相互的调用,Kubernetes 可以实现服务的编排、自发现、自修复,使得复杂服务的部署变成了一次 API 调用。

    如图所示,Kubernetes 管理了相互依赖的四个服务,全部部署在容器里面,分别运行在不同的机器上面。服务之间的调用通过服务名称进行,而非固定 IP 进行,而服务名称 Kubernetes 会管理起来。

    当一台服务器宕机的时候,服务 B 和服务 C 会被自动调度到另外两台机器上,由于服务是无状态的,所以没有问题。然而服务 A 和服务 D 如何再找到服务 B 和服务 C 能,这两个服务的物理主机变了,很可能 IP 也变了。其实是没有问题的,Kubernetes 会自动将服务名和对应的 IP 地址关联起来,服务之间只要配置的是服务名,而非 IP 地址,就依然能够相互访问。

    有了容器和 Kubernetes 这两个工具后,解决了管理复杂性的问题,但是需要专门的团队和技术力量,去玩转 Kubernetes。

    第三步,DevOps,可迭代。

    从前面的一张图中,Dev 和 Ops,开发和运维之间隔着长长的流程,导致迭代速度很慢。DevOps 就是可以加快迭代速度的一种方法。

    然而如何让开发直接进入到运维流程中呢?容器的镜像不可改变性提供了方案。

    Docker 可以保证容器中的运行环境,业务代码无论在哪个环境都是一致的,唯一不同的是不同环境的不同配置,可以通过环境变量注入的方式设置。有了这个模式,开发人员可以从很早就使用容器镜像的方式进行开发,并且以容器镜像的方式交付给测试,测试使用同样的镜像得到同样的环境进行测试用例的执行,当决定发布的时候,也确定真正到了生产环境的时候,同测试环境是一样的。这样避免了环境不断重复的部署过程。

    容器镜像可以手动维护和交付,但是也可以借助 CICD 持续集成的工具,来监控代码库的更改,当有程序员提交代码的时候,会触发一个 hook,这个 hook 会调用 CI 工具,告知他代码已经有更新了,可以根据最新的代码打成最新的镜像,CI 工具根据配置好的 Dockerfile,将代码打包成镜像,上传到镜像库,每次打镜像都应该有新的版本,而不应该总使用 latest。

    镜像打好了以后,接下来 CD 的工具会将镜像部署到测试环境,测试人员可以就这个新的测试环境进行一轮测试,如果测试成功,则可以告知线上管理人员,可以更新新的版本。

    线上管理人员在恰当的时间,使用编排工具,将容器镜像的版本改为最新的版本,从而生产环境也就更新了。如果发现生产环境有问题,新的版本有 Bug,没有问题,只要将镜像改为上个版本的镜像即可,可以保证原来那个能用的版本,所有的配置和原来一样,从而功能也一样,实现了升级和回滚功能。

    当然这套持续集成的工具和流程,需要开发人员和开发流程进行改进,才可以顺利使用。

    小结

    只需要逐步做到以下三步,就可以实现微服务和快速交付:

    1. 去状态化:将内存数据写入缓存,将持久化数据写入数据库,将文件写入对象存储。
    2. 容器化:可弹性伸缩,自我修复,动态迁移。
    3. 微服务化:可快速迭代,持续集成。
  • 相关阅读:
    September 17th 2016 Week 38th Saturday
    【2016-09-16】UbuntuServer14.04或更高版本安装问题记录
    September 16th 2016 Week 38th Friday
    September 11th 2016 Week 38th Sunday
    September 12th 2016 Week 38th Monday
    September 10th 2016 Week 37th Saturday
    September 9th 2016 Week 37th Friday
    c++暂停
    八皇后问题
    ( 转转)Android初级开发第九讲--Intent最全用法(打开文件跳转页面等)
  • 原文地址:https://www.cnblogs.com/laoxia/p/10342109.html
Copyright © 2011-2022 走看看