电商与物流的强心脏:京东云自动化运维体系构建之路

郑永宽 2018-04-19 14:07:43
作者介绍

郑永宽,京东云资深架构师,华中科技大学硕士。拥有6年自动化运维平台研发运营经验。2011-2016年任百度自动化运维平台经理,主要负责分布式任务调度系统、数据传输系统、百度部署发布系统。2016年至今,任京东云运维平台负责人,主要负责京东云自动化运维体系构建。

 

大家熟知的京东可能是京东电商,事实上京东有四个最主要的平台:电商、物流、金融和保险,京东云是这些平台能力的输出窗口。京东云有基础设施、主机网络,上面还有一些中间件和PaaS服务,主要是为了支撑电商和物流。

 

说到京东云,我们最看重运维,这就需要自动化运维平台。对此有几个关键问题,主要是围绕安全、部署变更、网络管理、监控管理……利用自动化运维来提高平台架构稳定性和人员的开发效率。

 

在京东云的整体环境中,除了有我们技术团队所管理和维护的云自身应用之外,还启用并提供着各种SaaS服务。

 

如何保持客户在云端业务的稳定性?我们对此进行了深入的研究和探索,下面分四个部分为大家讲解:

 

  • 京东云自动化运维基础组件

  • 京东云自动化运维部署介绍

  • 京东云自动化运维监控系统

  • 总结与展望

 

一、京东云自动化运维基础组件

 

针对上述问题,我们从四个方面进行入手:

 

  • 服务与资源管理

  • 任务调度管理

  • 监控平台

  • 客户端

 

京东云运维平台大致的搭建路线图如图所示:

 

 

从基础组件到客户端体系再到部署系统(包括各种发布系统、任务调度系统、以及监控系统等),最终对运维平台进行完善,从而更好地服务于我们的客户。

 

1、服务与资源管理
 

 

第一个基础组件是对服务组织资源的管理,即运用CMDB来实现所谓的配置管理。

 

 

通过CMDB的“服务树”概念,我们可以掌握如下三个方面:

 

  • 服务项之间的依赖关系。找到各个服务项之间的依赖关系,进而获知它们在哪里被用到、由谁在使用、以及其本身所具备的用处;

  • 机器状态。对于京东这样体量的大公司而言,机器的数量多达十万左右,我们需要掌握其中每一台机器的当前状态、具体的机型、坐落在哪个机房、以及它们是如何被使用的;

  • 角色管理与基于角色的权限控制。我们需要掌握到具体是谁、能够在什么时候、进行什么样的操作、实现什么功能。

 

所以说,“服务树”主要涉及到服务在系统中的实时信息,包括:哪个服务处于哪台机器之上、有哪些实例、属于哪个App、具有哪些内部逻辑过程、如何对外部申请所需的权限以及我们如何实现对它的监控等。这些都需要能从服务器上获取到。

 

其次是Naming Service,它能够解决服务之间的解耦关系,也就是服务和实例间的关联关系、以及服务向外所提供的窗口。

 

 

上图展示了“服务树”与名字服务的示意图,最下方展示了一个从应用到实例关系的解耦,往上则是客户端的Back Off(解耦合)。

 

2、任务调度管理
 

 

第二个基础组件是任务调度管理。

 

 

在实际场景中,不管我们是要协同做某个操作、还是进行发布上线、或是对文件进行部署与分发。

 

这些都需要系统去调度目标机器,以完成相应的任务,也就是我们必须要求指定的机器能够按照指定的策略,进行指定的命令。由于该过程具有实时性、批量性和共生性,因此对于系统的支撑能力极具挑战性。

 

同时,我们需要通过策略来定义不同类型的并发度,比如要对一百台机器进行发布上线,那么我们不会将它们予以同时部署,而是分批次地进行并发。

 

因此我们需要规定每次并发的具体任务,判定成功与否的逻辑关系,以及检验具体的完成程度,并且还要找出那些超时的状态。由于这些都是通过底层架构来构建出的各种业务,所以它们的调度逻辑实际上都是一样的。

 

另外,所有的执行操作都需要是可追溯的,包括能够知晓什么人、在什么时间、进行了什么操作,可见安全性和规范性是非常重要的。

 

而如果出现了故障,我们需要及时地截获输出,进而定位问题。这些都是任务调度系统需要基于服务树和Naming Service来实现的基础逻辑。

 

3、监控平台
 

 

第三个基础组件就是监控平台。

 

 

监控无非是从数据采集、到数据汇聚、再到存储处理的过程。

 

不同于平时常见的数据监控,我们构建的是时序性数据存储(TSDB)。由于需要查询的数据点非常多,因此我们将每次查询和收集到的监控点信息按照顺序存储起来。

 

另外,我们的系统具有“读少写多”的特点,即:“写”(写入数据)相对比较均衡;而“读”(读取数据)则具有突发性。

 

比如说:查看一个监控的状态,是属于随时做的操作。一般此类写操作是以1秒、10秒、或1分钟作为采集间隔,是一个比较频发的过程。而读操作则发生得比较突兀,所以我们需要做到读写分离。

 

因此,我们基于ES(ElasticSearch)实现了TSPD,其中涉及到两种封装:

 

  • 对于热点数据的封装,我们将较为重要的数据,以及那些实时的数据存放在Redis中;

  • 同样,我们对历史数据也会进行ES,然后再封装,从而实现了读写的分离。这种数据的双写过程,合理地保证了数据的高可用。

 

监控数据的另一个特点是自动抽样,有时候一些频发的查询会牵扯到较大的时间跨度。

 

例如:一个月甚至是一年。由于我们的采集数据间隔是1秒、10秒、或1分钟,那么如果直接去查询所有数据点,需要产生庞大的数据量,当然也就很难实现。

 

因此,我们对写操作进行了自动抽样。当查询15天以上的数据时,我们会把这些数据以每分钟、或每小时进行聚合,然后放在库中,进而查询一个月的数据。

 

通过自适应路由的方式,我们就可以查到有限量的一小时数据,同时我们的数据库及业务系统速度也能具有较快的水平。

 

另外,对于那些实时的数据处理,我们主要采用的是多地部署和基于JNS的多调度过程,从而实现了多维度的实时计算。  

 

4、客户端
 

 

第四个基础组件就是客户端。由于所有的业务都需要客户端,因此对于京东这样体量的公司而言,会细分为部署类(如 JNS)、监控类、初始化等客户端类型。

 

 

设想一下,如果我们需要对十万台机器进行加载部署或是上线升级,其工作量是可想而知的。

 

就算我们只是维护十几万机器的Agent,由于环境复杂,且存在着多个IP,如果只是按照单一维度去处理诸如“什么时候、出现什么了问题”的话,既耗时又耗力。

 

所以在此我们引入了Agent的资源超限这一重要概念。

 

比如说:对Agent的监控,由于占有了部分计算资源,则有可能将当前的服务宕机,那么这种本身处于服务之外的监控就影响到了服务本身的稳定性。

 

可见对于Agent客户端需要做到如下方面:

 

  • 管理所有Agent的部署和升级。

  • 维护各个Agent的存活性。即在发现哪台机器上的Agent宕机的时候,我们需要知道如何将其重新激活上线。

  • 资源超限守护。

  • 分级发布。

 

在具体实现上,我们运用ifrit进行管控。即当一台机器在引入某个服务时,负责管理的Agent会在我们的ifrit服务器上进行注册,以告知其当前所处的分机房和使用的Agent的版本。那么它对应的客户端就可以相应地将这些信息包下载下来,从而掌握Agent的最新版本等信息。这就形成了一个简单的客户端体系结构。

 

二、京东云自动化运维部署介绍

 

有了上述客户端与组件体系的构建基础,我们进一步构建部署和发布任务就相对比较容易了。

 

我们先看看应用的部署系统,它除了实现应用部署之外,还管理着各种服务的维护和资源、以及接入的过程:

 

 

如上图所示:我们除了“往前”进行了编译构建,还“往后”实现了流量接入。

 

 

如上图所示,该Agent在此处有着一个核心的要求:实现跨平台。由于京东整体平台的环境较为复杂,我们有不同的虚拟机、Docker、物理机,它们需要把前面所提到的多种操作融合起来。

 

因此我们需要做到如下容错功能:

 

  • 不允许出现由于单台宕机而引发服务故障;

  • 出现了服务故障,系统可以实现自我发现;

  • 面对双十一和618之类的重要促销场景。系统能够快速扩容,以应对此类流量的骤增。

 

针对上述功能的实现,我们在部署中分为两种类型:

 

  • 基于Docker的镜像输出。

  • 基于传统物理机或虚拟机的包输出。

 

 

一般的流程是:

 

编译构建自身产品库(其中包含代码包和代码项)→通过部署服务和上述调度系统的部署服务进行发布(在物理机和容器上都可实现)→部署完成开始运行→对运行予以维护(尤其对镜像日志进行收集)→通过日志服务,进一步做分析。

 

同时我们在前端做好了流量的接入,中间部分也提供了一个LB(负载均衡)的网络。通过上述两种部署方式,我们可以根据服务的实际需要进行按需升级。

 

另外,我们此处采用的是基于NS的服务自动化与资源管理。它并不需要关心当前服务的具体过程是如何被实现的,而只注重当前的容量、需要什么资源、以及能够获得的资源。

 

三、京东云自动化运维监控系统

 

除了上述提到的部署,我们对监控系统也十分重视。

 

 

监控最重要的作用就是在出现问题时能够及时恢复。要想实现这一点就必须做到如下方面:

 

  • 能在第一时间发现问题,这是恢复的基础;

  • 快速定位问题,及时判断问题出在哪里,是虚拟机上还是硬件上;

  • 能够自动运用既定的算法,通过自动调度预案或人工响应予以快速处理和恢复。

 

因此,面对既有虚拟机又有Docker的复杂环境,为了保证服务器不停止运行,我们在上线过程中采用的是部署联动式的分级发布。

 

它可以监控到某个服务是处于机器层、服务层,还是在对外流量接入层、甚至是在网络层。这些都是监控所需要解决的问题。

 

如图所示是监控的整体架构:

 

 

这里展示了从底层的数据抽象、到数据的采集,然后经过数据处理,以及离线处理的全过程。

 

其中数据的采集模式包括:采集Agent、外部探测和API推送。

 

同时在处理逻辑上包括了:如何去判断异常类型,以及针对异常所做出的报警类型和采取的是运维通讯还是研发通讯等方式。我们对这些步骤都事先进行了较好的规划。

 

当然,这些故障本身又属于事件类型。因此我们需要考虑如何将事件存储起来,以方便查询和进一步做出相应的决策。

 

由于先前的事件可能会影响到后续事件,因此如果您拥有一个很好的事件库,那么就能够让系统的下游获取到上游究竟是何时何地出现了何种故障,这些对于下游的排障都是极有帮助的。

 

与此同时,我们也会对监控的数据进行一些离线处理,通过各种高效的算法,反馈到计算相应的报警之中。最终各种数据都是以趋势图或Dashboard的方式来展示各种事件和报警。

 

有了前面的基础,我们所构建的京东云监控体系就由如下四种监控类型组成:

 

 

  • 基础监控,针对的是机器层面,不需要用户去配置,自动采集的是CPU、内存、硬盘、网络等简单的信息。

  • 存活监控,针对的是服务监控,包括监控进程、端口和语义等方面。

  • 性能监控,针对的是服务层的对外表现状况。我们通过四大核心指标,来解决服务性能上是否存在异常。同时我们运用日志监控来收集PV、错误和容量,并确定所谓的异常边界的问题。

  • 业务监控,类似于黑盒子,从用户的角度来观察服务,发现问题。例如:所有服务指标状态都显示OK,但是服务对外表现不佳,网站无法被访问。

 

这个问题实际上对于京东来说会非常地严重,因为它会直接影响到用户流量乃至用户订单的损失,所以我们要从用户的层面上做好黑盒检测。

 

1、基础监控
 

 

具体来说,对于机器监控,我们从采集、到计算、再到报警,实现了机器连通性的全程自动化,从而免于人工的干预。

 

 

同时我们给各种报警指标设定了默认值,比如说:通过发现某台机器的cpu.idle小于10%,我们就可以获知它所隶属的服务,从服务名称获知其维护者是谁,进而向其维护者发出报警信息,通过报警信息我们就能大概知晓相关的数据,这样便实现了后台联动。

 

2、存活监控
 

 

对于存活监控来说,主要查看的是进程以及端口两个方面是否存活。为了实现部署联动,我们规定了进程与端口的部署路径。

 

 

有了进程的路径,我们就能获知进程的类型和对外开通的端口,从而实现了自然监控。

 

3、性能监控
 

 

我们再来看性能监控方面:

 

 

它主要关注的是服务对外的指标,该指标一般来自于日志。

 

为了统一,我们事先规定、规范、并约定一种日志格式,从多个维度读取日志信息里的不同Tag(标签)值。

 

比如说:从宏观层面上看京东的整体流量是平稳的,但是我们通过多维度的聚合,就能发现某个省的机房流量存在着细微的底层波动。

 

当然在采集方式上除了从日志里主动抓取之外,我们还能从程序和用户处的报警来获知。

 

4、业务监控
 

 

 

业务监控是从用户处查看服务是否正常。例如:电商常用到的是通过模拟全国各地的用户访问来发现分省份、分运营商或者分机房访问的情况。

 

这就是运用外网或是自定义的方式来测试业务。另外,我们也会运用模拟云操作的方式,去监控云服务。

 

例如:模拟一个用户登录到云网站→购买一台主机→部署一个镜像→进行一次发布。

 

由我们来判断全程是否一切正常。如此,我们就能够从用户的角度,先于用户发现问题、处理问题、并排除故障。

 

四、总结与展望

 

就这样,我们最终在前面的基础上构建了京东云的自动化运维平台 ark:

 

京东云的自动化运维平台 ark)

 

在界面上,它能够提供:

 

  • 配置管理、JNS管理和资源管理;

  • 当天的部署过程;

  • 应用相关的工具和组件;

  • 各种报表;

  • 监控的对外展示,包括如何做对比、报表和查询。

 

总结起来,我们的自动化运维平台,通过各种技术的运用基本实现了服务化,做到了全生命周期的DevOps。

 

 

面对数量庞大的SaaS客户,我们的解决方案为他们保证了交付效率、节约了成本、并为各种可能碰到的问题做好了准备。 

 

活动预告