DCOS应用案例-不一样场景的应用上云迁移

0.前言

随着 Docker 技术的日渐火热,本就火爆的云计算行业进入了一个加速阶段。云计算最大的特色是弹性和灵活,帮助企业应对复杂的业务需求。因为云计算的IT构架和上一代的IT构架有很大不一样,云原生应用(Cloud Native Application)概念应运而生。html

云原生应用的优势体如今具备良好的可扩展性、伸缩性和容错性;不过想要享用云原生应用的种种良好特性并非轻松的事,企业开发人员在开发业务应用的时候,还要考虑将来应用的可扩展性和容错性,难免增长了开发的复杂度。PaaS 的出现,正是要帮助开发人员下降云原生应用的开发复杂度,让开发人员仍是专一于业务应用的开发,为开发人员屏蔽底层细节。前端

早器的 PaaS 平台过于复杂和笨重,没有获得普遍的应用,而基于 Docker 和 Mesos 打造的 DCOS 是下一代轻量级 PaaS 平台的典型表明。DCOS 极大地下降了 PaaS 平台的复杂度,更加方便企业开发人员实现各类业务应用,帮助企业轻松打造基于云计算的软件基础设施。python

DCOS 主要带来如下几方面好处:nginx

  • 横向扩展,自动恢复git

  • 快速部署,高效迭代web

  • 混合部署,提升资源利用率算法

若是对 PaaS、DCOS 不太了解的人一一解释这些概念,难免有些晦涩。本文将从实际案例出发,结合不一样的使用场景,为各位介绍 DCOS 的这些特性。sql

  • 登录爬虫shell

经过本案例说明,如何在DCOS上从头开始设计一个微服务架构的应用,在得到弹性扩展、高可用的特性下,如何进行服务发现数据库

  • 在线会议系统

经过本案例说明,如何改造原有的互联网应用上云,以及借助容器的快速部署特性,架构持续集成

  • 文章分类与热词统计

经过本案例说明,如何在DCOS上实现大数据应用,以及借助 Mesos 实现混合部署,提升资源利用率

名词说明

  • Mesos:Mesos是一个分布式资源管理器,支持在多种计算集群框架(frameworks)间共享服务器集群资源,提升了集群资源占用率的同事,避免了每种框架的资源冲突。为了知足复杂的资源调度方法,Mesos 经过资源提供(resource offer)实现了基于 DRF 算法的二层资源调度机制。Mesos是将来数据中心操做系统(DCOS)的核心。

  • Marathon:Marathon 是一个 Mesos 的框架,可以支持在集群环境中管理长运行服务,能够理解是分布式的 Init.d,它可以运行任何 Linux 二进制发布版本如 Nginx 等,并能够对应用的分布式多进程进行管理。

  • Chronos:Chronos 是一个具有容错特性的做业调度器, 也是一个 Mesos 的框架,支持使用 Mesos Slave 做为做业执行器,用于在分布式环境下替代 cron。

  • 服务发现:服务发现是指,任何一个应用的实例可以以编程的方式获取当前环境的细节,而新的实例能够嵌入到现有的应用环境而不须要人工干预。简单地说,在一个集群环境下,随着应用实例的增减或迁移,服务发现保证该服务仍然能够经过服务访问地址被访问。

  • 持续集成:持续集成(Continuous Integration)是一种实践,可让团队在持续的基础上收到反馈并进行改进,没必要等到开发周期后期才寻找和修复缺陷。通俗一点儿说,就是对于开发人员的代码提交,都自动地把代码库中的代码进行编译、测试、打包。

  • 微服务:微服务是一种新兴的应用软件架构,它经过一组服务的方式来构建一个应用,服务独立部署在不一样的进程中,不一样服务经过一些轻量级交互机制来通讯,例如 REST。每一个服务可独立扩展伸缩,而且定义了明确的边界,不一样的服务甚至能够采用不一样的编程语言来实现,由独立的团队来维护。

  • 数人云:数人云是国内第一款数据中心操做系统,基于Mesos管理容器生产环境,并集成了 Marathon、Chronos 等组件,对企业数据中心提供集群管理,容器管理,服务发现,持续集成等服务。

1.登录爬虫-微服务架构典型

该系统是一套实时的登录爬虫系统,用户输入待爬取网站的用户名和密码,系统会自动登录帐号,并爬取帐号内页面数据,以报告的形式提供给用户。这套系统经常使用于金融征信,评级机构得到用户的登陆信息,经过爬虫系统爬取该用户的信用相关信息,造成信用报告。

先了解一下微幅架构的几个主要的设计理念:

  1. 经过服务实现组件化。微服务使用服务的形式来实现各个功能组件模块,各个模块间的依赖经过服务的方式来组织,即一个模块经过远程过程调用来依赖另外一个模块,每一个模块是一个微服务。

  2. 企业按照业务功能来组织团队,每一个团队负责一个微服务,能够作到“谁构建,谁运行”,这将极大下降运维复杂度,缩短上线周期。

  3. 微服务能够方便地作到离散化数据管理。每一个微服务能够自行管理各自的数据,包括不一样业务的数据、不一样微服务的配置等等,更加切实匹配业务需求。

  4. 微服务构架使得持续集成和持续交付变得更加便捷。有了微服务,集成和交付的单元从大而全的总体应用变成了各个微服务,每一个微服务均可以灵活地集成和交付。

这个系统在设计之初就考虑采用微服务架构,以便部署在 DCOS 环境,并享受 DCOS 所带来的各类特性。

系统痛点:微服务架构

该系统但愿依照微服务架构原则进行设计,将功能模块组件化,每一个模块实现一个独立的功能,可单独部署,模块之间松散耦合。每一个模块可根据业务负载灵活地增长或缩减可承载容量,同时每一个模块由多个实例构成,避免整个系统因为单点故障而形成系统瘫痪。

第一步:系统设计

系统的业务需求大体以下图所示。

图片描述

在获得受权的状况下,用户输入所要爬取的网站的登录用户名和密码,提交爬取任务;

模拟用户行为登录,登录过程当中要判断用户名、密码的正确性,若是有验证码,须要让用户判断验证码图片并输入验证码信息;

成功登录后,即开始爬取帐户页面,根据报告要求,从页面中抽取出有效信息,造成报告;

因为数据是多实例并行爬取的,须要在爬取结束后进行数据整合;

异步获取结果;用户登录成功后,会提供一个查询码,并提示一段时间后进行查询;待爬取结束并造成后,用户方可查询到数据报告;

根据这些需求,须要如下系统组成:

  1. 一个 web ui,与用户交互;

  2. 模拟登录模块Loginer;

  3. 爬取模块 Fetcher;

  4. 信息抽取模块 Extractor;

  5. 信息整合模块 Combiner;

  6. ETL 模块:用于清洗数据,造成最终报告;

系统设计以下图所示。

图片描述

  1. 用户经过 Access portal 输入待爬网站的用户名和密码,有些网站还须要输入验证码;

  2. Loginer 接收到用户信息后,开始模拟用户登录;模拟登录能够采用 Selenium 或 Http Client 两种,须要渲染页面时使用 Selenium,不然用 Http Client 就够了;

  3. 登录成功后,Logginer 会将 cookie 和爬取任务一同写入消息队列,Fetecher 负责领取任务,进行页面爬取; 爬取过程当中,Fetcher 须要携带 Cookie 访问网站页面;

  4. Fetcher 将爬取的页面存入消息队列,由 Executor 负责从页面中抽取须要的元素信息,并将这些信息放入缓存系统;

  5. Combiner 负责将缓存中的数据进行拼装,并判断爬取是否结束;若结束,将爬取结果存入数据库;

  6. ETL 模块负责将爬取结果进行清洗和整理,造成最终的报告;

  7. 用户在等待一段时间后,能够查询爬取结果,下载报告。

其中,Fetcher、Extractor、Combiner 三个组件都须要了解本次抓取须要有多少 task,以及每一个 task 的状态,以便判断本次任务是否结束。

因为整个系统的每个处理环节都是多实例的,模块之间都不直接发生依赖关系,而是采用消息队列或者存储系统进行解耦。

注:为了防止被某些网站限制 IP,还须要在 Loginer 前面增长一个代理层,每次使用随机的代理服务器进行网站访问和登录,这样就避免了被封的风险。

第二步:服务发现

1 为何须要服务发现

从上面的设计中能够看出,大部分服务之间都经过分布式消息队列或存储系统进行交互,这样作的好处使得服务之间实现了异步交互,下降了耦合性。但这种异步方式并不适应于任何场合,例如 Loginer 的设计就必须采用同步调用的方式,主要缘由是:

  • 用户在输入用户名、密码后,须要 Loginer 马上进行模拟登录以验证输入的正确性;

  • 若是网站登录页的验证码是在用户名、密码输入后才显示,则还须要将验证码图片返回给用户,由用户判别并输入验证码信息(有的验证码可经过打码服务直接获取验证码信息,但并这并不适用于全部验证码系统)后,再进行登录操做;

Loginer 采用 Selenium 或 Http Client 进行模拟登录,当网站登陆页须要进行 JS 渲染的时候,就须要用到 Selenium;Selenium 经过浏览器 driver 打开浏览器,访问登陆页,开始进行模拟操做;为了简化浏览器状态的维护,在设计时限定每一个 Loginer 实例同时只能处理一个登陆请求,直到本次登陆彻底结束,关闭浏览器,才能够处理下一个登陆请求。可见,每一个 Loginer 须要维持一个状态机。

正因如此,Loginer 须要部署较多的实例数;另外,因为浏览器 driver 不够稳定,时而出现调用无效的状况,Loginer 须要有重启机制;

2 服务发现

数人云提供了一套完善的面向微服务架构的服务发现方案,以下图所示。

图片描述

现有服务发现根据 marathon+zookeeper+bamboo+haproxy 一块儿工做解决,具体说明以下:

  1. 应用动态变化致使 marathon 将状态信息写入 zookeeper(包括所在的主机 IP、端口等),而后把变化事件发给事件订阅用户, bamboo 做为订阅用户, marathon-leader 会将变化事件发送给 bamboo。

  2. bamboo 拿到事件后,按照事件给定的应用标示去 zookeeper 中取对应的状态数据。

  3. bamboo 拿到数据后按照预先设定的 haproxy 模版生成一个临时配置文件。

  4. bamboo 将临时配置文件和现有 haproxy 配置文件进行对比。

  5. bamboo 对比后,若是一致将直接结束任务。若是不一致,检查一下配置文件格式。

  6. bamboo 若是配置文件格式异常,将结束任务。若是正常,将 reload haporxy 加载新配置文件。

将 Loginer 经过数人云发布,发布应用时指定应用地址,即在 haproxy 上配置一个访问端口,再有服务发现机制将请求转发到具体的应用实例,具体请见数人云用户手册

若是某个 Loginer 实例在处理登录任务时出现异常,只须要结束进程,该 Docker 容器会自动 stop;Marathon 监听到有应用容器中止,会从新启动一个新容器以保证服务容量。注意,新容器不必定运行在结束运行的旧容器所在的主机,能够是指定集群范围内的任何主机,而服务发现会帮助咱们自动发现该容器并进行请求转发。

固然,在横向扩展时,增长 Loginer 的实例数,不只能够作到快速地平滑扩展(业务不停),也会将新实例经过服务发现加入到转发列表中。

数人云还在 Haproxy 设置了会话保持,若是是基于 cookie 的会话,Haproxy 会将同一会话请求转发到同一容器。

小结

至此,一套具有横向扩展能力,高可用的登录爬虫系统就设计完了。

回头来看,整个系统就是一个数据处理的 pipeline,每一个环节之间松散耦合,具有高可用,能够独自作到横向扩容或缩减,基本符合了微服务架构的特性。这样的架构也为持续集成创造了良好的基础,咱们会在下一个案例介绍基于DCOS的持续集成。

注:数人云新版的服务发现功能已经修改了策略,再也不须要用户选择将代理部在某几台主机上,而是由系统默认安装在集群除了 Master 以外的全部主机上,构成一个覆盖全计算资源的代理集群,确保服务发现的高可用;同时对 proxy 进行了优化,下降了运行带来的系统开销。

2.在线会议系统-互联网持续集成典型

这是一个在线会议工具,用户能够经过微信登录并接入系统,邀请好友开始远程会议。该应用架构复杂度中等,为典型的互联网应用。

该应用的技术架构以下图所示。

图片描述

如图所示,其架构图中包括 Redis,Mysql,OSS,file-server 等存储节点,也包括 web-server,api-server,push server 等服务节点,还有前端的 nginx 反向代理等。

服务节点间存在相互依赖。

全部节点都部署在阿里云,部分存储服务使用了阿里云服务。

系统痛点:

部署耗时:因为咱们的服务较多,版本发布的时候,须要每一个服务都单独编译、打包、部署,通常要1到2个小时才能完成部署任务;迁移麻烦:若是须要部署新的机器,每一个新机器还须要配置环境,很麻烦;扩展性差:如今的服务依赖都是单向直接依赖,没有作负载均衡,不能扩展。

第一步:系统 Docker 化 & 上云

通过对其业务流进行梳理,咱们大体获得如下架构。

图片描述

架构图中包括如下内容:

  1. 每一个服务的端口使用;

  2. 服务间依赖关系;

  3. 服务是否有状态;

  4. 分别标注对外服务、对内服务及存储;

对应用大体作了如下改造:

  1. 服务节点 Docker 化;

  2. 服务节点无状态化,具有横向扩展能力;

  3. 抽离配置文件,解耦组件间依赖;

  4. 多实例化的服务之间进行服务发现。

上云步骤:

  1. 为每个子项目编写 Dockerfile

  2. 安装私有 Docker Registry

  3. 部署应用

  4. 监控与测试

第二步:持续集成

持续集成是一种软件开发实践,即团队开发成员常常集成它们的工做,经过每一个成员天天至少集成一次,也就意味着天天可能会发生屡次集成。每次集成都经过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。而Jenkins是一个自动构建服务,使用Java实现,有成百上千插件,使用他能够很方便实现持续集成。

  1. 搭建 Jenkins

    对于 Jenkins 的安装和部署,这里再也不累述。

值得一提的是,数人云集群使用 Apache Mesos 进行资源的统一调度,经过数人云能够快速搭建 Jenkins。把Jenkins运行到 Mesos 上,或者说利用 Mesos 向 Jenkins 提供 slave 资源,一方面经过分布式特性加快构建过程,另外一方面也提升了资源利用率。经过配置 Jenkins-on-Mesos 插件,Jenkins Master 能够在做业构建时根据实际须要动态的向 Mesos 申请 slave 节点,并在构建完成的一段时间后将节点归还给 Mesos。

图片描述

具体教程请见 快速搭建 Jenkins 持续集成环境加速产品迭代

  1. 代码库建立工程

须要内部的代码库或者公共代码库为每个组件建立一个项目。本案使用了 Github 做为代码库,Jenkins 已原生支持 Github。这里要注意的是,须要保证 Jenkins 有权限 pull/push 上面咱们所建立的 git repo。另外,工程要包含 Dockerfile,以便在构建过程当中生成 Docker 镜像。

  1. 镜像构建任务

在 Jenkins 里建立构建任务, 任务从 git repo 拉取代码,指定 release 的 tag,使用 repo 里的Dockerfile,构建 Docker 镜像,并推送镜像到 Registry 里。

图片描述
图片描述
图片描述

根据不一样的系统架构,能够将构建任务拆成不一样的粒度。最简单的,一个任务构建全部的子项目。若是项目比较复杂的状况下,每次构建时间会比较长,形成没必要要的资源浪费,那么能够将构建任务拆分到颗粒度更小的子项目。

构建触发设置,能够为每次 push 后进行构建。但通常状况下,每一个子项目也是有多人协做的,并且并非每一次代码提交都须要进行构建,所以构建触发策略设为 Tag push 触发,及每当增长 tag 时,触发构建任务。

图片描述

  1. 镜像发布任务

在 Jenkins 里新建任务, 在这个任务里,经过调用数人云 Rest API 获取认证token, 发布应用到 Mesos 集群。

能够设置发布任务的自动触发,好比当一个构建任务完成后触发,或者天天晚上2点触发,要根据不一样的环境须要来进行选择。
图片描述

发布脚本中,经过调用数人云 Rest API 获取认证 token, 以应用的形式发布到数人云平台。这里用curl命令发布应用。也能够用 python、shell 等脚本调用 API 发布应用,咱们也推荐这样作,能够更好的检查调用API的返回。

图片描述

后续

以上,实现了整套系统上云以及构建持续集成的过程。下一步即是构建从开发、集成到生产的完整运维体系。通常状况下,针对一个互联网产品,开发环境由开发进行构建和发布,能够设置为 push 触发或者前面提到的 tag push 触发;集成环境由 QA 进行构建和发布,QA 按期发布并进行集成测试,发现问题后再回退到以前版本;生产环境每每经过手动方式触发发布,在发布前须要作好客户通知、应急处理等各项准备。

值得注意的是,将多份环境进行统一发布管理,还须要配备配置服务器用于管理不一样环境的配置信息,而这是另外一个话题了。

图片描述

重要提示:数人云新版已发布了持续集成服务,上述经过 Jenkins 部署和配置持续集成过程仍显得比较繁重,那么经过数人云管理界面,经过简单的操做就能够实现自动构建的全过程,具体请参见数人云用户手册

3.文章分类与热词推荐-混合部署、大数据典型

这是DCOS上的大数据项目。项目来源自一个互联网媒体客户,需求是将积累的媒体文章进行分类,并找出能表明一篇文章的关键词做为文章标签,用于进行文章的分类或热词统计等数据分析,文章数量近5万余篇,且在不断增长。

项目选用 Apache Spark 做为计算框架,并经过 Spark MLlib 提供的 LDA 算法对文章进行聚类,获得“文章-主题”和“主题-关键词”矩阵,并以主题词做为文章标签,对文章进行归类。

Apache Spark 做为一个分布式大数据计算框架,与 Apache Mesos 完美结合。Mesos 做为 Spark 集群的资源调度器,能够将 Mesos 集群的资源以粗、细两种粒度分配给 Spark;在 Spark 完成计算任务后,Mesos 能够将资源回收,供其余服务使用。

图片描述

从上图看出,项目一共包括数据预处理、模型训练、预测训练集三个离线计算任务,和一个提供预测、添加文章、热词查询等功能的服务模块。

系统痛点:

Spark 计算任务须要大量计算资源,主要工做时间在凌晨时间,这些资源在白天是闲置的。该系统还须要 Nginx、MySQL 等服务组件,若是能将它们混补在同一组服务器上,则能够下降成本,提升资源利用率。

本案经过数人云管理 Mesos 集群,经过 Marathon 管理长运行的服务型应用,经过 Chronos 管理离线计算任务,同时在集群中部署了 HDFS 分布式文件系统以及私有 Docker Registry。

图片描述

其中,MySQL 用于存放天天的新文章数据,以及预测后的结果数据集;Nginx 用于对外提供服务。天天晚上2点运行 Spark 计算任务,更新模型并对训练集数据从新预测。

第零步:搭建 Spark 计算环境

Spark 采用 Mesos 做为资源调度器时,由 Mesos 统一调度计算资源,所以,Spark 集群无需部署,Mesos 集群即为 Spark 集群。

图片描述

制做 Spark base 镜像,这部分再也不累述,请参见使用数人云运行 Spark,或者也可使用数人云开放的 Spark base 镜像:index.shurenyun.com/spark:1.5.0-hadoop2.6.0

本案存储层选用了 HDFS。Spark 链接 HDFS 时拥有数据位置识别能力,并会从集群内距离最近的节点处读取数据,从而最大程度下降数据在网络中的传输需求。为了充分发挥 Spark 的数据位置识别能力,你们应当让 Spark 计算任务与 HDFS 节点共同部署在一个集群中。

数人云提供为主机打标签的服务。若是 HDFS 只部署在集群的部分主机上,能够为这部分主机打上标签,在部署 Spark 计算任务的时候,能够限定在该标签范围内执行。具体请参见数人云用户手册

第一步:部署 Chronos 任务

将 Spark 计算任务经过 Chronos 发布到集群中,Chronos 是一个具有容错特性的做业调度器,支持使用 Mesos 做为做业执行器,用来在分布式环境下替代 cron。

  1. 制做任务镜像

由于代码和配置文件变更相对频繁,所以基于 Spark base 镜像制做一个包含二进制包和配置文件的任务镜像。

Spark 项目的目录以下:

├── README.md
├── build.sbt
├── conf
├── project
├── src
└── target

其中,conf 中包含了 Spark 的配置文件:spark-env.sh,spark-defaults.conf。

任务镜像的 Dockerfile 以下:

FROM index.shurenyun.com/spark:1.5.0-hadoop2.6.0

ADD target/scala-2.10/spark_lda.jar .
ADD conf .

CMD ./run.sh

Spark 程序经过 SBT 编译,二进制包生成在 target/scala-2.10/spark_lda.jar

根据调试或部署的须要,将 Spark 的配置目录导入并替换原文件,便于配置更新。

运行脚本run.sh是具体的 spark-submit 指令:

bin/spark-submit --class com.dataman.omega.service.Boot /opt/dist/spark/spark_lda.jar

将三个离线计算任务分别制做成镜像,而后将制做好的镜像上传到到镜像仓库。

  1. 发布任务

Chronos 是一个具有容错特性的做业调度器,支持使用 Mesos 做为做业执行器,用来在分布式环境下替代 cron。数人云已经集成 Chronos,并对外开放了发布定时任务的 REST API。为三个离线计算任务分别建立 Chronos 任务,名为preprocessJob,trainJob,predictJob。一个具体的定时任务发布指令以下:

curl -X POST https://api.shurenyun.com/api/v3/clusters/88/jobs \
      -H Content-Type: application/json \
      -H Accept: application/json \
      -H Authorization: 6d8c5051f09242408f966f762cc9b674 -d '{
        "name": "preprocessJob",
        "imageURI": "index.shurenyun.com/Spark_preprocess",
        "imageversion": "v1",
        "cpu": 4,
        "mem": 8192,
        "owner": "yma@dataman-inc.com",
        "ownerName": "yma",
        "schedule": "R/2016-03-15T02:00:00.000Z/P1D",
        "command": "",
        "parents": [
          ""
        ],
        "volumes": [
        ],
        "constraints":[["Tags", "LIKE", "HDFS"]]
      }'

有几个注意的地方:

  • schedule:R/2016-03-15T02:00:00.000Z表示任务定为晚上2点开始执行,P1D表示每隔一天执行一次;

  • parents:该任务执行的先决条件,不能和 schedule 字段同时使用;因为 preprocessJob 是第一个执行任务,所以设置 了 schedule,后面的任务好比 trainJob,则要设置 parents 为preprocessJob

  • command:原生 Chronos API 不容许该字段为空,数人云已经修补了该 bug。

具体的 API 说明请参见数人云 API 文档

第二步:部署长运行服务

Nginx,MySQL 这类长运行服务,经过 Marathon 发布。数人云已集成 Marathon,并提供了简洁的 UI,具体方法请参见数人云手册

小结

因为服务访问大部分发生在白天,而 Spark 计算只在晚上进行,所以彻底能够把以上任务和服务都混合部署在同一集群内,提升了总体资源利用率。

Mesos 具备处理各类异构任务负载的特性,于是使得在同一个平台上管理大数据应用和 Web 应用成为可能。数人云集成了平台监控工具,能够方便地监控集群、主机、应用三个层面的资源使用状况以及各类应用状态,简化了运维工做。
图片描述

注:HDFS 也能够经过 Mesos 部署,若是有的小伙伴以为部署原生 HDFS 很麻烦的话,能够参考将 HDFS 搬上数人云:轻松实现集群的扩展收缩

4.总结

本文针对不用的应用场景,提供了基于数人云 DCOS 的应用上云方案,并分别说明了 DCOS 的特性;其实,只要处理得当,每个场景都是能够受用 DCOS 的多种特性的。

因为应用的多样性和复杂性,应用上云并不止以上内容,更多内容请咨询数人云。

相关文章
相关标签/搜索