华为精益敏捷专家DevOps转型中的那些坑

陈军--原腾讯高级项目经理、华为精益敏捷专家 DevOps是现在非常流行的一个词,很多人都在提DevOps,在往那个方向去转,但转的时候坑特别多。 现实是很理想的,大家都觉得做了DevOps之后就会非常快了,业务就会非常好了,但其实做了DevOps之后,你的业务也不一定会非常好。在很多公司内部也有共识,工程跟业务没有任何关系,但做了总比没做好。 这是转型的J型曲线,这个曲线出现在DevOps2018的报告里,但这个曲线在很多变革当中都会出现,这个是Model的原型,做任何一场组织变革,DevOps也好,敏捷也好,都会经过这样的曲线,这中间有一个非常大的坑要过,经历过这个痛苦的过程之后,你的绩效会变得越来越好。 转型的时候我们希望大家有一个思考的逻辑。这个思考逻辑从上到下是Values、Principles、Methods、Tools&activities。不要一心铺到工作上,要想清楚价值是什么,采用的是什么原则,要用什么样的方法,再取决于用什么样的工具跟活动。 敏捷价值观就是敏捷宣言那四句话,那四句话是我们的价值观,价值观下面有原则、工具、实践活动,这是思考转型的逻辑,DevOps也是一样的。 DevOps里面有敏捷、精益、持续集成、持续交付 ,里面包括很多东西,你在真正解决问题的时候要得到什么样的好处,你用的是什么原则,用的是什么方法,然后再配相应的工具,这是你转型的原则。我觉得这样非常重要,如果思考不清楚就不要去用。 所以我们在做一件事情的时候,你要获得的价值是什么?这是你要思考的逻辑。 1-DevOps是个坑 这个图大家可以看得很清楚,第一个是Dev&Ops,原来的Dev和Ops是分开的。当我们用了DevOps之后,它还是一个坑。最怕的是把这个坑丢给客户了,所以我们这里非常重要的原则就是坑谁都不要坑客户,你不要把不好的东西给客户。 在华为有一个团队,领导意识到在转型的过程当中肯定会有坑,所以领导帮团队去承担了处分,最后处分的是领导。这个也是在DevOps转型时非常重要的点,团队一定会犯错,但作为领导要帮团队创造容错氛围,不要一犯错就指责团队,坑谁都不要坑客户,这是非常重要的点。 这是DevOps的模型,可以看到最底层的东西是精益管理。 精益的来源是谁?丰田。 丰田最重要的两个原则是自生产和自动化。但这两个原则其实是冲突的,这个厂讲流动要快,另一个厂讲出了问题要停下来,所以这两个是冲突的,丰田不仅要快而且质量要好。 最早丰田是做织布机的,把手动织布机改成了自动织布机。一开始的版本有问题,一旦织布机的线断了之后织布机不会停,跑着跑着出来的布是有问题的,因为里面的线断了,所以出来的是残次品,质量非常不好。后来丰田做了改进,一旦线断了织布机会停掉,需要人把线接起来再跑,这就是丰田注重质量的原则和方法。 建立以下游为中心而优化,做到质量内建。不能把问题留在下游,一旦这个过程出了问题,整个生产都要停下来,这是持续集成、持续交付非常重要的原则,一旦流水线出问题断了,你第一时间要处理流水线,而不是填新的代码,这是非常重要的原则。 2-技术债务拖后腿是一个坑 这是目前非常隐形的问题,虽然大家不是很在乎,但如果你的产品想长期发展,想速度越来越快,这是很重要的事情。我们可以从漫画里看到,这两个人一直在挖坑,发现自己挖到一定程度就出不去了。我们现在就是这样,我们是在给自己挖坑,虽然看起来还觉得很快,但回过头会发现,那些坑已经填不了了。 质量分外部质量和内部质量。外部质量是用这个产品时体会到的,通常是通过测试去覆盖的,内部质量是指代码。从这个系统思考图,可以看到有很多的恶性循环。如果外部质量差,测试信息会受到影响,测试周期会越来越长,因为不知道哪里会出问题,会影响到交付周期。可能会尽快交代码,交代码会乱写,内部质量会越来越差,这是恶性循环。内部质量和外部质量之间的影响是有实质的,不会那么快的反映出来,所以很多时候我们重视外部质量,但忽略了内部质量。内部质量差的时候,会发现核心功能会越来越慢。 怎么减少技术债务? 我们说衡量代码质量的唯一标准是你在做代码检视的时候每分钟说了多少个F词。我在一个关于DevOps的网站上看到一篇非常火的博文,推荐了DevOps相关的十本书。推荐的第一本书其实跟DevOps并不相关。要把DevOps做好,基础代码质量是非常重要的事情。 怎样减少技术债务?代码的规范是非常重要的。为什么代码的规范非常重要?首先你的代码是写给人看的,不是写给机器的,这是非常重要的事情。读代码和写代码的比例时间是10:1,你的代码一定要先写给人看再写给机器。你想想如果要看别人写的代码,如果你很痛苦,怎么改这个代码?很多的遗留代码我们不敢去改,因为看不懂,所以代码规范非常重要。在谷歌专门有一种人是做代码规范review的,他们内部有一个可读性的证书,有了这个证书才能review别人的代码,而且有权利把别人的代码打回去。如果他的代码没有通过,是没办法提交的,谷歌做的就是这么严格,可读性是非常重要的事情。 规范与度量包括代码规范、代码质量度量。谷歌的code review做的非常严格,一定要通过code review才能提交代码。工具辅助包括规范检查、代码质量检查。重构这个事很重要,比较重要的是童子军规则,在出营地的时候要比进营地时的这块地更干净。如果我看了这一段代码,当我关闭这段代码的时候,一定要改。重构不是运动,不是临时想起来就要大范围搞一下,一定是平时就要去做的习惯,看到代码不爽就要去改。 3-团队的一个案例中的坑 某实施DevOps的团队遇到下面的问题,一开始他们采用主干开发,但是频繁提交代码集成无法保证主干的质量(主干健康度的度量),QA会经常找团队,团队觉得非常烦,慢慢他们不再那么频繁提交,做完一堆需求再一起提交。后来PM抗不住了,改变策略采用分支开发,大量的问题在集成测试时爆发,导致集成测试时间很紧。如果是你,你会怎么给他建议? 我给的建议是,其实他们采用分支开发是往后退的,在持续集成里有一个非常重要的原则,他们绕过痛苦的事情就会更痛苦,频繁提交是ok的,他们要解决的问题是怎样把主干集成度做起来,而不是往后退。当时他们也有做单元测试,但他们的单元测试是后补的,不是跟代码一起提交的,所以主干健康度比较差。他们要改变的是把单元测试和代码同时提交,一定要跑过单元测试代码才能往上提。现在华为提交代码到主干的时候,都会有一个所谓的门禁,门禁里面要检查很多东西,包括代码、规范、质量指标、单元测试都要跑通才能提交代码。 这里面有两个,一个是机器检查,一个是Code Review,这两个都提交才可以。但不能说主干质量不好就往后退,要解决主干质量的问题,而不是往后退,所以越痛苦的事情越要经常做,越要频繁去做,痛苦的点才是你要改进的点。 让代码流动起来,并快速获得反馈。一定要小批量频繁提交代码,但提交代码是有前提的,要过门禁才行。 4-微服务是个坑 微服务也是我们现在提的比较多的东西,到底要不要做?很多人都在说。这里的理念是什么?如果你的代码是一坨shit,切成微服务就是N坨shit,是管理一坨还是N坨?你做微服务的基础是系统要比较好,微服务架构要紧的是如何正确划定边界,微不微其实不重要。我们最近有一个上海的团队,他们切了微服务尝到了一些甜头,但更痛苦的是服务间的耦合以及服务与硬件的耦合,这让他们非常痛苦,改一个地方要改好多服务。这个团队在跟南大教授合作,一个是微服务密度的问题,一个是微服务拆分的问题,其实很多服务不用拆,既然耦合度这么高干嘛要拆?微服务改了之后其他的都要动,干嘛还要改? 这是Martin Fowler2015年提出的 单体优先 。微服务本身在做的时候有很大成本,它的成本能不能给你带来更多的收益?这是我们在做一项决策时会考虑的,就是投资回报率的问题。 Martin Fowler强调单体优先,如果一开始做微服务很多的基础设施都要跟上,这个成本蛮高,所以他提到微服务溢价的问题,要看微服务的好处能不能抵消成本。 构建演进式的架构,地球以前的大陆是在一块地,随着时间的推移和环境的变化才慢慢演进出了各个洲、各个块,我们的架构也是一样的,不一定一开始就要创建合适的架构,可以创建演进式的架构,可以在特定的时间进行转换。我们要注意几个原则,讲的都是解耦的问题。 一是将大型的域分割成变更孤岛;二是针对可替代性进行设计。可替代性是什么?原来很多的系统跟模块不敢去改,虽然这块可能很多人没用,但我们也不敢改,因为有耦合性,我们不敢动。如果针对可替代性做服务,这个服务如果不用了,随时可以停掉,把服务直接杀死接新服务就可以了;三是最小化共享依赖,重点关注自治和冗余,而不是重用。 5-度量是个坑 度量我们听到的最多反馈是什么?这玩意儿就是给上面看的,没什么用。没有这些指标,我咋知道下面的人干的咋样?这是我们听到最多的说法。包括有人说为了确保数据的真实性,需要加上考核指标。有一些团队是分布式的,在很多地方,他们想知道异地团队在干什么事。我们有一个IT系统,怎么确保他们更新的数据是真实的?是不是要加一些考核指标去考核他?保证他更新的数据是真实的。这些都是我们常见的对度量的误解。 有哪些度量的误区?一是数据的生产者不是数据的消费者,数据生产者不关心数据的价值,也不关心数据准确与否。很多时候数据是给领导看的,不是给我们看的;二是数据的生产者关心是佛会对自己带来惩罚或受益,不关心数据跟软件开发的关系。这会产生什么问题?数据造假;三是数据等于控制,一定要看到数据才知道下面的人在干什么。 度量的意义到底是什么?我们觉得度量的意义是改进。改进在于什么?自己跟自己比,不要横向比较,每个团队都不一样,横向比较是非常痛苦的一件事情,我们在华为是踩过坑的,这个事我就不太好讲了。横向比较和晾晒的原因,导致很多团队的数据造假,这是华为真正踩过的坑,曾经是华为内部很轰动的事情。度量会告诉我们离目标还有多远,现状是什么,进展如何。 这是一个度量指标的体系,非常多,大家可以参考一下。 度量是一个系统工程,需要不断演进。首先你要知道度量不是免费的,有成本,需要有效性和可靠性,我们收集的数据最好是机器产生的,而不是人去填的,这个很重要。第二个是OMTM,这是精益数据分析的概念,叫单一关键指标。选择适合当前的产品阶段的指标,重点优化该指标。最好是这一段时间就优化这一两个指标,不要分得太散。第三个是随时审视,做加法也要做减法,不要让度量成为团队的负担。最重要的一点,不要跟考核挂钩,不要横向比较,这是华为踩过的非常大的一个坑,一旦跟考核挂钩,一旦横向比较,数据一定会造假。 ...

June 5, 2019 · 1 min · jiezi

CODING-受邀参与-DevOps-标准体系之系统和工具-技术运营标准技术专家研讨会

2019 年 5 月 24-25 日,国内领先的一站式 DevOps 解决方案供应商 CODING 作为腾讯云的深度合作伙伴,受邀参加在成都举行的由 TC608 云计算标准和开源推进委员会主办,中国信息通信研究院牵头,高效运维社区支持,DevOps 标准工作组负责组织的 DevOps 标准体系之系统和工具 & 技术运营标准技术专家研讨会。 在《研发运营一体化 DevOps 能力成熟度模型第 8 部分:系统和工具》与《研发运营一体化DevOps 能力成熟度模型第 4 部分:技术运营》标准技术专家研讨会上,围绕项目与开发管理、应用设计与开发、持续交付、测试管理与自动化写实、技术运营、安全开发等进行了技术研讨,并制定了相关规范。 本次会议专家组合影,第五排左起第四位为 CODING 产品总监王振威 本次会议还邀请了来自华为、平安科技、腾讯、阿里巴巴、中兴通讯、亚信科技、浙江移动、京东金融、中国联通、苏宁消费金融、百度、去哪儿网、新华三等行业顶尖企业的 40 余位 DevOps 实践与工具专家,对标准框架和内容进行了全面的研讨,将系统和工具 & 技术运营两部分标准内容进行完善与规范,并在第二天的会议中将部分内容定稿。 DevOps 能力成熟度模型第八部分 项目与开发管理 & 应用设计与开发此次会议“项目与开发管理”、“应用设计与开发”两个部分的内容依旧由华为、腾讯、阿里、CODING 等单位的专家通力合作完成部分定稿。 工作项管理能力域的部分文稿 持续交付持续交付部分此次主要对能力域及其内容进行了更新,主要包含版本控制系统、构建与持续集成、流水线、制品管理、部署管理、发布管理、环境管理、应用配置管理、数据变更管理 9 个能力域,就数据管理更改为数据变更管理达成了高度一致,完成了定稿目标。其中 CODING 自研的 CCI 系统也为此部分标准提供了参考内容。 会议现场讨论情况 测试管理 & 自动化测试测试管理与自动化测试依旧由中兴通讯、腾讯、亚信科技、CODING 等单位的专家通力合作,完成了测试管理以及自动化测试的最终定稿。 缺陷管理能力域部分文稿 技术运营此次研讨会的核心内容之一是系统和工具中技术运营的能力项划分,最终与会专家达成一致,主要包括通用、监控管理、事件管理与变更管理、配置管理、容量与成本管理、高可用管理、业务连续性管理、用户体验管理等部分,后续也将在中国信通院的指导下,继续开展相关编写以及研讨工作。 会议现场讨论情况 CODING 简介CODING 一站式 DevOps 解决方案 CODING 是面向软件研发团队的研发协作平台,涵盖了软件开发从构想到交付的一切所需,提供完整的研发协作工具,无需对接第三方服务。使研发团队在云端高效协作,实践敏捷开发于 DevOps,提升软件交付质量与速度,降低企业研发成本,助力企业实现数字化转型。 点击即可开启企业数字化转型之旅现五人以下团队可免费使用 CODING

June 3, 2019 · 1 min · jiezi

2019企业IT现状和趋势调研报告707的企业有云原生相关计划

2019年第一季度,灵雀云发起了“企业IT应用现状和云原生技术落地情况”的调研,通过定向邀请,3个月内共收集了400余份有效调研问卷,这些调研问卷80%以上都来自于国内政府、金融、能源、制造、汽车等传统行业的IT从业者。 发起本次调研的初衷,是我们希望了解当前企业,尤其是传统企业目前IT应用开发现状、以及以DevOps、Kubernetes、微服务等为代表的云原生技术在企业的应用情况,从而勾勒出传统行业IT发展趋势,并对于判断国内用户对云原生相关技术的认知度提供一个有价值的参考。 核心要点解读: 1、 约70%的参与调研者所在企业2019年IT预算有上浮; 2、 24.4%的参与调研者表示公司IT系统基本全靠自研,企业开始自建软件研发团队,主导IT应用的研发; 3、 70.7%的参与调研者所在企业表示在2019年有容器、DevOps和微服务方面的规划; 4、 11.4%的参与调研者所在企业已经试点了具有标杆意义的云原生实践,如精英团队的DevOps实践,小范围非核心应用的微服务拆分改造实践等。 本次调研的400多位调研对象中,80%以上来自金融、能源、制造、汽车等传统行业,其中17.3%来自基础架构部门, 22.5%来自运维部门,34.1%来自研发部门,还有约10%的被调研对象为企业的CIO/CTO等高级IT管理者。 被调研企业中,服务器规模在100-500台的比例为26.8%,500-1000台的企业占比22%,1000台服务器以上规模的14.6%。 IT系统自研还是外包 在数字化转型的背景下,传统外包的做法在被逐渐改变。在此次调查中,70.7%的参与调研者表示目前IT系统是自研外包兼而有之,其中核心业务系统以自己开发为主,24.4%的参与调研者表示公司IT系统基本全靠自研,只有4.9%的参与调研者选择了纯外包选项。这表明,企业开始不再将大部分业务系统,尤其是核心业务需求开发外包,开始自建软件研发团队,主导IT应用的研发。只有企业自己主导IT研发,才能够打造IT核心竞争力。 软件能力成为企业的核心竞争力,这恰好是数字化转型的本质之一。何谓成功的数字化转型?灵雀云认为,有三大衡量标志:IT部门由成本中心转为收入中心;企业自己主导IT产品的研发;改进工具、流程、文化来提高交付速度和质量。最终,实现客户满意度的提升、打造差异化竞争优势、加速产品上市。 IT系统更新频率 在IT系统更新频率方面,每月都要更新、升级的比例达到了51.2%的高占比。同时,每3-6个月更新一次的比例达22%。每个传统领域,都受到了来自Fintech金融科技、车联网、物联网、新零售等新技术驱动的创新业务的挑战,传统企业只有借助IT手段才能实现持续发展,在速度和规模上保持竞争力。 IT系统和研发团队TOP 3挑战 本次参与调研的企业以中大型企业为主,其中研发团队规模达到100人以上的比例高达44.3%,20-100人规模的占32.4%。 今天,许多企业都经过了大量IT建设,从分散到集中,造成IT系统越来越复杂,信息孤岛林立,架构臃肿等问题突出。调研中企业IT系统支撑所面临的压力位列前三的挑战分别是:系统复杂性越来越高(65.9%);应用交付压力大,交付速度无法满足业务需求(61.4%);运维管理复杂度提升,IT部门很难构建一支全功能团队(53.7%)。 同时,研发团队所面临的挑战前三甲分别是:部署和运维复杂,运维成本高(74.6%);研发、测试、运维等角色之间相互孤立(62.3%);升级和变更流程复杂,IT服务和应用交付周期长(45.7%)。此外,比较突出的挑战还有,工具链无法完整集成,工具使用困难(32.3%),单体应用过于庞大,迭代效率低下(20.4%)。 上述结果充分表明,面对高度创新、快速变化和充满不确定性的新型业务需求,传统开发模式和IT架构已经成为掣肘。70.7%的参与调研企业表示2019年有容器、DevOps和微服务方面的规划和实施计划。 只有朝着持续交付、敏捷部署、快速迭代,通过敏捷IT赋予业务足够的敏捷,才能够满足不断变化的业务需求,重塑自身的生产力,形成竞争优势,带来更好的用户体验,这最终落到以Kubernetes/容器、DevOps和微服务为核心的云原生技术的落地上。云原生架构和理念与数字化转型一脉相承,帮助企业更加顺畅地实施数字化转型。 业务上云需求最强烈,开源、数字化转型受追捧 在企业最关注的新兴技术趋势方面,云计算占比82.9%,企业将业务上云,提升IT资源效率作为首要关注对象。大数据和人工智能紧随其后,占比分别为73.2%和46.3%。其中开源解决方案在调研对象中的关注程度达到24.4%。 当前开源技术正在进入快速发展阶段,向着企业应用的方方面面深入。开源及开源社区不断将新的工具、方法和最佳实践用于云原生的实际业务用例,解决云原生用户的关键问题。借助许多开源解决方案,云原生部署的复杂性和难度也在得以降低。 此外,数字化转型的关注度为33.6%。如今每位IT从业者言必称数字化转型,IT能力也直接指向助力数字化转型。CIO和其他IT管理者已将企业的数字化计划置于新的高度,希望通过数字化来改变企业的商业和业务模式,数字化业务将从初步试验走向大规模应用。伴随企业数字化业务的不断成熟,预计未来几年,数字化转型将进入爆发阶段。 传统企业2019年IT预算稳中有升 本次调研中,被调研企业今年IT工作的重点包括业务上云(56.1%),云原生、大数据、人工智能等新技术采用(53.7%),打造数字化团队,引领企业的数字化创新(43.9%),选择传统业务应用的比例不足20%。越来越多的企业将工作负载放在云端,将正在开发的应用或服务托管在云平台上,云市场不断增长。 在IT预算方面,比客观经济形势略显乐观,和2018年IT预算相比,接近70%参与调研企业2019年的IT预算略有上浮,其中增长5%以内的企业占比37.5%,增长5-10%的企业占比21.2%,增长10%以上的企业达到12.7%。 此外,调研结果显示,数字化转型是一项需要通盘考虑的工作,需要项目管理部门、技术管理部门、开发部门、运维部门共同参与,制定统一的数字化转型方案和决策并推进。有些参与调研的企业特别强调2018年已经在全公司范围内试点了具有标杆意义的云原生实践,如精英团队的DevOps实践,小范围非核心应用的微服务拆分改造实践等,并且这些都将在2019年进行大范围推广。

June 3, 2019 · 1 min · jiezi

DevOps的工程化

孙敬云 --Worktile高级系统架构师,WTC成员 1.研发的困境互联网的环境互联网这个环境比较特别,包括现在不只是互联网,就算是被互联网赋能的这些“互联网+”的企业也在改变,用户在发生变化,用户构成的群体在发生变化,群体造成场景的变化,场景营造新需求,需求养成新用户习惯,新用户习惯造就一批新用户,周而复始。我们一直在追赶用户,但从用户的角度来说,他一直都期望有一个好的产品和一个稳定的服务。相信在座各位既是技术从业者也是普通的用户,大家会发现自己总是想尝试一些新的东西和好的东西。 软件交付的困境进度不可控: 我们的研发团队会面临一个问题,一些传统的行业也好,或者现在在实行Sprnit的团队也好,你会发现研发 进度非常不可控 。你有时候感觉一切都很可控,完成任务的时候前80%也觉得没问题,一定能交付。但一旦到了后20%,测试报出海量的bug,运维问你怎么部署?好多东西还没有定,越来越忙。尤其是上线的晚上,一定要搞一个通宵才能把所有的问题解决。这种复杂的困境是技术不可控的; 流程不可靠: 我们公司总是有各式各样的流程发生,但你会发现这个流程走着走着总是需要有一些 关键角色 蹦出来,必须有一些企业大牛或团队经理站出来说这个事情应该怎样做,或者说今天谁谁没来,这个流程没法往下做。 环境不稳定: 线上怎么就出问题了?测试环境好好的,本地就没问题,是不是因为线上没有按照我说的做?环境这个问题在哪个公司都会遇到。 沟通不顺利: 研发同学跟运维同学在争论,研发同学说上线之后跑脚本,运维跑完了上线出了问题。研发同学就问他“你跑脚本了吗?”他说“跑了”,“是部署前跑的还是部署后跑的?”他说“你没有跟我说这个。”这就是沟通不顺畅,这个本来是可以避免的。 我们需要一种工程手法,让软件在很短的周期内稳定部署上线。 关键词是 “很短” 和 “稳定” ,甚至一键部署到任何版本任何环境中,甚至这些操作都在可视化的环境进行。我们在研发团队中说,凡是要定目标做计划,怎么办?我们今天每个人给自己定一个目标: 从今天开始每个团队一天部署三次 。大家觉得不可能,安排计划Sprint两天就够呛了,怎么可能一天上线三次? 举一个真实的例子 汇丰银行在2014年的时候全年release24次,这个数字相当于 两周有一个 release的版本,很高效。但是2018年全年release12000次,这是什么概念?你今天一天release 几十 次,大家觉得这不可能,开发代码能写完吗?这就是一种思维方式的转变。 如果我们今天说一定要达成这个目标,不管可能不可能,给我一个执行方案和参考的借鉴点。 概念的组合我们把这个事情分为四个步骤: 第一步 ,自动化的流水线,这是稳定可重复使用的。第二步 ,支持构建流水线所需要的技术平台和工具。第三步 ,运行这些平台完成流水线所需要的人和角色。第四步 ,支持能够把这些所有东西全部落地并有稳定持续改善方案的文化与规则。 2.DevOps是什么?DevOps在维基百科上的定义DevOps是一种重视软件开发人员和IT运维技术人员之间沟通合作的文化、运动或惯例,透过自动化软件交付和架构变更的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。 所以前面所有的都是定语,只有最后一句最关键,就是 :频繁可靠的发布软件,这就是我们的终极目标。 针对刚才定义的原始阐述,从这个环形图上的工作方式,一直在持续演进,好像看起来没有什么特别的,这个神奇点在哪? 如果你跟别人说你今天看了一篇分享是DevOps,或者你去搜DevOps,会发现所包含的含义和相关的含义特别多,包括 精益思想、自动化、持续集成、持续部署、价值流、三步工作法、持续交付、分级部署、敏捷思想、敏捷开发、团队合作 。 在我看来这是大家对于美好事物的一种期望,期望DevOps能承担更多。即使我们今天不提DevOps这个词,把敏捷这个词说出来,你也会说敏捷包含这些部分,换个词也是这样。我认为我们 千万不要陷入于这个词的含义是什么 ,我是想谈 工程化 ,谈 工程化背后美好的东西 。 “持续交付”和“DevOps”我们挑两个特别容易被网上的人或大家所对比的词汇,一个是 持续交付 ,一个是 DevOps 。 持续交付也好,DevOps也好,他们的共同点是秉持交付思想,他们都崇尚精益思想,他们都喜欢自动化,他们都以快速和稳定的变更为目标,这是两个共同点。持续交付偏向于将不同的过程集中起来,并且更快更频繁地执行这个过程。 虽然我们对比了这两个词,但我希望大家不要过度陷入于概念本身,不是说我今天学的究竟是DevOps还是持续交付,这个没有意义。我们要把好的思想带回项目组,带回团队,能不能落地是我们的关注点,我们不要过多对比概念。 基础参与人凡是涉及人的话题,一定是比较特别的,你只要不把人的范围说清楚,这个事情就别想落地。只要你没说这个事情让他做,他就不会主动问你,如果你主动问你说明这个人是优秀员工。 把敏捷开发单独四个字列出来,持续部署跟持续交付看似范围一样,但持续交付指的是我有交付能力,但我没说一定要部署到线上环境。持续部署讲的是现在既然已经完成了构建的流水线,那么就从头走到尾就结束了,这个讲的是自动化。DevOps讲的是什么?范围好像一模一样,但 DevOps不强调每一个角色应该干什么,而是将所有的角色汇集在一起 ,有点像敏捷思想里面的 角色互换 ,大家谁都能干这个事情,不用指定这个事情,大家可以角色互换一起来做,所以 DevOps不强调每一个人谁是谁,而是强调这些人汇集到一起之后,你能够将开发编译测试一次性完成 ,这是他们的区别点。 ...

May 29, 2019 · 1 min · jiezi

github上Go项目使用Travis-CI和Docker-Hub实现持续集成

介绍在本文中,我们将介绍如何使用Github,Travis-CI和Docker Hub创建一个简单的持续集成过程。 项目这次使用的一个项目是自己写的一个爬虫小程序(https://github.com/Han-Ya-Jun... 项目目录news_watch_notice├── cmd //main├── conf├── dis├── Dockerfile├── Makefile├── pkg├── qrcode├── .travis.yml├── README.md├── vendor├── utilsDockerfileFROM alpine:3.6MAINTAINER hanyajun0123@gmail.comRUN apk update && apk add curl bash tree tzdata \ && cp -r -f /usr/share/zoneinfo/Hongkong /etc/localtimeADD news_watch_notice /usr/bin/ADD news_watch_notice.sha /usr/bin/CMD ["news_watch_notice"]makefileTARGET=news_watch_noticePKG=$(TARGET)TAG=latestIMAGE_PREFIX?=hanyajunIMAGE_PREFIX_PRD=hanyajunTARGET_IMAGE_DEV=$(IMAGE_PREFIX)/$(TARGET):$(TAG)TARGET_IMAGE_PRD=$(IMAGE_PREFIX_PRD)/$(TARGET):$(TAG)all: image$(TARGET): CGO_ENABLED=0 go build -o dist/$(TARGET) $(PKG)/cmdgitlog:target: mkdir -p dist git log | head -n 1 > dist/news_watch_notice.sha docker run --rm -i -v `pwd`:/go/src/$(PKG) \ -w /go/src/$(PKG) golang:1.11.5 \ make $(TARGET)image-dev: target cd dist && cp ../Dockerfile ./ && \ docker build -t $(TARGET_IMAGE_DEV) .push-dev: docker push $(TARGET_IMAGE_DEV)image-prd: target cd dist && cp ../Dockerfile ./ && \ docker build -t $(TARGET_IMAGE_PRD) .push-prd: docker push $(TARGET_IMAGE_PRD)clean: rm -rf dist.PHONY: image target clean push $(TARGET).travis.ymllanguage: gogo: # 语言版本号 - "1.11.5" # 默认使用最新版本,注意,需要 "1.10" 版本的时候必须表示为字符串形式,如果写成 1.10 则会使用 1.1 版本;x表示对应前缀的最新版本services: - docker #需要的docker环境install: - make image-dev #buildscript: - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin - make push-dev # pushtravis的配置(https://travis-ci.org)打开项目ci开关 ...

May 16, 2019 · 3 min · jiezi

CODING-签约天津大学助力高校产学接轨

近日,CODING 与天津大学顺利达成合作,将通过 CODING 的一站式 DevOps 解决方案为天津大学师生提供软件研发管理方面的先进理念和产品。根据中共中央、国务院印发的《中国教育现代化 2035》中提出的“更加注重融合发展,更加注重共建共享”理念,同时进一步响应国家“产学融合校企合作”的号召,实现教育资源与优势产业资源结合,秉承协同育人的原则,CODING 与天津大学将在培训课程设立、实习实践、就业指导等方面进行深入的探讨与合作。借助工具承载软件研发行业最新的理念,帮助天津大学的学生掌握软件研发项目从策划到发布的不同管理阶段,内容包括需求管理、项目迭代、文件管理、代码仓库等全方面,让天津大学的学生通过 CODING 提前接触实际工作场景,了解企业研发管理团队的运作方式,助力高校“产学”接轨。为天大学生构建起规范化、合理化和科学化的研发管理学习体系。 关于天津大学天津大学,简称天大,其前身为北洋大学,始建于 1895 年 10 月 2 日,是中国第一所现代大学,开中国近代高等教育之先河。“甲午战争”失败后,学校在“自强之道以作育人才为本,求才之道以设立学堂为先”的办学宗旨下,由清光绪皇帝御笔朱批,创建于天津,由盛宣怀任首任督办。 改革开放后,天津大学是“211 工程”、“985 工程”首批重点建设的大学,入选国家“世界一流大学建设”A 类高校。学校坚持“强工、厚理、振文、兴医”的发展理念,形成了工科优势明显、理工结合,经、管、文、法、医、教育、艺术、哲学等多学科协调发展的综合学科布局。 专业与课程设立天津大学秉承的“兴学强国”的使命、“实事求是”的校训也是本次合作的基础。为了更好地推动产学融合,遵循学以致用的原则,CODING 将通过“基础+实践”相结合的合作方式,在为天大学生夯实如怎么使用 Git 进行协作等基础内容的同时辅以实战式的培训,以 Google、Netflix、腾讯等国内外知名科技公司的研发管理为例,为天大学生提供更为广阔的实践机会,增强社会能力。更早地接触工作场景也能帮助青年学生更好的评估自己想做什么、能做什么和适合做什么,让他们在踏入社会时能更有准备,更有规划,也更有能力。 引入先进的研发管理理念CODING 基于硅谷先进方法与中国团队实践所打造的一站式开发平台,立志满足研发项目交付质量和速度的要求,实践 DevOps 理念,提高研发效率、优化研发管理模式。在了解到 CODING 自主研发的一站式 DevOps 工具平台和其简单、高效、快捷的特质后,天津大学决定和 CODING 合作帮助天大培养软件产业发展急需人才,更好地推动产学合作和软件产业发展。 快速提高学生信息化水平CODING 研发管理系统将全套研发流程整合到一个平台,从需求管理、代码仓库、代码评审到数据分析、文件管理,全部在一个平台打通,全功能高度整合,提高代码协作效率,保障代码质量,提高交付质量。免去了学生们浪费在不同流程中的时间和精力,同时避免了在不同工具间来回切换带来的效率损耗,快速提高信息化水平。 互联网+ 下的教学手段CODING 的任务系统支持看板,能与 MR、文件、Wiki 高度关联,帮助学生和教师随时随地协作,为课堂带来更好的支持。CODING 的任务管理系统非常容易上手,帮助学生在项目管理、研发、产品设计、创新管理、战略管理等场景下高效学习。 任务还能与代码管理无缝结合,强关联每次提交,方便教师在教学过程中实时查看学生的代码内容,及时反馈问题。同时教师作为企业管理员,能通过 CODING 的统计功能轻松把控每次作业「启动、计划、执行、统计、收尾」的各个关键阶段,更好地掌握学生的项目情况,因材施教。 同时 CODING 还将为天津大学提供软件研发管理方向的权威专家,对合作进行全方位的支持,助力教育教学质量迅速提升。双方还将就教材编写、课题研究、科技创新等领域充分合作共享,助力天津大学输出更多符合现代社会发展需求的创新型、复合型人才,为社会主义建设添砖加瓦。 此前 CODING 已经与复旦大学、北京理工大学等高校达成了实验性的合作,本次与天津大学的正式合作,也将推动高校与行业企业协同育人,促进软件产业产学结合、校企合作,加快软件研发管理在大学中的学习与实践,立志于把更多社会优质资源转化为育人资源。未来 CODING 将继续善用自身的优势资源,为更多院校提供更深入更全面的合作解决方案,为校企双方发展注入新的活力,共同深化产学融合,加速推动教育现代化进程。 点击体验 CODING一站式 DevOps,提升研发效能

May 10, 2019 · 1 min · jiezi

后端好书阅读与推荐续七

后端好书阅读与推荐系列文章: 后端好书阅读与推荐后端好书阅读与推荐(续)后端好书阅读与推荐(续二)后端好书阅读与推荐(续三)后端好书阅读与推荐(续四)后端好书阅读与推荐(续五)后端好书阅读与推荐(续六)后端好书阅读与推荐(续七) Spring微服务实战Spring微服务实战 (豆瓣): https://book.douban.com/subje... Spring体系用来做微服务在当下可谓是风头正劲,这本书就用一个实例来手把手教我们实现微服务。实战系列的口碑一直不错,这本也不例外,看完就可以对微服务的概念有一个完整的理解,并且想上手也有路可寻。 亮点: 编码就像艺术,是一种创造性活动。构建分布式应用就像指挥一个管弦乐队演奏音乐,是一件令人惊奇的事情微服务是一个小的、松耦合的分布式服务,分解和分离大型复杂应用程序的功能,使它们独立,这样负责每个功能的团队都拥有自己的代码库和基础设施,技术不限,能灵活地独立开发部署,职责分离,降低团队协作成本。随着云的普及,微服务单元的增减(每个服务单元都是完整的)变得非常容易,使得整个应用更具弹性伸缩能力。Spring勇于自我革新,当初出场取代了沉重的J2EE,后面的Spring Boot使用简单注解去掉了自己原本繁重的配置,后来的Spring Cloud更是为分布式服务提供了一套完整的解决方案,所以Spring体系是我们构建微服务的绝佳选择微服务构建的一个关键是划分,而划分的一个关键是粒度,这个没有绝对标准,但是有几个原则:开始可以让服务设计范围大一些,后续可以重构至更小的服务;重点关注服务之间如何交互;随着对问题域的理解变化,服务的职责也要变化(演化思维)。需要注意微服务的几个坏味道(太粗;太细):职责过多,跨表超过5个,URL太长,测试用例太多;数量巨大、彼此依赖严重、成为简单的curd、只在一个表操作等微服务没有标准,但是作者提出了12种最佳实践:独立代码库、显式依赖、配置存储、后端可切换、构建发布运行必须完整、进程无状态、端口命令行制定、横向扩展并发、可down可up、环境一致、日志流式处理、管理脚本化。微服务的生命周期:装配、引导、发现、服务和监控、关闭少量程序可以使用低层级文件(YAML、json、XML)来存储配置,将其与代码分开,但是到了数百单元(每个单元可能有多个实例)时就不行了。手动管理既慢又复杂还可能配置漂移,这时应该引入配置管理工具(etcd、eureka、consul、zookeeper、spring cloud config等),服务启动时通过环境变量注入配置或者从集中式存储中获取服务发现提供了快速水平伸缩的能力,且当服务不健康时可以快速删除,还能取代传统的手动管理负载均衡。主要涉及服务注册、客户端服务地址查找、信息共享、健康监测4个方面一般大家关注高可用都是某个组件彻底不可用(容易检测)的情况,但是一个性能不佳而没有完全垮掉(不易检测)的服务也可以彻底拖垮整个应用,因此也需要保护这些不佳服务,避免连锁效应,导致彻底不可用。一般有客户端负载均衡(Ribbon)、断路器、后备、舱壁(Hystrix)等四个弹性模式来实现保护缓冲区AOP的思想帮我们分离关注点,那么要在微服务中实现靠啥?答案就是网关(比如Zuul,核心就是反向代理)了,我们可以在网关中实现验证授权、数据搜集与日志等关注点,但是要注意,避免网关成为单点要注意使其轻量且无状态(无状态就可以很容易扩展,而服务发现必须有状态,所以要扩展还要用Gossip等协议来同步状态数据,保障一致性和可用性)安全注意事项:都要使用HTTPSSSL、所有服务都要经过网关、将服务划分为公共API和私有API、封锁不必要的端口来限制微服务的攻击面微服务不是单体,其好处是灵活,代价就是解决问题时难以定位,所以需要追踪并聚合日志,最终定位问题。spring cloud 给每一个事务开启之前注入关联ID(一般由网关完成),每个服务都可以传播关联ID并将其添加进日志中,这些日志被统一发送到日志聚合点中,就可以供我们统一检索了,常见实现有ELK、Splunk等。光能检索还不够,一张直观的事务流图抵过1万条日志,Sleuth和ZipKin一起可以实现该功能微服务强调灵活迅速,所以一个成熟的构建与部署管道(引入CI/CD)必不可少:提交代码、自动构建(钩子实现)、构建期间进行单元测试与集成测试后获得一个jar(自包含tomcat)、用jar构建并提交机器镜像、在新环境中拉取机器镜像并进行平台测试后启动镜像、每个新环境都要重复前面一个步骤书很厚,所以很多具体工具可以跳过,尝试几个即可,将来使用的时候知道这本书里有就行了。 持续交付持续交付 (豆瓣): https://book.douban.com/subje... 微服务离不开CI/CD,而CI/CD核心就是几点:自动化、连续、小范围、快速、可靠。我们通过这本书来了解CI/CD,也看看持续交付是如何解决“Last Mile”问题,让软件交付不再令人紧张,成为一件简单平常的事情。 亮点: 从决定修改到结果上线的时间为周期时间,CI/CD技术能让周期从传统手段的周月单位变成小时甚至分钟级别(产品快速落地,降低机会成本),发布过程可靠可重复(减少错误与人力资源),核心技术就是部署流水线(一个应用从构建、部署、测试到发布这整个过程的自动化实现,过程中需要的所有东西包括需求、源码、配置、脚本、文档、运行环境等都要纳入VCS的管理,但是结果性的东西比如二进制镜像就不用,因为它可以随时构建得到,作者罗列了一些相应的工具)提出了一些反模式,让我们避免:手工部署软件(复杂 不可重复和审计 易出错)、开发完成之后才向类生产环境部署(不确定性很大 发布有风险)、生产环境手工配置管理(不能完全掌握 不可重复)。同时也提出了一些应该遵循的正面原则持续集成的前提是版本控制、自动化构建、团队共识,需要做到频繁提交、自动化测试、保持构建和测试过程较短、管理开发工作区、构建失败之后修复成功之前不能提交新代码、提交之前自己运行测试、提交测试通过之后再继续工作、时刻准备回滚(回滚之前要有一个修复时间)、为自己的问题负责、测试驱动等等持续集成能提高团队对复杂系统的自信心与控制力,其主要关注是开发团队,并不能解决软件部署、交付过程的低效,所以需要一个端到端的自动化构建、部署、测试和发布流程,也就是部署流水线(关注的是软件从CVS到用户手中这个过程),它有一些相关实践:只生成一次二进制包、不同环境统一部署、对部署进行冒烟测试、向生产环境的副本部署、每次变更都要立即在流水线中传递、只要有环节失败停止整个流水线。CI/CD的关键都是记录变更,为尽早发现问题提供信息,消除低效环节部署流水线的几个要点:构建与部署脚本化(配置初始化数据、基础设施、中间件等)、提交阶段快速反馈与及时修复、自动化验收测试(验收测试是验证客户的期待,单元测试是验证开发人员的期待)、注意非功能测试(主要指性能)、部署与发布要有策略并且可重复执行(文本化)且可回滚(不同版本文件不删除,用符号链接到当前版本)作者说无论项目大小都应使用CI/CD,这个我感觉有点偏激了,所谓磨刀不误砍柴工,前提是这个柴要么很多,要么很大,如果只是几根细柴,有那个磨刀的功夫柴都砍完了。但是实际工作中这么小的项目应该很少,所以大多数项目我们还是都还是应该搭建部署流水线,用上CI/CD。书很厚,其实好多地方可以跳过,你只需要看标题就能抓住主旨而无需多看。PS:可以先看看这本持续集成。 敏捷革命敏捷革命:提升个人创造力与企业效率的全新协作模式 (豆瓣): https://book.douban.com/subje... CI/CD 实际上正是敏捷开发的最佳实践,有了前面的铺垫,我们可以通过这本书我们来真正了解敏捷开发的全貌。 亮点: 2005年之前,大多数软件开发项目都是采用“瀑布法”:整个项目被划分为多个阶段,每个阶段都要经过严格的评审,以期为客户或软件使用者提供完美的产品(甘特图表现),每一阶段的工作做得足够好时才允许进入下一阶段。这种工作方式看似完美,实际全凭想象和猜测、华而不实,往往导致开发进度缓慢,常常超出预算,且现实和规划差异巨大,Scrum(敏捷开发流程)的出现就是解决这个问题的(不凭猜测,而是PDCA:计划、执行、检查、行动)任何项目的管理都需要实现两个目标:可控性与可预测性管理层的职责在于制定战略目标,团队的工作则是决定如何完成目标。无论任何人,只要不在现场,都不可能及时跟上事态变化的步调,所以团队要有自主决策权,此外一个团队需要包含完成一个项目的所有技能,同时要小而精(7人左右)。团队成员之间不要互相指责,而是尽量改善制度“冲刺”(一般以星期为周期)可以让团队成员集中精力快速做出成果并得到反馈,“每日立会”(15分钟以内)能让成员清楚地知道冲刺进度如何。Scrum的核心就是节奏确定懂项目、懂市场、懂顾客的产品负责人,拟定待办事项清单并检测两遍,重要的事情优先做这本书细看的话真的很洗脑,看完感觉自己迫不及待地想要冲进一家公司试试Scrum了。 DevOps实践指南DevOps实践指南 (豆瓣): https://book.douban.com/subje... DevOps是软件开发、运维和质量保证三个部门之间的沟通、协作和集成所采用的流程、方法和体系的一个集合(所以也要基于CI/CD,前4本书可以看做一个连续的专题,核心都是敏捷)。它取代了传统开发、测试、运维职责大分离的思想,填平了部门之间的鸿沟,让大家更有效的工作。我们可以通过这本书来对DevOps有一个全面的了解。 亮点: 开发部通常负责对市场变化做出响应,以最快的速度将新功能或者变更上线。而运维部则要以提供稳定、可靠和安全的服务为已任,让任何人都很难甚至无法引入可能会危害生产环境的变更。这种配置方式让开发部门和IT运维部门的目标和动因之间存在“根本的、长期的冲突”——公司对不同部门的考核和激励不同,这种冲突造成了一种恶性循环,阻碍了公司全局目标的实现。DevOps能够提高公司业绩,实现开发、QA、IT运维、信息安全等各职能技术角色的目标,同时改善人们的境遇DevOps是精益、约束理论、丰田生产系统、柔性工程、学习型组织、康威定律等知识体系的集大成者DevOps“三步工作法”:流动、反馈、持续学习与实验,并阐述了DevOps实施需遵守的原则与最佳实践(流动:它加速了从开发、运维到交付给客户的正向流程;反馈:它使组织构建安全可靠的工作体系,并获得反馈;持续学习与实验:它打造出一种高度信任的文化,并将改进和创新融入日常工作中)为了能识别工作在哪里流动、排队或停滞,需要将工作尽可能地可视化,如在看板或Sprint计划板上,使用纸质或电子卡片将各项工作展示出来,通过这种方式,不仅能将工作内容可视化,还能有效地管理工作,加速其从左至右的流动,还可以通过卡片从在看板上创建到移动至“完成”这一列,度量出工作的前置时间。此外,看板还能控制在制品数量(队列长度)文中关于小批量和大批量的差异,我以前在博客中也提到过。如此看来,两种方式各有优劣,关键看能分配的资源是什么?更追求总体效率还是效果出现的等待时间?对返工的要求是什么?再来决定使用方法第一步描述的原则,使得工作能够在价值流中从左向右快速地流动。第二步描述的原则,使得在从右向左的每个阶段中能够快速、持续地获得工作反馈。快速发现问题、群策群力解决问题,可以避免把问题带入下游环节,避免修复成本指数增加。根据精益原则,我们最重要的客户是我们的下游(不一定是最终付费用户),为他们而优化我们的工作,在源头保障质量。第三步描述的原则可以持续提升个人技能,进而转化为团队的财富......感觉历史的天平总是左右摇摆,一开始职责混乱、一个人干所有的事,后来职责分离、分工明确,现在又提倡填平鸿沟、部门融合。随着时代的发展,适用于时代的技术也总是不停变更,要想不被淘汰就得终身学习呀。 Web容量规划的艺术Web容量规划的艺术 (豆瓣): https://book.douban.com/subje... 容量规划(很早就有了,如道路规划、电力运营)是一门省钱的艺术,保证用合理的资源来实现最大化需求,通过这本书我们来敲开容量规划在互联网世界中实际运用的大门。 亮点: 容量规划整个过程:首先要明确定义响应时间、可供消耗容量以及峰值驱动处理等明确指标来定义总体负载和容量需求,然后了解当前基础设施的负荷特征,预测需要的资源来达到这种性能,然后如何管理资源,最后不断迭代,最终目标介于“没有买足够资源”和“浪费太多资源”之间有几个方法:预测系统何时失败、用统计图表(比数字更直观)呈现问题、性能调优与容量规划要同步进行、搜集数据驱动未来的规划测量是规划的前提,要有坚实的数据支撑而不是猜测,有许多工具可以测量,他们应该可以随着时间记录和保存数据、自定义度量、比较指标、导入和导出指标,当然测量工具本身要轻量,尽量对资源本身影响较小。如果说测量是对已有情况的了解,那么估计就是根据数据趋势预测未来。预测部分靠直觉,部分靠数学。我们可以做曲线拟合,注意到趋势和变更,并进行迭代和校准(看来基于机器学习或者说AI的运维是未来啊)文章除了基于传统模式的容量规划,还涉及到了基于虚拟化和云计算的模式,所以我们学习也要注意趋势和变化。 领域驱动设计领域驱动设计 (豆瓣): https://book.douban.com/subje... 构建程序之前,我们都要对业务进行梳理和理解,然后是领域划分与建模等一系列重要步骤,最后才是编码实现,这就是一本讲解这些步骤的好书。而且本书会告诉你,设计和实现可以交错进行和演化,来达到最优。还提出了专业术语,你在和别人交流时可以使用。我在读到假同源这个词语时真是犹如醍醐灌顶,因为之前开发项目就有过:同一个对象,这个模块改吧改吧,那个模块改吧改吧,最后导致对两个模块而言,这个对象都不完全属于它,要修改都得小心翼翼怕影响对方,本书告诉我,遇上假同源,要么重新理解和建模,统一该对象表示,要么果断分开这两个模块,用两个对象分别服务这两个模块。 亮点: 模型是一种简化,是对现实的解释,把与解决问题密切相关的方面抽象出来,而忽略无关的细节(所以需要我们消化和提炼已有知识,包括深层次探索)。用户应用软件的问题区域就是软件的领域(有形的如机票系统,无形的如会计系统)。成功的项目有一个共同特征:都有一个丰富的领域模型,这个模型在迭代设计过程中不断演变(我们要持续学习),与实现绑定,成为项目不可分割的一部分很多因素可能会导致项目偏离轨道,但真正决定软件复杂性的是设计方法。当复杂性失去控制时,开发人员就无法很好地理解软件,因此无法轻易、安全地更改和扩展它,而好的设计则可以为开发复杂特性创造更多机会。一些设计因素是技术上的,很多技术人员都能轻易注意到并改进,但是很多程序主要的复杂性并不在技术上,而是来自领域本身、用户的活动或业务,这部分往往被许多人忽略要避免不设计和过度设计(极限编程)模型、设计的核心、实现互相影响和关联;模型是团队所有人员沟通的中枢,使得开发人员和领域专家无需翻译就能沟通,高效简洁;模型是浓缩的知识技术人才更愿意从事精细的框架工作,试图用技术来解决领域问题,把学习领域知识和领域建模的工作留给别人去做。软件核心的复杂性需要我们直接去面对和解决,如果不这样做,则可能导致工作重点的偏离——软件的初衷以及核心就是为了解决领域问题对于比较重要的业务规则(这个知识点需要我们自己去理解)比如货船超订110%,应该单独抽象成1个实体(具体就可以是1个方法),而不是简单的用一个guard clause来实现,这样既能明确这个知识点本身,又利于代码的扩展性。当然,把不重要的细节也单独抽象就是典型的过度设计了以文本为主,简洁的小图为辅(大而全的图反而失去了解释能力)来阐释模型最好。文档是代码和口头交流的补充,为团队提供稳定和共享的交流。只用代码做文档容易使人陷入细节,不能把控全局,所以应该文档和代码互补,文档不再重复阐述代码能表现的内容而是着重核心元素,阐明设计意图,文档还要注意和代码保持同步不脱节(不再适用的文档要进行历史归档),不然就失去了意义。模型与实现也要同步,通过模型驱动设计MDD实现,保证模型既利于实现,也利于前期的分析要想创建出能处理复杂任务的程序,需要做到关注点分离,使设计中的每个部分都得到单独的关注,行业普遍采用分层架构,分层的价值在于每一层都只代表程序中的某一特定方面,每个方面的设计都更具内聚性,更容易解释。分层设计大都是“用户层界面-应用层-领域层-基础设施层”这种四层架构的变体,其中领域层是软件的核心,将其分离才是MDD的关键,也是领域驱动设计DDD的前提。领域层与应用层的区分关键在于领域层包含实际业务规则(如转账操作),而应用层是为了实现业务的辅助功能(如导入转账文本记录)DDD适用于大型项目,小项目用“Smart UI”更合适,还有其他的架构模式都有自己的使用场景和局限领域中用来表示某种具有连续性和标识(比如银行账户)的事物是ENTITY,用于描述某种状态的属性是VALUE OBJECT(不可变,无标识,比如数字3,尽量设计为不可变,便于复制和共享),动作或操作最好用SERVICE来表示(在大型系统中,中等粒度、无状态的SERVICE更容易被复用),对象之间的关联可以通过限定条件进行简化,MODULE是一种更粗粒度的建模和设计单元(提供了两种观察模型的方式,一是可以在MODULE中查看细节,而不会被整个模型淹没,二是观察MODULE之间的关系,而不考虑其内部细节)。领域模型中的每个概念都应该在实现元素中反映出来由于汽车的装配和驾驶永远不会同时发生,因此将这两种功能合并到同一个机制中是毫无价值的。同理,装配复杂的复合对象的工作也最好与对象要执行的工作分开。应该将创建复杂对象(比如依赖其他对象B的对象A就是复杂对象,不要直接在A构造函数中调用B的构造函数)的实例和AGGREGATE(一组相关对象的集合,比如车辆与发动机)的职责转移给单独的对象:FACTORY初始模型通常都是基于对领域的浅显认知而构建的,不够成熟也不够深入,通过重构(不仅是一般的代码细节的重构,还有领域的重构,后者通常风险很高,但是回报也很高,需要在前者的不断积累下寻找突破)最终开发出能够捕捉到领域深层含义的模型,这也是管理项目的规模和复杂性的要素,加上柔性设计(软件易于修改)就能让项目稳步发展。持续重构渐渐被认为是一种“最佳实践”,但大部分项目团队仍然对它抱有很大的戒心。人们虽然看到了修改代码会有风险,还要花费开发时间,但却不容易看到维持一个拙劣设计也有风险,而且迁就这种设计也要付出代价代码除了要能准确得到结果外,还要能显式的表达出领域的规则,易于理解和预测修改代码的影响。所以有一些原则:揭示意图的接口,能避免用户去研究它的实现(失去了封装的价值);无副作用的函数,安全地预见函数的作用,避免组合爆炸;断言可以帮助展示和理解副作用技术角度的设计模式中的一些也适用于领域设计,比如Strategy和Composite模式,把设计模式用作领域模式的唯一要求是这些模式能够描述关于概念领域的一些事情,而不仅是作为解决技术问题的技术解决方案大型系统的模型很复杂,需要注意三个要素:上下文(不要强制在大型系统中统一模型,可以在不同的上下文使用不同的模型(注意重复概念和假同源),划定好边界即可)、精炼和大型结构,才能操纵和理解这个模型......DDD我们可能都用过,但是很可能没把它当成一项正经学问,都是大概过一下需求,稍微捋一捋逻辑然后就开始编码了,实际上,在我们这个过程我们已经经历了ddd,看完本书以后希望能把这个过程正规化,流程化,高效化。 Go语言实战Go语言实战 (豆瓣): https://book.douban.com/subje... 上本书给我们讲了go的基础知识和原理,这本书就带领我们用go的各种库和工具进行实战。 亮点: 计算机一直在演化,但是编程语言并没有以同样的速度演化。现在的高性能服务器拥有 64 核、128 核,甚至更多核。但是我们依旧在使用为单核设计的技术在编程。Go语言对传统的面向对象开发进行了重新思考,并且提供了更高效的复用代码的手段。Go语言还让用户能更高效地利用昂贵服务器上的所有核心,而且它编译大型项目的速度也很快经验,如果需要声明初始为零值的变量,应该使用 var 关键字声明变量;如果提供确切的非零值初始化变量或者使用函数返回值创建变量,应该使用简化变量声明运算符 :=go vet工具不能让开发者避免严重的逻辑错误,或者避免编写充满小错的代码。不过可以很好地捕获一部分常见错误。每次对代码先执行 go vet 再将其签入源代码库是一个很好的习惯;在保存文件或者提交到代码库前执行 go fmt可以统一代码风格go在函数之间传递变量时,总是以值的方式传递的。函数间传递数组可能涉及大量数据拷贝,最好传递数组的指针,就只用拷贝8字节的指针而非拷贝数组本身。相反,与切片关联的数据包含在底层数组里,不属于切片本身,所函数间直接传递切片没有性能影响,映射也是;在创建切片时设置切片的容量和长度一样,就可以强制让新切片的第一个 append 操作创建新的底层数组,与原有的底层数组分离,可以安全地进行修改而不影响原切片,同时也保持了为切片申请新的底层数组的代码简洁性关键字 func 和函数名之间的参数被称作接收者,将函数与接收者的类型绑在一起。如果一个函数有接收者,这个函数就被称为方法。值接收者使用值的拷贝副本来调用方法,而指针接受者使用实际值来调用方法。Go语言会调整传入的参数,无论是指针接受者还是值接受者都可以接受指针或者值两种类型,说是方便开发,但我觉得这反而是一个不必要的歧义,比如到了接口的方法集中,如果使用指针接收者来实现一个接口,那么只有指向那个类型的指针才能够实现对应的接口。如果使用值接收者来实现一个接口,那么那个类型的值和指针都能够实现对应的接口,主要原因是编译器并不是总能自动获得一个值的地址通过嵌入类型,与内部类型相关的标识符会提升到外部类型上。这些被提升的标识符就像直接声明在外部类型里的标识符一样,也是外部类型的一部分,可以无缝实现对象组合,需要注意嵌入类型不需要声明字段。如 ...

May 7, 2019 · 1 min · jiezi

信通院发布云原生技术实践白皮书灵雀云深度参与

在24日由信通院主办的首届云原生产业大会(CNIC2019)上,云原生产业联盟CNIA正式授牌成立。灵雀云CEO左玥被任命为联盟平台架构组副组长,CTO陈恺受邀担任联盟云原生技术专家。作为联盟的首批理事单位,灵雀云深度参与了《云原生技术实践白皮书》的编写工作。 云原生产业联盟(CNIA)前身为云原生技术实践联盟(CNBPA),系由灵雀云牵头,行业顶尖平台提供商、行业解决方案与服务商和行业云原生典型用户联合发起的机构。作为首批创始成员,灵雀云充当桥梁,构建了云原生产业联盟与国内优秀解决方案服务商及终端用户的首次链接,相继将招商银行、中油瑞飞、东华软件、北明软件、中科软、深信服等CNBPA成员引入联盟。 同时,为推广云原生技术理念,推动产业实践落地,灵雀云积极参与了联盟工作组会议,对于国内云原生平台标准的制定与及未来研究方向与各成员单位进行了深入探讨。在本次云原生产业大会正式发布的国内首个“云原生技术实践白皮书“和首个”无服务架构技术白皮书”中,灵雀云均承担了核心的编写任务,将自身的云原生技术能力和解决方案能力进行了输出。 “云原生技术实践白皮书”重点介绍了云原生技术概念、技术实践以及发展趋势,梳理了云原生技术理念特点以及与传统架构的对比,分析了云原生技术在公有云典型场景的应用以及云原生在传统行业中的落地实践。在白皮书的“附录:云原生落地案例”中,引入了招商银行数字化转型实例、云原生技术在网商银行核心系统的应用实例、云原生技术助力广汽丰田数字化转型实践、中石油梦想云平台在能源行业的落地应用等四个案例,旨在从架构、研发流程等角度为企业或组织从传统单体架构过渡到云原生架构提供现实参考。 灵雀云是以容器技术为基础的新一代PaaS平台服务商的突出引领者,以帮助企业快速构建云原生应用,实现微服务架构改造以及 DevOps 落地,助力各传统行业数字化转型为己任。未来将在CNIA的带领下持续推进云原生技术产业化落地,协助推进行业标准化工作,推广领先解决方案,并参与到更多企业快速创新和数字化转型的进程中去。

April 28, 2019 · 1 min · jiezi

灵雀云CEO左玥被任命为信通院云原生产业联盟平台架构组副组长 推动云原生国家标准制定

4月8日-10日,中国信息通信研究院云计算标准和开源推进委员会(TC608)第三次全体会员大会在成都隆重召开。大会旨在对多项云计算标准进行讨论,进一步推动云计算技术的发展、标准的落地和产业共性问题的解决。本次会议由中国信息通信研究所云大所所长何宝宏、云计算标准和开源推进委员会常务副主席栗蔚领衔指导,灵雀云CEO左玥被任命为云原生联盟平台架构组副组长,出席了大会授牌仪式并被颁发证书。在10日上午的工作组会议中,云计算开源产业联盟(OSCAR)下设的子联盟——“云原生产业联盟(Cloud Native Industry Alliance,简称CNIA)”正式通过了TC608全体会员审议。栗蔚主任对联盟的成立背景、组织架构、联盟宗旨和愿景等进行了介绍。联盟下设技术专家委员会与平台架构组、DevOps工作组、用户工作组和生态伙伴工作组等四个工作组。其中平台架构工作组包含容器项目、微服务项目、Serverless项目及更多云原生与其他领域融合的项目组,承担了云原生平台技术与实践经验标准化制定与推广的重任。灵雀云CEO左玥被提名为联盟平台架构组副组长。与此同时,招商银行苏贝、浦发银行杨欣捷提名为用户工作组组长;东华软件王昕提名为生态伙伴工作组组长。随后,何宝宏所长颁发证书,对联盟各工作组的组长予以委任。云原生产业联盟(CNIA)前身为云原生技术实践联盟(CNBPA),系由灵雀云牵头,行业顶尖平台提供商,行业解决方案与服务商,行业云原生典型用户联合发起的机构,CNBPA旨在促进国内云原生行业间交流,加强企业和行业用户之间的沟通,推进云原生技术在国内的发展和落地,是国内首个以云原生技术应用实践为核心的组织。CNIA沿用了原CNBPA部分章程制度及工作规划,并平移了原CNBPA成员。首批吸引了腾讯云、阿里云、华为、灵雀云、金山云、浪潮、中油瑞飞、东华软件、北明软件、中科软、深信服等18家理事会员单位与数十家普通会员单位加入。作为联盟首批创始成员,以及国内云原生技术及实践落地的推动者,灵雀云积极参与了国内云原生平台标准的制定与及未来研究方向的探讨。在CNIA发起的国内首个“云原生技术实践白皮书“和首个”无服务架构技术白皮书“中,灵雀云分别承担了核心的编写任务,将自身的云原生技术能力和解决方案能力进行了输出。至此,云原生产业联盟CNIA的筹备工作全部结束。 4月24日, CNIA将在云原生产业大会上正式宣布成立。以灵雀云为代表的企业将在CNIA的带领下持续推进云原生技术产业化落地,推进行业标准化工作,推广领先解决方案,构建技术带动实践、实践反哺技术的良性生态,进一步推动我国云原生技术的成熟发展!

April 15, 2019 · 1 min · jiezi

他山之石——运维平台哪家强?

DevOps 全链路下图是我们熟知的软件研发环节,在迭代频率高的研发组织里,一天可能要经历多次如下循环。对于用户群体庞大或者正在经历大幅业务扩张的企业研发组织,除了重点关注应用的快速上线之外,如何保障应用的高可靠、高可用也成为焦点,即服务上线要快,运行要好。如何让开发更简单,运行更高效,接下来我们从两个角度来探讨这个问题:组织方式研发工具关于运维人员的组织方式一种方式是组建专门的运维团队,一个运维团队往往会承接多个开发团队的协作。除了 DBA 这类针对某个中间件的运维之外,这种模式的弊端在于不少运维工程师深陷于环境配置、日志收集、业务恢复、现象记录等琐碎事情当中,没有时间阅读项目源码以及提升能力,对较为深入的业务问题分析困难,开发团队又往往无暇分身,运维容易陷入被动的境地。另一种方式,开发人同时负责各自模块的开发与运维。好处自然是由于开发人员熟悉本模块源码,定位问题的效率要高出不少。同时开发者可以直接得到下游用户使用反馈,将其融入到研发当中去。坏处在于,让开发人员陷入到频繁的用户问题定位之后,难以保证代码开发的时间。近年来,国内也兴起了 SRE 这种高级运维职业,特别是在云计算行业,SRE 的职业要求非常高,需要精通诸如网络、编程、算法、数据结构、操作系统、安全等知识与技能。当云平台出现网络故障、系统故障等问题,这对云租户/用户有时甚至是致命的,所以不少 SRE 是由高级别开发人员转型而来。在 Google SRE 的服务可靠性层级当中,SRE 通过产品、开发、容量规划、测试、根因分析、事件响应、监控七个层次的实践来确保应用服务的健康状态。从这个层级当中我们可以看出 Google 提倡运维要积极控制服务发展的方向,而不仅仅在事故发生后反应性地灭火。目前来看,SRE 这种精英式的运维在国内还有待探索与实践。粗暴地将开发运维拆开,或者将开发运维简单合并,都不是特别合适的一种方式。从笔者的研发经验看,一种方式可供大家思考与讨论——根据业务实际情况做分工:比如由团队内的开发者轮流负责整个项目运维。由于各个开发者对项目公共代码都需要熟悉,在理解其它模块代码也相对快速,这种方式基本能消灭大部分的问题,剩下的一小部分可以和指定模块的负责人结对定位。除此之外,为“每个服务团队分派运维联络人”,“邀请运维工程师参加开发团队的会议”都是能够加强运维与开发之间协作的措施。关于工具的使用除了恰当的人员组织方式之外,合适的工具也能给研发团队注入能力。在配置研发环境时,研发组织可以选择通过开源工具自建代码管理和持续构建环境。这种方式的缺点在于需要有专门的 CI 团队来维护持续构建环境,一旦环境被破坏,开发的脚步就会停滞。并且由于各个开源工具数据未打通,开发人员要在多个工具之间切换使用。另外一种方式就可以通过现有的软件研发管理系统,例如 CODING 研发管理系统,来实现一站式的研发流程管理,无需自建、维护众多的研发工具与研发环境,支持在浏览器中完成全套软件开发流程,真正做到了 Coding Anytime Anywhere。当开发人员通过 CODING 研发管理系统快速开发并部署好应用后,下一步就要让应用在运维工具的辅助监控下可靠运行(并不是所有应用都需要运维工具,需对症下药)。研发组织可以选择自己开发运维工具,也可以选择现有的运维工具。目前的运维工具逐渐地朝以应用为中心发展,因为应用是直接向用户提供业务能力的,无论是开发还是运维,都是被业务价值驱动的。主流的运维工具主要涵盖基础设施层监控、应用层面监控、业务层面的分析与监控。接下来我们看看现有的运维工具一般会提供哪些具体能力:基础设施环境的监控:对服务器整体的 CPU、内存、磁盘、文件系统、网络等资源占用情况进行上报。应用性能监控:针对应用使用的中间件,例如持久化数据库、缓存数据库、消息中间件等访问效率进行监控;以及对应用本身请求响应速度进行监控,包括延迟、吞吐量等等。应用调用链路追踪:在分布式系统下,一个请求往往需要经过多个进程处理完毕。当出现用户请求调用失败或者出错时,运维平台支持整个调用链路的分析与故障环节定位。日志数据采集与分析:日志的采集主要是为了辅助应用调用链路分析以及性能监控,运维人员无需进入后台去大量翻找日志。故障自动恢复灵活的告警可视化面板展示监控与告警信息国外热度较高的运维工具包括 ZIPKIN(分布式追踪),pinpoint(分布式追踪),logstash(数据收集)等等。目前国内各大云厂商也基本都提供了应用运维平台,包括腾讯蓝鲸、阿里 ARMS、华为 APM 等。以下是这几个运维平台能力的简要对比:目前大部分的运维平台主要通过 Agent 和探针的方式去采集应用的指标信息,汇总处理后反应在可视化界面上。除上述的工具和平台之外,AIOps 也逐渐成为未来的一个趋势,AIOps 通过 AI 技术的运用来进行智能业务故障诊断,同时自动恢复应用故障,企图让研发组织彻底告别人肉运维时代,笔者也万分期待这天的到来。运维人员不用担心因 AIOps 失业,工具和平台只是提升运维效率,不会取代运维。在运维阶段发现缺陷后,开发人员可在 CODING 中处理对应的缺陷,记录下每个缺陷的类型、优先级、模块、描述、处理人等信息。软件缺陷是不可避免的,但只有通过对缺陷进行管理和复盘才能知道缺陷产生的原因(人为因素 / 环境因素 / 工具问题等),从而改进,避免类似缺陷的重复。对缺陷的管理也有助于管理人员对软件质量的正确评估。缺陷处理人通过 CODING 实现缺陷的快速修复和部署,可大大缩短故障恢复时间,减少因缺陷产生的业务损失。在 DevOps 理念的指导下,笔者建议开发人员在开发业务代码时,除了功能之外,也应当思考如何开发可运维的代码,通过适当的日志、错误码、异常等措施来提升运维效率;运维人员也需逐步提升能力,从传统的繁杂运维当中转型,走上敏捷自动化的运维之路。写在最后我们可以看到随着 DevOps 工具链自动化显著提升,DevOps 的门槛变得更加地低。拥抱自动化的结果是研发过程会变得越来越安静,顶尖的开源项目里的 committers 在日常仅仅是通过邮件和 issue 将事情说清楚,没有热火朝天、冗长拖沓的会议;也没有花花绿绿,色彩斑斓的工作表格。但这些都是建立在 DevOps 良好实践的基础之上。我们相信在践行 DevOps 的道路上,未来软件的开发会更简单,运行也会更加高效。参考:https://www.collab.nethttps://landing.google.com/sr…吉恩·金(Gene Kim);耶斯·亨布尔(Jez Humble);帕特里克·德布瓦(Patrick Debois);约翰·威尔斯(John Willis).《DevOps 实践指南》

April 10, 2019 · 1 min · jiezi

阿里小程序云应用上线了,有哪些看点?

3月21日,在2019阿里云峰会·北京上,阿里巴巴旗下的阿里云、支付宝、淘宝、钉钉、高德等联合发布“阿里巴巴小程序繁星计划”:提供20亿元补贴,扶持200万+小程序开发者、100万+商家。凡入选“超星”的小程序,入驻支付宝、淘宝、钉钉、高德后还能得到流量重点支持。阿里云近期发布小程序云应用,提供一站式云服务,为开发者提供稳定和便捷的后端云服务,包括 Serverless 开发套件、应用托管服务、函数计算等。开发者可在这些小程序端上进行统一的应用发布、资源管理、数据管理。接下来,我带大家来了解一下小程序云应用的具体内容:小程序云应用限量免费申请入口云应用产品架构产品价值通过一站式的资源编排、应用托管、DevOps 的能力降低企业和个人对小程序后端的开发成本。产品特色直接搭建和初始化好运行环境。支持 Node.js、Spring Boot 等主流框架应用托管。一站式的发布、运维、监控操作。方案优势资源编排通过对 ECS、RDS、SLB、EIP 等资源进行编排,帮助用户根据自身的业务情况提供不同规格配置自动搭建好符合业务场景的最优运行环境,低成本、高效率。应用托管为开发者提供主流应用框架的运行环境,直接上传 Node.js、Spring Boot、Java Web 部署包发布,开箱即用,极大的降低了前后端开发者对云服务的开发成本。一站式 DevOps支持开发者一站完成测试环境、生产环境的版本发布、扩容、资源监控等操作。无需运维即可高效进行线上服务的自动扩容、业务指标监控等。产品操作指引查看详情:https://yq.aliyun.com/activity/820?utm_content=g_1000051340扶持计划 - 云应用篇扶持计划说明:https://help.aliyun.com/document_detail/113009.html申请入口:https://yq.aliyun.com/activity/820?utm_content=g_1000051340本文作者:管理贝贝 阅读原文本文为云栖社区原创内容,未经允许不得转载。

April 10, 2019 · 1 min · jiezi

基于OVN的Kubernetes网络架构解析

【编者的话】Kubernetes经过了几年的发展,存在着很多的网络方案。然而网络虚拟化在Kubernetes出现前就一直在发展,其中基于OpenVswitch的方案在OpenStack中已经有了很成熟的方案。其中OVN作为OVS的控制器提供了构建分布式虚拟网络的完整控制平面,并已经成为了最新的OpenStack网络标准。我们将OVN的网络架构和Kubernetes的容器平台进行结合,将业界成熟的网络架构引入Kubernetes大幅增强现有容器网络的能力。Kubernetes网络的局限性Kubernetes提出了很多网络概念,很多开源项目都有自己的实现。然而由于各个网络功能都是在不同的项目中实现,功能和性能也各有千秋,缺乏统一的解决方案,在使用过程中经常会陷入到底该用哪个的抉择中。同时CNI、DNS、Service的实现又在不同的项目,一旦网络出现问题,排查也会在多个组件间游走,是一个十分痛苦的过程。尽管Kubernetes提出了很多网络的概念,但是在真实应用中很多人会有这样的感觉:网络这块还是很薄弱,很多功能缺乏,方案也不够灵活。尤其是和搞传统基础设施网络的人沟通会发现,在他们眼里,Kubernetes的网络还很初级。我们熟悉的Kubernetes网络是CNI、Service、DNS、Ingress、Network Policy这样的模式。而做IaaS的视角完全不同,他们每次提起是VPC、Subnet、VNIC、 Floating IP,在此之上有DHCP,路由控制,安全组,QoS,负载均衡,域名解析这样的基础网络功能。从IaaS的视角来看,Kubernetes的网络功能确实比较单薄。经常碰到来自传统网络部门的挑战,诸如子网划分VLAN隔离,集群内外网络打通,容器NAT设置,带宽动态调节等等。现有的开源网络方案很难完美支持,最简单的一个例子,比如提及容器的固定IP功能通常就要上升到意识形态斗争的层面去讨论。这本质上还是Kubernetes的网络功能不足,模型也不够灵活导致的。从更高层面来说,Kubernetes中抽象类一层网络虚拟化的内容,然而网络虚拟化或者SDN并不是Kubernetes带来的新东西,相关技术已经发展很久。尤其是在IaaS领域里已经有着比较成熟且完善的一整套网络方案。传统网络部门的人都会问,为什么不用OVS来做网络方案,很多需求用只要容器网络接入OVS网络,剩下事情网络部门自己就知道怎么去做了,都不用我们实现太多额外的功能。也有很多人向我们推荐了OVN,用这个能很方便地实现这些功能。也正由此我们开始去关注OVS/OVN这种之前主要应用于OpenStack生态系统的网络工具。下面我就来介绍一下OVS和OVN。OVS和OVN网络方案的能力网络的概念比较晦涩一些,但是好在大家都对Docker和Kubernetes比较熟悉,可以做个类比。如果说Docker是对单机计算资源的虚拟化,那么OVS就是对单机网络进行虚拟化的一个工具。它最基本的功能是实现了虚拟交换机,可以把虚拟网卡和虚拟交换机的端口连接,这样一个交换机下的多个网卡网络就打通了,类似Linux Bridge的功能。在此之上,OVS很重要的一点就是支持OpenFlow,这是一种可编程的流量控制语言,可以方便我们以编程的方式对流量进行控制,例如转发,拒绝,更改包信息,NAT,QoS 等等。此外OVS还支持多中网络流量监控的协议,方便我们可视化监控并跟踪整个虚拟网络的流量情况。但是,OVS只是一个单机软件,它并没有集群的信息,自己无法了解整个集群的虚拟网络状况,也就无法只通过自己来构建集群规模的虚拟网络。这就好比是单机的Docker,而OVN就相当于是OVS的Kubernetes,它提供了一个集中式的OVS控制器。这样可以从集群角度对整个网络设施进行编排。同时OVN也是新版OpenStack中Neutron的后端实现,基本可以认为未来的OpenStack网络都是通过OVN来进行控制的。01.jpeg上图是一个OVN的架构,从下往上看:ovs-vswitchd和ovsdb-server可以理解为单机的Docker负责单机虚拟网络的真实操作。ovn-controller类似于kubelet,负责和中心控制节点通信获取整个集群的网络信息,并更新本机的流量规则。Southbound DB类似于etcd(不太准确),存储集群视角下的逻辑规则。Northbound DB类似apiserver,提供了一组高层次的网络抽象,这样在真正创建网络资源时无需关心负责的逻辑规则,只需要通过Northoboud DB的接口创建对应实体即可。CMS可以理解为OpenStacke或者Kubernetes这样的云平台,而 CMS Plugin是云平台和OVN对接的部分。下面我们具体介绍一下OVN提供的网络抽象,这样大家就会有比较清晰的认知了。Logical_Switch最基础的分布式虚拟交换机,这样可以将多台机器上的容器组织在一个二层网络下,看上去就好像所有容器接在一台交换机上。之后可以在上面增加诸如ACL、LB、QoS、DNS、VLAN等等二层功能。Logical_Router虚拟路由器,提供了交换机之间的路由,虚拟网络和外部网络连接,之后可以在路由器层面增加DHCP、NAT、Gateway等路由相关的功能。Loadbalancer,L2和L3的Loadbalancer,可以类比公有云上的内部LB和外部LB的功能。ACL基于L2到L4的所有控制信息进行管控的一组DSL,可以十分灵活,例如:outport == “port1” && ip4 && tcp && tcp.src >= 10000 && tcp.dst <= 1000。QoS,可以基于和ACL同样的DSL进行带宽的控制。NAT,同时提供DNAT和SNAT的控制方便内外网络通信。DNS,内置的分布式DNS,可以在本机直接返回内部DNS的请求。Gateway控制内部和外部之间的集中式通信。了解了这些,大家应该就能发现,Kubernetes目前的网络从功能层面其实只是OVN支持的一个子集,基本上所有Kubernetes的网络需求都能在OVN中找到映射关系,我们简单来看下他们之间的映射。OVN和Kubernetes的结合Switch/Router -> Kubernetes基本的东西向互通容器网络。这块OVN的能力其实是大大超出,毕竟OVN的这套模型是针对多租户进行设计的,而Kubernetes现在只需要一个简单的二层网络。Loadbalancer → ClusterIP以及Loadbalancer类型的Service,可以取代kube-proxy的功能,OVN本身也可以实现云上ELB的功能。ACL -> Networkpolicy本质上更灵活因为可以从L2控制到L4并且DSL也支持更多的语法规则。DNS -> 可以取代Kube-DNS/CoreDNS,同时由于OVN实现的是分布式DNS,整体的健壮性会比现在的Kubernetes方案要好。可以看到Kubernetes的CNI、kube-proxy、Kube-DNS、NetworkPolicy、Service等等概念OVN都有对应的方案,而且在功能或者稳定性上还有增强。更不要说还有QoS、NAT、Gateway等等现在Kubernetes中没有的概念。可以看到如果能把IaaS领域的网络能力往Kubernetes平移,我们还有很多的提升空间。Kubernetes网络未来增强的方向最后来说说我认为的未来Kubernetes网络可能的增强方向。Kubernetes网络功能和IaaS网络功能打平现在的Kubernetes网络模型很类似之前公有云上的经典网络,所有用户大二层打通,通过安全策略控制访问。我们现在也都知道公有云多租户不能这么做VPC肯定是标配。因此未来Kubernetes网络可能也会向着多租户方向前进,在VPC的基础上有更多的路由控制、NAT控制、带宽控制、浮动IP等等现在IaaS上很常见的功能。性能现有的开源方案其实主要还是依赖原有的Linux网络栈,没有针对性的优化。理论上容器的密度比传统虚拟化高,网络压力会更大。OVS现在有DPDK等Kernel bypass的DataPath,绕过Linux内核栈来实现低延迟和大吞吐网络。未来随着容器的密度越来越大,我认为会出现这种针对容器架构专门优化的网络方案,而不是依旧依赖Linux网络栈。监控和问题排查现有的网络问题排查十分困难,如果所有的数据平面都由一个项目完成,比如OVN,那么学习成本和排障都会容易一些。此外OVS社区已经有了很多成熟的监控,追踪,排障方案,随着容器的使用场景变多,我认为外围的工具也需要能够很好的支撑这种模式的网络运维问题。Q&AQ:OVS方案与基于三层交换机方案对比,各有什么优缺点?A:OVS最大的优点在于可编程,灵活性比较好。虚拟网络不用手动插网线,而且有OpenFlow加持,可以实现一些普通交换机无法实现的流量控制。物理交换机的主要有点就是性能好,而且比较稳定,不容易出问题。Q:OVN不支持ECMP,貌似现在还是active-standby机制,你们怎么解决Gateway瓶颈问题?A:有几种方式:1. Gateway用DPDK这样的高速DataPath;2. 多Gateway,用策略路不同的IP段走不同Gateway,可以分担流量;3. 不使用OVN概念的Gateway,自己做一些手脚从每台宿主机直接出去,也是分担流量降低单点的风险。Q:OVN-Kubernetes好像只支持每个部署节点一个虚拟网络网段。如何避免IP池浪费和不均衡?A:这个其实是这个项目实现的网络模型的一个局限性。在我们的实现里是以namespace为粒度划分子网,可以对每个namespace进行控制,情况会好很多。Q:OVN如果有不同的Chassis,但是相同IP就会造成网络异常(比如物理机,VM装上OVN,注册到远端后,被重建,后面又注册到远端,但是Chassis已经改变),会导致大量节点Geneve网络异常。你们怎么解决这个问题?A:暂时没碰到这个问题,但是我们在实现的一个原则就是尽可能保证所有的操作都是幂等的。向这种可能需要在重连前做一个检查,判断是否有过期的数据需要清理,再连接,或者复用旧的连接信息去连接。Q:如何debug OVN逻辑拓扑是否配置有问题?A:目前debug确实很多情况只能靠眼看,也可以使用ovn-trace这个工具可以打印数据包在逻辑流里的链路来排查。Q:OVS跟Calico等有啥区别?A:Calico主要依赖Linux的路由功能做网络打通,OVS是在软件交换机层面实现网络打通,并提供了更丰富的网络功能。Q:OVS的封包支持有STT和Geneve,你们选用哪种,为什么?A:其实还支持VXLAN,我们选的Geneve。原因比较简单,Geneve是第一个OVN支持的封包协议,而且看了一些评测,据说在搞内核开启UDP Checksum的情况下性能会比VXLAN要好一些。Q:OVS如何实现固定容器IP?A:这个其实OVS有对应的设置可以给每个端口设定IP和MACE,这样网卡启动时配置相同的信息就可以了,难点其实是如何控制OVN来分配 IP,感觉这个话题可以再开一场分享来讨论了。Q:可以简单介绍下你们准备开源的网络功能吗?A:每个namespace和一个logical_switch绑定,支持子网分配,支持固定 IP,支持 QoS,支持NetworkPolicy,内置的LB,内置的DNS,大致就是把OVN的概念映射到Kubernetes。Q:想了解一下,如果采用OVN,是不是意味着使用OpenStack平台和Kubernetes网络可以直接互通?完成业务在虚拟机和Pod之间的全新负载方式?A:是这样的,如果涉及的合理可以做到容器和VM使用同一个底层网络基础设施,VM和容器之间可以IP直达,所有的ACL、LB都是打通的。Q:直接把OpenShift OVS抽出来做Kubernetes的网络插件和灵雀云做的这个区别在哪?A:功能上有很多是相同的,因为底层都是OVS。如果关注Roadmap会发现OpenShift之后也会采用OVS的模式。从架构的角度来看,现在openshift-multitenant的实现很类似Neutron之前那一套,各种Agent,之后会统一到OVN。另一方面OpenShift的网络插件绑定的太死了,所以我们决定还是自己抽出来,顺便能实现我们的一些特殊功能,比如固定IP,子网共享,以及一些网关控制层面的功能。Q:请问Geneve和VXLAN的区别有哪些?A:Geneve可以理解为下一代VXLAN,VXLAN相对VLAN来说头部更长可以支持更多的VLAN,但是由于是固定长度的封装头,不能任意加控制信息。Geneve采用变长的封装头,可以加很多自定义的控制信息,方便之后做更复杂的网络管控。Q:Docker CNM也支持固定IP,和你说的固定IP是一回事吗?另外,基于OVS建立的网络是CNI还是CNM的呢?A:基于CNI,因为我们依赖Kubernetes的模型。不过话说回来我很喜欢Docker CNM那套模型,比CNI要实用很多。固定IP其实只是个功能,各种模型下都可以实现,效果就是可以给Pod指定IP启动,Workload下的多个Pod实用的是一组固定的地址。Q:目前你们对企业的解决方案里会默认采用这种网络模式么?A:这个方案是我们这几年需求和碰到坑的一个积累吧,现在还不会直接给企业用,我们还需要一些功能的开发和测试,但是之后Overlay的场景这个肯定是主推了,主要是取代原来的Flannel VXLAN网络。Q:你了解Contiv网络方案吗,和贵公司的实现有哪些区别?A:Contiv是思科做的,也是OVS实现的,不过它的实现比较早,自己手动实现了整个控制平面,可以认为自己写了个跟OVN类似的东西来控制 OVS。不过看它最近已经很少更新了。用OVN能用很少的代码就实现基本相同的功能。Contiv有个比较独特的功能就是支持BGP的网络间通信,这个是OVN暂时不支持的。以上内容根据2019年3月26日晚微信群分享内容整理。分享人刘梦馨,灵雀云高级工程师。2014年加入灵雀云容器团队,长期参与容器调度平台和容器网络架构的产品研发和技术架构演进,参与自研容器网络和容器应用网关。目前主要专注于容器网络功能的拓展和架构优化。DockOne每周都会组织定向的技术分享,欢迎感兴趣的同学加微信:liyingjiesd,进群参与,您有想听的话题或者想分享的话题都可以给我们留言。

April 1, 2019 · 1 min · jiezi

DevOps是如何出现的?前因后果

DevOps是如何出现的?前因后果更多物联网高并发编程知识请移步:https://www.yuque.com/shizhiy…软件开发的演变多年来,DevOps从现有的软件开发策略/方法发展而来,以响应业务需求。让我们简要地看一下这些模型是如何演变的,以及它们最适合的场景。缓慢而繁琐的瀑布模型演变成敏捷,开发团队在短时间内完成软件开发,持续时间甚至不超过两周。如此短的发布周期帮助开发团队处理客户反馈,并将其与bug修复一起合并到下一个版本中。 虽然这种敏捷的SCRUM方法为开发带来了敏捷性,但它在运维方面却失去了敏捷实践的速度。开发人员和运维工程师之间缺乏协作仍然会减慢开发过程和发布。DevOps方法就是基于对更好的协作和更快的交付的需求而产生的。DevOps允许用较少复杂问题的持续软件交付来修复和更快地解决问题。讲故事为了能够更好的理解什么是DevOps,我们很有必要对当时还只有程序员(此前还没有派生出开发者,前台工程师,后台工程师之类)这个称号存在的历史进行一下回顾。如编程之道中所言:老一辈的程序员是神秘且深奥的。我们没法揣摩他们的想法,我们所能做的只是描述一下他们的表象。清醒的像一只游过水面的狐狸警惕的像一位战场上的将军友善的像一位招待客人的女主人单纯的像一块未经雕琢的木头深邃的像一潭幽深洞穴中漆黑的池水i am you father程序员开发了机器语言,机器语言又产生了汇编语言,汇编语言产生了编译器,如今的语言已经多不胜数。每一种语言都有其各自的谦卑用途。每一种语言都表达出软件的阴和阳。每一种语言都在此道之中有其一席之地。遥想当年,软件程序员的大部分办公司那时还被称作实验室,程序员那时还叫做科学家。为了开发出一套优秀的软件,程序员们必须深入了解他们需要的应用相关的所有问题。他们必须清楚知道这个软件应用在什么场合,这个软件是必须在什么系统上运行。本质上说,程序员对所要开发的软件的所有环节都有透彻的了解,从规格说明书编写、到软件开发、到测试、到部署、再到技术支持。过了不久,人类(客户)贪婪的特性就开始表现出来,他们开始不断的进行更多的索求。更快的速度,更多的功能,更多的用户,更多的所有所有。作为一类谦虚、谦卑、且平静的生物,我们的老一辈程序员们将很难在这种爆发性的过度的需求索取中幸存。最好的取胜办法就是往不同的方向进化成不同的新物种。很快,程序员这个称号就开始绝迹于江湖,而那些叫做开发者、软件工程师、网络管理员、数据库开发者、网页开发者、系统架构师、测试工程师等等更多的新物种就开始诞生。快速进化和快速适应外界的挑战成为了他们的DNA的一部分。这些新的种族可以在几个星期内就完成进化。网页开发者很快就能进化成后台开发者,前台开发者,PHP开发者,Ruby开发者,Angular开发者…多得让人侧目。很快他们就都忘却了他们都是起源于程序员这个共同的祖先的事实,忘却了曾经有过这么一个单纯且平静的,想要让这个世界变得更好的科学家。然后他们开始不断的剑拔弩张,都声称自己才是“程序员”的纯血统继承人。随着时间的转移,各门各派开始独占山头,很少进行交流互动,只有在迫不得已的时刻才会进行沟通。他们开始不再为同源的遥远的同宗兄弟们的成功而欢呼雀跃,甚至再也不会时把的遥寄张明信片进行嘘寒问暖。但是在深夜仰望星空的时候,他们还是会发现他们的心底深处的程序员基因还是会不停的闪烁着,期盼着这闪烁的火花能照亮整个银河系并带来和平。瀑布开放流程在这场自私且以自我为中心的欲征服世界的赛跑旅程里,程序员的子孙们早把他们真正的工作目标置之脑后-为客户解决问题。面对一拖再拖的项目交付日期,昂贵的开发代价,甚至最终失败的项目,客户们开始对这种情况深恶痛绝。偶尔,也会有一个闪亮的明星站出来,灵机一动的提供一种办法来尝试结束这种混乱并带来和平。所以瀑布开发流程就应运而生了。这是一个非常了不起的创意,因为它利用了不同团队的开发者们只在必须的时候才进行沟通的这个事实。当一个团队完成了他们的工作的时候,它就会和下游的团队进行交流并把任务进行往下传,如此一级接一级的传递下去,永不回首敏捷开发这种方式在一段时间内发挥了效用,但很快,一如既往,贪婪的人们(客户)又开始提出更多的诉求。他们希望能够更多地参加到整个软件的开发流程中来,不时的提出他们的建议,甚至在很晚的时候还提出改需求这种丧心病狂的事情来。结果就是如大家有目共睹的事实一样,软件项目非常容易失败这个说法已经作为一个行业标准被人们所接受。数据表明超过50%的项目最终都是以失败告终的。更可悲的是,在当时看来,人们对这种情况是束手无策。值得庆幸的是,每一个时代总会有那么几个思想开放的英雄如漆黑中的萤火虫般冒出来。他们知道这些不同团队的开发者们必须要找到一个可以协同工作、进行交流、并且能够弹性的向客户保证对方将会拿到最优的解决方案的方式。这种尝试最早可以追溯到1957年,伟大的约翰·冯·诺依曼和同行们的努力。但是我们最终却是等到2001年才收获到革命的果实,当时行业的十多个精英创造出了如今闻名世界的“敏捷宣言”。敏捷宣言基于以下十二条原则:我们的首要任务是通过尽早地、持续地交付可评价的软件来使客户满意。乐于接受需求变更,即使是在开发后期也应如此。敏捷过程能够驾驭变化,从而为客户赢得竞争优势。频繁交付可使用的软件,交付间隔越短越好,可以从几个星期到几个月。在整个项目开发期间,业务人员和开发人员必须朝夕工作在一起。围绕那些有推动力的人们来构建项目。给予他们所需的环境和支持,并且信任他们能够把工作完成好。与开发团队以及在开发团队内部最快速、有效的传递信息的方法就是,面对面的交谈。可使用的软件是进度的主要衡量指标。敏捷过程提倡可持续发展。出资人、开发人员以及使用者应该总是共同维持稳定的开发速度。为了增强敏捷能力,应持续关注技术上的杰出成果和良好的设计。简洁——最大化不必要工作量的艺术——是至关重要的。最好的架构、需求和设计都源自自我组织的团队。团队应该定期反思如何能变得更有战斗力,然后相应地转变并调整其行为。敏捷宣言是为银河系带来和平以及维护各自的平衡所迈出的很重要的第一步。在很长的时间里,相比此前基于流程和机械化的方式,这是第一次基于文化和“人性”来将不同的关键项目关系人连接在一起的方式。人们开始互相交流,进行基本的碰头会议,并开始不断的交流意见和看法。他们开始意识到他们是有着很多比想象中还多的共同点的,客户也开始成为他们之中的一员,而不再是像以往一样只是往项目砸钱然后开始求神拜佛祈求一切顺利如愿。精益软件开发尽管前面还是有不少的障碍需要克服,但是未来已经光明了许多。敏捷意味着开放和拥抱(需求)改变。但是,如果改变过多的话,人们就很难专注到最终的目标和交付上来。此时精益软件开发就开始破土而出了。因为对精益软件开发的着迷以及为了达成放逐和驱赶风险的目的,一些程序员的子孙们就开始探首窗外,开始向软件之外的行业进行取经。他们从一家主要的汽车生产商身上找到了救赎。丰田生产系统在精益上面的成就是不可思议的,同时它们的精益生产的经验也是很容易应用到软件开发上来的。精益有以下7个原则:杜绝浪费内建质量创建知识(放大学习)延迟决策(尽量延迟决定)快速交付尊重人员(团队授权)全局优化将这些放到敏捷上去的话,精益原则就能让人们在从精神上关注做正确的事情,同时还能够让整个开发流程拥有足够的弹性。DevOps一旦敏捷和精益软件开发被软件开发团队采纳,那么下一步就是把这一套原则应用到IT团队上来。把IT也纳入到整体战略上,然后我们就来到了DevOps跟前了!进入DevOps – 高速公路的三条车道老一派的软件开发团队成员会包含业务分析员,系统架构师,前端开发者,后端开发者,测试员,等等。优化如敏捷和精益原则等的软件开发流程的关注点就在这些地方。比如,软件一旦达到”可以生产“的程度,就会发到系统工程师、发布工程师、DBA、网络工程师,安全专家这些“运维人员”的手上。这里该如何将横在Dev(开发)和Ops(运维)之间的鸿沟给填平,这就是DevOps的主要关注点了。DevOps是在整个IT价值流中实施精益原则的结果。IT价值流将开发延伸至生产,将由程序员这个遥远的祖宗所繁衍的所有子孙给联合在一起。这是来自Gene Kim的对DevOps的最好的解析。你不应该重新招聘DevOps工程师,且DevOps也不应该是一个IT的新部门。DevOps是一种文化,一种理念,且是和IT糅合成一整体的。世间没有任何工具可以把你的IT变成一个DevOps组织,也没有任何自动化方式可以指引你该如何为你的客户提供最大化的效益。DevOps通常作为下面这三个方式而为人所熟知,而在我眼里我是把它们看成是一条高速公路上的三条车道。你从第一条车道开始,然后加速进入到第二条车道,最终在第三车道上高速行驶。车道1 – 系统级别的整体效率考量是最主要的关注点,这超过对系统中任何一个单独个体元素的考虑车道2 – 确保能提供持续不断的反馈循环,且这些反馈不被忽视。车道3 – 持续的学习和吸取经验,不停的进步,快速的失败。车道1 – 获取速度要采纳DevOps的原则,理解整个运作系统的重要性并对工作事项进行合适的优先级排序是组织首先要学的事情。在整个价值流中不能允许任何人产生瓶颈并降低整个工作流程。确保工作流程的不可中断是身处流程中的所有成员的终极目标。无论一个成员或者团队的角色是什么,他们都必须力图对整个系统进行深入的理解。这种思维方式对质量会有着直接的影响,因为缺陷永远不会被下放到“下游“中,这样做的话将会导致瓶颈的产生。确保整个工作流程不会被瓶颈堵塞住还不够。一个高产的组织应该时常考虑该如何提升整个工作流程。有很多方法论可以做到这一点,你不妨去看下“约束理论”,“六西格玛”,精益,或者丰田生产系统。DevOps原则不关心你身处哪个团队,你是否是系统架构师,DBA,QA,或者是网络管理员。相同的规则覆盖所有的成员,每个成员都应该遵循两个简单的原则:保持系统运作流程不可中断随时提升和优化工作流程车道2 – 换挡加速不可中断的系统流程是定向的,且预期是从开发流向运维。在一个理想的世界中,这就意味着快速的开发出高质量的软件,部署,并为客户提供价值。但是,DevOps并非乌托邦式的理想国。如果单向的交付方式是可行的话,我们的瀑布模式早就能胜任了。评估可交付产品和整个流程中的交流对确保质量是至关重要的。这里首个必须实现的”面向上游”的交流通道是从Ops到Dev。我们独自意淫是件非常容易的事情,但是获取别人的反馈和提供反馈给别人才是探究事实真相的正确方法。下游的每一步(反馈)都必须紧跟着有一个上游的确定。你如何建立反馈循环机制并不重要。你可以邀请开发人员加入技术支持团队的会议,或者将网络管理员放到Sprint计划会议中去。一旦你的反馈机制就绪,反馈能够被接收并被处理,你就已经可以说是走到了DevOps高速车道上来了。车道3 – 飞速前进DevOps这条快速车道并不适合意志脆弱的人。为了进入这条车道,你的组织必须要足够的成熟。这里充满了冒险和对失败教训的学习,不断的尝试,并认同屡败屡战和不断的实践是走向成功这条康庄大道的前提条件。在这里你应该会经常听到”套路“这个词,这是有原因的。不断的训练和重复所以能培养出大师,是因为其让复杂的动作常规化。但是在你要将这些复杂的动作连接起来之前,你很有必要先去掌握好每一个单独步骤。“适合大师的动作并不适合新手,脱胎换骨之前你必须先要明白道的真谛。“DevOps的第三个方式/快速车道包括每天分配时间来持续的进行试验,时常的奖励敢于冒险的团队,并将缺陷特意引入到运作系统上来以增加系统的抗击打能力。为了确保你的组织能够消化好这些方法,你必须在每个团队之间建立好频繁的反馈循环,同时需要确保所有的瓶颈都能够及时的被清理掉,并确保整个系统的运作流程是不可中断的。实施好这些措施可以让你的组织时刻保持警惕,并能够快速且高效的应对挑战。DevOps清单下面是一张你可以用来检验你的组织对DevOps的应用情况的清单。开发团队和运维团队之间没有障碍。两者皆是DevOps统一流程的一部分。从一个团队流到另一个团队的工作都能够得到高质量的验证工作没有堆积,所有的瓶颈都已经被处理好。开发团队没有占用运维团队的时间,因为部署和维护都是处于同一个时间盒里面的。开发团队不会在周五下午5点后把代码交付进行部署,剩下运维团队周末加班加点来给他们擦屁股开发环境标准化,运维人员可以很容易將之扩展并进行部署开发团队可以找到合适的方式交付新版本,且运维团队可以轻易的进行部署。每个团队之间的通信线路都很明确所有的团队成员都有时间去为改善系统进行试验和实践常规性的引入(或者模拟)缺陷到系统中来并得到处理。每次学习到的经验都应该文档化下来并分享给相关人员。事故处理成为日常工作的一部分,且处理方式是已知的总结使用现代化的DevOps工具,如Chef、Docker、Ansible、Packer、Troposphere、Consul、Jenkins、SonarQube、AWS等,并不代表你就在正确的应用DevOps的原则。DevOps是一种思维方式。我们所有人都是该系统流程的一部分,我们一起分享共同的时光和交付价值。每个参加到这个软件交付流程上来的成员都能够加速或减缓整个系统的运作速度。系统出现的一个缺陷,以及错误配置的团队之间的“防火墙”,都可能会使得整个系统瘫痪,所有的人都是DevOps的一部分,一旦你的组织明白了这一点,能够帮你管理好这些的工具和技术栈就自然而然的会出现在你眼前了。

March 31, 2019 · 1 min · jiezi

CODING 如何使用 CODING 研发管理系统来敏捷开发

之前我们分享过《CODING 如何使用 CODING 开发 CODING》的文章,时过境迁,现在 CODING 研发管理系统已经上线了如持续集成、缺陷管理、测试管理等 DevOps 中的重要功能,并增加了对 SVN 的支持。借此机会我们以自身的研发流程为例,来展示一下 How CODING uses CODING to build CODING 2.0。企业级一站式软件研发协作平台CODING 现在的团队有 100 多人,分布在全球各地(深圳、北京、成都、西雅图等),均使用 CODING 研发管理系统作为云端协作平台。在 CODING,不仅研发相关的团队使用 CODING 来进行研发管理,市场、运营、行政的部门也同样使用 CODING 进行任务分配与追踪、文件分享等日常工作。同时通过 CODING 的企业微信/微信小程序,还能实现随时随地同步与协同任务,小程序可以直接查看任务详情、评论任务,还能实现代码合并(MR)等功能,真正做到 Coding Anytime Anywhere。CODING 研发管理系统是基于项目进行的,我们依据组织架构建立了相关项目并使用【成员管理】添加相应部门的人员。通过项目这种扁平化的管理形式,帮助企业加快反应速度,提高自身敏捷性。下周即将上线的 CODING 权限管理功能,可以帮助项目管理员方便地根据项目成员角色来分配相应的权限,减少误操作带来的安全隐患。同时支持自定义用户组,增加研发管理的灵活性。Push Everything,Review Everything,CI EverythingworkflowCODING 研发部门的工作流都是在项目内进行:我们使用任务功能来管理需求,使用文件来保存产品原型,使用代码功能进行开发,使用持续集成来进行自动化测试,使用缺陷管理来收集反馈,同时还使用 wiki 模块对知识进行储存与共享。通过在任务中添加关注者的方式来方便相关同事随时 follow 和 review 任务动态。CODING 强大的任务系统支持标签、跨项目引用、版本控制等多项功能,并会实时记录用户的每一次操作。同时 CODING 需求管理功能也即将上线,将在任务系统之外为用户提供更细分更场景化的使用方式。产品CODING 的产品经理在正常的产品功能排期之外,会定期在缺陷管理中查看用户的使用反馈并对相关问题的修复进行排期。当产品经理研究决定我们要实现某一个功能/修复缺陷时,会以任务的形式发布该需求。但是在发布需求之前有几件事情需要先做。给任务定性产品经理会把任务放入“需求反馈池”看板,并给任务定性:纯技术问题(含纯技术 Bug),则指派给研发负责人进行跟进。纯设计问题,则指派给设计负责人进行跟进。(真)产品问题,则准备与发任务的源头沟通分析此问题。问题分析伪需求,或者反馈方理解有误,则直接在相关任务中回复,并关闭任务即可。真需求,则完善对应的背景信息,并将任务拖入“已分析需求池”。Bug 类,可以内部请测试人员来尝试复现此问题。如果可复现,则给此任务打上“Bug 池”、“已确认”标签,再将任务放入“已分析需求池”。分析完需求后即可创建任务,如该任务涉及大型产品改动,则会由相应产品经理撰写完整的产品说明文档和必要的原型图等文件;方案完成之后,产品经理会根据任务的紧急程度给任务设定优先级,方便后续设计和开发的同事更方便的安排工作。在产品设计过程中,我们使用 CODING 的文件管理功能对产品进行原型管理和版本管理。功能开发完成后,产品经理还会配合研发进行 Staging 环境的验收。如在 Staging 环境中发现问题,则需要与发布负责人协商回退或是重新发版,成功完成验收则通知运维上生产环节。开发在产品经理完成原型图和产品说明后,便会把任务移交给研发负责人,进行评估和排期,完成排期后研发负责人会根据任务情况安排里程碑。开发人员开始基于自己的里程碑任务进行开发,其后的代码评审也是通过项目内提交 MR (合并请求)进行的。CODING 使用了 Feature Branch Workflow,即团队成员共用一个私有项目仓库进行管理协作,开发者在各自的 feature-branch 中进行开发。Code Review开发完成后通过提交 Merge Request 进行代码评审,通过代码评审后 merge 进入 master 分支(master 分支是可部署到 staging/生产环境的分支)。持续集成当开发人员 push 代码时,将会自动触发已设置好的持续集成,CODING 的持续集成会自动编译并测试该 commit。CODING 持续集成支持在任意阶段触发并支持 cvm 模式。当测试通过后,我们会更新代码到 Staging 环境。测试更新 Staging 的代码后,测试人员开始进行相关测试。现在 CODING 的测试管理功能由 18 年收购的专业测试工具飞蛾( FEIE.WORK)承载,已实现了企业账号打通,可直接在测试管理中点击跳转到飞蛾的工作界面。接到测试任务后,测试的同时会先在飞蛾中制定相应的测试计划。制定好测试计划后,即可开始编写相关测试用例并开始执行测试计划。Staging 环境测试无问题后,该功能会以 Feature Flags(内部测试新功能)的形式发布其到生产环境,通知相关的产品或设计人员开启 Feature Flags 进行内部 Review,如果存在问题或缺陷,我们会新建一个任务进行产品反馈,确保功能及设计细节的正确性。运营产品正式上线后,CODING 的运营同事会开始收集用户反馈,通过各个渠道反馈的问题都会在 CODING 缺陷管理功能中以创建缺陷的方式进行归纳。运营会定期将收集来的缺陷进行分析,将 Bug 类的缺陷转给产品经理进行排期。如在生产环节发现重大 Bug 则会立即和产品经理沟通并通知运维,协商回退版本或者临时修复。市场在确认功能顺利上线后,产品经理会在 CODING Wiki 中更新 Roadmap,提示功能已经上线。方便市场部进行 Campaign 的计划。市场部的同事使用 CODING 任务管理中的讨论功能,可以实时讨论和跟踪项目进度。让开发更简单工欲善其事,必先利其器,在现在数字化的商业环境中,企业对于软件的依赖已经达到了前所未有的高度。如何选择一套适合中国软件研发团队的开发工具和高效的研发流程,以解放开发人员的效能,打造更好的产品,已经成为每个企业必须要思考的问题。逆水行舟,不进则退,我们自身使用 CODING 进行开发,旨在不断完善 CODING 的功能,优化提升 CODING 的使用体验,让 CODING 成为最适合中国式敏捷的研发管理系统,真正做到让中国的软件研发团队开发更简单!欢迎试用 CODING 研发管理系统,同时我们也欢迎各种反馈,如果你有任何需求或建议,请不要忘了提交给我们 :D官方反馈渠道:联系电话:400-930-9163 邮箱:enterprise@coding.net ...

March 26, 2019 · 1 min · jiezi

持续集成实操视频演示

点击观看持续集成实操视频演示持续集成在现代软件研发流程中,扮演了十分重要的角色。通过对每次提交的代码不断进行自动化的单元测试、代码检查、编译构建,甚至自动部署,持续集成大大降低了开发人员的工作负担,减少了重复劳动,提升代码质量和开发效率。CODING 企业版正式推出持续集成功能后,已经有近 200 家企业进行了超过 30000 次的构建。在这个过程中我们也收到了很多宝贵的意见与建议,在综合考虑了用户反馈后,我们对持续集成功能进行了一次大更新,增加了 Docker 支持、持久化缓存、多任务并行等重要功能。什么是持续集成集成指的是工程师个人研发的部分向软件整体进行合并交付的过程。持续指工程师把任务分成很多部分,每完成一个部分就进行一次交付,这样能尽早发现问题,马上进行调整。简单的说,持续集成(Continuous Integration)强调的是工程师提交了新代码之后,立刻进行自动化的构建、(单元)测试。根据实时测试结果确定新代码和原有代码能否正确地集成在一起放大,及时的反馈也能有效减少发现问题时的回溯时间,提高研发效能。用好持续集成,提高研发效能持续集成可以帮助你的企业:最及时的发现问题:持续集成的及时反馈机制能帮助工程师在第一时间发现问题并修复。解放了重复性劳动:自动化的流程可以解放集成、测试、部署等重复性劳动,提高研发效能。更高的产品质量:集成服务器往往提供代码质量检测等功能,对不规范或有错误的地方会进行标记,提高产品质量。CODING 持续集成新功能上线对 Docker 的支持CODING 持续集成现支持 CVM 模式下对 Docker 镜像的支持,免去安装、配置烦恼,让部署更加方便。支持通过 Dockerfile 创建自定义镜像,同时可以使用 hub.docker.com 上的镜像资源。支持持久化缓存,加速构建速度。持久化缓存进行持续集成构建过程中,每次会用大量的时间重复下载依赖文件,致使构建过程时间过长。CODING 持续集成在 CVM 模式下支持持久化缓存的功能,开启后,首次构建时会下载所需依赖文件,并存储到缓存区,后续的构建将使用缓存中的依赖文件,大幅降低构建的时间。多任务并行CODING 持续集成现已实现以不同服务器并行构建过程,降低等待时间。同时支持针对不同的分支进行独立构建。镜像优化为了帮助构建更快,maven、gradle、npm、python、ruby 默认使用了腾讯云的源(https://mirrors.cloud.tencent…)。php 目前支持了其他国内的源(https://packagist.phpcomposer…)。CODING 持续集成的优势一站式服务:CODING 持续集成是 CODING 研发管理系统的一部分,统一的账号体系能帮助开发者在单一平台完成从设计到部署的全流程,免去在工具间切换带来的效能浪费。完美兼容 Jenkins :CODING 持续集成完美兼容 Jenkinsfile 配置。简单容易上手:提供完整的帮助文档和示例,帮助您快速上手。无缝协作:在 CODING 研发管理系统中,持续集成的触发和结果都可以直接在其他模块中调用,方便任务的分配和验收。完整的构建报告:每次构建都会自动生成完整的报告。极速反馈:支持复数构建并行集成测试,能在最短的时间内反馈结果。点击立即体验 CODING 企业版一站式提供需求管理、代码管理、持续集成、开发环境管理、测试管理、缺陷管理等功能适用于传统模式和敏捷模式的软件研发项目和产品运营助力企业实现 DevOps!

March 26, 2019 · 1 min · jiezi

【融云分析】从过剩存储资源到分布式时序数据库的长存储

背景介绍:作为一名 Infra,管理平台的各种基础组建以及基本的服务质量是必修的功课,而如何对复杂和繁多的基础平台,甚至包括上面运行的 Ops 系统、业务系统,其稳定性的各项指标都是衡量 Infra 是否称职的非常重要的标准。单纯离散的指标本身是没有实际意义的,只有将离散的指标通过某种方式进行存储,并支持对终端用户友好的查询以及聚合,才会真正的有意义。因此,一个性能足够的,分布式的,用户友好且方便下面 DevOps 团队进行部署的 TSDB ( Time Series Database )就成了一个不可缺少的系统。常见的 TSDB 包括 InfluxDB , OpenTSDB , Prometheus 等,其中,开源版本的 InfluxDB 虽然优秀,但并不支持集群部署,且 TICK Stack 本身对数据清洗的灵活性支持并不太好,直接使用开源版本,会有统计信息被收集并上报;而 OpenTSDB 由于基于 HBase ,在部署时成本过高,且本身并不是一套完整的监控系统,而基于 Prometheus 与 TiKV 进行开发的话,整个系统可在保持最简洁的同时,也有非常丰富的生态支持。因此,基于实际情况,融云最终选择 TiPrometheus 作为 Infra 部的监控平台存储方案。项目简介:上图为 Prometheus 的官方系统架构图,而实现 TiPrometheus ,用到了上图中没有体现到的一个 Prometheus 的功能:Remote Storage ,如其名所示,其主要功能是给 Prometheus 提供了远程写的能力,这个功能对于查询是透明的,主要用于长存储。而我们当时的 TiPrometheus 实现了基于 TiKV 以及 PD 实现的 Prometheus 的 Remote Storage 。核心实现Prometheus 记录的数据结构分为两部分 Label 及 Samples 。 Label 记录了一些特征信息,Samples 包含了指标数据和 Timestamp 。Label 和时间范围结合,可以查询到需要的 Value 。为了查询这些记录,需要构建两种索引 Label Index 和 Time Index ,并以特殊的 Key 存储 Value 。l Label Index每对 Label 为会以 index🏷️<name>#<latency> 为 key ,labelID 为 Value 存入。新的记录会 “,” 分割追加到 Value 后面。这是一种搜索中常用的倒排索引。l Time Index每个 Sample 项会以 index:timeseries:<labelID>:<splitTime> 为 Key,Timestamp 为 Value ,SplitTime 为时间切片的起始点。追加的 Timestamp 同样以",“分割。l Doc 存储我们将每一条 Samples 记录以 timeseries:doc:<labelID>:<timestamp> 为 Key 存入 TiKV ,其中 LabelID 是 Label 全文的散列值。下面做一个梳理:写入过程生成 labelID构建 time index,index:timeseries:<labelID>:<splitTime>“ts,ts"写入时序数据 timeseries:doc:<labelID>:<timestamp> “value"写入时序数据 timeseries:doc:<labelID>:<timestamp> “value"查询过程根据倒排索引查出 labelID 的集合,多对 Label 的查询会对 labelID 集合求交集。根据 labelID 和时间范围内的时间分片查询包含的 Timestamp 。根据 labelID 和 Timestamp 查出所需的 Value 。Why TiPrometheus该项目最初源于参加 PingCAP 组织的 Hackathon ,当时希望与参与者一起完成大家脑海里的想法,其实最重要的事情就是,做出来的东西并不是为了单纯的 Demo ,而是要做一个在实际工作中应用于生产环境的实际能力,且能解决生产中的问题。刚开始还有过各种奇思妙想,包括在 TiSpark 上做一套 ML ,Hadoop over TiKV 等,不过这些想法实现起来都有些过于硬核,对于只有两天工作时间就需要完成的项目来说,可能性太小;或者说,如果希望实现 Demo ,所需 Hack 的点过多。而 GEO 全文检索在融云现有的生产上,以及现有的系统中,也并没有需要去填补的大坑,因此,也就没有什么必要去在这方面花费力气去解决一个并不存在的问题。由于 IM 服务是一种计算密集型的服务,且服务质量是融云的核心竞争力;而目前存储资源呈现出零散分布的节点,且每个节点的存储资源使用率并不高,为了最大化利用现有的闲置资源,融云最终设计并实现了这套 TiPrometheus 系统。Result打通了 TiKV 与 Prometheus ,为基于 K , V 存储的时序数据库设计提供了一个可行的思路。为 Prometheus 的长存储提供了一套实用的解决方案。 ...

March 15, 2019 · 1 min · jiezi

灵雀云获邀加入CDF(持续交付基金会),成为中国区三大创始成员之一

3月12日,在加州Half Moon Bay举行的开源领导者峰会(Open Leadership Summit 2019 )上,CDF(Continuous Delivery Foundation )持续交付基金会正式宣告成立。灵雀云以全球首批创始成员身份获邀加入,也是中国区三大创始成员之一,另外两家为华为和阿里。CDF基金会隶属于Linux基金会,Linux基金会是一个通过开源实现大规模创新的非营利组织,为多样化的持续集成和交付(CI / CD)领域奠定了新的基础。CDF基金会将作为一个中立的家园,为最重要的开源项目提供持续交付和规范,以加快发布流程。CDF创始成员包括灵雀云、阿里巴巴、Anchore、Armory.io、Atos、Autodesk、Capital One、CircleCI、CloudBees、DeployHub、GitLab、Google、HSBC、华为、IBM、JFrog、Netflix、Puppet、Rancher、Red Hat、SAP、Snyk和SumoLogic等。入驻CDF基金会的第一批项目将包括Jenkins、Jenkins X、Spinnaker以及Tekton。其他项目将通过即将成立的技术监督委员会(TOC)加入CDF基金会,其重点是将CD持续交付生态系统整合在一起,以围绕可移植性和源代码库建立规范和项目。CDF基金会将促进行业顶级开发人员,最终用户和供应商之间的协作,以传播CI / CD方法论,定义/记录最佳实践,并创建培训材料,以使全球任何软件开发团队能够实施CI / CD最佳实践。灵雀云是以容器技术为基础的新一代PaaS平台领军企业,是国内推动云原生落地的重要力量。围绕应用的全生命周期管理,帮助企业客户快速构建云原生应用,实现微服务架构改造及 DevOps 落地。在云原生DevOps领域,灵雀云致力于打造开放式的DevOps工具链集成与编排平台。平台可以灵活兼容客户的工具选型,通过集成将各类工具串联起来,形成一套工具链,通过编排实现DevOps工具链与容器平台联动,形成一个完整系统。同时,不断结合自身的经验,提炼DevOps落地最佳实践,将最佳实践自动化,作为服务进行输出。灵雀云CTO陈恺表示:“寻求持续创新的现代组织需要高度自动化、灵活性和一致性的软件交付流程。我们很高兴看到CDF基金会的成立。它将培育一个充满活力的社区,促进文化转变、方法论、最佳实践以及工具链生态的建设,使组织能够持续地交付价值。我们期待为这一使命作出贡献。“

March 15, 2019 · 1 min · jiezi

灵雀云CTO陈恺:从“鸿沟理论”看云原生,哪些技术能够跨越鸿沟?

历史进入2019年,放眼望去,今天的整个技术大环境和生态都发生了很大的变化。在己亥猪年春节刚刚过去的早春时节,我们来梳理和展望一下整个云原生技术趋势的发展,是一件很有意义的事情,这其中有些变化在不可避免地影响着我们身处其中的每一家企业。如果说云原生在2017年还仅仅是冒出了一些苗头,那么2018可以说是普及之年,云原生变成了一个成熟的、被普遍接受的理念。灵雀云作为云原生理念的拥趸,也不断顺应这种趋势,聚焦云原生的核心场景,围绕容器平台、DevOps和微服务黄金三角进行产品的研发和业务场景的落地。早在1991年Jeffery Moore针对高科技行业和高科技企业生命周期的特点,提出了著名的“鸿沟理论”。这个理论基于“创新传播学”,将创新性技术和产品的生命周期分为五个阶段:创新者(Innovator)、早期使用者(Early adopters)、早期大众(Early majority)、晚期大众(Late majority)、落后者(Laggard)。在Early adopters和Early majority之间有个巨大的鸿沟(Chasm),每个新技术都会经历鸿沟,大多数失败的产品也都是在鸿沟里结束了其整个生命周期,能否顺利跨越“鸿沟”,决定了创新性技术的成败。今天我们尝试以鸿沟理论为基础来分析云原生领域颠覆性的创新技术。“Kubernetes is Boring”,边缘创新有亮点Kubernetes在2017年底成为容器编排事实标准,之后以其为核心的生态持续爆发,在传播周期上可以说已经跨过鸿沟了,进入Early majority早期大众阶段,开始占领潜力巨大的主流市场。根据CNCF在2018年8月进行的第六次测量容器管理市场的温度,83%的受访者更喜欢Kubernetes的容器管理工具,58%的受访者在生产中使用Kubernetes,42%的受访者正在进行评估以备将来使用,40%的企业(员工规模在5000 )正在使用Kubernetes。Kubernetes在开发人员中已经变得非常流行。回过头来看,灵雀云从早期全力投入Kubernetes技术栈,是最早进行Kubernetes产品化的厂商。我们并未满足于把Kubernetes当作一个容器编排工具来使用,而是将它定位成构建上层平台的核心框架,通过合理运用Kubernetes本身的扩展机制、架构模式与API规范,构建出一系列“Kubernetes原生”的产品体系。这样做不仅真正发挥出Kubernetes作为云计算核心框架的最大优势,也可以与以Kubernetes为核心的云原生生态无缝集成。进入主流市场的Kubernetes开始变得“Boring”,这很正常,甚至是一个好的现象。核心项目的创新速度会减慢,最新的版本中主要关注点聚焦在稳定性、可扩展性这些方面,尽可能把代码从主库往外推,让它的主库变得干净,其他功能通过一些扩展机制来做,同时开始关注安全性。Kubernetes项目本身已经过了现象级创新爆发的阶段,但由Kubernetes独特的架构属性催生出的周边生态的二次创新仍然在高速发展,例如诸多与Kubernetes集成或者基于Kubernetes框架开发的上层服务与平台。这个话题我们下次讨论,今天还是主要关注与Kubernetes项目关联最紧密的创新亮点:早期容器化workload大多聚焦在无状态服务,跑的最多的是Nginx,而对有状态应用避讳不谈。现在Kubernetes进入主流市场,显然需要对“现实中的应用”,包括有状态服务提供良好的支持。2019年,对于复杂应用的管理以及Kubernetes本身的自动化运维将会更多的表现为Operator。Operator是基于Kubernetes扩展机制,将运维知识编写成“面向应用的Kubernetes原生控制器“,从而将一个应用的整体状态作为API对象通过Kubernetes进行自动化管理。这个应用通常来说是比较复杂的有状态应用,如MySQL数据库、Redis集群、Prometheus等等。现在基本上常见的有状态应用都有自己相对应的Operator,这是一种更为有效的管理分布式应用的方式。其次是应用跨集群部署与管理。早期社区里有Federation联邦集群的方案。我们不少大金融客户都有跨集群部署、管理业务的需求。当时深入研究Federation v1之后,觉得这个方案复杂度高,观点性强,对于我们实际的需求灵活度不足而又不够成熟。所以我们最终选择自研跨集群部署。后来出现的Federation v2在设计方向上有不小改观,是我们持续关注的项目。早期采用容器技术的用户都会尽可能兼容企业原有的IT基础设施,比如底层物理机,保留物理机之上的虚拟层,虚拟机之上再跑容器。当然,面向资源管理的硬件虚拟化和面向应用的容器化本质上没有冲突。随着Kubernetes的普及并且在应用上超越了容器编排的范畴,后Kubernetes时代如何搭建管理基础设施是值得思考的。我们也观察到一些有意思的趋势,比如在Kubernetes上同时管理容器和虚拟机(所谓的“容器原生虚拟化”),或是使用Kubernetes来管理OpenStack。总之,Kubernetes在云计算领域成为既定标准,会越来越多的往下管理所有种类的基础设施,往上管理所有种类的应用。这类标准的形成对于技术社区有很大的益处,会大大降低围绕Kubernetes技术投入的风险。因此,我们会看到越来越多的周边技术向它靠拢,在Kubernetes之上催化出一个庞大的云原生技术生态。DevOps独辟蹊径:开放式DevOps工具链集成与编排DevOps理念、方法论和实践已经走到了Early Majority早期大众阶段,是已被实践证实的高效开发运维方法。做容器的厂商都经历过用容器搞CI/CD,灵雀云也不例外,CI/CD是容易发挥容器优势的显而易见的使用场景。在去年,我们做了重大的产品升级,将原来的CI/CD功能模块扩展为完整的DevOps产品—Alauda DevOps平台,覆盖应用全生命周期。DevOps包含好几层概念,首先是组织文化的转变,然后涉及到一系列最佳实践,最终这些最佳实践需要用工具去落地。我们在帮助很多大型企业客户落地DevOps的过程中发现:在DevOps的整个流程里涉及到很多类别的工具,每一个类别都会有大量的选择;2. 每个客户的工具选型多少会有些不同,并不存在一个固定的、完全标准的工具组合;3. 随着时间的推移工具选择会发生变化,多数客户意识到目前使用中的工具在未来很可能会被替代。基于这些观察,Alauda DevOps的定位并不是要提供一个新的DevOps产品,去取代客户已有的工具选型。相反,我们致力于打造一个开放式的DevOps工具链集成与编排平台。这个平台可以灵活的兼容客户的工具选型,通过集成将各类工具串联起来,形成一套工具链,通过编排让DevOps工具链与容器平台联动,形成一个完整系统。同时,不断结合自身的经验,提炼DevOps落地的最佳实践,平台将这些最佳实践自动化,作为服务进行输出。这个思路在和客户的交流以及实际落地过程中不断获得认可。值得一提的是,我们对于DevOps工具链的编排也是基于Kubernetes来实现的。Kubernetes不仅是出色的容器编排工具,扩展之后也很适合编排DevOps工具。换句话说,我们开发了一套“Kubernetes原生的DevOps平台”。微服务:落地需要一套完整的基础设施提起微服务治理,很多人会条件反射般的联想到某些特定的技术,例如Spring Cloud,或者Service Mesh。我们不妨先退后一步,系统考虑下企业微服务架构改造和落地所需要的完整的基础设施。首先,在微服务应用的底层需要一个应用管理平台,这在今天毋庸置疑是一个基于Kubernetes的容器平台。微服务本质上是分布式应用,在我们获取敏捷性的同时不可避免的增加了运维和管理的难度。微服务对自动化运维,尤其是可观测性的要求很高。支持微服务架构的基础设施必须具备完善的监控、告警、日志、分布式追踪等能力。在微服务应用的前方,通常需要一个API网关,来管理对外暴露的API。API治理策略,包括安全、路由、流控、遥测、集成等对于任何应用平台都重要,但在微服务架构下尤为关键。我们需要通过定义、封装对外API来屏蔽应用内微服务组件结构细节,将客户端与微服务解耦,甚至为不同客户端提供个性化的API。云原生应用的一大准则是应用与状态分离。在微服务架构下,每个微服务组件更是应该完全掌控自己的数据。所以,云原生应用通常依赖外部数据服务(Backing Services),而在微服务架构下,多元化持久性(Polyglot Persistence)是常态,也就是说一个微服务架构的应用会依赖非常多种类的 Backing Services。面向微服务架构的基础设施需要将这些外部服务暴露给微服务应用消费,甚至直接支撑各类Backing Services 的部署和管理。一个团队之所以采用微服务架构,一定有敏捷性的诉求。所以通常微服务团队也会拥抱DevOps理念。一个完善的面向微服务架构的基础设施需要考虑 DevOps 流程以及工具链的自动化。最后,我们回到狭义的微服务治理,这里关注的是微服务组件之间的连接与通讯,例如服务注册发现、东西向路由流控、负载均衡、熔断降级、遥测追踪等。现在有个时髦的术语来描述这类功能,就是大家熟悉的Service Mesh。其实早期 Sping Cloud 之类的框架解决的是类似的问题,但在实现的方式上,尤其是mesh 和业务代码的耦合度上,有本质的区别。当我们考虑一个平台如何支撑微服务架构的时候,需要涵盖上述提及的方方面面,从产品的角度我们会保持一个开放的态度。这其中一部分需要我们自己去做,其他一些可以借助生态合作伙伴的能力去补全完善。此外,微服务架构也进入到了后Kubernetes时代,早期基本上是微服务作为用例推动容器技术的发展。今天已经反过来了,成为标准的Kubernetes其实在驱动和重新定义微服务的最佳实践。容器和Kubernetes为微服务架构的落地提供了绝佳的客观条件。Service Mesh: 下一个亟待爆发的现象级技术创新业界对于Service Mesh的布道已经持续了一段时间,我们今天不再重复基本的概念。当我们把Service Mesh和上一代以Spring Cloud为代表的微服务治理框架以及更早的Service Oriented Architecture (SOA) 作比较的时候,会看到一个有意思的演化。 我们知道,SOA有企业服务总线(ESB)的概念,ESB重且复杂,其实会混杂很多业务逻辑。SOA架构下,ESB最终容易变成架构以及敏捷性的瓶颈。早期推广微服务架构的时候,一个重要的概念就是“Smart Endpoints and Dumb Pipes”,针对的就是SOA下ESB的痛点,从而每个微服务能够独立、自治、松耦合。但是仔细去想的话,就会发现它其实走到了另一个极端:它把一些基础设施提供的能力放到微服务的业务组件里面了,通常每个组件需要加载一些治理框架提供的库,或是调用特定的API,其实就是在业务组件里内置了基础设施的功能。到了Service Mesh其实又把它们分开了,从架构角度这样也比较合理,应用是纯业务的东西,里面没有任何基础设施,而提供微服务治理的基础设施,要么在Mesh里面,要么由底层的Kubernetes平台来提供,对应用是透明的。Istio的出现促使业界对于Service Mesh的架构有了新的共识:控制平面(Control Plane)与数据平面(Data Plane)解耦。通过独立的控制平面可以对Mesh获得全局性的可观测性(Observability)和可控制性(Controllability),让Service Mesh有机会上升到平台的高度。相对于需要在业务代码层面使用的上一代微服务治理框架,这点对于希望提供面向微服务架构基础设施的厂商,或是企业内部需要赋能业务团队的平台部门都具有相当大的吸引力。在Data Plane,Envoy的领导者地位毫无争议。Envoy使用C 开发,在资源使用效率和性能上(尤其是长尾性能差异)相较早期主要竞争对手Linkerd有明显优势。Envoy提供基于filter chain的扩展机制,从Kubernetes的成功当中我们已经学习到,可扩展性对于大规模采用十分关键。Envoy定义了一套“通用数据平面API”(Universal Data Plane API),也就是它的xDS协议。不仅确保了Envoy本身的动态可配置性,更重要的是为Service Mesh中Control Plane和Data Plane解耦提供了一个标准的接口。由于主流Control Plane(例如Istio)对Envoy以及xDS的采纳,xDS成为Service Mesh Data Plane API的事实标准,Envoy也成为无可争议的Data Plane领导者。在Control Plane,Istio是最具光环的明星级项目。它正在引领Service Mesh创造出一个全新的市场,不过从传播周期看现在还没有跨过技术鸿沟,处于Early adopters阶段。过去一年中,Istio项目在技术上的表现并不完全令人满意,主要体现在对其复杂度的诟病,以及稳定性和性能的质疑。1.0版本的推出并没有完全令人信服。不过,这些似乎并不影响Istio在社区获得的巨大成功。在开源领域,并不存在对Istio有实质性威胁的竞品。可能在经历了Kubernetes之后,以及Istio早期迅猛的发展和在社区中巨大的影响力之下,很少有开源项目愿意在Control Plane和Istio正面交锋。长远来讲,Data Plane会慢慢变成commodity,尤其在有了Universal Data Plane API之后。我们有理由相信成熟稳健的Envoy会保持领先,但最终多数用户会越来越少去关心具体的Data Plane技术。这个情境似曾相识,和当初Docker与Kubernetes的关系有点类似。下个阶段Service Mesh的赋能和创新会更多聚焦在Control Plane。AWS在Data Plane选择成熟的Envoy,而自己开发App Mesh的Control Plane,就很容易理解。灵雀云已经在ACE/ACP两条产品线中集成了Istio,提供企业就绪的Service Mesh。云原生为机器学习输出工程化最佳实践云原生的理念与相关技术对于应用开发与交付的巨大价值已经被普遍接受。但云原生不仅仅可以作用在普通的应用开发上。站在容器平台的角度看,机器学习毫无疑问是一类极为重要新兴工作负载。在未来,可能所有的公司都会是AI公司,所有的应用都会是智能应用,使用算法、模型就像今天应用会依赖数据库一样普遍。如果我们分析数据科学家的工作流,会发现和传统应用开发有很多相似的挑战。如何方便的获取实验环境;如何让实验可重复;如何将数据处理、特征提取、模型训练、模型验证、模型发布这些步骤自动化,并且可重复;如何让研究和生产环境保持一致;如何在生产环境做模型变更、AB测试、灰度发布;如何在生产环境运维模型服务;如何将模型服务化,等等。在软件工程领域,云原生的理念、方法论和最佳实践已经为类似问题找到了良好的解决方案。这些方案其实非常适合应用在机器学习场景。换句话说,我们需要“云原生机器学习”。这仍然是一个相对早期的概念,从鸿沟理论的周期来看,云原生机器学习大致还处在Innovators创新者尝鲜的阶段。我们去年发布的Alauda Machine Learning (AML) 就是一个“云原生机器学习平台”,目标是从云平台的角度,用云原生的思路去落地机器学习工程化的最佳实践。 ...

March 11, 2019 · 1 min · jiezi

对话 CTO〡听 GrowingIO CTO 叶玎玎讲无埋点数据分析的业务理想

专栏介绍「对话 CTO」是极客公园的一档最新专栏,以技术人的视角聊聊研发管理者的发展和成长。本专栏由ONES 的创始人&CEO 王颖奇作为特邀访谈者。王颖奇曾参与金山软件 WPS、金山毒霸等大型软件的核心开发工作;2011 年创立了正点科技,旗下产品正点闹钟、正点日历在全球用户过亿;2014 年,王颖奇在知名美元基金晨兴资本任 EIR,并以个人身份参与十余家公司的管理咨询工作;2015 年,王颖奇创立 ONES,致力于提供企业级研发管理解决方案。摘要创立之初,GrowingIO 以无埋点技术切入市场。为了让数据平台可以帮助客户做深度的用户转化、留存分析,GrowingIO 花了三年多时间去打磨产品。正如 GrowingIO 联合创始人&CTO 叶玎玎所说,真正去做一个 SDK 来采数据其实很容易,但是要做 SaaS 服务,要针对不同用户的不同写法去做通用型的开发,还要考虑应用开发本身的一些易变化特性等等,这些都需要很强的技术支持。叶玎玎曾在网易杭州研究院从事工程数据库相关工作,2009 年接触 SaaS,2015 年到 GrowingIO 负责核心产品研发。本期对话 CTO,我们请到了 GrowingIO 联合创始人&CTO 叶玎玎。关于 GrowingIO 产品如何支持业务发展,以及数据分析产品的历史演进,叶玎玎谈了谈自己的看法。产品做给业务端颖奇:很高兴 GrowingIO 的 CTO 叶玎玎同学能接受我们的访谈,我觉得可以先大概讲一下 GrowingIO 在技术方面的一些特长。叶玎玎:OK,如果要研究 GrowingIO 的技术,一定要先了解它的形态。GrowingIO 是一家云的公司,做 SaaS 的公司,所以我们所有的客户数据的采集都会在云上。目前我们第一个技术特点就是外界所熟知的无埋点,自动去采集用户从打开应用或者打开网站到离开的所有行为数据,这个行为数据通过可视化的定义方式去展现。其实这会涉及到你如何去理解客户端的实现,无论是对浏览器本身的实现,还是对于 iOS 或者安卓操作系统的实现,这里都需要很多黑科技的东西。去了解它的实现后才能更好地在上层去研究怎么做无埋点的逻辑。所以这个是我们在过去三年花了很多时间去研究的东西。真正去做一个 SDK 来采这些数据其实很容易,但是要做 SaaS 服务,如何针对不同用户的不同写法去做这个通用型的开发,并且是插件,包括这里面还要考虑如何去应对应用开发本身的一些易变化特性等等,这里需要做很多东西。所以我们在这个过程中自己也用了很多方法,通过算法、模型、机器学习等方式,考虑怎么去让前端采集到的数据跟后端用户的数据逻辑之间更好的匹配,所以这个就是外界所熟知的 GrowingIO 的无埋点。但本质上另外一个挑战在于,当有这么大数据量进来的时候,我怎么去处理数据?我相信 GrowingIO 数据量在国内应该算蛮大的。颖奇:因为无埋点本身是没有筛选的来进行数据采集,所以肯定会有很大的数据量。叶玎玎:一方面是这个,另外一方面也在我们数据系统本身。举个例子,我们每天可能有个两三千亿条的消息,我相信大部分公司都达不到这个量,这是第一点。第二点是,GrowingIO 有一些几个亿 DAU 的客户,单体客户几个亿,再加上云端有这么多其他的客户,怎么更好地处理、存储、查询,都是一个很大的挑战。颖奇:那对比市场其他竞品,在数据量这方面,GrowingIO 有没有一些技术上的先进性?叶玎玎:是有的。 GrowingIO 目前有一个很多客户认为很方便的功能——指标维度的多维交叉,实现任意去拖拽指标维度,瞬间出图。举个例子,你要进行基于人的指标维度任意交叉的时候,GrowingIO 是可以快速出结果的。具备这些属性的用户,然后做过哪些事情的用户,在历史上的任何一个时间点,能立刻知道这群人,立刻计算出来他们有谁。这个东西在之前的数据系统里面相对来说是比较少的。大部分数据系统,无论是 T+1 还是实时,还是一个小时这种,它都是基于事件的处理。颖奇:这就是说分析过程上你们应该是做了更多事情的。叶玎玎:我觉得是在用户画像本身,就是我们如何去更好的找到一批用户。然后这个过程包括,如果你找一个其他的用户分析系统,你想要看留存,或者说要去做转化路径,要找到哪些优化点,那核心其实就在于对于用户之间群体的对比。对单一人群去做分析其实很容易,但是一旦要将用户之间对比各种东西,然后又要达到非常快的响应效果,这个其实是其他竞品很难做到的。这里最核心的差别是说,因为我们一直是做给业务端的,就是产品运营等等,所以我们的要求就是他们能非常简单的从我们的分析工具里面去得到结果。颖奇:所以 GrowingIO 在无埋点等技术上有哪些关键特点呢?叶玎玎:无埋点肯定是我们一个关键特点,因为使用其他产品的话,你可能需要自己去梳理所有东西,我们是让那个业务直接可以自己去做。然后第二点是基于这个能力上来说,本身我们会演变出来新的一层能力,我们能快速做实验。比如我现在想要一个东西,这个时候我不是找研发去帮我做打点,而是直接可以看到结果。我当时自己为什么觉得 GrowingIO 很值得做,就是因为我之前用其他数据分析工具时,陷入到数据采集-使用、采集-使用的整个不停的轮回之中,这个过程中,大量时间其实被浪费在前端的采集和处理这一块,真正进入到核心的产品逻辑的迭代和产品的改进的时间是比较少的,而 GrowingIO 就不会有这样的问题。高效能远程工作颖奇:我了解到您之前是有做过远程团队的工作,您觉得远程工作这样的方法在中国现在是不是真正能够去很好的来实行?叶玎玎:我个人判断相对是比较难的,它必须变成两种模式。远程工作要么就是全员远程,这个事情反而是可以做的。因为全员远程意味着大家每个人都接受了,我必须要为了我们的效率提高付出额外的努力,然后为了降低我的沟通成本,我要做哪些事情。我觉得这个是非常关键的。但这里面如果存在大部分人不远程,某一两个人、两三个人远程的情况的话,这个就会变得非常尴尬。因为很多时候最高效的沟通肯定是面对面沟通,然后在面对面沟通过程中,有一个人如果在远程的话,那很多时候他其实不知道其他人在聊什么,因为除了语音、视频以外,还有一些肢体语言等等,然后聊着聊着很容易的一点就是大家把远程的人忽略掉了。所以我个人的建议是如果全员远程,这个是 OK 的。但是这种模式是否能演变出来非常快地去响应变化,这是有一些潜在风险的。所以这个意味着整个团队的认知需要达到一定的高度,然后整个团队为了达到更高的效率,更好的沟通,愿意付出什么。如果你去评估这两点之后,觉得这是自己可承受的风险,那可以选择。如果对一个创业公司的话,我觉得这个可能是比较难的。但是如果对于一些看着需求做事的公司来讲可能是没有任何问题的,因为这个过程中无非是我怎么把项目管理做的更好。或者还有很多公司选择了另外一种模式,其实不算远程,就是一个多地的办公室。颖奇:前一两年的时候,因为一些效率工具的出现,大家都说可能未来是远程工作的时代,人会越来越依赖工具。但是现在我们越来越觉得,真正工具刚需的来源不是因为远程工作,面对面的时候我们也是需要工具的。叶玎玎:我觉得工具的核心不是为了解决远程的问题,而是人是在流动的,是不一定都在一起的。比如风车到最后服务的团队可能是在一个 office,但是因为大家都出去了,所以在这个过程中怎么去分配工作,怎么去沟通等等,(工具本身)还是解决类似这类问题。围绕用户做分析颖奇:您怎么看待中国数据分析行业的过去、现在、未来?包括过去一代二代的数据分析产品,现在的数据产品,可以来分享一下您的看法。叶玎玎:我觉得最早的应该不叫分析工具,叫统计工具。像 CNZZ 也好,像百度统计也好,做流量的一些统计,核心是在流量层面。然后再往下,大家会说光是统计还不行,要进入分析,要了解一下我的用户整个情况是怎样的,那这个时候会演变出来第二代的数据分析产品,就是基于事件的。因为每个事件都会对应到人,既有事件的模型又有用户的模型,这个用户到底做了哪些事情,然后去筛选用户,这个是第二个阶段。目前大部分的工具应该也在这一层,包括在 2010 年左右出来的友盟、Talking Data 为代表的一系列工具,当时它们承载的很多可能就是流量统计的功能,但是它们也有事件模型。然后再到下一代,从事件本身到开始运营用户的生命周期了,就是到用户这一层。颖奇:到用户这一层了,就是会把它组合起来看。叶玎玎:是的,我通过事件去更具体的去看一个用户,核心围绕着用户来做分析,不是核心围绕着事件来分析。所以我们所有的人的模型在整个数据分析里面就会成为第一个关注点,这个是很重要的。然后再往下的东西也跟这个时代相关,因为现在有很多机器学习,你要去做个性化,这个过程中,你怎么去更好的基于机器学习来做东西,无论是从各种推荐引擎,或者说各种的计算模型,这样演变出来比如做 alert(提醒)、anomaly detection(异常检测),那这些又会进入到下一个阶段。但是这里的所有都是基于你的数据层是干净的。数据这一层要有一个好的基础,不然想着跳到下面步骤的话是很难的。颖奇:在您刚才讲的用户精准个性化的一些业务上,我们现在看到的这些数据平台更多是帮忙分析,你们会有一天能够真正走到业务中去吗?比如说可能会提供一些数据的接口,或者提供一些非常精准的画像,每一个客户最终都会跟真正业务端的服务对应起来。叶玎玎:其实我们现在就在做了,我刚才提到,理论上我们的客户主要打的还是业务端,比如产品、运营,他们用我们系统就在做这件事情,真正走到业务里面去,他们在我们系统上去定义各种东西。举个例子,我们可以让系统找出来,比如昨天注册了,看了 Demo,但是没有继续去做创建项目的人。这群用户筛出来以后,针对这些用户可以去做触达。然后比如在做哪些事情的过程中,你到底要给他一个什么样的动作,这些东西是我们在帮我们客户做的,所以它其实是非常业务化的。颖奇:能否给大家介绍下您的个人职业经历?叶玎玎:我之前在网易杭州研究院工程数据库相关的组里面工作了一年半,2015 年之后在做 GrowingIO。中间有几个节点,第一个是我最早远程是 Freelancer,那时候更多是帮美国的一些创业者去做 0 到 1。然后 09 年到 12 年,我从自己研发的这个点更加往外扩出去,负责产品研发,做企业社交这一块。但是我是从 09 年开始真正去接触 SaaS 这个行业,然后接触 to B 这个方向。09 年的时候,我们非常看重怎么去做实时 Web,因为它在 09 年的时候其实没有太好的解决方案,但那个时候我们为了自己做的东西,就做了很多技术上的突破。然后到做协作工具也是,就是怎么把用户体验和当时实施的技术更好的打包成一个方案表给到用户。然后到 14 年底开始做无埋点,也是在当时非常新的一个东西。12 年底到 13 年又做了另外一个蛮好玩的事情,就是 Teahour,一个技术播客。我觉得当时 Teahour 对很多刚工作一两年的或者在刚毕业要找工作的那群人给了很多方向性的指导。颖奇:您之前一直在做程序员,也一直在做自己的项目,那最终变成一个这么大公司的 CTO,中间有什么特别重要的一些转变,或者您觉得比较关键的时间点或者里程碑,经历了之后就变成一个 CTO 了。叶玎玎:因为我从 06 年毕业的时候就开始创业,无非是一开始创业相对来说团队的人数可能比较少,然后会经历一个团队从小变大的过程。我会非常关心用户到底是怎么想的,对我来说,为什么我对数据分析很感兴趣的一点,在于我会尝试通过这个去理解到底用户在用我的产品的时候他心里的想法。所以我觉得很核心一点是,我自己是在思考到底这个业务和产品应该怎么来做的,所以我觉得我跟大部分的技术不太一样,我会很容易在用这样的视角去思考。颖奇:非常棒。最后可不可以推荐一些您最近看的认为比较好的书给大家。叶玎玎:我看的书会比较更加偏意识形态一点,更加偏管理一点。我最近一直在看《赋能》,《赋能》这本书核心讲在现在这个时代,你到底应该有什么心态,应该怎么去更好的发展等等。颖奇:好的,今天有很多收获,非常感谢。想要更好更快地发布产品?请扫描二维码,或访问http://ones.ai 了解更多。 ...

March 5, 2019 · 1 min · jiezi

CODING 缺陷管理功能正式开始公测

在这辞旧迎新之际, CODING 研发管理系统又迎来一重大更新,期待已久的缺陷管理功能正式开始正式公测,帮助研发和测试人员更好追踪和管理软件缺陷,提供软件研发效能。在任何软件的生命周期周,几乎必然会出现不同原因造成的缺陷,CODING 的缺陷管理功能作为 CODING 一站式 DevOps 工具链中的一环,帮助企业研发团队快速建立一套高效的缺陷反馈和追踪机制,通过高效的标准化流程取代了很多企业使用的如代办事项等非专业工具,通过缺陷类型、模块信息、优先级等标签功能快速帮助经办人定位和了解问题,这样极大减少由于沟通不畅导致的额外修复时间,并能有效降低由于软件缺陷带来的负面影响。如何使用 CODING 的缺陷管理功能CODING 研发管理系统的缺陷管理功能涉及缺陷生命周期管理,包括缺陷创建、复现、修复、验证、重新打开/关闭缺陷、统计分析和报告等功能。目的是为了减少软件缺陷出现的几率,降低由于软件缺陷带来的负面影响。缺陷管理模块主要包括缺陷列表、缺陷处理、统计和设置四个主要功能。在 CODING 研发管理系统的左侧导航栏进入缺陷管理界面,第一次使用会提示创建第一个缺陷。创建缺陷,填写缺陷名称后对缺陷进行详细描述并上传必要的截图或附加。完善了缺陷信息后选择缺陷的类型,预置的类型有:性能问题、安全问题、易用性问题、UI 界面问题和功能缺陷。可以通过设置界面对缺陷类型和模块进行自定义添加和设置。进入设置界面后可根据项目情况对缺陷类型进行添加和修改。点击所属模块后可以根据项目情况对功能模块进行定义,更好地帮助经办人对缺陷进行定位。完成模块设定后可以回到缺陷页面,点击缺陷查看完整信息的同时可以在上方状态栏选择实时进度并在最下的留言区对进度进行补充。最后在统计页面,可以清晰看到项目所有缺陷的状态统计、趋势统计和个人经手的任务情况,直观地展现项目情况帮助管理人员更好地对项目进行规划和总结。对于处于数字化转型企业来说,在缺陷管理上的投入,可以大幅度地降低由于标准流程缺失导致的人力,财力和时间的浪费,同时提升产品的用户提样并能帮助研发团队进行更快更高效的软件交付。通过 CODING 研发管理系统的缺陷管理功能可以更好更高效的进行缺陷管理从而帮助企业提高产品质量,加速交付时间,增加企业收益。同时配合 CODING 研发管理系统的其他功能模块,让企业能以最低的时间和人员成本开始践行 DevOps 的方法论。点击立即体验一站式 DevOps 工具链

February 20, 2019 · 1 min · jiezi

DevOps自动化工具集合

版本控制&协作开发:GitHub、GitLab、BitBucket、SubVersion、Coding、Bazaar自动化构建和测试:Apache Ant、Maven 、Selenium、PyUnit、QUnit、JMeter、Gradle、PHPUnit持续集成&交付:Jenkins、Capistrano、BuildBot、Fabric、Tinderbox、Travis CI、flow.ci Continuum、LuntBuild、CruiseControl、Integrity、Gump、Go容器平台: Docker、Rocket、Ubuntu(LXC)、第三方厂商如(AWS/阿里云)配置管理:Chef、Puppet、CFengine、Bash、Rudder、Powershell、RunDeck、Saltstack、Ansible微服务平台:OpenShift、Cloud Foundry、Kubernetes、Mesosphere服务开通:Puppet、Docker Swarm、Vagrant、Powershell、OpenStack Heat日志管理:Logstash、CollectD、StatsD、ExceptionLess监控,警告&分析:Nagios、Ganglia、Sensu、zabbix、ICINGA、Graphite、Kibana

February 15, 2019 · 1 min · jiezi

CODING 最佳实践:快课网研发效能提升之路

快课企业移动学习平台是上海快微网络科技有限公司自主研发的企业级 SaaS 平台,提供移动学习、考试练习、培训管理、知识分享、统计分析等学习和培训功能,为员工、经销商及客户等全价值链合作伙伴提供全面的知识服务。本文将详细介绍快课网的研发团队是如何使用 CODING 研发管理系统提高研发效能。为什么选择 CODING快课网从创立至今已有 4 年多,作为一个规模比较小的创业团队,我们一直在寻找和尝试各种能提升研发效能的管理方案,这样能够帮助团队节省时间,更加专注于业务。第一步就是上云,我们一开始使用的是阿里云,通过容器化、弹性计算和可视化管理帮助我们节省了不少运维成本。但是仅有这些还不够,要开发还需要搭建很多服务,例如 BUG 跟踪管理、代码版本管理和同步、npm 私服、maven 私服、docker 私服等等。虽然后台团队通过使用 docker 让搭建服务方便了不少,但是我们还不满足。大量的服务为研发团队带来了极高的管理成本。再加上不菲的服务器成本、所使用的开源项目更新较慢等原因导致很多问题短时间内都解决不了,同时很多管理方案还不支持中文。所以我们决定寻找一个集成度比较高的国内的商业平台来帮助我们进行研发流程管理。当时的想法很简单,只要功能齐全,收费能够弹性一些就好。在尝试了很多平台之后,我们最后决定使用 CODING,主要是看中 CODING 的网络连接速度比较快,界面简洁,交互比较友好,功能齐全,反馈处理也非常及时,可以很好地帮我们解决代码托管和 BUG 管理等研发流程问题。我们最开始使用的是 CODING 个人版的团队功能,在 CODING 推出企业版之后我们团队很快迁移到了企业版,相对于个人版来说企业版功能更完善,管理起来也更方便,后续还有持续集成和部署相关功能升级,这些功能正是我们团队所需要的。目前快微团队的整个开发是在 CODING 和阿里云上完成的,CODING 主要用来管理代码、里程碑和持续集成等研发流程。版本规划与任务流程里程碑是我们使用比较多的功能之一。最初,我们使用 CODING 的里程碑来规划版本,比如 1.0 版本对应的里程碑就叫做 1.0,每个任务都是版本中的功能点。后来由于新版本的重构采用了分布式服务化开发,由多个子项目组成。由于各个子项目地版本相对独立导致粒度太细不方便产品的规划,便做了一些调整。目前里程碑主要是用来做长周期的规划,每一个任务都是一个小的项目,由一个或多个人来完成,比如将课件服务 1.1 版本分就单独为一个任务。快课技术团队目前的绩效考核也是基于 CODING 的任务管理和里程碑实现的:由产品发布相关版本的产品说明书,包含原型图和功能点文档部分。创建任务,分派给项目负责人,项目负责人需要评估任务的工作量。工作量给定的有参考标准,将最简单的帐号密码登录接口的工作量定为 1,最小为 1。评估工作量之后进行审核,确定起止时间和奖金。进入开发阶段,开始倒计时。开发完成之后进行验收,由技术审查代码(每次发起合并请求也有审查),产品检查 UI 交互,顺利完成验收则关闭任务,将工作量的值作为绩效值。对于不能按期完成的任务,进行惩罚措施,每逾期一天扣 10% 绩效。对于工作量比较大的任务,可以由一个人主要负责,多人完成,负责人需要为每个人安排详细的工作内容,最终由负责人按贡献比例分配绩效和奖金。这样累计下来,每半年或一年可以根据绩效进行一次评定,给表现好的员工涨薪。分支管理快课目前的分支管理方案与 CODING 文档中的最佳实践比较接近,master 作为主分支只发布正式版本,新增一个 dev 分支作为开发中的分支,并且同时对这两个分支设置保护,禁止直接推送代码到这两个分支上。快课的每个子项目都在项目配置文件里写有明确的版本号,后端 maven 项目写在 pom.xml 中,前端 node 项目写在 package.json 中。开发中的版本号一律带有 SNAPSHOT 后缀,以表示这是快照版本,会不断发生变化,不能在生产环境使用。比如正在开发 1.1 版本,此时 master 分支的版本号是 1.0.0(随着补丁的增加,最后一位也会不断增加,比如版本号有可能为 1.0.9),dev 分支的版本号是 1.1.0-SNAOSHOT。当需要开发一个新版本的时候,首先基于 dev 分支新起一个分支,可以根据实际情况来命名新分支,比如可以叫 dev-v1.1 或者 dev-tom 等等,没有限制。在新分支上完成开发之后,在 CODING 上发起合并请求申请合并到 dev,此时合并请求的标题和内容必须写的详细一些,审核之后进行合并,合并的同时删除原分支,只在 CODING 上保留 master 和 dev 两个分支。最终所有新开发内容都完整合并到 dev 分支后,测试通过,再从 dev 分支新起一个分支,更改版本号为正式版本号,进行推送并新建合并请求,合并到 master 分支上。对于已经上线的版本,如果有 bug 需要修改,则从 master 分支新起分支进行修改,完成后将版本号最后一位 +1,然后推送并新建合并请求合并到 master。持续集成我们团队很有幸获得了 CODING 持续集成功能的内测资格,之前也有尝试过自建 Jenkins 服务,对持续集成有一定积累能很快上手,于是我们便开始转向 CODING,毕竟一站式的 DevOps 工具链服务更方便,可以给研发团队节省很多精力。CODING 对 Jenkins 进行了封装,只需要在项目根目录下创建一个 Jenkinsfile 文件,配置好之后推送上去,推送完成之后在后台开启持续集成即可。持续集成主要用在后端 maven 项目上,来做规范检查(checkstyle 插件)、单元测试和代码质量检查(spotBugs 插件),这样当团队成员在创建合并请求时,管理者可以看一下代码是否规范并跑通了必要的测试,在 CODING 上构建成功后才能继续对修改进行审查。自动化构建为研发提供了很大的便利,避免了一些人为的不稳定因素,也为项目管理者节省了不少时间。目前快课的项目都是直接发布到 docker 私服上的,推送成功之后修改 k8s 中的镜像版本来完成自动部署。我们也期待 CODING 未来会上线的部署管理功能,能支持在目前的构建基础之上自动发布 docker 镜像,然后再自动更新 k8s 相关配置的镜像版本,补充 CI/CD 功能,这样的话就能更好的实现研发流程的自动化了。点击立即体验一站式 DevOps 工具链 ...

February 12, 2019 · 1 min · jiezi

工具的价值演进

随着互联网时代进入深水区,云计算、AI、IoT 等新一代的信息技术开始对传统企业进行更深层次的改造,对企业而言,现在仅仅 “拥抱互联网”是远远不够的。在全球经济进入数字化转型的时期,数字化转型已经成为企业必须付诸行动的不可忽视的选项。那么,从根本上说企业为什么要进行数字化转型呢?如何把握数字化转型的时机?哪些工具是帮助企业进行数字化转型的关键呢?2019 年 1 月 19 日,CODING 创始人及 CEO 张海龙受邀参加 2019 极客公园创新大会(GeekPark IF 2019)并发表了以 《工具价值的演进》 为题的主题演讲。作为一家服务了超过 100 万开发者和近 4000 家企业的,从代码托管服务起家一直拓展到提供 一站式全 DevOps 工具链 的 SaaS 公司创始人,他从工具的角度切入,展示了人类历史中生产力的发展进程,并解释了为什么现在是企业数字化转型的关键期,揭示了 DevOps 才是企业数字化转型的关键。 工具的演化促进了生产力的飞速发展首先我们看这张图,图上展现了从人类社会初始阶段开始,一直发展到现代数字时代,所经历的几次生产力的飞速提升,这里可以清晰的看到生产力和生产工具之间的关系——在石器时代,工具以简单的木石结合为主,简陋的工具带来的生产力是非常有限的。之后锻造技术出现,给人类带来了更加高效的金属工具,原来需要一天的活半天就干完了,人们开始有空闲时间,闲着闲着,文明就诞生了。随着科技的发展,蒸汽机和电力拉开了机器生产时代的序幕,二十世纪成为了世界发明史上最璀璨的一个世纪。到了 2000 年,互联网让距离消失,把很多不可能变成了可能。而未来,云技术和数字化的浪潮,注定会掀起新一轮的生产力革命。 数字化转型是一个十年的旅程互联网的出现让信息变得触手可及,同时也促使新技术的迭代达到了一个不可思议的速度。这使得很多体型庞大的传统企业感到措手不及,复杂的组织架构让他们好不容易接纳一种新技术后,就发现速度快的公司已经迭代好几代了。根据 IDC 对未来企业数字化的趋势预测,2017 年是数字化转型的原点,很多企业开始进行破釜沉舟式的变革,这中间将经历十年的时间,到 2027 年结束,届时 60% 的 GDP 将和数字化相关,并且全球 40% 的物理设备将被数字化取代。我觉得别的行业不说,汽车行业可能是最感同身受的。2017 年以前造汽车最关键的是什么,是内燃机技术,也就是汽车里的心脏。到现在为止中国的发动机技术跟国际一流还差了大概 2030 年的水平,毕竟从工业革命开始,西方国家对内燃机的研究已经超过 200 年了,而我们只有几十年的时间追赶。但是从 2017 年开始,这个形势发生了改变,为什么呢? 因为 Tesla 和他的自动驾驶技术掀起了汽车行业数字化转型的浪潮,开启了电动汽车和无人驾驶技术的时代,把复杂的内燃机系统简化为电池+马达的组合,将重心放在了行车系统和传感器上,完全打破了大众对传统汽车行业的认知,把汽车这种产品直接带入了数字化时代。通过收集每一辆汽车的行驶数据对行车系统进行不断的迭代和升级,因此我们认为 Tesla 本质上其实是一家软件公司,二级市场的人应该也是怀着同样的想法才给了 Tesla 将近 40 倍的 PE 和 600 亿美元的估值,反观丰田作为估值最高的汽车厂商只有 470 亿美元左右,这完全是将 Tesla 当作一家数字化软件公司看待了。同时,这也给了中国汽车产业很大的机会,20172018 年优秀的电动车企业喷涌而出,在这个关键的时间点开始数字化转型,抓住了弯道超车的机会。 DevOps 是数字化转型的关键那么回到主题,现在企业数字化转型的问题在哪里?在数字时代又有哪些工具能帮助企业快速掌握变化,更好的完成数字化转型呢?先说结论,想进行数字化转型的企业需要 DevOps。我们先来看问题,我觉得中国大部分企业无法快速转型的根本原因在于研发效率低下。之所以研发效率低下,是因为:1.人才缺口大,很多企业找不到合适的人才。2.由于落后的管理方式和组织架构导致的效能浪费。中国每年的 IT 行业人才缺口基本固定在 100 万左右,虽然一部分缺口会通过社会培训之类的方式填补,但总的来说缺口依然很大。这就要求企业必须在研发效率上有所提升。而现有的组织架构却因为落后的管理导致效率很难提升,软件开发最高效的组织形式是“One Man Work”,只有一个人干活,写个小项目,从需求到开发,从测试到部署全部独立完成,非常高效。但随着业务的增长,项目开始逐渐变得庞大,变成团队,出现了分工,出现了产品经理、项目经理、开发、数据、测试、运维等等角色。这些角色间存在天然的工作目标上的矛盾。举个例子,对于运维来说,稳定压倒一切,新 Feature 越少越好。而对于研发来说,却希望能开发更多的功能。这种矛盾会导致大量资源和时间的浪费。就像两匹马拉一辆车,如果马头向着的方向不一致,肯定是没法全速前进的。DevOps 的理念就是希望能打破这种屏障,让研发(Development)和运维(Operations)一体化,让团队从业务需求出发,向着同一个目标前进。再通过工具搭建自动化流水线,更高效地进行软件交付。纵观软件研发的历史,如果类比成工厂生产力提升的历史:从最早的作坊,到小工厂,到富士康式的专业化流水线,再到现在很多智能制造企业已经进入的自动化流水线,都是机器人在流水线上工作。那软件开发行业也是一样经历了这个过程,只不过周期缩短到了几十年。现在优秀的软件研发团队已经进入了自动化流水线时代,也就是 DevOps 时代,而大部分国内的研发团队可能还停留在小工厂时代:有统一管理能力但是管理方式落后;工具化程度底,使用的工具比较过时;分工明确但是协作效率低;能制定计划,但是交付质量难以把控;遇到问题的解决方案可能就是拉大家一起开会,这样效率极其低下,结果就是企业在数字化转型的进程中被落后的研发管理效率拖累,逐步丧失市场竞争力。DevOps 就是数字时代的自动化流水线,看不见,摸不着,但在工作中是真实存在的。研发团队不同的角色通过这个流水线来协作完成工作,打破角色之间的隔阂,提高研发效率。 CODING 产品研发流程一条数字化的流水线是到底是什么样的呢,我们来简单的解剖一下。这个图展示的是 CODING 如何使用 CODING 来 coding 的,可能比较拗口,简单来说就是我们如何使用自身的产品,来搭建一条数字化流水线。比如我们要做一个 CODING 的小程序,那么首先由产品经理整理出需求文档,然后同步给开发,在统一的集成开发环境中进行代码的编写,通过自动化的持续集成来进行自动化的测试和构建,确认无误后交给运维,通过自动化测试高效地反馈问题,测试通过后再通过一键部署,快速上线完成高效的版本迭代。CODING 已经算是一个比较庞大复杂的系统了,但通过这条流水线,我们可以达到每周迭代一个版本。这个流程是一个完整的闭环,就像最开始举的例子一样,当你选用的工具越高效,这条流水线运转的越快,团队的研发效率就越高效。大家可以看到这里涉及到很多的角色,很多的环节,其实每一个环节都有对应的工具。我们挑一个环节来看一下,比如编码环节。在编码环节工具经历了怎样的演变呢? 数字化时代的工具是在云上的这里展示的是不同时代的集成开发环节,是程序员每天都要用到的开发工具。这个工具的演化进程,最左边是 90 年代,DOS 时代的开发工具,非常基础,只有文字,连光标都没有。再往后,中间这张图展现的是 04 年左右的开发工具,此时已经有了完备的图形界面和辅助功能,但是仍局限于物理设备。到了近年,编程工具开始云端化,出现了 Cloud Studio 这样的数字化时代的云端工具产品,完全运行在云端,通过浏览器就能访问,不需要安装,没有任何硬件设备的限制。它可以做到以下本地工具目前还不能完成的任务。比如说随意切换开发环境,你可以从编写 Java 的开发环境瞬间切换到编写 Python 的开发环境;再比如说可以通过 Web 终端连接到任意的云端计算资源,瞬间获得大量计算能力;再比如说邀请伙伴一起编写程序,两个人可以同时编写同一份代码等等。这极大地提高了编码环节的开发效率,我们可以想象刚才展示的流水线上的工具都在发生同样的演进,这将促使我们进入一个新的开发时代,那就是云端开发时代。我们相信开发的效率会成倍提升,满足这个数字化社会对于 IT 效率的要求。同时开发门槛也会降低,云技术将使这些工具触手可及。每一个时代都对应了一个大的生产力变革,而诞生于这个时代的工具是推动变革的根本因素。随着云端开发时代的到来,企业需要像 DevOps 这样的研发管理方法论和工具链来打造属于自己的数字化流水线,提高效能,让研发与业务同频共振,方能在如今这种高速竞争的市场环境下和数字化转型的浪潮中保持自身的竞争力。最后,我也希望 CODING 作为一个专业的研发工具厂商,也是一个云服务的厂商,能够在数字化年代,在一个云端开发的时代,能够贡献自己的一份光和热,做到让开发更简单。 点击链接,立即体验一站式 DevOps 工具链。 ...

January 23, 2019 · 1 min · jiezi

DevOps时代,企业数字化转型需要强大的工具链

伴随时代的飞速进步,中国的人口红利带来了互联网业务的快速发展,巨大的流量也带动了技术的不断革新,研发的模式也在不断变化。传统企业纷纷效仿互联网的做法,结合DevOps进行数字化的转型。通常提到DevOps,大家浮现在脑海里面可能是研发规范、持续交付、敏捷迭代相关的一系列事项,组织上推行打破部门墙,文化上推行活泼、皮实、互助等方式促进效能提升。但是,除了这些,还需要更多的工具、技术来让这一切真正的落地。所谓的DevOps,指的是开发运维一体化,也被称之为开发运营一体化、开发测试运维一体化,现在有些领域也衍生出来更多提法:开发安全运维一体化(DevSecOps)。总之,都是在致力于产品从开发到落地的整个生命周期过程管理。我们目前也处于数字化转型的新时期,面对DevOps的具体落地,大家需要了解这几样新时代神器:Docker、Kubernetes、Jenkins、Spring Cloud、Service mesh.他们是DevOps技术栈的典型代表,也可以说必不可少的支撑技术,我们来悉数一下这些神器们。Docker的出现可谓是极大的推动了DevOps的发展,让DevOps重新燃起新的青春。Docker最大的颠覆在于镜像的理念,将应用所需的依赖环境,全部隔离起来,让应用的部署插上了翅膀。可以说基于容器来构建服务栈的方式变得非常优雅,远远超越了自动化脚本的方式。Kubernetes代表了新一代云计算热潮的PaaS平台技术方案,可以简单的类比为OpenStack、CloudFoundry的替代方案(当然还是有很多不同之处的)。作为容器集群管理系统,为容器化的应用提供部署运行、资源调度、服务发现和动态伸缩等一系列功能,可以将容器编织成一个大大的云。Spring Cloud,这个名字起的可以说,非常契合时代发展的脉络!在很多场合,很多人眼里,Spring Cloud就是微服务!虽然这么理解有失偏颇,但他提供的众多特性,确实解决了微服务研发过程中的很多痛点,是微服务架构的集大成者。这是继Dubbo RPC框架以后的新秀,也迅速的深入人心,几乎成了业界写微服务代码的主要框架。Docker容器的出现,从另一个角度来讲,极大的促进了微服务的发展,每一个容器可以形象的打包为一个个的小盒子,而微服务就是装在小盒子里面的宝藏,每一次的服务调用,就像是在散发光芒。器技术的火爆,彻底的颠覆了PaaS平台的构建方式,企业进行数字化落地也有了更好的选择。尤其是弹性伸缩、自定义网络、环境隔离等特性,加上CI、CD过程可以结合Docker镜像和Compose编排,使得新一代PaaS平台脉络也更加清晰,应用从源码态到运行态,一条链路就可以完美跑下来。以下是可供参考的基于DevOps工具链的平台架构:有了上面的这些神器,一个基于DevOps理念的PaaS平台就基本落地了,但人类不止于这点小进步,在服务调用的层面不断开拓创新,提出了更优秀先进的提升方案,于是就有了Service Mesh。Service Mesh 又译作“服务网格”,作为服务间通信的基础设施层,是云原生应用的必要支撑,可以将它比作是应用间的TCP/IP,负责应用间的网络调用、限流、熔断和监控,可以将网络功能从代码中剥离出来。采用 Service Mesh, 你不用在服务代码中实现用于可靠通信的模式如断路、超时等,类似地,Service Mesh 也提供了服务发现、服务可见性等其他功能。以下是Service mesh的架构图:可以说Service Mesh经历了几个发展阶段,也代表了以应用为中心的网络通信进步:1.从最原始的主机之间直接使用网线相连;2.网络层的出现;3.集成到应用程序内部的控制流;4.分解到应用程序外部的控制流;5.应用程序的中集成服务发现和断路器;6.出现了专门用于服务发现和断路器的软件包/库,如 Twitter 的 Finagle 和 Facebook 的 Proxygen,这时候还是集成在应用程序内部;7.出现了专门用于服务发现和断路器的开源软件,如 Netflix OSS、Airbnb 的 synapse 和 nerve;8.最后作为微服务的中间层 service mesh 出现;可以看到,技术界发展到这个时期,针对DevOps落地这件事,实现工具已经很丰富了,可以说层出不穷,不断的刷新着我们的工具链。企业在数字化转型的过程中,也可以根据团队的实力,选择适合自己的工具。当然,真正的转型成功,是需要工具、规范、文化、技术、业务等全方位配合,匹配到企业的发展节拍,创造新的业务增长奇迹。

January 22, 2019 · 1 min · jiezi

当我们谈论 DevOps 时,我们在谈论什么?

本文作者:张海龙,CODING 创始人兼 CEO本文字数约 3700 字,阅读时间约 8 分钟。2018 年对许多人来说是艰难与变革的一年,势如破竹的发展势头似乎被打破,小微创新型企业生存艰难。“产业互联网”“企业数字化转型”等寻求从内破局的呼声也越来越高。有趣的是,类似的情况不是第一次出现。1999 年金融海啸来袭,经济下行周期内,大家都寄希望于当时先进的信息技术,希望能以此提升自身的管理水平,增强企业竞争力。导致当年 ERP 进入中国后迅速走红,令无数缺乏管理经验的中国企业心驰神往。而到了数字化转型的浪潮之年,这个风口上的词变成了 DevOps(/de’vps/)。大家纷纷开始讨论要不要采用 DevOps 、DevOps 到底有没有那么神奇。Google Trends 中 DevOps 历年的热度数据DevOps 到底是什么2018 年,我们走访了近百个分布在各行各业中的 IT 团队,意外的发现,大多数的 IT 团队寻求改革并非来源于部门内部的自我革新,而是来源于业务部门的服务压力。正如同当年企业寻找 ERP,今天的企业将目光投向了 DevOps。但是 DevOps 并非像 ERP 那样可以直接部署的东西,而是一种由主流互联网巨头们所总结出来的的研发管理理念,是 Google、Netflix 等大型互联网公司实现快速迭代的秘诀。 作为一家专注于研发 DevOps 工具链的公司创始人,我在接触客户的时候,发现一个很有趣的现象:所有人都想“做” DevOps 并期待其能为他们带来商业上的成功,却对 DevOps 的核心理念知之甚少。这很大一部分原因是市面上对 DevOps 有着各种各样的说法,导致大家概念的混淆。想要弄清楚 DevOps 到底是什么,必须先从它的本质说起。软件开发最高效的组织形式是“One Man Work”,只有一个人干活,写个小项目,从需求到开发,从测试到部署全部独立完成,非常高效。但随着业务的增长,项目开始逐渐变得庞大,变成团队,出现了分工,出现了产品经理、项目经理、开发、数据、测试、运维等等角色。这些角色间存在天然的工作目标上的矛盾。举个例子,对于运维来说,稳定压倒一切,新 Feature 越少越好。而对于研发来说,却希望能开发更多的功能。这种矛盾会导致大量的资源和时间的浪费。就像两匹马拉一辆车,如果马头向着的方向不一致,肯定是没法全速前进的。DevOps 的理念就是希望能打破这种屏障,让研发(Development)和运维(Operations)一体化,让团队从业务需求出发,向着同一个目标前进。字面意思上说 DevOps 是指“开发运维一体化”,即通过工具辅助开发完成运维的部分工作,减少成本。但深入理解了 DevOps 之后,你会发现 DevOps 其实是一种软件研发管理的思想,方法论,他追求的是一种没有隔阂的理想的研发协作的状态,可能涉及到的角色有开发、测试、产品、项目管理、运维等等。所以我们认为,为了帮助研发团队在保持质量的前提下提高交付效率的方法和方法论都隶属于 DevOps 的范畴。比如 Google 提出的 5 个 DevOps 原则,这套原则中必须依赖于工具辅助的部分只有后两点,更多的则是对于开发组织形式的内省:精简组织架构;愿意承担一部分试错带来的损失;分阶段地一小步一小步地进行转型;最大化地利用工具和自动化流程;对所有的过程和结果进行记录和分析。所以 DevOps 不是简单的开发软件化,而是企业的学习能力不断提升的结果,将企业改造成敏捷应对的学习型组织,运用新的工具,优化组织架构和流程,不断地进行自我革命和创新的方式。工具是辅助,而非基础。困难重重的 DevOps 落地在弄清楚了 DevOps 的宏观定义之后,我们再来观察一下 DevOps 目前在国内的实践现状。根据南京大学 «DevOps 中国•2018 年度调研» 的调研报告,目前设有 DevOps 实践团队的公司中,科技和互联网行业占比接近 70%。其他行业的从业者对 DevOps 的认知还存在一定的不足。这与我们的调研走访体验一致:大多数企业都愿意尝试运用 DevOps ,但是在实践 DevOps 中,普遍碰到了比较大的困难。主要是以下三个原因:对 DevOps 有不切实际的预期部分团队为了做 DevOps 而做 DevOps,并没有真正的从业务的角度出发来考虑。如前文所说,DevOps 不是银弹,高水平的研发团队在 DevOps 实践中将快速找到研发质量与业务增长的平衡点。但对于许多仍然在使用中心化的研发组织形式的团队来说,DevOps 的尝试无法立即获得肉眼可见的增长数据,思索与尝试带来的对团队的训练可能会是第一份收获。步子迈得太大新生代互联网公司诞生于 DevOps 理念已经相对成熟的年代,且互联网公司天生地将迭代速度作为追求目标之一,使得这些公司能够在发展的初期,就将 DevOps 的理念融入到公司的架构设计中。上图是 Netflix 的整个系统架构。如此复杂的系统架构同时还能每天迭代几十个版本,无法通过传统的研发管理模式来维护,只有通过实践 DevOps 的理念,来优化组织的分工、资源和能效,才能得以实现。在这样的组织里,已经不需要有人了解所有模块是做什么,每个人只需要对自己的模块负责。而很多企业,为了巩固和提高自己的市场竞争力,非常急于达成上述高效的状态,并且希望能一步到位。国内其实大部分团队都没到大规模实践 DevOps 的时间点,有些团队甚至连分支开发、并行开发的方式都没有。我给这类的企业建议是:不要想着一口气吃成个胖子,一步一步来,先理解 DevOps 的理念和对业务的实际意义,然后搭建一只小的 DevOps 团队来承接一项新业务,旧的业务仍然使用旧系统,双轨并行,等待小团队适应了 DevOps 的管理节奏之后再向其他团队进行推广。之前出过一篇关于 DevOps 的专题报告《四周年 · 专题报告:双速 IT》,也可以作为参考。Toolchain Crisis实践 DevOps 的原则中很重要的一点就是对工具的运用及依赖工具搭建合适企业的自动化流程。但是目前市面上缺乏成熟的 DevOps 工具链,各个服务商的细分工具层出不穷,企业为了搭建整套 DevOps 流程,需要研究几十种工具,并选取其中的 7-8 种进行落地实践。非常依赖于管理者的项目经验,没有 DevOps 经验的团队起步将会比较困难。以 CODING 为例。2018 年之前 CODING 产品仅有任务及代码管理模块。我们是这样进行工作的:产品经理在 CODING 上撰写文档创建任务,研发 Leader 将任务分配给开发,开发完成后提交代码,并创建 MR,我们在本地部署了 Jenkins 进行持续集成进行构建和测试,再由其他工程师进行人工评审,通过后并到发布分支,进行预发布,再通过持续集成进行构建,自建 Docker registry 进行构建物管理。构建出的 Docker 镜像在测试环境和预发布环境上依次进行自动化测试及人工测试,测试通过后,使用我们运维自己搭建的工具进行部署管理。目前 CODING 每天都进行产品迭代,可以快速响应用户需求并保证服务质量,但搭建这一整套的流程高度依赖于团队能力,门槛非常高。为了降低工具的成本和使用门槛,包括 CODING 在内的很多云服务厂商都在做打通全流程的 DevOps 工具链的尝试,希望可以做到让企业开箱即用,低成本的践行 DevOps 理念,不过目前产品仍处于迭代期,无法满足所有企业的需求。DevOps 是未来的趋势既然 DevOps 这么难,坑这么多,为什么还要做呢?因为这是企业未来的长期诉求。从大趋势上分析,未来所有企业都将是软件企业,制造软件、服务软件、构建于软件。比如全世界最大的出行公司 Uber,其实是一个软件公司,而非出租车公司。从企业自身诉求出发,中国的中大型企业已经逐步进入了创新驱动的阶段。无论是供给侧改革还是智能制造 2025 都要求企业修炼内功,提高效率促进创新。过去几年中在塑造前沿行业的 DevOps 理念将在 2019 年左右成为主流,成为企业能否在行业内脱颖而出的关键性因素。在 Statsia 2018 年的报告中,有超过 72% 的企业或多或少地开始践行 DevOps 的理念,其中完整采用 DevOps 的比例高达 17% ,而在 2017 年这个数字仅有 10%。真正能够实践 DevOps 的团队也会为自身的业务带来巨大的提升。根据 Puppt 的2017 DevOps State Report,DevOps 型团队将部署频率提高46倍,交付速度提高 440 倍。可见,在国际上来说,DevOps 已经处于企业爆发性需求的前夜。而在国内公司中,新兴企业的成功实践也在为中国企业的 DevOps 输送方法论与有经验的专家。字节跳动可以说是 DevOps 最佳践行者之一。在其创始人张一鸣看来:公司的业务越复杂,人越多,组织就越大。这导致信息失效、(下属)向上管理和业务变大。他把类似组织的负规模效应称为“自嗨”,这是他所不能接受的。故而字节跳动在组织架构上,总共只有 3 个核心部门:技术、Growth 和商业化,分别负责研发、推广和收入。今日头条、抖音、西瓜视频……字节跳动的每款 App 都基于这三个部门来发展。在项目开始时,公司会为每个项目设置虚拟项目组,由三个核心部门抽调人员组成,试水成功后直接推广。所有产品共用一条技术线,快速试错。针对 App 类产品的快速迭代的业务特性,字节跳动依据 DevOps 理念对组织架构进行调整和优化,从结构上保证了技术支持业务创新的能力。Why Now?DevOps 的理念和优势被说了很多年,但一直都只在少量公司有能力实践。软件的工程化历史还比较短暂,业务需求与技术理念都日新月异,前两年大量的团队还在为了研发新的业务疲于奔命,没有精力关注研发效能升级的问题。许多团队的研发管理还停留在靠微信喊话和 Excel 管理的阶段。而如今,在市场遇冷和企业数字化转型的契机下,更多的公司开始将目光放在企业内部的效率提升和研发成本的控制上。在 Netflix、Google 这样发展比较久的的巨型公司可以耗费大量的内部资源从底层服务开始从零搭建 DevOps 流程。而像字节跳动这样的新型公司可以如此快速实现敏捷,也得益于云服务的逐步成熟。尤其是在当前环境下,运维业务逐步多样化和复杂化,很多传统的运维技术和解决方案已经不能满足当前运维所需,越来越多的团队选择使用 Docker kubernetes 等技术提升运维能力。同时,云厂商的 SaaS、IaaS 和 PaaS 服务相对于传统的运维业务帮助企业节省大量硬件维护的成本和时间,让企业能专注于业务的发展与创新。结语孙子兵法有云,凡兵法韬略,在道不在术。面对日新月异的的市场,企业必须逼迫自己不断的进行革新来应对市场变化。就像马化腾在互联网大会上提到的,现在互联网已经发展到了深水区,甚至是无人区。只有不断的迭代,迅速反应,才能应对未来的变化,而这也正是 DevOps 所强调的。点击立即体验一站式 DevOps 工具链。 ...

January 17, 2019 · 2 min · jiezi

Jenkins: 创建第一个 Pipeline

流水线视图可以很直观地看到每一步执行的时间和进度,方便追踪部署过程中的每一个环节。搭建 jenkins 参考 上一篇文章工作流本文目的是搭建一个简单的 pipeline,当 git 仓库有提交时,builder server 进行构建和测试,完成之后 deploy server 进行部署。本地 -> SCM: 提交代码SCM -> Build Server: 触发 jenkins 任务Build Server: 启动 pipelineBuild Server -> Deploy Server: 部署服务SCM Source Code Management,如 githubBuild Server jenkins 所在机器,负责构建Deploy Server 线上服务所在机器新建 Task首先创建一个 Task,然后选择流水线模板配置Pipeline在这里可以配置 pipeline 的脚本,definition 可以选择 Pipeline script 或 Pipeline script from SCM。选择前者后,jenkins 脚本需要在下方填写,当任务启动后,jenkins 会执行这里配好的命令;选择后者后,任务启动后,jenkins 会去执行 SCM 仓库下配置的 script path 下的脚本。一句话说,两者区别在于脚本是写在 jenkins 配置里,还是写在你的代码仓库里。所以修改脚本的时候在 jenkins 里配就行,方便调试,没问题之后使用 SCM 管理更好。编写 pipeline script以 node 服务举例,部署过程分为四步:Build: 在 build server 上 npm installTest: 在 build server 上进行测试Deploy: 在 deploy server 上部署这个脚本如下,需要将 [user] 和 [ip] 替换成 deploy server 的登录用户和 ip:pipeline { agent any stages { stage(‘Build’) { steps { sh “npm install” } } stage(‘Test’) { steps { sh “npm test” } } stage(‘Deploy’) { steps { sh """ ssh -o stricthostkeychecking=no [user]@[ip] " source /etc/profile cd /root/projects/my-api-server git pull npm install pm2 reload wool-digger-api " """ } } }}当然这是一个很粗糙的构建方式,我们下次使用 docker 进行改造。主要概念有agent 指示 Jenkins 分配一个执行器和工作空间来执行下面的Pipelinestage 表示这个 Pipeline 的一个执行阶段,对应流水线中各个环节steps 表示在这个 stage 中每一个步骤sh 命令用来执行一条 shell 语句。 这个配置文件被执行后:首先 jenkins 会在工作区(一般来说在 ~/.jenkins/workspace/)下拉取配置仓库指定分支的代码pull 成功后进行 npm install(Build)build 成功之后进行 npm test(Test)test 成功后远程执行一段脚本,即登录 deploy server 并 cd 到服务目录,然后进行服务的更新重启操作。npm/pm2 not found 的问题注意上面 Deploy 中有一行 source /etc/profile,这是 login shell 和 no-login shell 的不同。如果使用 ssh 登录再执行命令和脚本,用户会获得 login shell,shell 首先会加载 /etc/profile 文件,然后依次尝试 /.bash_profile、/.bash_login 和 ~/.profile。而如果直接使用 ssh 远程执行命令和脚本,如上面的 ssh -o,它不会去执行 /etc/profile 文件,而会去用户的 HOME 目录检查 .bashrc 并加载。所以在 /etc/profile 中设置的 path 不会生效。如果 nvm 在此文件中,那么 node、npm、pm2 等等就找不到了。解决方法可以在 shell 脚本中先手动加载配置文件。Build Triggers在这里可以配置 pipeline 触发的类型Github hook trigger fro GITScm polling启动该项后可以通过 GitHub 的 webhook 来触发,参考 Github Plugin 文档这里说一下最简单的配置,即手动配置。在 Jenkins -> 系统管理 -> 系统设置中,可以找到 Git 配置,点击右边的问号按钮,可以看到默认的 jenkins hook 地址。一般来说默认都是 $JENKINS_BASE_URL/github-webhook/。拿到这个地址后,添加到 github 的 webhook 中。注意 这个地址是没有项目信息的,因为 github 调用这个 hook 地址时,会把仓库信息传过去,所以就只剩在 jenkins 中把 pipeline 和这个 git 仓库关联起来。这需要在 pipeline 中选择 Pipeline script from SCM 并填写 git 地址。轮询 SCM启动该项后,jenkins 将定时对 SCM 仓库进行轮询,当仓库有新提交时,会自动触发 pipeline。Schedule 填写规则与 crond 类似,如 H/5 * * * * 代表每 5 分钟查询一次。详细规则可以点击右边的问号。启动点击 立即构建,或去仓库提交一个 commit(如果配置了 github hook),或提交一个 commit 并等待(如果配置了轮询 SCM),然后就能看到我们的第一个 pipeline 启动了! ...

January 11, 2019 · 2 min · jiezi

基于开发者中心DevOps流水线快速上云

导读:“DevOps”这个词现在很流行,它具体指的是什么呢?本文介绍了DevOps和开发者中心DevOps流水线,图文并茂,解答您的疑惑。那么DevOps是什么?开发者中心<DevOps流水线>是什么?或许在这里能解决你的一些疑惑……DevOps是什么?“DevOps”是现在非常流行的一个词,它代表的是什么呢?是一种理念?还是一种工具?还是一种技术?其实觉得迷茫的绝对不止您一个人。词意表述为“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通合作的文化、运动或实践。其实可以理解为通过自动化“软件交付”和“架构变更”的流程,来使得构建、测试、发布软件能够更加地敏捷、频繁和可靠。那么开发者中心<DevOps流水线>是什么呢?可以理解为一种通过自动化“软件交付”的方案及实现,那么我们先来了解下整体架构。开发者中心<DevOps流水线>部分流程总览开发者中心DevOps流水线运行效果流水线基于Git获取代码源解惑支持两种方式:ssh、 httpssh方式使用Git -i指定私钥文件。(借助一个shell脚本来实现)脚本源码:http方式使用git clone 命令直接下载,具体如下:git clone http://${Password}:${UserName}@github.com/yangxyd/xxx.git流水线配置中心解惑使用配置中心功能:把需要修改的配置文件提取到配置中心,在容器启动前会从配置中心拉取相关配置到指定的目录下。使用说明如下:配置后,通过容器控制台即可查看替换后的文件内容。

January 11, 2019 · 1 min · jiezi

Centos 7 安装 java、搭建 Jenkins

本文在 centos 版本 7.4.1708 与 7.6.1810 中验证查看 centos 版本# lsb_release命令用来查看当前系统的发行版信息lsb_release -a# 或查看 centos-release 文件cat /etc/centos-release安装 java 8本地下载,然后传到服务器访问 oracle jdk 下载地址,同意协议后点击下载地址下载完成后,登录服务器,新建 /usr/java 目录,然后在本地 scp 过去# 服务器mkdir /usr/java# 本机scp [jdk所在目录]/jdk-8u192-linux-x64.tar.gz [user]@[ip]:/usr/java/直接在服务器上下载因为下载 jdk 需要同意协议,所以不能用 wget 直接下载,需要添加 header。下面命令适用于下载上图中 jdk 版本。需要根据版本替换下面的 download 页面和 jdk 下载地址。参考 stackoverflow上图版本地址为: https://download.oracle.com/o...mkdir /usr/javacd /usr/javawget –no-cookies –no-check-certificate –header “Cookie: gpw_e24=http%3a%2F%2Fwww.oracle.com%2Ftechnetwork%2Fjava%2Fjavase%2Fdownloads%2Fjdk8-downloads-2133151.html; oraclelicense=accept-securebackup-cookie;” “https://download.oracle.com/otn-pub/java/jdk/8u192-b12/750e1c8617c5452694857ad95c3ee230/jdk-8u192-linux-x64.tar.gz"安装1. 解压cd /usr/javatar zxvf jdk-8u192-linux-x64.tar.gz2. 配置环境变量vim /etc/profile添加以下内容,需要把内容中的 jdk1.8.0_192 替换为自己的安装版本名JAVA_HOME=/usr/java/jdk1.8.0_192JRE_HOME=/usr/java/jdk1.8.0_192/jreCLASS_PATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/libPATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/binexport JAVA_HOME JRE_HOME CLASS_PATH PATH重新生效环境配置source /etc/profile测试 java 是否安装成功java -version安装 jenkins可以直接参考 官方教程下载最新稳定版:wget http://mirrors.jenkins.io/war-stable/latest/jenkins.war启动java -jar jenkins.war –httpPort=8080.然后访问服务器 8080 端口,按界面操作即可。第一次访问需要输入密码,界面上会有提示,一般存放在 ~/.jenkins/secrets/initialAdminPassword注意这个过程可能比较长,所以后台运行 jenkins 会比较好nohup java -jar jenkins.war –httpPort=8088 >/root/jenkins/logs/out.log & ...

January 10, 2019 · 1 min · jiezi

基于kubernetes+docker+jenkins的DevOps实践

基于kubernetes+docker+jenkins的DevOps实践之前自己的项目开发就搭了个cicd的环境,那时候是在本就小的可怜的服务器上搭了一套 jenkins + docker registry + docker 见之前的笔记 docker学习下面 总的差不多这样: 之后对kubernetes的接触后,就在之前的基础上加入kubernetes,其实也就是在服务器拉取镜像docker run的时候改变为通知kubernetes的apiServer对提前配置好的项目配置文件xx.yaml进行更新kubectl appply -f xx.yaml,它会对配置里的镜像拉取在多个pod里运行,当然还需要对应的service,如果需要暴露给外部还可以添个ingress。 一个小服务器加本地一个闲置从机撑进去这么多东西很显然爆了,于是把jenkins , docker registry拆出来,用上了公共的ali云服务CodePipeline,容器镜像服务。 这里记录一下。docker搭建ubuntu安装docker官方教程kubernetes搭建之前写的kubernetes学习下面有使用ali云CodePipeline替代jenkins创建任务配置->项目名称:最好为github上代码的demo项目名称,这里以bootshiro为例配置->源码管理->Git:URL为github上的项目clone url,下面默认master分支配置->构建触发器->填写代码分支:eg:master 点击生成触发器地址留下备用(github webhook配置会用到)配置->构建项目类型可选maven项目 node python等(按自己需求改编译打包册测试脚本)eg: maven项目 编译打包: mvn package -B -DskipTests 用例测试: mvn test配置->镜像构建和发布: 这里使用ali云的免费docker镜像仓库镜像版本号最好用jenkins环境变量标记,registry地址证书等就是自己开通的ali云registry地址和账户,docker路径是相对于当前代码仓库的Dcokerfile文件路径,用这个Dockefile文件来生成镜像。eg: bootshiro的Dockefile#VERSION 1.1.0#基础镜像为openjdk:12-alpineFROM openjdk:12-alpine#签名MAINTAINER tomsun28 “tomsun28@outlook.com"RUN rm -rf /opt/running/bootshiro*ADD ./target/bootshiro.jar /opt/running/bootshiro.jarEXPOSE 8080WORKDIR /opt/running/CMD [“java”, “-jar”, “bootshiro.jar”,”–spring.profiles.active=prod"]配置->部署Kubernetes(新): 这里配置对搭建好的k8s环境的apiServer连接,之后好使用apiServer对kubernetes操作认证方式:选择认证证书API服务器地址:为apiServer通讯地址证书:使用docker授权模式,客户端Key(key.pem)和客户端证书(cert.pem)在/etc/kubernetes/admin.conf,服务端CA证书(ca.pem)在/etc/kubernetes/pki/ca.crt部署配置文件:为k8s部署这个项目的配置文件位置,也是以当前项目代码仓库为相对路径,eg :bootshiro.yaml# ———————-bootshiro——————— ## ——bootshiro deployment—— #kind: DeploymentapiVersion: apps/v1beta2metadata: name: bootshiro-deployment labels: app: bootshirospec: replicas: 1 selector: matchLabels: app: bootshiro template: metadata: labels: app: bootshiro spec: containers: - name: nginx image: registry.cn-hangzhou.aliyuncs.com/tomsun28/bootshiro:${BUILD_NUMBER} ports: - containerPort: 8080—# ——-nginx-service——— #apiVersion: v1kind: Servicemetadata: name: bootshiro-servicespec:# type: NodePort ports: - name: server port: 8080 targetPort: 8080 selector: app: bootshiro# !———————-bootshiro——————— #这里配置部署文件创建了一个pod实例,创建了与其想对应的service在集群内部暴露服务。如果部署的应用需要对集群外提供服务,这里还要创建对应的暴露服务的方式,如ingress, nodeport等-到此cicd就差不多了,我们开发代码push到github仓库上,跟着DevOps流程走,最后项目就会自己运行到kubernetes集群里面了,pod挂了或者从机挂了,k8s会重新启保证设定数量的pod。使用ingress对集群外暴露服务这里使用的是traefik-ingress,在kubernetes中部署traefik有官方部署手册,基本按着走一遍就能部署上去了。 整合部署的traefik.yaml:—kind: ClusterRoleapiVersion: rbac.authorization.k8s.io/v1beta1metadata: name: traefik-ingress-controllerrules: - apiGroups: - "" resources: - services - endpoints - secrets verbs: - get - list - watch - apiGroups: - extensions resources: - ingresses verbs: - get - list - watch—kind: ClusterRoleBindingapiVersion: rbac.authorization.k8s.io/v1beta1metadata: name: traefik-ingress-controllerroleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: traefik-ingress-controllersubjects:- kind: ServiceAccount name: traefik-ingress-controller namespace: kube-system—apiVersion: v1kind: ServiceAccountmetadata: name: traefik-ingress-controller namespace: kube-system—kind: DaemonSetapiVersion: extensions/v1beta1metadata: name: traefik-ingress-controller namespace: kube-system labels: k8s-app: traefik-ingress-lbspec: template: metadata: labels: k8s-app: traefik-ingress-lb name: traefik-ingress-lb spec: serviceAccountName: traefik-ingress-controller terminationGracePeriodSeconds: 60 containers: - image: traefik name: traefik-ingress-lb ports: - name: http containerPort: 80 hostPort: 80 - name: admin containerPort: 8080 securityContext: capabilities: drop: - ALL add: - NET_BIND_SERVICE args: - –api - –kubernetes - –logLevel=INFO—apiVersion: v1kind: Servicemetadata: name: traefik-web-ui namespace: kube-systemspec: selector: k8s-app: traefik-ingress-lb ports: - name: web port: 80 targetPort: 8080—apiVersion: extensions/v1beta1kind: Ingressmetadata: name: traefik-web-ui namespace: kube-system annotations: kubernetes.io/ingress.class: traefik traefik.frontend.rule.type: PathPrefixStripspec: rules: - host: tom.usthe.com http: paths: - path: /ingress backend: serviceName: traefik-web-ui servicePort: web使用traefik来暴露service:apiVersion: extensions/v1beta1kind: Ingressmetadata: name: chess namespace: default annotations: kubernetes.io/ingress.class: traefik traefik.frontend.rule.type: PathPrefixStripspec: rules: - host: tom.usthe.com http: paths: - path: /usthe backend: serviceName: usthe-service servicePort: http - path: /nginx backend: serviceName: nginx servicePort: http转载请注明 from tomsun28 ...

January 4, 2019 · 2 min · jiezi

Jenkins,我都不用手动配置

Jenkins 非常灵活,如今已成为实现 CI/CD 的事实标准,同时拥有一个活跃的社区来维护几乎所有工具和用例的插件。但是灵活也是要付出代价的:除了 Jenkins 核心之外,许多插件需要一些系统级别的设置才能正常工作。在某些情况下,“Jenkins 管理员”是一个全职职位。Jenkins 管理员在负责维护基础设施的同时,还要为一个巨大的 Jenkins master 提供数百个已安装的插件和数千个托管作业。维护最新的插件版本是一项挑战,故障转移(failover)也会是一场噩梦。这就像几年前系统管理员必须要为每个服务管理特定的机器一样。在 2018 年,通过使用基础架构自动化工具和虚拟化,一切都可以作为代码进行管理。需要一个新的应用服务器作为你的应用的暂存环境吗?那你只需要部署一个 Docker 容器。基础设施缺少资源吗?那就在你喜欢的云服务上分配更多资源来使用 Terraform。在这种情况下,Jenkins 管理员的角色怎么样?他们是否还要花费数小时来点击网页表单上的复选框?也许他们已经采用了一些自动化、依赖于 Groovy 脚本或一些自己写的 XML 模板。今年早些时候我们发布了第一个 alpha 版本的 “Jenkins Configuration-as-Code” (JCasC),它是一种基于 YAML 配置文件和自动模型发现的 Jenkins 配置管理新方法。Jenkins 已经升级为 Jenkins 顶级项目。 同时,对应的 Jenkins 增强提案已经被接受。JCasC 能为 Jenkins 管理员做些什么?JCasC 允许我们在启动时或通过 web UI 按需在 Jenkins master 上应用一组 YAML 文件。与 Jenkins 用于实际储存配置的详细 XML 文件相比,这些配置文件非常简洁易读。这些文件还有用户友好的命名约定,使管理员能够轻松地配置所有 Jenkins 组件。下面是一个例子:jenkins: systemMessage: “Jenkins managed by Configuration as Code"securityRealm: ldap: configurations:server: ldap.acme.comrootDN: dc=acme,dc=frmanagerPasswordSecret: ${LDAP_PASSWORD}cache: size: 100ttl: 10userIdStrategy: CaseInsensitivegroupIdStrategy: CaseSensitive如你所见,不需要很长的解释你就可以理解这个 YAML 文件如何配置你的 Jenkins master。优点JCasC 最直接的好处就是可重复性。管理员现在可以使用完全相同的配置通过一个简单的设置来引导新的 Jenkins master。这允许他们创建一个测试实例并检查升级插件在沙盒环境中的影响。这也使他们对故障转移和灾难恢复方案更有信心。当管理员开始在源代码管理中管理 Jenkins 的 YAML 配置文件时,他们也会感受到类似使用 Terraform 一样的好处。这样做可以让他们对 Jenkins master 配置进行审核,使其具有可逆性。他们可以建立一个合理的配置改变运行 Jenkins 实例的工作流,并确保在实际应用任何修改到他们的 Jenkins master 之前配置是健康的。最后也是最重要的是,由于能够快速设置 Jenkins master 并且能用一组共享的 YAML 配置文件控制它们,管理员现在可以给每个团队提供一个 Jenkins 实例,并且在安装插件有更高的灵活性。只要他们还在使用 Jenkinsfiles 管理构建定义(build definition),master 就会或多或少地成为你们团队的短期的基础架构。使用 Configuration-as-Code,我们可以不再像对待宠物那样对待我们的 Jenkins master,而像对待牛那样管理它们,你也可以毫不费力地替换它们。欢迎来到 “as-code” 的世界。他们仍然很可爱,对吧?Ok, 那么之后呢?你可以在项目中阅读有关 Jenkins Configuration-as-Code 插件的更多信息。与社区和贡献者们交流,加入我们的 gitter 频道,或者来我们的 Jenkins World 一起讨论 JCasC 项目及其未来!另外,不要错过 Configuration-as-Code 系列的下一篇文章,我们将会了解 JCasC 如何处理密码及其他凭据等敏感数据。 ...

December 25, 2018 · 1 min · jiezi

这样来轻松自定义 Jenkins 发行版!

今天,我打算给 Jenkins 管理员和开发者们介绍一个新的工具 Custom WAR Packager。该工具可以打包 Jenkins 的自定义 WAR 发行版、 Docker 镜像以及 Jenkinsfile Runner 包。它可以打包 Jenkins、插件以及配置为开箱即用的发行版。 Custom WAR Packager 是我们曾在一篇博客– A Cloud Native Jenkins –中介绍过的无状态 Jenkins master 工具链的一部分。这个工具链已在 Jenkins X 中被用于构建 serverless 镜像。在这篇文章中,我将会介绍几种 Custom WAR Packager 常见的使用场景。历史正如 Jenkins 本身一样,Custom WAR Packager 开始于一个小的开发工具。在 Jenkins 内运行集成测试很长时间以来都是一个难题。对此,我们有三个主要的框架: Jenkins Test Harness, Acceptance Test Harness, 和 Plugin Compatibility Tester。这些框架都需要一个 Jenkins WAR 文件来运行测试。但是,假如你想在类似 AWS 一样的自定义环境中进行 Jenkins 测试呢? 或者,你希望基于 Pluggable Storage 的环境也可以复用 Jenkins 流水线测试,来确保没有回归缺陷,又如何呢?这并不是没有意义的问题。云原生 Jenkins、Jenkins Evergreen 以及 Jenkins X, 这些 Jenkins 项目中正在进行的主要活动,都需要大量的集成测试来实现持续交付流程。为了复用已有的框架,我们需要打包一个自带配置的 WAR 文件,以便可以在现有的框架中运行集成测试。这正是 Custom WAR Packager 于 2018年4月 创建的原因。到 2018年9月,它相继支持了 Docker 镜像和 Jenkinsfile Runner,后者由 Kohsuke Kawaguchi 创建并由 Nicolas de Loof 完善。揭开面纱Custom WAR Packager 是一个工具,可以作为命令行、Maven 插件或者 Docker 程序包来用。该工具可以从用户处获取配置,并根据用户请求进行打包。所有内容都由一个 YAML 配置文件管理:该工具支持多种输入类型。插件列表可以来自 YAML,pom.xml 或一个 BOM(jep:309[] 提出的 Bill of Materials) 文件。Custom WAR Packager 不仅支持发布版本,还可以构建部署到 增量仓库 (Jenkins 核心及插件的 CD 流程 - jep:305[]),甚至直接从 Git 或指定目录中构建。它允许从任何来源构建包,而无需等待官方版本。由于插件已经通过 Commit ID 缓存到了本地的 Maven 仓库中,因此其构建过程也非常快。自定义Custom WAR Packager 还支持下面的配置选项:Jenkins 配置即代码 的 YAMl 文件Groovy Hooks (例如:预配置的 init hooks)系统属性WAR打包每当这个库构建时会打包出来一个 WAR 文件。通常,Custom WAR Packager 会根据下面对 Jenkins 核心和 JCasC 的配置把所有内容打包的一个 WAR 文件中。样例配置:bundle: groupId: “io.jenkins.tools.war-packager.demo"artifactId: “blogpost-demo"vendor: “Jenkins project"description: “Just a demo for the blogpost"war: groupId: “org.jenkins-ci.main"artifactId: “jenkins-war"source: version: 2.138.2plugins:groupId: “io.jenkins"artifactId: “configuration-as-code"source: # Common releaseversion: 1.0-rc2groupId: “io.jenkins"artifactId: “artifact-manager-s3"source: # Incrementalsversion: 1.2-rc259.c9d60bf2f88cgroupId: “org.jenkins-ci.plugins.workflow"artifactId: “workflow-job"source: # Gitgit: https://github.com/jglick/wor...commit: 18d78f305a4526af9cdf3a7b68eb9caf97c7cfbcetc.systemProperties: jenkins.model.Jenkins.slaveAgentPort: “9000"jenkins.model.Jenkins.slaveAgentPortEnforce: “true"groovyHooks:type: “init"id: “initScripts"source: dir: src/main/groovycasc🆔 “jcasc"source: dir: casc.ymlDocker 打包为了打包 Docker,Custom WAR Packager 使用官方的 Docker 镜像 jenkins/jenkins 或同样格式的其他镜像。在构建期间,WAR 文件会被该工具构建的文件所替换。这也就意味着镜像的 所有 特色在该自定义构建中都可用: plugins.txt, Java 选项, Groovy hooks 等等。…## WAR configuration from above## …buildSettings: docker: build: trueBase imagebase: “jenkins/jenkins:2.138.2"Tag to set for the produced imagetag: “jenkins/custom-war-packager-casc-demo"例如:示例 展示了打包带有将构建日志存储到 Elasticsearch 的 Docker 镜像。 尽管这些已经作为了 jep:207 和 jep:210 的一部分,你还是可以查看这个示例,了解该 Docker 镜像是如何配置、连接到 Elasicsearch、然后启动外部的日志存储,而不需要改变日志的界面。一个 Docker Compose 文件对于运行整个集群是必要的。Jenkinsfile Runner 打包这可能是 Jenkinsfile Runner 最微妙的模式。三月,在开发者列表中 宣布了一个新的项目 Jenkinsfile Runner。大体的思路是,支持在单一 master 上只运行一次并打印输出到控制台的 Jenkins 流水线。 Jenkinsfile Runner 作为命令或一个 Docker 镜像来运行。虽然只推荐 Docker 的形式,但是 Custom WAR Packager 都能够生成。使用 Jenkinsfile Runner ,你可以像下面的方式来运行流水线:docker run –rm -v $PWD/Jenkinsfile:/workspace/Jenkinsfile acmeorg/jenkinsfile-runner当我们开始在云原生特别兴趣小组(Cloud Native SIG)中研究无状态(也就是“一次”)时,有一个想法就是使用 Custom WAR Packager 和其他已有的工具(Jenkinsfile Runner, Jenkins Configuration as Code 等)来实现。也许只是替换 Jenkinsfile Runner 中的 Jenkins 核心的 JAR 以及插件,但这还不够。为了高效,Jenkinsfile Runner 镜像应该启动得 很快。在构建流程实现中,我们使用了 Jenkins 和 Jenkinsfile Runner 一些实验性的选项,包括:类加载预缓存、插件解压等等。有了这些后,Jenkins 使用 configuration-as-code 和几十个插件可以在几秒钟内启动。那么,如何构建自定义 Jenkinsfile Runner 镜像呢?尽管目前还没有发布,但这不会影响我们继续实现上文提到的内容。…## WAR Configuration from above##…buildSettings: jenkinsfileRunner: source: groupId: “io.jenkins"artifactId: “jenkinsfile-runner"build: noCache: truesource: git: https://github.com/jenkinsci/j … r.gitcommit: 8ff9b1e9a097e629c5fbffca9a3d69750097ecc4docker: base: “jenkins/jenkins:2.138.2"tag: “onenashev/cwp-jenkinsfile-runner-demo"build: true你可以从 这里 找到用 Custom WAR Packager 打包 Jenkinsfile Runner 的例子。更多信息还有很多其他的特色没有在本文中提到。例如:它还可以修改 Maven 构建配置或增加、替换 Jenkins 核心中的库(例如:Remoting)。请查看 Custom WAR Packager 文档 获取更多信息和示例。如果你有兴趣对这个库做贡献,请创建 PR 并抄送 @oleg-nenashev 和 Raul Arabaolaza。(编者注:Raul Arabaolaza 是第二位正在研究 Jenkins 自动化测试流程的维护者。)下一步还有很多值得改进的地方可以使这个工具更加高效:增加对插件依赖传递的检查以便在构建过程中发现冲突允许在 YAML 配置文件中设置各种系统属性和 Java 选项改进 Jenkinsfile Runner 的性能集成到 Jenkins 集成测试流程中,(查看 Jenkins 流水线库中的 essentialsTest())即使目前,该工具已经能够让 Jenkins 用户构建他们自己的发行版,从理论上来讲,仍有许多其他任务可以在 Custom WAR Packager 中实现。 ...

December 20, 2018 · 2 min · jiezi

灵雀云K8s培训走进『招商银行』总部

12月13日-14日,灵雀云企业定制k8s培训在深圳招商银行总部圆满结束。来自招行总部信息技术部PaaS平台团队的二十余位核心开发、运维工程师,在两天的培训时间里,全面梳理了K8s 从基础到高阶的理论知识体系,并在灵雀云官方认证讲师的帮助下,对K8s环境搭建部署和重点实验进行了全方位的实操演练。如今,云原生技术规模化应用于企业,不仅需要在技术层面有所突破,同时也需要将团队能力、组织架构等与云原生技术进行适配,形成合力。作为招商银行PaaS平台的产品和服务提供方,灵雀云不仅帮助招商银行实现了全容器化部署及构建PaaS平台,同时还将通过培训、咨询等一系列手段,协助招行打造掌握全新的云原生技术,更具有战斗力的技术队伍。灵雀云K8s培训中强调理论、实践、工具落地相结合。每个知识点讲解后不仅进行相应的实操演练,还将植入灵雀云自身在容器服务领域的丰富经验和案例,帮助学员进一步加深对K8s的理解及知识点的灵活应用。本次K8s培训的落地,提升了招行技术人员对云原生技术的掌控,加速了企业与云原生的融合,受到了企业和学员的广泛好评。灵雀云是 Linux Foundation /CNCF 官方认证培训合作伙伴/服务提供商。获准在全球范围内向个人和企业提供Linux基金会官方授权的认证的云原生系列培训课程,目前将主要面向中国企业和个人用户客户提供CNCF推出的标准化CKA ( Certified Kubernetes Administrator)认证考试培训课程,以及各阶段K8S理论基础+实操培训定制课程。同时,灵雀云还与全球领先的国际ICT认证组织 EXIN 达成合作,成为 EXIN DevOps认证培训合作伙伴。不久之后,灵雀云还将推出微服务的培训课程。作为国内领先的容器PaaS服务商,灵雀云致力于帮助企业在数字化转型的过程中,提供完善的PaaS解决方案和优质的全栈服务。未来,灵雀云将为更多企业IT人员建立云原生知识框架以及实操方法,帮助个人从容应对企业数字化转型过程中的问题和挑战,加速企业与云原生技术的融合。

December 20, 2018 · 1 min · jiezi

K8s、DevOps & 微服务三驾马车,带您走上云原生转型之路

今天很荣幸能在这里跟大家一起分享下灵雀云在金融行业的云原生解决方案。CNCF的云原生核心理念是快速交付业务价值,而云原生时代,主要由三驾马车驱动:容器、DevOps和微服务。在容器领域,几年前容器兴起时,我们准确地判断出这是未来可以改变软件交付模式的方向,所以灵雀云坚定地走在容器领域前沿,并很早就走上了Kubernetes路线;在DevOps领域,敏捷开发的概念十几年前开始兴起,但是到现在实际落地特别好的案例不多,所以后来出现了DevOps的概念,更侧重于工程实践;微服务也差不多同时期兴起。为什么CNCF提出云原生的概念得到了业内的一致认可?因为容器、DevOps、微服务这三者就是一个铁三角,企业要想实现长远目标,打造良好完善的IT体系规划,就需要不断参考云原生的理念去实践。云原生DevOps起点企业如何定义自己在云原生的阶段和位置?主要看以下几个方面:研发实力:包括自有和外包人员在内,研发团队规模如何?是不是做了微服务拆分,或者团队本身是否具备这样的技术能力?DevOps工具链用到多少?团队文化:有的研发团队很积极向上,愿意接受新技术和开源技术,他们接触和使用的本身就是云原生化的工具,这样的团队就很适合做云原生。这是落地云原生最好的切入点,我们建议可以让精英团队优先去做,然后再带动其他团队。业务场景:考虑业务变更是否频繁,是否有大并发场景,稳态业务是否多于敏态业务?我们有个客户有100多个项目,变更相对频繁,并发不大,这类客户就比较适合建设标准化的DevOps体系。云原生DevOps天梯云原生实际落地,我们建议可以从容器切入。以前企业也有直接落地DevOps的情况,但可能效果没有那么好,因为对于团队来讲,短期看不到实际的效果,团队会觉得用处不大,继而失去信心,而团队的士气是决定DevOps成败的关键因素之一。DevOps链条很长,一个月之内很难达到一定效果,我们一般建议,团队做DevOps要拿出一年的周期来规划,这个周期对很多企业来说可能比较长,这也是我们为什么建议以容器为切入点来做的原因。容器迁移,比如在两周内将单体应用、web应用容器化会相对轻松很多,对团队来讲是很有利于提升士气的,况且可以在容器迁移的过程中,穿插着顺带把DevOps的核心流水线做了,可以让团队平滑地开始DevOps实践。当然了,客户的情况不同,也决定了路径不同。比如作为试点,团队可以先容器上云,然后做DevOps,再做微服务化。也有的企业一开始已经有了微服务框架,而且架构合理,缺的是容器化和DevOps体系建设、流程梳理。针对这样的客户,灵雀云除了提供容器云,还会基于容器云提供DevOps工具链和咨询服务。我们不会仅限于工具链,还要把工具链的数据打通以及整合。当团队级的DevOps试点达到预期效果后,可以扩大到部门级。我们接触的客户目前在第一、第二阶段的居多,尤其是第二阶段。在第二阶段,也不是每个客户都做了微服务,但是能看到一些正在做试点的客户,这里需要把握一个节奏。第三阶段,是上云原生。理论上,容器云、DevOps和微服务化都做的有一定基础,并且在整个公司50%以上的研发部门铺开应用,才可以算作正式进入云原生阶段。云原生DevOps落地路径在实际落地时,客户也知道云原生是个好东西。但它是长期的,到底应该怎么落地呢?DevOps落地时要分层次来看:组织文化DevOps化:需要考虑团队的文化、公司的文化,指定标准流程,输出文档标准。它不一定需要调整组织架构,我们可以组成虚拟团队,把最精英的一拨人组织起来,组成类似专家团队去做DevOps的探讨和落地。DevOps活动全局化:活动偏向日常活动,交付协作、技术支撑、度量改进等等都需要组织沟通交流,需要各种会议的讨论。细分领域自动化:工具这层,DevOps工具链把每一层做细分,一步步做。云原生落地要勇于走出第一步。第一个应用容器化,快速得到效果,团队也会对这种效率感到兴奋和新奇感:用了行业内顶尖的技术,我的应用已经容器化了。比如灵雀云的一个客户,我们首先帮助他们做了容器的迁移,然后找准一个精英团队去做DevOps,作为公司内部未来能力输出的团队。每家公司里一定有这么一拨志同道合的人,希望为IT的变革付出努力,同时公司也要给他们一些鼓励。第三,打造初始工具链。不一定很完美,比如一开始把持续集成、持续交付打通,自动化测试都可以先不做,然后慢慢地去完善。单体应用上容器之后,下一步就要考虑服务分层,最终目标是要微服务化。但每家企业情况不同,有的可以一步到位全部微服务化,中间过程全部省掉;有的稳态应用比较传统,很长时间内不会变,我们也建议暂时不要动,先不要着急做核心应用的微服务化。灵雀云建议,先做边缘应用系统的微服务化,或者单体直接应用上云。这也会涉及到企业基础架构的考量,基础架构部门要去探讨怎么定微服务框架,如何做选择和取舍。云原生DevOps实践找到跨职能的精英团队,把云原生落地当成项目来做,成立一支虚拟团队,这个团队是专家职能还是业务职能,可以在做的过程中详细讨论。最终我们希望DevOps专家组能成为能力输出的源泉。灵雀云会帮助客户成立DevOps专家组,实践敏捷活动和DevOps工具链一整套的解决方案。同时,穿插云原生理念、DevOps工具链、容器化和微服务化。我们的目标是帮助团队形成敏捷意识,给客户打造一支敏捷团队,未来可以带领公司大大小小的团队去做敏捷开发的项目,从而给客户带来比较长远的价值。关于工具链,我们的最终目标是将所有工具链都打通,从需求管理到开发、测试、上线、运维、容灾等等DevOps所涉及的工具链都在我们考虑范围内。灵雀云会考虑用行业内开源的通用的工具来做,也会对接客户自定义的工具链,最终让客户对云原生工具链有很好的把控。最后,用一句话来结束今天的演讲,这也是来自一位客户的原话:只有技术的进步,才能更好地赋能业务的发展!谢谢大家!

December 19, 2018 · 1 min · jiezi

DevOps工程师到底做些什么?

我们之前已经听到很多谈论DevOps和DevOps世界的最新趋势的事情,但是就DevOps工程师本身,到底干些什么呢?在最纯粹的存在形式上来说,DevOps工程师是为了加快开发和运营团队之间的交付效率而存在的桥梁。DevOps工程师在软件生命周期中能带来什么?在传统的交付周期中,软件开发人员会在经年累月的编写代码后,将软件交给QA团队进行测试,然后将最终版本交给运营团队部署。这三个阶段,即开发,测试和部署之间是缺乏协作的。开发编写的代码最终并交给运维团队,然后运维团队来解决代码部署过程中出现的问题,或者将代码交还给开发团队来解决遇到的问题。所有这些都导致了软件开发过程的放慢。但是在DevOps模式下,这三个团队不再孤立。大多数时间内,从开发、测试、部署到运营,相关的工程师合并成一个团队并且贯穿整个软件生命周期,开发不再限制于某一个技能而是一整套技术解决方案。当然安全团队也因此有可能在这个软件生命周期中与开发和运营更紧密地工作,及早发现安全问题。为什么DevOps工程师的角色各不相同呢?DevOps工程师并不是什么新鲜事物。比如系统工程师,自动化工程师,软件工程师,Linux工程师等等工程师都能成为DevOps工程师。但是,DevOps工程师的工作性质因组织而异。比如有些是在基础设施自动化和维护中发挥作用,而在另外一些组织中却是在整个交付链中发挥作用而已。DevOps工程师的角色各不相同,因为他必须通过克服传统协作障碍与开发和运维人员进行协作。而不同的组织有不同的障碍,因此其扮演的角色自然不同。DevOps工程师日常工作中最重要的两个方面尽管DevOps工程师的角色各不相同,但几乎所有DevOps工程师每天都会触及两件事 - 自动化和持续集成。自动化:与维护基础设施有关的大部分任务仍然是手动的。公司更喜欢使用传统的经过验证的方法,而不是自动化相同的流程,因为他们不想冒任何风险。但事实是自动化任务将有助于更快速地开发和部署软件,这意味着能加快公司从客户处赚取利益的速度。为了阐述清楚这一点,我们可以考虑下面这个情况,系统工程师如果每天按要求手动备份所有服务两次,那么他可以通过在云端设施上编写脚本来完成这项工作而不是浪费时间来完成这项工作。通过自动执行备份过程,您可以让系统工程师更专注于重要的事情,例如对由于某些因为虚拟机问题而需要关闭的服务进行故障排除。手动执行相同的操作会导致您的系统工程师的负担过重,而这些工程师的效率将大大降低。这只是一个非常简单的例子,通过不实施自动化来阐述资源浪费的概念。DevOps因此可以作为敏捷的扩展,因为它可以降低由于开发人员、QA和运维团队之间的非协作而可能出现的风险。DevOps通过认识到高质量的软件开发要求包括质量保证和运营专家在内的所有利益相关方的持续参与和反馈,扩大了敏捷原则的范围。有很多事情可以通过自动的方式来完成,比如在发布新的补丁的时候更新ApacheWeb服务器,更新部署在服务器上的开源软件的版本。DevOps工程师可以通过创建脚本环境自动完成配置服务器的过程。您可以在一个节点上运行脚本,但如果在数千上百个节点上手工运行相同的脚本将变得不切实际。脚本在这里就变得不再是一个可扩展的解决方案了。因此,需要以可扩展的方式跨大量节点自动化进行软件配置、配置管理和应用程序部署。这是配置管理工具(如Chef,Puppet和Ansible)在DevOps世界中派上用场的地方。持续集成:关于DevOps的另一个重要方面是在软件开发实践中实施持续集成(CI), CI允许开发人员不断更新自动化构建、测试使用到的资源库。持续集成系统通常包含一个可以持续监控版本控制系统的工具。只要检测到对版本控制系统的更改,系统就会自动构建并测试您的应用程序。如果构建或测试没有通过的,系统会立即通知开发人员解决问题。持续集成可确保持续交付,因为所有代码更改都会不断部署到构建阶段之后的测试和生产环境中。通过持续集成,开发人员可以从人工任务中解脱出来,提高工作效率,因为现在在CI中以自动化方式完成自动构建任务,并且由于更加频繁的测试,错误和bug更容易找到和解决,从而最终用户的更新可以更快,更频繁地进行。有不同的产品和工具可以帮助您在组织中实现持续集成。有些工具可让您将CI 服务器托管在您自己的网络基础架构中。最受欢迎的是从Sun的Hudson项目更名为Jenkins的工具。还有一些其他托管的CI产品,如完全托管在云中的CircleCI和Travis CI.这些托管的CI产品越来越受到小组织的欢迎,因为它使工程团队能够尽快开始持续集成。总结DevOps工程师扮演的最重要角色是弥合软件开发和运营团队之间的差距,提高软件交付速度。尽管DevOps工程师在组织中的角色各不相同,但有两个共同点:自动化和持续集成。

December 18, 2018 · 1 min · jiezi

jmxtrans+influxdb+grafana监控zookeeper实战

序本文主要研究一下如何使用jmxtrans+influxdb+granfa监控zookeeper配置zookeeper jmx在conf目录下新增zookeeper-env.sh,并使用chmod +x赋予执行权限,内容如下JMXLOCALONLY=falseJMXDISABLE=falseJMXPORT=8999JMXAUTH=falseJMXSSL=false指定JMXPORT为8999搭建influxdb及grafana这里使用docker构建,如下docker network create monitoring-networkdocker run -d -p 8083:8083 -p 8086:8086 \ –net monitoring-network \ –name influxdb \ influxdb:1.5.4curl -POST http://192.168.99.100:8086/query –data-urlencode “q=CREATE DATABASE zookeeper"docker run -d -p 3000:3000 –net monitoring-network –name grafana grafana/grafana:5.2.4curl ‘http://admin:admin@192.168.99.100:3000/api/datasources’ -X POST -H ‘Content-Type: application/json;charset=UTF-8’ --data-binary ‘{“name”:“influx”,“type”:“influxdb”,“url”:“http://192.168.99.100:8086”,“access”:“proxy”,“isDefault”:true,“database”:“zookeeper”,“user”:“admin”,“password”:“admin”}‘创建monitoring-network,让docker中的influxdb与grafana连通,然后使用rest api创建zookeeper数据库创建grafana并指定net为monitoring-network,然后使用rest api配置数据源jmxtrans配置下载jmxtranswget http://central.maven.org/maven2/org/jmxtrans/jmxtrans/270/jmxtrans-270-all.jar下载执行脚本wget -q https://raw.githubusercontent.com/jmxtrans/jmxtrans/master/jmxtrans/jmxtrans.shchmod +x jmxtrans.sh配置zookeeper.json{ “servers”: [ { “port”: 8999, “host”: “localhost”, “alias”: “zk”, “queries”: [ { “outputWriters” : [ { “@class” : “com.googlecode.jmxtrans.model.output.InfluxDbWriterFactory”, “url” : “http://192.168.99.100:8086/”, “database” : “zookeeper”, “username” : “admin”, “password” : “admin” } ], “obj”: “org.apache.ZooKeeperService:name0=ReplicatedServer_id*”, “attr”: [ “QuorumSize” ] }, { “outputWriters” : [ { “@class” : “com.googlecode.jmxtrans.model.output.InfluxDbWriterFactory”, “url” : “http://192.168.99.100:8086/”, “database” : “zookeeper”, “username” : “admin”, “password” : “admin” } ], “obj”: “org.apache.ZooKeeperService:name0=ReplicatedServer_id*,name1=replica*,name2=”, “attr”: [ “MaxClientCnxnsPerHost”, “MaxRequestLatency”, “AvgRequestLatency”, “MinRequestLatency”, “MaxSessionTimeout”, “MinSessionTimeout”, “OutstandingRequests”, “PacketsReceived”, “PacketsSent”, “PendingRevalidationCount”, “TickTime” ] }, { “outputWriters” : [ { “@class” : “com.googlecode.jmxtrans.model.output.InfluxDbWriterFactory”, “url” : “http://192.168.99.100:8086/”, “database” : “zookeeper”, “username” : “admin”, “password” : “admin” } ], “obj”: “org.apache.ZooKeeperService:name0=ReplicatedServer_id,name1=replica*,name2=,name3=InMemoryDataTree”, “attr”: [ “NodeCount”, “WatchCount” ] }, { “outputWriters” : [ { “@class” : “com.googlecode.jmxtrans.model.output.InfluxDbWriterFactory”, “url” : “http://192.168.99.100:8086/”, “database” : “zookeeper”, “username” : “admin”, “password” : “admin” } ], “obj”: “org.apache.ZooKeeperService:name0=ReplicatedServer_id,name1=replica*,name2=,name3=Connections,name4=,name5=”, “resultAlias”: “Clients”, “attr”: [ “AvgLatency”, “LastLatency”, “MaxLatency”, “MinLatency”, “OutstandingRequests”, “PacketsReceived”, “PacketsSent” ] }, { “outputWriters” : [ { “@class” : “com.googlecode.jmxtrans.model.output.InfluxDbWriterFactory”, “url” : “http://192.168.99.100:8086/”, “database” : “zookeeper”, “username” : “admin”, “password” : “admin” } ], “obj”: “org.apache.ZooKeeperService:name0=StandaloneServer_port”, “resultAlias”: “Clients”, “attr”: [ “AvgLatency”, “LastLatency”, “MaxLatency”, “MinLatency”, “OutstandingRequests”, “PacketsReceived”, “PacketsSent”, “NumAliveConnections” ] }, { “outputWriters” : [ { “@class” : “com.googlecode.jmxtrans.model.output.InfluxDbWriterFactory”, “url” : “http://192.168.99.100:8086/”, “database” : “zookeeper”, “username” : “admin”, “password” : “admin” } ], “obj”: “java.lang:type=Memory”, “resultAlias”: “Memory”, “attr”: [ “HeapMemoryUsage”, “NonHeapMemoryUsage” ] }, { “outputWriters” : [ { “@class” : “com.googlecode.jmxtrans.model.output.InfluxDbWriterFactory”, “url” : “http://192.168.99.100:8086/”, “database” : “zookeeper”, “username” : “admin”, “password” : “admin” } ], “obj”: “java.lang:type=OperatingSystem”, “resultAlias”: “Process”, “attr”: [ “OpenFileDescriptorCount”, “ProcessCpuLoad” ] }, { “outputWriters” : [ { “@class” : “com.googlecode.jmxtrans.model.output.InfluxDbWriterFactory”, “url” : “http://192.168.99.100:8086/”, “database” : “zookeeper”, “username” : “admin”, “password” : “admin” } ], “obj”: “java.lang:type=Threading”, “resultAlias”: “Threading”, “attr”: [ “ThreadCount” ] } ], “numQueryThreads”: 2 } ]}放在跟jmxtrans.sh脚本同一个目录下即可自动加载启动JAR_FILE=jmxtrans-270-all.jar ./jmxtrans.sh start日志输出实例2018-10-04 11:28:30 [main] level org.quartz.impl.StdSchedulerFactory [StdSchedulerFactory.java:1179] - Using default implementation for ThreadExecutor2018-10-04 11:28:30 [main] level org.quartz.core.SchedulerSignalerImpl [SchedulerSignalerImpl.java:60] - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl2018-10-04 11:28:30 [main] level org.quartz.core.QuartzScheduler [QuartzScheduler.java:229] - Quartz Scheduler v.1.8.6 created.2018-10-04 11:28:30 [main] level org.quartz.simpl.RAMJobStore [RAMJobStore.java:139] - RAMJobStore initialized.2018-10-04 11:28:30 [main] level org.quartz.core.QuartzScheduler [QuartzScheduler.java:255] - Scheduler meta-data: Quartz Scheduler (v1.8.6) ‘ServerScheduler’ with instanceId ‘Mars.local1538623710548’ Scheduler class: ‘org.quartz.core.QuartzScheduler’ - running locally. NOT STARTED. Currently in standby mode. Number of jobs executed: 0 Using thread pool ‘org.quartz.simpl.SimpleThreadPool’ - with 10 threads. Using job-store ‘org.quartz.simpl.RAMJobStore’ - which does not support persistence. and is not clustered.2018-10-04 11:28:30 [main] level org.quartz.impl.StdSchedulerFactory [StdSchedulerFactory.java:1324] - Quartz scheduler ‘ServerScheduler’ initialized from an externally opened InputStream.2018-10-04 11:28:30 [main] level org.quartz.impl.StdSchedulerFactory [StdSchedulerFactory.java:1328] - Quartz scheduler version: 1.8.62018-10-04 11:28:30 [main] level org.quartz.core.QuartzScheduler [QuartzScheduler.java:2267] - JobFactory set to: com.googlecode.jmxtrans.guice.GuiceJobFactory@263f04ca2018-10-04 11:28:30 [main] level com.googlecode.jmxtrans.JmxTransformer [JmxTransformer.java:177] - Starting Jmxtrans on : .2018-10-04 11:28:30 [main] level org.quartz.core.QuartzScheduler [QuartzScheduler.java:519] - Scheduler ServerScheduler_$_Mars.local1538623710548 started.2018-10-04 11:28:30 [main] level com.googlecode.jmxtrans.model.output.InfluxDbWriterFactory [InfluxDbWriterFactory.java:121] - Result Tags to write set to: [ResultAttribute(name=typeName), ResultAttribute(name=objDomain), ResultAttribute(name=className), ResultAttribute(name=attributeName)]2018-10-04 11:28:30 [main] level com.googlecode.jmxtrans.model.output.InfluxDbWriterFactory [InfluxDbWriterFactory.java:102] - Connecting to url: http://192.168.99.100:8086/ as: username: admin2018-10-04 11:28:31 [main] level com.googlecode.jmxtrans.model.output.InfluxDbWriterFactory [InfluxDbWriterFactory.java:121] - Result Tags to write set to: [ResultAttribute(name=typeName), ResultAttribute(name=objDomain), ResultAttribute(name=className), ResultAttribute(name=attributeName)]查询influxdb数据docker exec -it influxdb influxConnected to http://localhost:8086 version 1.5.4InfluxDB shell version: 1.5.4> use zookeeperUsing database zookeeper> show MEASUREMENTSname: measurementsname—-ClientsMemoryProcessThreading> show series from “Memory"key—Memory,attributeName=HeapMemoryUsage,className=sun.management.MemoryImpl,hostname=zk,objDomain=java.lang,typeName=type=MemoryMemory,attributeName=NonHeapMemoryUsage,className=sun.management.MemoryImpl,hostname=zk,objDomain=java.lang,typeName=type=Memory之后通过select * from “Memory"可以查看具体指标数据查询到有数据之后,就可以在grafana上面进行配置可视化,然后进行监控小结对于zookeeper、kafka之类应用来说,内置了jmx,因而其监控可以通过jmxtrans进行指标收集转换,然后输出到influxdb或者graphite或者prometheus等,最后通过grafana进行可视化及监控报警。docjmxtransjmxtrans-270-all.jarHow do i enable remote jmx with port in zookeeper zkServer.cmdMonitoring Apache Kafka with Grafana / InfluxDB via JMX ...

October 4, 2018 · 3 min · jiezi

8分钟丨教你玩转 API

欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~本文由织云平台团队发表于云+社区专栏背景当下,业界越来越多公司在项目架构设计时,会采用微服务架构。微服务架构,可以让我们的产品有更好的扩展性,更好的伸缩性;但同时也会带来微服务的一系列问题,比如微服务接口怎样规范管理?怎样在多团队协作中开放与复用?等等。同时,业界也在逐渐的引入DevOps理念,来实现开发,测试,运维,运营更紧密的高效配合,提升产品迭代的效率,质量。这里,织云API平台将从“部门内微服务API开放复用”,“产品线API DevOps实践”来分享腾讯社交网络运营部踩过的坑和API平台在“开放”,“DevOps”的理解及实践。1API开放与复用部门长期运营,积累了很多优秀的系统/平台,各个系统/平台也很早的开放了自己的Open API 给其它团队做二次开发和使用。 作为开放接口使用方:要集成A平台的B服务时,你可能会遇到:找不到平台开放接口文档;从平台官网下载的接口文档好像未更新;接口文档定义太简单。看不懂;使用前,不清楚接口的质量现状(成功率,耗时等);出异常时,没法快速界定问题的边界。作为开放接口提供方:你在运营上可能会遇到:接入方很多,长久下来,自己都不清楚调用方是哪些?最近我的接口调用量大增,不清楚这些调用是否合理?旧接口要下线,但仍有请求。不方便快速找到调用者。2产品线API那些事儿织云,是腾讯SNG海量业务运维能力经验沉淀出的产品,它采用微服务架构。在微服务的开发,测试,交付,运营中,我们遇到这样子的问题:web工程师:版本迭代很紧,但是后台同学的接口迟迟出不来,我的工作delay很久了后台工程师:版本迭代很紧,写代码的时间都没有。哪来时间写用例。但每次修改代码,人工自测耗费很多时间。两位工程师:上次不是好说接口长xx样子吗?怎样现在变成这样子了?质量工程师:这个迭代,织云性能是否达标呢?看不见,摸不着,快慢主要凭感觉。运维工程师:客户反馈操作有异常。一个问题都转几手开发。我怎样快速定位问题根源客户:你们的XX能力很好。我们想基于它们接口做二次开发。有开放接口吗织云API平台,就是这种大背景下应运而生。API平台简介定义织云API平台,是一个以API服务管理和代理以基础,赋能接口开发,测试,上线运营,下线管理于一体的API管理与开放平台。应用场景功能介绍1、织云API平台,实现了API统一规范管理与开放。 2、以服务代理为基础,实现了安全认证,过载保护。 3、对于服务调用支持日志查询,数据画像,异常告警,链路分析等功能。 4、可以基于API平台实现基于织云所有能力的定制开发的能力。接口规范和接入成本接口规范屏蔽接口URI层级差异:API平台,统一采用三级结构,通过/平台/服务/接口的层次来管理所有接入API,屏蔽实际接口URI的层级差异;屏蔽接口响应结构差异:API平台,自动转换接口响应结构,屏蔽实际接口的结构差异化。大大简化了集成开发,特别是Web前端同学适配后台接口的复杂度。全局业务错误码:确保服务间的每个错误码都是唯一能溯源的。接入成本–零改造API平台在设计之前就考虑到用户接入的成本。以上规范,API平台都能自动屏蔽差异,自动转换,自动生成。用户接入零改造。注册API服务 — 示例现成的API接口现在我有一个容量的分析接口:查询模块容量持续高低负载数据接口。url: http://capacity/load/sustaine… method: get 入参:type=1&m1id=468095&m2id=468095&m3id=468095&m4id=468095 出参: [ { “m1id”: 1256, “m2id”: 1256010, “day_cnt”: 14, “m4id”: 468095, “avg_load”: 0.25, “type”: 1, “model_cnt”: 1, “m3id”: 11120 } ]创建接口对应的平台,服务操作相似。如创建服务:其中的英文缩写,将是最终API url中对应的服务名。注册接口 - 基础信息注册接口 - 定义请求示例自动生成入出参:在入参,出参示例部分,只须贴入:入参:type=1&m1id=468095&m2id=468095&m3id=468095&m4id=468095, 出参: [ { “m1id”: 1256, “m2id”: 1256010, “day_cnt”: 14, “m4id”: 468095, “avg_load”: 0.25, “type”: 1, “model_cnt”: 1, “m3id”: 11120 } ]API平台会自动帮我们解析结构(当前支持key/value, json结构等解析)用户,只须录入字段是否必填,以及中文说明即可。注册接口 - 定义接口返回码接口开放查看开放API接口列表页:在API平台注册接口后,可以在API平台列表中查询每个开放接口:明细面:在明细面,可以查看接口详情。以及自动生成的调用示例。自动生成接口文档 访问权限申请API平台的接口开放模式暂时有两种:全开放,须审核。全开放:用户须在API平台应用组进行登记注册,API平台会分配一个唯一的apikey给到用户。对于全开放的接口,用户访问时,只须header带上apikey即可。须审核:对于一些敏感数据接口,用户访问前,须进行权限申请,将请求所在的业务模块与当前接口进行绑定。API平台只允许目标业务模块下的IP访问目标接口。场景一:接口开发-无中生有应用前-出现的问题:1.开发耦合:项目迭代刚启动,经常会出现后台开发间,前后端开发间接口相互依赖,导致工作相互delay。2.相互“扯皮”:开发间当面对齐接口,经常出现今天说“一套”,实际输出“一套”。没有接口落地及佐证的地方。应用后-规范的工作流程,实现了并行开发:有了API平台,大家的工作流程规范是这样:1. 接口提供方,注册新接口到API平台;2. 提供方与接口使用方通过API平台对齐接口,达成两方最终接口;3. 使用方使用API平台提供的伪接口进行功能开发及联调;(不再阻塞)4. 接口提供方严格按最终接口参数实现真实接口。5. 接口提供方将测试接口录入API平台,模式从“伪接口”切换成“测试”,接口使用方可以“无感知”的切换成真实接口服务中去。不需要额外联调。场景二:接口测试-可视化用例+自动测试“ 写代码的时间都没有。哪来时间写用例。但每次修改代码,人工自测耗费很多时间。” 这种现象其实在开发中很普遍。有没有一种模式,可以让开发不用写代码就能快速实现接口单元测试用例?甚至让不写代码的测试同学来帮开发实现测试用例?API平台,提供了可视化用例在线编辑:用户只须录入预设值,即可生成用例。一键执行用例,查看测试结果。API平台也实现了依赖第三方环境API的接口本地化测试。关于API平台测试能力这一部分,后面我们再专门单独做介绍。场景三:质量运营安全认证分配apikey: 所有API访问,须在API平台注册,由平台分配唯一的apikey。用户每次请求须带上apikey方可访问;限制开放源:对于敏感API接口,接口使用方须在API平台登记请求来源业务模块,经审核后,方可访问。过载保护每个接口可以自定义访问频率。API平台可以对接口进行限频保护。接口巡检API平台可对线上服务接口进行自定义的主动探测与巡检。在用户察觉问题前发现问题与修复问题。异常告警若API服务出现异常,API平台会主动通知接口使用方与提供方。异常告警案例CMDB下发配置(16:30,17:30灰度),未切走流量,导致接口请求小部分异常。 告警短信:查看API日志: 发现:后台spp服务异常跟进原因: 调用链路分析应用场景应用前-问题场景:A业务页面提示xx保存失败–>A业务开发卷入排查(重现问题+分析)–>发现是公共B服务异常–> B开发卷入相似分析–> 发现是平台服务C异常–> 卷入C开发相似分析–> 确认是redis服务异常。这种问题,如果发生在客户环境,会有ABC三个开发同学要:申请登录客户环境(有时很繁琐很费时)–> 排查–> 内部反馈,流转问题单。有时排查分析时间还没有前后协调时间耗费得多。应用后-链路分析场景:API平台调用链路分析能力,方便不懂业务的运维同学,一键在线查看整个调用链,直达问题根节点:1.获取异常请求ID:前端页面或后台服务出现异常时,定位者可以从页面或日志中获取调用请求的ID,2.还原问题现场:根据请求ID,在API平台获取调用链,快速全方位的还原现场数据:链路中每个请求的入参,出参,耗时,返回码,异常日志等。告别登机子查日志-重试重现问题-大量开发介入-问题修复效率低慢的问题。API调用链路分析API平台根据起始请求,将接口间调用关系生成一棵调用树.我们可以一目了然的看到:1.请求的调用链路;2.每一层调用现场:服务调用方,服务提供方,接口返回码,耗时, 入参,出参, 异常日志(若有异常)利用API平台的调用树能力,我们可以:1、快速了解服务的调用关系,发现不合理调用;2、帮助售后快速定位问题;减少开发介入频率;3、现场复原:不须再重现;避免重现不了问题的定位4、web可视化分析:减少上机子查日志的次数。提升定位效率。案例一:发现不合理调用(1)问题现场devtest环境,执行工具市场工具异常.(2)获取requestId获取id, 输入查询(3)重现调用树+问题现场(4)发现原因/问题结论一(问题原因):命令通道接口-判断设备连通性:发现设备不可通。结论二:通过调用链,发现工具市场存在重复调用cmdb接口问题。工具市场下个迭代修复。案例二:CMDB异常(1)问题现场:执行工具市场时,只提示CMDB异常。但不知道原因。(2)查看API平台调用树:不需求上机子查日志啦。可见原因是DB连接异常。场景四:数据画像API平台有实时日志查询、实时数据画像、性能分析等数据画像能力。这里,针对成功率,耗时做下介绍: 对于运营者来说,我们很关心线上接口的成功率,耗时,这样将直接影响服务质量,用户体验。横向分析查看接口成功率分布及趋势 & 查看接口耗时分布及趋势。平均成功率,平均耗时,会在“平均数据”下掩盖了一些细微的问题。API平台画像,会采用分段模式,下钻一层看问题。纵向分析以“天+接口”纬度查看明细数据:性能优化案例刚接入API平台时,织云自动化服务,共有39个接口有调用记录。其中29个接口(66.7%)不达标(接口耗时超过500ms)。经开发性能后,慢接口大幅减少。小结织云API平台,是结合我们部门“接口开放”,“接口生产”需求、痛点和DevOps理念的一次新探索,新实践。在传统API网关的能力基础上,拓展到更多API周期阶段,实现API的DevOps赋能与管理。以上是API平台简单的介绍和分享,抛砖引玉,希望大家都能打造好自己的微服务管理与开放平台。共勉!· 分 · 割 · 线 · 啦 ·织云企业版预约体验织云社区版 V1.2下载问答无法从API获取数据?相关阅读模型剖析 | 如何解决业务运维的四大难题?混合云管理问题,你解决了么?Pick一下,工具上线前运维必备原则 【每日课程推荐】机器学习实战!快速入门在线广告业务及CTR相应知识 ...

September 30, 2018 · 1 min · jiezi

有赞容器化实践

前言容器化已经成为一种趋势,它可以解决很多运维中的痛点,比如效率、成本、稳定性等问题,而接入容器的过程中往往也会碰到很多问题和不便。在有赞最开始做容器化是为了快速交付开发测试环境,在容器化的过程中,我们碰到过容器技术、运维体系适配、用户使用习惯改变等各种问题,本文主要介绍有赞容器化过程中碰到的问题以及采取的方案。有赞容器化的初衷在有赞同时会有很多个项目、日常在并行开发,环境的抢占问题严重影响了开发、测试和上线的效率,我们需要给每个项目提供一套开发联调(daily)、测试环境(qa),并且随着项目、日常的生命周期项目环境也会随着创建和销毁,我们最早的容器化需求就是怎么解决环境快速交付的问题。[有赞环境]上面是有赞大致的研发流程,在标准流程中我们有四套稳定环境,分别是 Daily 环境、Qa 环境、预发环境和测试环境。我们的开发、测试、联调工作一般并不会直接在稳定环境中进行,而是会拉一套独立的项目环境出来,随着代码经过开发、测试、预发验收最终发布到生产环境后再同步回 Daily/Qa 的稳定环境中。[项目环境]我们提供了一套以最小的资源投入满足最大项目并行度的环境交付方案,在 Daily/Qa 稳定环境的基础上,隔离出N个项目环境,在项目环境里只需要创建该项目所涉及应用的计算资源,其它缺失的服务调用由稳定环境提供,在项目环境里,我们大量使用了容器技术。[持续交付]后面我们又在项目环境快速交付的解决方案的基础上实现了持续交付流水线,目前已经有超过 600 套项目/持续交付环境,加上 Daily/Qa 稳定环境,涉及计算实例四五千个,这些计算实例无论是 cpu 还是内存使用率都是非常低的,容器化可以非常好的解决环境交付的效率问题,以及提高资源使用率来节省成本的投入。有赞容器化方案我们的容器化方案基于 kubernetes(1.7.10)和 docker(1.12.6)、docker(1.13.1),下面介绍一下我们在各个方面遇到的问题以及解决方案。网络有赞后端主要是 java 应用,采用定制的 dubbo 服务化方案,过程中无法做到整个单元全量容器化,和原有集群在网络路由上互通也就成了刚需,由于我们无法解决公有云上 overlay 网络和公有云网络的互通问题,所以一开始我们放弃了 overlay 网络方案,采用了托管网络下的 macvlan 方案,这样既解决了网络互通的问题也不存在网络性能问题,但是也就享受不到公有云弹性资源的优势了。随着有赞多云架构的发展以及越来越多的云厂商支持容器 overlay 网络和 vpc 网络打通,弹性资源的问题才得到了缓解。隔离性容器的隔离主要利用内核的 namespace 和 cgroup 技术,在进程、cpu、内存、IO等资源隔离限制上有比较好的表现,但其他方面和虚拟机相比存在着很多的不足,我们在使用过程中碰到最多的问题是容器里看到的 cpu 数和内存大小不准确,因为/proc文件系统无法隔离,导致容器里的进程"看到"的是物理机的 cpu 数以及内存大小。内存问题我们的 java 应用会根据服务器的内存大小来决定 jvm 参数应该怎么配置,我们是采用 lxcfs 方案来规避的。CPU 数的问题因为我们有超卖的需求以及 kubernetes 默认也是采用 cpu share 来做 cpu 限制,虽然我们使用了 lxcfs,CPU 数还是不准的。jvm 以及很多 Java sdk 都会根据系统的 CPU 数来决定创建多少线程,导致 java 应用在线程数和内存使用上都比虚拟机多的多,严重影响运行,其他类型的应用也有类似的问题。我们会根据容器的规格内置一个环境变量 NUM_CPUS,然后比如 nodejs 应用就会按照这个变量来创建它的 worker 进程数。在解决 java 类应用的问题时,我们索性通过 LD_PRELOAD 将 JVM_ActiveProcessorCount 函数覆盖掉,让它直接返回 NUM_CPUS 的值[1]。应用接入在容器化之前,有赞的应用已经全部接入到发布系统,在发布系统里已经标准化了应用的打包、发布流程,所以在应用接入方面成本还是比较小的,业务方无需提供 Dockerfile。nodejs, python,php-soa 等用 supervisord 托管的应用,只需要在 git 仓库里提供 app.yaml 文件定义运行需要的 runtime 和启动命令即可。java 标准化启动的应用业务方无需改动java 非标准化的应用需要做标准化改造镜像集成容器镜像我们分了三层,依次为 stack 层(os),runtime 层(语言环境),应用层(业务代码和一些辅助agent),应用以及辅助 agent 由 runit 来启动。由于我们的配置还没有完全分离,在应用层目前还是每个环境独立打包,镜像里除了业务代码之外,我们还会根据业务的语言类型放一些辅助的 agent。我们一开始也想将各种 agent 拆成多个镜像,然后每个 pod 运行多个容器,后来因为解决不了 pod 里容器的启动顺序(服务启动有依赖)问题,就把所有服务都扔到一个容器里去运行了。我们的容器镜像集成过程也是通过 kubernetes 来调度的(会调度到指定的打包节点上),在发布任务发起时,管控系统会在集群中创建一个打包的 pod,打包程序会根据应用类型等参数编译代码、安装依赖,并且生成 Dockerifile,然后在这个 pod 中使用 docker in docker 的方式来集成容器镜像并推送到仓库。为了加速应用的打包速度,我们用 pvc 缓存了 python 的 virtualenv,nodejs 的 node_modules,java 的 maven 包等文件。另外就是 docker 早的版本里,Dockerfile ADD 指令是不支持指定文件属主和分组的,这样会带来一个问题就是需要指定文件属主时(我们的应用是以 app 账号运行的)需要多运行一次 RUN chown,这样镜像也就多了一层数据,所以我们打包节点的 docker 版本采用了官方比较新的 ce 版本,因为新版本支持 ADD –chown 特性。负载均衡(ingress)有赞的应用内部调用有比较完善的服务化和 service mesh 方案,集群内的访问不用过多考虑,负载均衡只需要考虑用户和系统访问的 http 流量,在容器化之前我们已经自研了一套统一接入系统,所以在容器化负载均衡上我们并没有完整按照 ingress 的机制来实现 controller,ingress 的资源配置是配在统一接入里的,配置里面转发的 upstream 会和 kubernetes 里的 service 关联,我们只是做了一个 sync 程序 watch kube-api,感知 service 的变化来实时更新统一接入系统中 upstream 的服务器列表信息。容器登录和调试在容器化接入过程中开发会反馈是控制台比较难用,虽然我们优化了多次,和 iterm2 等的体验还是有所不足,最终我们还是放开了项目/持续交付环境这种需要频繁登陆调试的 ssh 登陆权限。另外一个比较严重的问题是,当一个应用启动后健康检查有问题会导致 pod 一直在重新调度,而在开发过程中开发肯定是希望看到失败现场的,我们提供了调试发布模式,让容器不做健康检查。日志有赞有专门的日志系统,我们内部叫天网,大部分日志以及业务监控数据都是通过 sdk 直接打到天网里去了,所以容器的标准输出日志仅仅作为一种辅助排查问题的手段。我们容器的日志收集采用的是 fluentd,经过 fluentd 处理后按照天网约定的日志格式打到 kafka,最终由天网处理进入 es 做存储。灰度发布我们涉及到灰度发布的流量主要包含三部分:用户端的 http 访问流量应用之间的 http 调用应用之间的 dubbo 调用首先,我们在入口的统一接入上统一打上灰度需要用的各种维度的标签(比如用户、店铺等),然后需要对统一接入、http client 以及 dubbo client 做改造,目的是让这些标签能够在整个调用链上透传。我们在做容器灰度发布时,会发一个灰度的 deployment,然后在统一接入以及灰度配置中心配置灰度规则,整个链路上的调用方都会感知这些灰度规则来实现灰度发布。标准环境容器化标准环境的出发点和项目环境类似,标准稳定环境中的 daily,qa,pre 以及 prod 中超过一半运行在低水位的服务器的资源非常浪费。因为成本考虑 daily,qa,pre 里都是以单台虚拟机运行的,这样一旦需要发布稳定环境将会造成标准稳定环境和项目环境的短暂不可用。虚拟机交付速度比较慢,使用虚拟机做灰度发布也比较复杂。虚拟机往往会存在几年甚至更长的时间,运行过程中操作系统以及基础软件版本的收敛非常麻烦。标准环境容器化推进经过之前项目/持续交付的上线和迭代,大部分应用本身已经具备了容器化的条件。不过对于上线来说,需要整个运维体系来适配容器化,比如监控、发布、日志等等。目前我们生产环境容器化准备基本完成,生产网已经上了部分前端 nodejs 应用,其他应用也在陆续推动中,希望以后可以分享更多生产环境中的容器化经验。结束语以上是有赞在容器化上的应用,以及在容器化过程中碰到的一些问题和解决方案,我们生产环境的容器化还处于开始阶段,后面还会碰到各种个样的问题,希望能够和大家互相学习,后面能够有更多的经验分享给大家。参考文献[1] https://github.com/fabianenar… ...

September 29, 2018 · 1 min · jiezi