Docker
Aug 23
开篇

这篇文章是对之前几篇文章的一个续,主要介绍项目开发过程中发生的问题并以案例的方式介绍。

前两篇文章
Docker2.0 项目过程总结  http://blog.puppeter.com/read.php?52
Docker3.0 项目过程总结 http://blog.puppeter.com/read.php?56

你真的了解你的用户么?
一个项目能够成功需要看是否了解用户的真实的需求,但很多时候与用户沟通发现用户是不知道自己想要什么的,所以这里就要收集很多数据帮用户来排序与选择并最终给他一个选择题。以下是一个未了解用户真实需求的案例。
年中公司团建内部小鲜肉(kanesong)组织了一个泰国团,我个人是非常想去泰国的因为确实没有去过也很感兴趣泰国的美食,但从以往经历上看这团并不好组织所以也协助小鲜肉在拉人。 这里我提前设想了一下尽量的让泰国团能够真的筹集到人数成团的方法。
首先私下问了一些比较熟悉的朋友筹集首批用户而首批用户以女生为重点用户,因为女的多了男的才会有去的心思即便不去也可能会帮我们吆喝。人数很快筹到了13个人差2个人就可以成团了,但心里知道很多已经入团的人仍然处于犹豫期的未必会去,所以要了解大家真实的需求是什么好趁热打铁,我们收集了大家的想法与需求后经过汇总分类后如下:
1. 我想去泰国,但之前去过所以只想去指定的地点与路线,譬如芭提雅;
2. 我想去泰国,但是需要了解最终的团费是多少。而最终的团费和出团时间出团人数都是有关系的没有最终成团前这问题很难回答;
3. 我想去泰国,但只在6月中旬有时间;
4. 我想去泰国,去哪无所谓,主要是能吃到地道泰国美食,看到真正的泰国人妖;
5. 只要泰国能在短时间成团我就去;
6. 没说肯定去,也没说肯定不去。
从需求看上去真的是众口难调,但仔细思考问题也不大我想如果能满足这类人群中的大多数的需求那少数部分也就不成为问题了。我们边收集想法边推广,以以上需求的角度,以团内都是美女的角度,通过秘书与大家口口相传希望能筹集到最后的最少两个人,不过随着时间的渡过发现很多已经入团的同学没有了耐心已经有开始有退群的打算了,我都是先说等有新人进来再退但很无奈人就是凑不齐。 一天同组同学老司机(brinkmai)组织了一个休闲的广东省内团(http://blog.puppeter.com/read.php?59)开始我并不太看好,因为我觉得大家都是年轻人年轻的时候就应该能走多远就走多远多看一下外面的世界, 而吃惊的是两周后听说人数已经筹够达到出团的要求。 brinkmai也在邀请我来这团,其实我本想的是如果泰国不成团我就参加数据组同事组的台湾团,不过发现很多组内的同学都参与了,从更多与组内同学沟通的机会上看最终我还是选择了这个团,当我进入这团的RTX群后人数慢慢攀升到了30人这也给我了很大的触动,为什么泰国团组建就这么难而广东省内肇庆团就这样容易,分析后发现团内老员工占比比较多,大家主要还是借此机会能够得到充分的休息,所以用户最真是的需求是实惠休闲,当能聚类出这类用户的需求的情况下组织一个团成功率就会高很多,虽然不能满足每一位团友的需求但已经抓住了主体用户的需求组织起来也就没那么了。




Docker3.0的过去、现在和将来
开篇中提到的是一个生活的案例,可以看到在组团前我们是有意识通过历史经验来提升组团的成功概率的,工作中做项目也一样如何让做的项目能够成功? 这就需要考虑的维度更多一些。下面来介绍一下Docker3.0项目(Docker3.0是我们开发的一个内部系统版本代号)我主要通过时间维度来介绍一下此项目的过去、现在和将来,并介绍在每个环节中遇到的问题与思考。

“过去”
1. SNG运维场景;
2. 容器在场景下的需求分析。

1. SNG运维场景:
我个人觉得我们运维了业界最复杂的系统,复杂的原因产品线多、产品历史悠久譬如qq、qzone,腾讯成立于1998.11.11到2018.11.11日正好20周年,qq也从花季雨季步入小青年,qq和qzone是我们业务的主干为了不断满足用户的需求我们在主干上也不断迭代新的产品特性,但也有很多产品特性随着时间被主流的用户遗忘而变为了长尾业务,而这些业务都在我们的服务范畴内复杂程度可想而知。我们在运维这样复杂的系统同时也需要与时俱进不断跟上技术的革新,譬如Docker容器很火在公司内部其他BG如游戏王者荣耀都在应用,容器在技术上实现了弹性伸缩节约我们的成本也统一了“交付物”,在业务层面助力了王者荣耀的快速发展,所以我们有理由相信我们SNG也是可以用的。经过与同事的讨论与之前的运维经验,我们分析出玩容器在SNG可以分为4个场景,以下是4个场景的优缺点:
点击在新窗口中浏览此图片      

2. 容器在场景下的需求分析
容器应用场景已经分析出来了,如果站在我的角度出发,我可能先做离线再做在线业务与离线的混部,同时在开发系统过程中我们肯定会发现很多问题通过发现的问题在来迭代下一版本的需求,但主线依然是以上所提的SNG运维场景,所以假如我对SNG运维场景做一个排序的话,我的优先级排序是 1 3 2 4 这样做的方式优点是风险比较低相对容易出成果。但实际执行过程并没有想象的这样简单要综合很多人的意见权衡利弊,以下是前期与中期收集了大家的想法。
大老板: 我们要做容器、 不追求上量但能力一定要达到,希望我们做的不要比其他BG差;
中老板: 支持容器机器,底线是稳定与易用可推广,建议与织云体验融合可以无感知的推广与上量;
小老板: 系统一定要做出亮点。通过实现弹性伸缩,解决效率问题的同时也解决了我们成本问题。
经过各种权衡最终我们选择了在线业务的弹性伸缩(4)是四个场景中最难的一个场景,有时老板思路占比重会大一些。
确认应用场景后内部对开发形式又有一些争论:
开发同学1(t3): 建议使用lighthouse(内部开发系统代号),因为lxc(全称Linux Container)通过lighthouse管理对它做简单的改造就可以支持Docker的管理,无需重复照轮子。
开发同学2(t2): 是否使用lighthouse无所谓,但没有使用过python心里没底,希望开发同学1更多支持与帮助, 不过经过最终的权衡选择了重新开发。
我个人观点: 开发1与2的同学观点都对我们在做系统的时候要尽量避免的重复造轮子,但也要尊重每个人的选择让每个人在项目中得到收获与成长,而后者的权重通常要高于前者。

“现在”
时间到了年中,现状我们已经开发出了弹性扩容的系统灰度了很少一部分业务但并没有上量,从技术角度看此系统是成功的达到了预期效果,但从上量角度看还短期达不到还需要很多细节打磨。 一天坐公交偶遇一个老同事目前已经是一家创业公司的技术骨干,我们聊起了我做的Docker3.0项目,他其中一句话印象令我十分深刻,他说在腾讯内部开发的系统没有规模上量是有问题的。实际上从KPI角度看在年中没有上量也是有问题的,我复盘了一下整个过程个人总结有以下几点:

1. 缺少对用户需求的理解:
从“过去”这环节中大家可以看到我们前期分析了SNG的容器应用场景,在分析的过程中也与负责业务与开发天天打交道的业务运维进行了沟通分析了痛点这里要说一下强调一下“痛点“这词,在聊得过程中我个人感觉有时确实用户是不知道自己想要什么的,只能描述出业务特性比较复杂开发与运维“交付物”不明确等,如果可以通过镜像来实现开发与运维的“交付物”,通过容器来实现弹性伸缩是可以解决我们的效率问题降低运营的成本。而我们忽略了最真实的使用用户是开发,同时也没有一套简易的UI来描述开发后的用户体验而开始开工建设系统,最后导致系统建设出来但最终的使用用户反馈新系统学习成本比较高推动困难。 所以最开始如果我们做的是离线系统,通过此目标建设系统在后续做在线与离线系统混部的环节能给开发提前演示效果,有可能会比当前状态推动会更容易一些。

2. 没有遵循目标最小化原则:
其中目标最小化原则是以最小的代价来满足用户需求,再通过用户的反馈不断的迭代新的需求;以下这张截图很形象的说明了目标或产品最小化原则,这思路也是来自《精益创业》 一书中提出了“精益创业”(Lean Startup)的理念。

点击在新窗口中浏览此图片

而现状是(如截图no like this)确实初期定的目标有些高,短时间推动上量很多细节需要打磨,譬如页面的用户体验、对用户无感知和与旧运营系统融合等等。而目标较高在KPI的背景下短期没有过多收益会有很多流言蜚语影响大家的心态;

3. 没有推动上量的手段:
通常在内部开发的系统推动上量有几种方式:
1. 确实解决用户痛点,对整体(成本、质量、效率和安全)有明显受益;
2. 至高向下推,由leader或者更高职位的领导帮推动。 举个例子譬如安全,如果服务器不做安全加固短期可能没事,但万一出现安全漏洞服务器又没有加固就会导致数据泄露风险。而在没有安全漏洞的情况下,推动别人去做一些安全加固没有至高向下推是比较难推进的;
3. 通过其他手段譬如卡资源来推动本项目。 这里我们也没有做到,虽然我们组名叫计算资源组,但资源并不归我们负责用户上下线也不走计算资源组。2015年是节约成本年,很多产品业务快速发展拿不到资源,通过资源来卡业务是一个没有办法的办法,因为当时运营系统效率达不到弹性伸缩。但目前是17年业务手中不缺少资源,所以很难推动。
而目前1-3情况都不具备,没有一个很好的推动上量手段。

“将来”
0.  邮件记录每一个环节:
前期的需求分析、规划、里程碑、短期目标、中长期目标、参与人员和每次例会的内容都要记录邮件并定期输出,防止沟通不清楚和信息不对称导致项目出现的风险。

1. 不断的复盘与总结过程中发现的问题:
在“现在”这环节中,我们对项目的过往进行分析与总结,做项目还是要充分了解用户的需求,如果在用户说不清楚需求的情况下要拆分场景用产品最小化原则来建设系统,通过建设系统是否解决用户的痛点或是系统运营中的过程数据发现的细节问题来不断迭代下一版本,并在之前拆分的主线上慢慢前行同时还要不断的复盘过程中发现的问题并一一解决才做出一个好的系统。

2. 别迷信权威:
在项目开发很多思路来源于书本上的方法论,但书本上的知识方法论在项目过程中应用并落地还真不容易,所以不能不学这些方法论但又不能过于相信所有的方法论。

3. 尽量发现每个人的长处:
在项目过程中确实发现每个人性格是不一样的,所以在做项目的过程中根据性格特征每个人也有着自己的长处,有的同学不善于沟通但写代码很强,有的同学文档写的不错,有的同学推动能力很强,在做相同项目过程中发现每个人的长处可以让大家有成就感的同时推动最终项目的成功。



总结
本文标题是如何做一个项目,从本文第一个案例与第二个案例中看做的项目都不是十分的完美,大家看完可能觉得有些标题党的感觉所以这里介绍的并不是如何做一个成功的项目,而是在做项目过程中通过案例方式如如何将风险降到最低同时又能权衡利弊让大家受益最大化。当然在做项目过程中也有很多拿不准的东西以下留了一些过程中遇到的问题,如果是你应该如何应对也欢迎与我沟通讨论邮箱:8851970@qq.com 。 最后,引用爱迪生的一句话  "天才都是百分之九十九的汗水加百分之一的灵感。后面是那百分之一要比百分之九十九重要的多" 。

讨论的问题
0. 如果根据自己历史的项目经验觉得当前的方案是对的而老板又不这样认为应该怎么处理?
1. 项目开发过程中肯定会遇到很多细节的问题,当遇到细节问题争执不下时(在方案没有最终落地前,两方争执结论都是无懈可击的)这时找leader又两面为难不给最终建议,这时你应该怎么做?
2. 项目过程一但版本封板不准许增加需求,而产品为应对市场需求又怎需要增加一些需求导致版本期限延期,应该怎么处理?

Apr 14
作者:研究僧
文章地址:http://blog.puppeter.com/read.php?56

开篇
       我们在2015年中的时候就在做Docker1.0(琥珀 http://blog.puppeter.com/read.php?4),当时主要针对离线场景。到2016年初 Docker1.0(琥珀)已经小有规模,同时也解决了很多生产环境的问题,而得到大家的认可。在2016年3月份中心内部开始讨论要做在线Docker版本,而这只是需求并不是目标。所以我们从需求角度出发设定了目标,当时针对中间层(spp ,内部组建工具)业务进行了调研,设定目标是做在线业务的弹性伸缩,主要是通过Docker来解决资源的快速扭转,这样大家使用机器时一方面可以更方便地获得,另一方面可以减少人为参与上下线,将有限的人力用到更重要的工作中,使大家能快速学习与成长。
点击在新窗口中浏览此图片
  上面的这幅漫画很生动地描写了我们当时的心情(因为整个项目的难点不是技术,而是如何改变用户习惯与思路), 围绕这一小目标从2016.3.31发出第一封Docker邮件到目前已经有一年多了,经历了多次的PK,从技术选型、是否使用开源、人力的配备、项目的优先级等内部讨论,到为什么搞了这么久没有上量、Docker搞了这么多版本是否有意义、Docker的长期目标是什么、是否可以保持现有织云体验等外部质疑。我总感觉项目走在十字路口,选每条路可能都是对的,但每一条路都未必是捷径,总是在被挑战中。这里我不得不承认确实理想很丰满,现实很骨感,我们在谈理想时总想着要把我们的运营系统往前再走一小步,而落地到现实时,往往需要更多的时间、人力、每个人的情怀、领导的支持、需要顶住外界压力、寻找更多合作团队一起努力才能达到目标。 本邮件主要总结我们在项目运作中遇到的问题、对项目的疑问、我们的思路等。


0)如何开发一个项目
    因为我个人并不是专业的项目经理,所以项目开发的过程也是我学习的过程。我也在思考如何能把整个项目做的更好,能尽快达到短期小目标。前期我参考了软件工程的方法论需求分析、概要设计、详细设计、测试、维护和用户手册等,但感觉不是特别适用于互联网的项目管理。譬如软件工程中的详细设计基本拿到文档就可以开发写程序,而目前我们还做不到这样的详细设计,所以只能部分借鉴。后期我参考了《打造Facebook》一书其中的一章,个人感觉还是比较适用的,但在原有的基础上我也补充了一下本项目开发过程中的案例。
点击在新窗口中浏览此图片

1)描绘远景,设立目标
描绘远景,设置短期、中期和长期目标,这样在不同的时间需要的伙伴与切入点才一目了然。以下是我们项目的一个基本项目流程图(图2):
点击在新窗口中浏览此图片
图2 Docker项目流程图


2)头痛的需求分析
在收集想法,排查优先级的过程中我们也出现了一些问题。
前期我们会找很多业务运维与开发同事进行需求分析,分析的问题是用户从不同的角度结合自己业务来向我们提出需求,就导致了平台满足A用户就满足不了B用户的问题。
收集同事们的开发观点如下:
1. A开发,希望通过Docker能管理从开发->测试->上线到持续集成的整个流程。
2. B开发,希望能用开源工具譬如k8s来管理Docker,这样更符合业界玩法。
3. C开发,只要系统稳定能提供资源,使用什么都无所谓。
4. D开发......
收集同事们的运维观点如下:
1. A运维,希望保证与现网体验一致。
2. B运维,希望可以实现弹性伸缩,解决快速扭转设备及成本问题。
3. C运维,希望能实现弹性伸缩,解决人力参与问题。
4. D运维,因为其他BG都在搞混合部署,我们也不能落后,希望通过k8s把业务管理起来。
5. E运维 .....
以上是真实的前期需求分析,有意思的是这里有的问题是互斥的,具有代表的譬如A运维与B\C运维的需求,保持一致是保持完全一致还是部分一致莫衷一是。这种情况下,就还需要分析老系统为什么不能实现弹性伸缩,分析出老系统本身确实无法实现弹性伸缩,新系统又想要和老系统保持体验一致,这就是互斥的问题。上面只是我们遇到的一个问题,类似的情况还很多。这种感觉有点像做数独游戏(见图3),业务主要关注横向相加的结果,而我们还需从全局出发关注横向纵向的安排。所以分析下来有时会有点头痛,无法完全按照大家观点来开发又需要权衡大家的观点与意见,同时又要尽量反馈大家我们这样做的原因,所以有的时候系统开发出来,再找之前的用户时,会被吐槽并不是其想要的需求。

3) 总结版本控制的三个优点:
1. 方便总结与回顾。
记录每个版本的细节可以更好的回顾总结项目中遇到的问题、难点和后续优化空间等,为未来开发项目沉淀一些经验。
2. Deadline(截止时间)才是最大生产力。
每个版本都有版本的启动时间与截止时间且都由个人自己评估确定。我们工程师一般情况下每天或多或少会被一些紧急不重要的事打断,而项目在组内又有很多交集,如何确保合理安排项目时间交集部分减少不表要的等待时间管理,事物优先级排序就很重要,有了Deadline就是最大的生产力。
3. 版本一旦确定不接受其他任何需求。
特别在开发与外界交集比较多的项目过程中时间难以把控,只能是尽量的协调控制外部交集的时间点所以一旦需求确定,哪怕加一个很小的需求,项目之间有依赖关系都可能会导致项目的延期或项目质量的下降。关于时间评估这里有一个经验值,在开发与外界交集比较多的项目过程中,尽量是自己评估时间的1.5倍到2.5倍间,具体视情况而定。

4) 是否采用开源工具
我们现在采用了自研的方式来管理我们的Docker容器,但在开发的过程中也不断有同学推荐开源的工具,譬如messos\swarm和k8s等这些工具都非常优秀且有着庞大的用户人群和市场空间,我了解到的很多创业公司都有在应用,个人觉得这些工具的设计思路非常先进有很多借鉴的意义,更重要的是他就像一种行业的协议,特别在与其他公司交流时虽然公司的业务不同,但用了相同的协议这样交流起来更顺畅同时收益也更大。个人并不排斥开源工具甚至更推荐用谈理想没有问题,但现实把这些工具在内部落地就很困难,总结原因有以下两点:
1. 因为部门大、产品多、产品历史背景长、复杂接口调用、高于一切的安全管控和与老运营系统兼容等,在落地的过程中都需要考虑周全,而开源工具内部落地遇到这些问题不免需要进行二次的开发能力、这种能力不是一个人而是一个组都需要具备的,特别在海量运维场景下不同产品有自己的业务特性,开源组件未必满足业务特性,导致异常查找成本会很高。还有在看到其他的部门在使开源工具为符合内部业务情况下进行大量二次开发,当业界升级工具时又需要持续迭代等头痛问题。
2. 引入开源工具譬如k8s需要开启NAT功能而内部系统都是定制的为了安全关闭了部分功能的情况下又要打开,又要保障系统安全这两个问题是需要慎重思考与权衡的。
所以按短期目标来看,我们还是使用了自研的方式来管理我们的Docker容器,长期看开源工具已经在我们的蓝图中。

5)  原生Docker思路在内部应用未必是对的
Docker 官方文档强调(build - ship - run) 其中:
build: 构建镜像,把整体环境软件依赖包和操作系统用户态构建成镜像,更新配置通过版本区分镜像。而构建镜像方式又分为两种:
           1. 直接将软件包安装到已经生成的Docker中来打包构建;
           2. 通过Dcokerfile来构建镜像
           这两种方式我们都有应用,其中1对应Docker2.0 ,2 对应Docker3.0
ship: 通过docker register 来分发构建好的镜像。
run : 只要kernel支持,上层使用标准的协议镜像,就可以运行在各种环境下,迁移非常方便。
问题出在升级镜像版本时需要重启镜像,这种方式有优势也有缺点,看在什么场景下:
优点:
1.在并行开发环境下,通常最头痛的问题就是环境不一致引发的线上故障。 而在Docker场景下开发只需要关注镜像版本,运维只要关注资源利用率,OD分离互补干扰,解决资源利用率同时也解决环境的问题;
2.现网环境一致实现标准化,有了标准化就可以实现自动化;
3.镜像生命周期短,每次更新版本镜像需要重启镜像,如果程序质量有问题,譬如运行时间长oom ,进程不释放fd 导致磁盘满情况都能很好的解决。
缺点:
海量运维场景下,线上环境频繁的变更,Docker生命周期短频繁重启不现实。当然Docker在这方面也是有考虑的,譬如分层文件系统的引入,但分层文件系统有128层限制,且目前测试情况看到40多层性能出现下降,而负责的业务在部分场景下可能1小时内发布频率就超过128层限制,所以这种方案是有问题的。
在开始我一直认为推动我们的系统往前走一小步,让频繁变更的业务适应Docker比较短的生命周期是正确的,但实践证明海量运维场景下Docker原生思路中的优点在我们验证下是不可以的,因为业务分层运维、配置频繁变更、运维的生态系统不完善都是问题。 或许在不久的将来,整体运维观念改变,运维架构上有更方便的调度系统与服务发现功能的背景下,使用Docker原生思路才是对的。

6)规范”如果没有工具的辅助就相当没有规范
我们为什么要制定规范,因为规范是标准化的前题,而自动化又是基于标准化基础之上,所以我们要制定规范。但问题来了有规范就一定可以实现标准化自动化? 这个真的不一定。生活中法律是一种规范,如果一个美女穿着很暴露的衣服走在夜晚12点后的街道小巷,即便有法律这种规范遇到色狼的风险也是很高的,如何避免呢? 提高法律的惩罚力度? 我觉得会有点效果但治标不治本,这时美女要尽量不穿着暴露的衣服,尽量不要在夜晚12点后出门,即便出门也不要走街道小巷,才会大大降低遇色狼的风险概率。做系统与架构也一样,通过规范来让系统标准化收效不大,规范与法律相比并没有更多的处罚力度,这就直接导致了规范不到位,标准化没有里程碑,自动化遥遥无期。
我曾想借鉴一下业界譬如某阿是否也遇到过我们目前面临的问题,他们是如何解决的?是否可以借鉴。一次机会听某阿朋友分享容器其中也提到了规范,某阿一直想试着梳理规范流程因为某阿也分很多bg(business group)不同bg运营的业务不同人也不同导致规范也不同,在一个公司体系下业务有可能会被轮换,不同业务轮转到不同的规范下又要保持业务正常运行短期只能加人,长期需要梳理规范,分享的嘉宾也说曾多年试图将这里的规范梳理统一但是发现比较难,推动成本也比较高,所以这里container(集装箱)是解决的方案之一,试想一下集装箱的发明正式把很多不标准的东西变成了标准尺寸,这样在码头才可以通过工具自动的搬运这些集装箱提升人们的效率。而先有了规范再通过工具去约定,这样才能达到我们预期的效果。


待续。。。。。。。。。。。
Jan 19
作者:研究僧
文章地址:http://blog.puppeter.com/read.php?52

项目时间:201603-201608

通常做项目标方向和理想是非常好的,但现实总有这样那样的问题,如以下截图。 所以引出本文在做项目中发现的一些问题:
点击在新窗口中浏览此图片

开篇
      腾讯SNG(社交网络事业群,后简称“SNG”)事业群担负着QQ、Qzone、QQ音乐和相册等核心社交产品运营,从运营的这些产品就能看出部门的历史。笔者没有进入腾讯前在北京工作过多年,记得在2010左右北京的各种IT大会风起云涌当时可以看到各大公司分享自己的架构与运维理念但很少能看见腾讯的分享,当时很纳闷为什么看不到腾讯分享,多年后走进腾讯当年很多疑惑慢慢揭开了神秘的面纱。  
      从架构层级上腾讯和很多公司相同即接入、逻辑和存储但腾讯BG(Bussiness Group 事业群,后简称“BG”)制,外人可以理解BG为腾讯内部子公司,彼此有独立的方向、业务与架构,不同的BG架构不同(接入、逻辑和存储), 与其他公司不同的是,腾讯在各BG架构上又多了一层“大存储”,这里大存储指各BG数据最终落到统一的BG下,即TEG(技术工程事业群)。以SNG为例接入使用qzhttp(web服务)逻辑之间调用关系用了l5(名字服务),程序开发有spp框架, 数据间传输使用了私有协议,存储使用了MySQL和一些自研的数据存储,可以看到腾讯这里走出了一条有自己特色的道路,它更多使用的是自研组件和私有协议,这也就解释了之前笔者的疑惑为什么很少看见腾讯的分享原因。相比很多公司使用开源组建在基础上做二次开发,但腾讯更多是学习开源组建再开发,区别是后者配置文件些许区别维护学习上有一定成本,但优势更加适合业务使用,足够的轻量级和安全,但问题是业务的需求量有限很多自研组建放慢迭代脚步,甚至停滞迭代为业务发展埋下隐患。
     那为什么腾讯内部的工具不走开源路线呢? 开源接受的市场更多的需求,需要持续的打磨与迭代, 这问题也是笔者在入职腾讯后一直的疑惑 直到一次公司技术分享A同事的一个问题,A同事大概问的意思是腾讯现在在互联网行业内有一定的影响力与同等公司相比开源做的并不是很好,这是为什么? 当时公司CTO(首席技术官,英文Chief Technology Officer,即企业内负责技术的最高负责人)张志东是这样回答的。首先对A同事问题的肯定,也介绍了这里的背景,早年腾讯业务爆发式增长工程师更多的精力是应对需求以及当业务发生故障时去救火,再者考虑的就是开源软件对数据安全的问题,如果本身能力未达到应用开源软件后遇到风险不能快速解决结果是致命性的。 这两点笔者身有体会特别是随着互联快速发展,网络安全很重要网各种暴库(csdn 索尼)等事件,做过一个公司的CTO需要更加关注用户数据的安全,这也是我们公司的底线用户安全置上。但Tony也说随着腾讯各个业务步入正轨、技术的沉淀和人才的储备,我们也逐渐考虑去做一开源的工作,鼓励各BG开源。老板的一句话给我们带来更多的思考是如何去开源? 而开源的前题也是如何更好的使用开源的工具在基础上有机会再开源,所以当时笔者也在想自己的业务上去寻找一些场景适合开源工具的解决方案。

Docker缘
    2014年什么最火,相信很多人会说是Docker ,它诞生于2013年,感觉它的诞生就是一鸣惊人且有不断蔓延趋势,国内很多技术分享也谈了很多Docker的发展趋势应用案例等。2014年底笔者接手了一些长尾业务,由于部门对机器低负载考核比较严格,所以当时也试着将一些高负载业务与低负载业务进行混合部署,混合部署、虚拟化是很多公司解决成本问题的一些手段,像网上经常看到Google很早之前就在用容器技术来实现业务间的混合部署, 当时公司也有很多BG以各种方式实现了不同业务间的混合部署,而由于SNG历史背景的原因很多业务还没有实现混合部署。笔者当时负责系统运营情况,在没有隔离情况下的这种混合部署方案并不好,因为高负载与低负载的业务混部在一起特别是晚高峰期一个大CPU毛刺就会影响到低负载业务从而导致线上投诉,所以在2014底和2015年初借鉴了其他BG的玩法,在部分场景下我们开始通过Docker来实现我们业务间的混合部署,实践证明这种混部要比前者更好,经过2015年一整年系统的开发与迭代初见规模,我们内部称呼为“琥珀离线系统”把高负载业务与低负载业务混部同时,也将高负载业务部署到了部门与公司的Buffer、数据库备机和低负载等资源上,如果业务使用Buffer资源系统,通过建设的系统能力可以将业务请求迅速的从Buffer上调走, 就这样我们把部分业务迁移到了Docker上。
   2015年下半年到2016上半年社交类业务出现了很多转码的需求,转码是用户从PC上传视频通过服务器进行格式与码率的转换在其他终端(ipad,手机)上都能看到,通过我们Docker + Buffer 、低负载形式再次解决了这类业务的需求,为部门解决了大量的成本,Docker离线再一次进入应用的小高峰。
  这时老板们也提出了更高的要求,是否可以实现在线的Docker化,毕竟离线底层用的是Buffer 、低负载资源是有一定天花板的,因为在海量运维中这些资源占比可能连10%都不到,2016年上半年我们开始做在线Docker研究。
   我们做了内部的研究与需求调研,在过程中也经过N轮的PK有人同意有人反对,记得有次一位同事说我们的运营效率可以在分分钟扩容千台机器,什么上Docker?
   答:因为,Docker宣称(Build, Ship and Run Any App, Anywhere!) 它通过镜像串联了开发的整个路径,并保障线上的一致性,你可以把镜像看作App,它可以运行在内部云和公有云上,方便业务以后在各种云上快速的拓展。
   同事:那织云(内部运营系统)在打磨一下也可以实现类似的这功能,为什么还要上Docker?
   答: 额。。。。
   其实当时笔者心里的想法是,是啊其实我们早实现这功能再稍改造就可以,但为什么火的不是腾讯SNG的织云而是Docker呢? 值得思考。。。
   最终还是决定试探性的来用Docker管理在线服务,Docker这么火而且已经有成功的内部案例,但为什么是试探性这么没底气?
   开篇的时候讲过我们有很重的历史背景,在这种历史背景下没有最牛逼的工具,只有最适合我们的工具,很多创业公司把Docker玩得转因为没有任何历史的包袱,所以这里我们只能说是试探性来玩Docker,看它是否符合业务需求,还有另外还有一些原因:
          1. 刚的对话中已经说明了,内部运营系统早就支持了类似镜像功能,为什么还火的不是织云而是Docker ? 3分产品7分也运营,我想这也是Daocloud(Docker母公司)把Docker当作产品去做,所以这是我们值得学习的。
          2. 很多公司都在搞Docker,当一个新员工入职,你和他说织云,他会问什么是织云,但你说docker很多人会知道,所以不管什么技术,如果他能形成一套“协议”就会让彼此间更好的去沟通。
          3. 内部虚拟化也应用了Kvm,做弹性扩缩容Docker比Kvm更加的轻量级,在社交类业务中镜像有突发流量增长和计算的场景都很适合用Docker。
          4. 部门的运维的质量、效率、成本和安全都做的非常好,如果能以得分衡量应该是98分,但是对追求极致的我们需要的是100分,所以我们要关注开源产品、使用开源产品来寻找自研产品的不足
          5.  笔者曾经看过一篇文章《 为什么要探索宇宙》 文章大意(文章地址见参考):
          1970年,赞比亚修女 Mary Jucunda 给 Ernst Stuhlinger 博士写了一封信,他因在火星之旅工程中的原创性研究,成为 NASA(美国航空航天局)Marshall 太空航行中心的科学副总监。信中,Mary Jucunda 修女问道:目前地球上还有这么多小孩子吃不上饭,他怎么能舍得为远在火星的项目花费数十亿美元。结论是探索宇宙可以带来相关产业的发展,太空探索就像一面人类审视自己的镜子,利远大于弊。
   相信探索在线Docker与为什么要探索宇宙是一样的,我们他做整个过程当作我们的镜子审视自己系统的不足,并推动改进。

探索在线Docker起航
     从中心下各组抽了一些热心同事,2016年4月份开工在线Docker。 作为运维最不好管控的就是时间前一秒在做项目,突然一个故障立即处理,处理完回过来忘记从哪开始做起刚有头绪又收到新的需求,所以我们需要一套管控手段来保证项目的目标与进度。首先,时间上每个人每天拿出30%来搞项目,其次我们引入了Scrum(敏捷开发框架) 来管理项目, 它的好处就是能在一段时间内,有一个共同目标,大家向着目标不断的跟进持续打磨,信息尽量的彼此间透明,最终保障短期目标与质量。
    前期很多事物在探索阶段整体看Scrum带来的收益还是不错的,我们发现了很多问题,这里有Docker本身问题、还有也有部门运营系统问题低层系统的问题,在线系统上线了300+ 容器运行过程中Docker本身并没有太大的问题。 一个小插曲一台母机上运行了多个容器,其中有的容器是测试机有的容器是在线服务器,某工程师登录测试容器修改了系统时间,由于Docker隔离型不是十分的好,导致整个母机时间都被更改影响各业务,这并不影响在线Docker持续探索,但也提醒我们如果拿整套在线Docker技术方案来做一个产品的化,我们需要一个产品的准入的规则,譬如小明家买了一个洗衣机,洗衣机对小明来说是一个产品,小明并没有看洗衣机的说明说就把衣服放入洗衣机,最终衣服大于洗衣机承载重量导致洗衣机的报废,同样在线Docker也需要一套说明书即准入规则、注意事项、测试过程中发现的问题、案例和潜在风险等,如果超出了准入规则的不准许接如,否则与洗衣机的结局是差不多的。
    运营了一段时间Scrum我们也发现了一些问题, Scrum可以解决一个小团队的问题,但我们需要依赖其他团队时从效率上看就没那么好了,如果Scrum两周为一周期,小团队在一周期内可以解决10件事,而涉及到依赖就只可能解决一件事,因为每个团队有自己的重点及KPI,遇到这种情况Scrum也是无能为力 。

小团队作战
      像Scrum应用中发现他解决不了的问题的案例,在一个大的公司中更多的讲究是团队作战群策群力一个需求来了后对他做需求分析,并拆分需求分给不同团队提升需求的效率和质量。每个部门,每个团队,每个人都是有KPI (关键绩效指标 ,英文全称 “Key Performance Indicator”),KPI的优势是不同环节认同一个目标并持续推进保证收益, 团队与团队之前的协作如果KPI是一致的那事情推进会非常顺利反之只能像Linux进程一样陷入中断状态。
      在这样背景下Scrum可以很好的解决小团队KPI目标、进度、质量,但与其他部门或组交集太多就无能为力了。在线Docker正是这样情况,当你申请其他团队资源时,在KPI的背景下首先被问的目标与收益是否明确,也正因为是探索型项目这些问题很容易被挑战,更多的时间在PK目标与收益。但要知道Google的GFS最初也只有三个人设计开发出来的,所以这种探索型产品前期需尽量少的人参与,与其他团队尽量的解耦 ,短期带来的问题可能是系统的重复建设,长期的收益是整个生态链质量的提升是值得的。笔者也在想Docker离线为什么会成功? 原因也是开始团队比较小很多问题在内部可以很快的解决,时间上保障项目进度,同时也令大家的成就感更愿意去投入。

设立项目标及流程负责人
    经过一个月的试探,到5月底我们大概掌握了业务Docker在线相关系统的一些问题,解决问题同时也在并行实现Docker在线系统的产品化。 开始讲过参与Docker在线同学来自不同组,结合自己的业务大家从不同的视角希望Docker能带来更多的改善。其实大家的目标是一致的做Docker在线,但过抵达目标的过程却有很多分歧,有分歧是好事做一个产品如果连分歧都不没有就太没成就感了,但此项目就是分歧太多了且都有道理,怎么办?
   解决分歧更好的方式是拿案例来表明自己的想法正确的。PK案例:
   现有流程 : 测试-> pkg (软件包管理系统) ->预发布 -> 线上系统
   改造流程:  测试机-> pkg ->预发布 (构建镜像机) -> 镜像仓库 -> 线上系统
   旧系统问题:历史原因导致 od未分离,开发可以任意登录线上系统导致系统配置不一致,当预发布环境有问题时,可以任意选择线上机器配置反录入到pkg系统再次发布,相当于给od为分离打了一个补丁。
   改造后流程 : 预发布构建镜像后,由镜像保持整体链条环境一致性 。但历史原因导致我们的用户(运维/开发)习惯,扩容时是任意选择一台参考机来发布的,分歧就是改造后流程省略了选择这一步,而且首次选预发布机器后为了保障镜像里垃圾信息最少,后续不可以更改预发布机器, 有的同学就会疑问为什么不保持原有习惯?预发布机故障怎么办? 就这样一个案例PK了多次,最终还是保持改造后的流程方案。
    PK是有必要的,但多次PK就会拉长战线和时间,再加上各种需求就会导致小团队每天很忙接需求,PK需求一段时间过去并没有什么起色,大家对项目的成就感也会打折。Docker在线项目成员来自不同的组,大家一起搞Docker在线形成了虚拟组,其实开始我们就忽略了虚拟组的技术负责,经常出现意见不一致开会PK没有结果再PK浪费时间的情况。有了技术负责人后,它来帮我们屏蔽不合理需求,当遇到问题不断PK时能及时站出给出方向加以解决,保障短期目标,同时提升大家项目中的成就感。
   每天晚上5:00大家都需要碰头沟通Docker在线的进度与问题,有意思的是经过一段时间大家都认为自己负责的环节已经OK了,但整体串联起来就有问题。我们分析了一下原因原来是这样,我们每个人负责的是在线Docker生产链上的一个环节如图1,一个在线Docker包含了多个环节,当自己负责的环节流程1没有问题也就确认自己是没有问题的,结合之前的结果看并没有什么问题。 但成功并仅仅需要自己的成功还要确保自己下游、下游的下游全部成功才可以,所以需要每个人对系统的流程负责,当自己的环节或自己下游环节出现问题需要主动把问题抛出来,同时尽快推进问题的解决。
点击在新窗口中浏览此图片
图1,生产链

用数据来证明
     5-6月底我们通过运营系统在逐步小规模上量验证Docker玩法的可行性,但是随着时间推移发现量并没有快速的上升,原因是资源有限每天在串行的上量,系统的扩容流程一旦发生问题只能停滞待问题解决后再继续。开始感觉经过一段时间量没有上去,没有上去的原因自己也说不清楚,所以当时一直在思考为什么自己也说不清楚,因为流程不稳定错误每天都在发生,每天发生完当时解决完就完了,没有沉淀数据也看不到全局数据能看到哪里的问题比较多。 邮件是一个很好的工具针对这种情况,我们沉淀了所有的日问题数据,并在每周5进行分类汇总,对分类后的结果进行排序,并根据排序的原因设定负责人推进。 经过一段时间数据的沉淀大概能分析出一些问题主要分两类:
1. 运营系统设计的目标和准入标准
     1.1 部门之前一直在提一键运维,从这个目标上看运营系统确实已经达到了,但Docker的扩缩容目标更多的是无人值守运维,目标显然是与目前项目不契合的导致在上量过程中遇到了很多问题。
     1.2 我们运营系统设计过程中的一个重要环节借鉴了Unix设计哲学中的思路,即一切接文件,通过管道来串联文件的输入和输出关系,这也说的是我们运营系统中的流程系统。由于历史原因导致流程系统的环节很长通常扩容一批机器需要16+以上步骤,而流程长就会间接导致成功率的低,从Docker小规模上量过程中期表象更多是运营系统的问题因为他直接暴露给用户,但实际更多是后端错综复杂的逻辑没有接入标准导致流程系统的不稳定。在一个大的系统中需要保证自己成功率的同时,依赖系统也要有严格的准入标准,并通过数据来找出问题,设定责任人并推进优化改善,同时尽量的减少流程环节。
2. 是业务符合架构还是架构符合业务
    笔者时常在思考这个问题,有意思的是笔者在部门中两个角色都做,相信站在不同的角度的答案也是不一样的,笔者之前做过业务所以站在业务的角度希望更多的是架构来符合业务,因为部门负责业务产品比较多每个产品都有快速发展的时候,如果跟不上发展将会被淘汰所以更希望架构来符合业务,实际上从运营系统发展历程上也能看到很多历史的影子 。 而目前笔者从事的是架构,更多希望是业务来符合架构,原因是在实际运营过程中发现运营系统和架构在符合各自产品标准上已经慢慢没有了自己的标准,导致系统臃肿与效率的下降, 另外很多人已经习惯了这种架构符合业务的方式,而最难改变的就是用户习惯,我们能做到的只能是增加架构与业务间彼此沟通,制定架构的准入标准,尽量满足业务的需求,并持续的完善与迭代。这里有一个模式可以借鉴就是微软的windows系列,推翻老的系统不断的更新操作系统的大版本,在实际运营过程中,发现问题再打补丁,同时系统尽量向下兼容,满足客户的需要。

end..



参考文章
1)Docker历史 http://www.oschina.net/news/57838/docker-dotcloud
2) 为什么要探索宇宙 https://www.douban.com/note/321442729/
3)Google 全球研发总监访谈 http://news.cnblogs.com/n/542090/

May 9
开篇
     “古巴比伦王颁布了汉摩拉比法典,刻在黑色的玄武岩,距今已经三千七百多年,你在橱窗前,凝视碑文的字眼,我却在旁静静欣赏你那张我深爱的脸……”,想必大家都听过这首周杰伦演唱的《爱在西元前》,由方文山填词,歌词生动美妙不落俗套。作为周杰伦的御用作词人,方文山其实只有高中学历,但他才华横溢,创作了不少经典之作,有些作品甚至被收录进了学校的课本中。那么他是如何写出这么美妙的歌词呢?直到看了他的访谈笔者才了解到其实他的歌词大多来源于生活中的灵感,这首《爱在西元前》就是他在某日逛完博物馆后有感而发,他从现实的场景获得灵感再进行文字加工,从而文思泉涌,妙笔生花。其实运维工作也亦然,需要我们时时从工作中寻找灵感。笔者从事运维工作接近8年,多年的工作经验总结出一个道理:我们要善于从运维工作中发现问题,并根据问题及过往经验发明创造改进工具,接着再从发明创造中提炼技术,最后根据技术提炼原理。近来以Docker为代表的容器很火,很多互联网公司都在使用。那么Docker是如何获得互联网公司的青睐的,我们又应该如何来应用Docker,本章将从以下几个方面逐一介绍:
 我们为什么使用Docker
 离线系统业务架构
 Clip名字服务
 Clip名字服务与Docker应用场景



我们为什么使用Docker
     首先来看一下我们在运维中发现了哪些问题。以笔者就职的腾讯公司案例为例,腾讯产品战线很长,笔者所在的团队负责运维腾讯的QQ、Qzone等核心产品,而这些产品也算是中国互联网骨灰级的业务了,整体架构都有着复杂的历史背景。不仅团队的老员工发现架构逐渐产生的问题,团队新入职的同事也会指出与原任职公司比较架构存在的一些问题等等。如何将很多好的技术融入到我们的业务架构中,以解决产品的问题是摆在每一个运维架构师面前的难题。架构的复杂性与历史沉重的包袱决定着牵一发而动全身,并且架构支持的业务为近半数的中国互联网网民所使用,还有着不少的优点,在对其进行改进优化之前,我们主要先分析了它的优缺点:
  优点:目前还是单机或单集群对应一个业务模块的形式,彼此间没有交集与复用(见图1),其架构优势应对爆发式增长扩容方便,成本结算简单,架构形成的历史原因更多的是前者流量的爆发增长。
点击在新窗口中浏览此图片
图1
  缺点:随着网民的饱和,相同业务模块下移动流量上涨,PC流量直线下降,很多业务出现了低负载情况。海量服务器的运维场景中即使只有1%的低负载规模也是惊人的,在实际运营中低负载+长尾业务下的机器数量可能达到了25%-30%甚至更高。当然这里不排除业务对流量做了冗余与灾备,但是多个业务模块的灾备就会出现浪费资源的情况。除低负载与长尾业务外,为了应对业务的流量徒增团队为产品留出了足够富裕的Buffer资源以应对某业务徒增,而导致这些资源的实际利用率不高。

分析了优缺点后以及运营中发现的这问题后,从2014年中我们就开始着手离线业务混合部署项目。项目的思路是通过高负载业务譬如音频转码、视频转码、图片人脸计算和图片特征提取业务(注:后统称“离线业务”)与低负载、长尾业务和部门buffer业务进行混合部署,来提升机器利用率并同时为部门节约机器成本。不过经过半年多的运营,我们也发现了很多问题:
  在低负载与长尾业务上部署离线业务,如果离线业务抖动出现大的CPU毛刺(特别在晚高峰时段)就会影响用户的使用体验,从而导致部分投诉产生的情况。
  部署在buffer池上的离线业务,由于在线业务申请机器导致机器上的离线环境没有及时清理,继续运营影响在线业务的正常使用。
这两个问题比较有代表性的问题也是我们最不希望看到的,所以总结经验教训后在2015年上半年我们又重新打磨项目开发了新版离线系统,新项目与老项目相比通过Docker技术将离线业务与在线业务的低负载、长尾业务和Buffer池进行了部署,从而顺利解决了上述的问题。这里主要利用了Docker的三个优势:
  Cgroup对资源的隔离让离线与在线业务彼此间对资源使用有了保障;
  命名空间,让相同框架多业务跑在相同物理机上成为可能;
  容器的快速回收上线下线,使用Buffer资源时不再为回收离线资源而头痛。



离线系统业务架构
上文中笔者提到QQ、Qzone的整体架构着很复杂的历史背景,而希望仅仅通过Docker或一两种工具来解决现实存在的所有问题是不现实的,所以我们在保持现有架构与内部用户习惯的基础上另辟蹊径逐渐解决我们产品运营上的一些问题,具体部署见图2。
点击在新窗口中浏览此图片
离线系统业务架构(图2)

从图2中可以看到在部门Cmdb基础之上,我们建立了数据分析系统,通过它可以分析出哪些是低负载业务,哪些是时段低负载业务。在此基础之上我们使用Clip名字服务系统在Cmdb基础之上重新建立了业务之前的IP关系,并根据重新划定关系的IP进行了业务流量与资源快速的调度。其中Etcd为服务发现工具,根据Clip名字服务系统传入的信息通过Confd重新生成HAproxy的配置文件并热重启它,离线业务流量通过HAproxy的虚拟IP屏蔽底层资源信息,建立离线与资源的生态供应链,同时上层监控与调度均为Clip名字服务系统。这里读者有可能会有疑问,尽管HAproxy的虚拟IP屏蔽底层资源信息(其为动态的),但如果程序有问题,如果能快速到机器上去debug自己的程序呢? 这里我们使用的是Clip名字服务。




Clip名字服务
Clip(http://blog.puppeter.com/read.php?7)是一个名字服务C/S架构,它将传统的IP管理维度替换为名字服务即有意义可记忆的String。Clip将IP对应的String关系保存在Server端。Client端可以下载SDK,通过SDK遍历Server端的String对应IP的关系,并在本地对获取的IP模块关系进行重新的组织与编排。传统服务器IP方式与String方式相比,String方式有3点优势:
  传统IP管理方式,IP由4组无意义的数字组成,比较难记忆。String更方便记忆;
  管理海量服务时,IP相似经常会导致运营故障,譬如A模块(10.131.24.37 )和B模块(10.117.24.37),后两组数字一致,系统惯性的认为B模块就是A模块,发送配置导致线上故障。通过string管理方式可以规避此问题;
  String 可以解析1个IP,也可以解析一组IP ,根据IP也可以反解析String对应关系,使得管理一组服务更加方便。
    Clip中的String由四段(字段含义idc-product-modules-group)组成,读者会发现String与Cmdb的结构很像:四级模块定位一个服务。但是为了充分利用资源我们的业务要求一个IP可能要对应多个服务,不同的服务有自己的波峰与波谷,在相同的IP上只要保证各业务的波峰不重叠就满足了业务的需求,也充分了利用资源。而在一台服务器上混合部署不同的业务模块,四级模块就只能定位到服务的IP级别,而无法精确定位到真正的服务,所以Clip名字服务在Cmdb的基础上增加了port端口,即五段(字段含义idc-product-modules-group-port)定位一个服务。我们可以将动态的IP通过Clip接口注册到指定含义的String上,通过Clip自带工具来解析实时的String对应IP关系,譬如:

# clip cstring -q idc-product-modules-group-port
192.168.0.1
192.168.0.2
192.168.0.3
192.168.0.4
192.168.0.5

Clip数据存储结构分为两层:
关系层保存了String对应IP或内部系统Cmdb的模块关系(见图3)。
点击在新窗口中浏览此图片
Clip名字服务关系表(图3)
关系层数据含义见表1
点击在新窗口中浏览此图片
关系层数据含义表1
数据层保存了String与IP的具体关系(见图4)。
点击在新窗口中浏览此图片
Clip名字服务数据表(图4)
点击在新窗口中浏览此图片
Clip名字服务在存储String对应IP关系基础上,在SDK上还提供了远程端口扫描、远程ssh、远程文件拷贝和查找String关系结构的工具子命令等,更多可以见http://blog.puppeter.com/read.php?7。




Clip名字服务与Docker应用
如笔者上文所提,离线系统的建设思路就是将离线业务通过Docker快速的部署在资源空闲的机器上,而空闲的机器是通过数据分析系统长期分析沉淀的结果,Clip名字服务就是这两种资源建立联系的桥梁,但只有Clip绑定关系还是不够的,还需要建立绑定关系String对应Docker环境的关系,所以在Clip名字服务的基础上我们又扩充了Docker的资源关系表。
点击在新窗口中浏览此图片
Docker资源关系表图5
其中Docker资源使用的关系表的字段含义见表3:
点击在新窗口中浏览此图片
我们来看一个需求案例:某视频转码业务在上海需要使用资源约1000核心,对应的关系表为表4
点击在新窗口中浏览此图片
由于buffer资源不时在变动,我们需监控String (sh-buffer-qq-video-2877)整体核数是否低于mcount值,如果低于则出发自动扩容策略。同时也需针对Docker资源使用关系中的app_port字段来监控整体String (sh-buffer-qq-video-2877)业务是否处于健康状态。在这里我们沉淀了String (sh-buffer-qq-video-2877)的一些基础数据如负载、内存、网络和磁盘IO等为资源的调度奠定的基石(见图6)。
点击在新窗口中浏览此图片
离线运营系统图6
Sep 23
作者:研究僧
文章地址:http://blog.puppeter.com/read.php?4

背景
由于历史的原因我们的机器目前还是单机或单集群对应一个业务模块的形式,优势应对爆发式增长扩容方便,成本结算简单。但是随着网民的饱和,相同业务模块下移动流量上涨,PC流量直线下降,很多业务出现了低负载情况,海量服务器运维中只要有1%的低负载(既机器利用率不饱和)规模也是惊人的,在实际运营中低负载+长尾模块机器数量可能达到了25%-30%之间,当然这里也不排除业务对流量做了冗余与灾备,但是多个业务模块的灾备就会出现浪费资源的情况。我们从运营中发现了这问题的存在,而运维的核心价值也是通过技术优化,能在(成本、质量、效率与安全)四块做优化达到一个很好的收益,所以从2014年中我们开始做离线业务部署项目。项目的思路是通过高负载业务(离线计算)与低负载业务进行混合部署,提升低负载机器利用率同时逐步下线高负载业务的机器为部门节约机器成本。不过经过半年多的运营中我们也发现了很多问题,离线业务的负载均衡权重统一,但是混合部署后的机器负载不均有高有低,混部的结果经常会导致部分机器高负载影响业务,可以看出这里缺少监控负载的和业务合理的手段,经常导致高负载业务影响低负载业务,接口超时影响用户的情况,这是我们不希望看到的,所以总结经验教训,在2015年上半年我们重新打磨项目开发了离线业务混合部署(琥珀自动调度系统)项目,新项目与老项目相比通过docker技术将混部业务控制在容器中,消除争抢资源对业务影响,同时对容器流量进行根据负载调度,在此基础上实现了分时调度等功能。见截图1
点击在新窗口中浏览此图片
希望通过技术架构优化与升级来充分扎干硬件资源,为公司节约服务器成本。在开发过程中,相关业务也向我们提出了以下需求(已经实现功能见图2):
1.机器主动与被动下线不影响在线业务;
2.可以方便的查看到系统运行状态;
3.可以连接到容器内部查询日志以及debug程序;
3.沉淀各系统日常数据,并根据沉淀的数据进行戳峰调度。
点击在新窗口中浏览此图片
系统访问逻辑及接入方式
根据系统需求,最终访问逻辑分为三部分(用户接入、程序逻辑、和容器生成),每层之前交互通过接口,尽量把复杂的逻辑对上一层透明,见图3。
点击在新窗口中浏览此图片

琥珀系统提供两种接入方式:
方式1:
  通过vip方式接入(推荐),用户不必关心底层系统。首次接入将业务环境打为docker,并测试。后续业务流量通过vip引入计算集群(注:计算集群与首次docker业务环境一致),用户不必关系集群内部机器数量与机器状态,系统保证相应的计算量已经容灾调度。见图4
点击在新窗口中浏览此图片
方式2:
  业务流量通过接口获取动态IP列表,并将流量下发到列表IP中。当机器下线接口主动通知业务流量踢IP。与方式1同样首次接入需要打docker镜像源。见图5
点击在新窗口中浏览此图片

系统架构
我们通过介绍开源软件(docker + haproxy + confd + etcd+ clip)来完整整个琥珀系统的架构,见图6
点击在新窗口中浏览此图片

其中开源软件(docker + haproxy + confd + etcd+ clip)介绍如下:如下:
1.Docker(官方网站:https://www.docker.com/)是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化;
2.HAproxy (官方网站:http://www.haproxy.org/ )为负载均衡软件可以根据IP权重自动分发流量,支持8种负载均衡算法;
Confd(官方网站:https://github.com/kelseyhightower/confd)是一个轻量级配置管理工具,它可以从 etcd, consul, dynamodb, redis,zookeeper 或 env获取最新的数据更新本地模板文件;
3.Etcd (官方网站:https://github.com/coreos/etcd) 是一款高可用的键/储存储系统,主要用于服务发现与共享配置,同时聚焦;
   简单:支持 curl 方式的API (HTTP+JSON);
         安全:可选 SSL 客户端证书认证;
         快速:单实例可达每秒 1000 次写操作;        
         可靠:使用 Raft 实现分布式。
etcd是由CoreOS开发并维护使用Go语言编写,并通过Raft一致性算法处理日志复制以保证强一致性。目前很多大项目都使用了etcd,如:Google的Kubernetes、Pivotal的Cloud Foundry、Mailgun、Apache Mesos与Mesosphere的DCOS。除开这些大型项目,在GitHub上还有超过500个项目使用了etcd;
4.Clip是(cmdb + tools)的结合(官方网站:http://blog.puppeter.com/read.php?7)。将传统的对IP管理维度替换为String维度,其中String格式为(机房-产品-模块-组-端口),通过Clip可以对IP进行打标签,并根据便签对应属性形式区分服务来源。

程序安装
1)HAproxy安装

# wget http://www.haproxy.org/download/1.5/src/haproxy-1.5.14.tar.gz
# tar –xvzf haproxy-1.5.14.tar.gz  && cd  haproxy-1.5.14
# make install

HAproxy源码编译安装,启动和关闭建议采用以下方式。

# 重启
$ haproxy  -f /etc/haproxy/haproxy.cfg  -p /tmp/haproxy.pid
# 热重启
$ haproxy -D -f /etc/haproxy/haproxy.cfg -p /tmp/haproxy.pid -sf $(cat /tmp/haproxy.pid)


HAproxy 二进制命令参数

-d 前台,debug模式
-D daemon模式启动
-q 安静模式,不输出信息
-V 详细模式
-c 对配置文件进行语法检查
-s 显示统计数据
-l 显示详细统计数据
-dk 不使用kqueue
-ds 不使用speculative epoll
-de 不使用epoll
-dp 不使用poll
-db 禁用后台模式,程序跑在前台
-sf 程序启动后向pidlist里的进程发送FINISH信号,这个参数放在命令行的最后
-st 程序启动后向pidlist里的进程发送TERMINATE信号,这个参数放在命令行的最后
-d 前台,debug模式
-D daemon模式启动
-q 安静模式,不输出信息
-V 详细模式
-c 对配置文件进行语法检查
-s 显示统计数据
-l 显示详细统计数据
-dk 不使用kqueue
-ds 不使用speculative epoll
-de 不使用epoll
-dp 不使用poll
-db 禁用后台模式,程序跑在前台
-sf 程序启动后向pidlist里的进程发送FINISH信号,这个参数放在命令行的最后
-st 程序启动后向pidlist里的进程发送TERMINATE信号,这个参数放在命令行的最后

HAproxy优化

net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_max_tw_buckets = 5000

2) confd安装
Confd的用途是监听etcd中键值变化,并根据变化更新模块中的数据。(注:这里confd 需要安装在HAproxy相同机器)

wget https://github.com/kelseyhightower/confd/releases/download/v0.6.3/confd-0.6.3-linux-amd64  
# mv confd /usr/local/bin/confd  
# chmod +x /usr/local/bin/confd  
# /usr/local/bin/confd -version  
# mkdir /etc/confd/{conf.d  templates}

在conf.d目录中创建haproxy.toml文件。haproxy.toml是confd的配置文件,其作用是当etcd中的数据发生变化,根据haproxy.toml中的(src)模板信息重新生成目标(dest) 模板,最后重新加目标程序配置文件。它支持所有带配置文件的软件,譬如(nginx,apache,haproxy,lighttpd)等。以下为haproxy.toml文件内容。

haproxy.toml
[template]
src = "haproxy.cfg.tmpl"
dest = "/etc/haproxy/haproxy.cfg"
keys = ["/app/servers/","/app/weiyun"]
reload_cmd = "/usr/local/services/hupo/haproxy-1.4.21/haproxy_reload"

在templates目录中创建haproxy.cfg.tmpl文件,内容如下(注:haproxy.toml中的keys与haproxy.cfg.tmpl模板中遍历的数组要一致):

global
   maxconn 2000
uid 99
gid 99
   daemon
   nbproc 10
   #debug
   #quiet
defaults
        retries 3
        option redispatch
        maxconn 10000
        contimeout      5000
        clitimeout      50000
        srvtimeout      50000
#       stats uri /haproxy-admin
listen  admin_stat 0.0.0.0:8080
        mode http
    stats refresh 70s
        stats uri /admin_stats
listen  tcp-in 0.0.0.0:1991
        mode tcp
        balance roundrobin

{{range gets "/app/weiyun/*"}}
        server {{base .Key}} {{.Value}} check inter 5000 fall 1 rise 2
{{end}}

{{range gets "/app/servers/*"}}
        server {{base .Key}} {{.Value}} check inter 5000 fall 1 rise 2
{{end}}


关于模板更多内容见(https://github.com/kelseyhightower/confd/blob/master/docs/templates.md)

3)etcd安装

# wget https://github.com/coreos/etcd/releases/download/v0.4.6/etcd-v0.4.6-linux-amd64.tar.gz
# tar -zxvf etcd-v0.4.6-linux-amd64.tar.gz
# cd etcd-v0.4.6-linux-amd64
# cp etcd* /bin/

启动

# etcd  -name ip_data   -addr IP:4001 -data-dir 数据文件地址 -bind-addr IP:4001

其中etcd常用参数如下:
-name:节点名称;
-addr : 客户端连接地址与端口;
-data-dir: 数据文件存储地址;
-bind-addr:绑定IP + 端口;
其中RESET-API例子

# 增
$ curl -L -X PUT http://127.0.0.1:4001/v2/keys/message -d value="Hello"
{"action":"set","node":{"key":"/message","value":"Hello","modifiedIndex":4,"createdIndex":4}}
# 查
curl -L http://127.0.0.1:4001/v2/keys/message
{"action":"get","node":{"key":"/message","value":"Hello","modifiedIndex":4,"createdIndex":4}}
#删
$ curl -L -X DELETE http://127.0.0.1:4001/v2/keys/message
{"action":"delete","node":{"key":"/message","modifiedIndex":19,"createdIndex":4}}


分页: 1/1 第一页 1 最后页 [ 显示模式: 摘要 | 列表 ]