一个软件工程师对职场、管理、企业的思考——上篇

想象离开目前这家公司,你还能去哪? 如果你发现,你只有和这家公司流程、政治、上下文等等强相关的能力,那么,你也只能靠“办公室政治”保留住自己的位子。因为,离开了这家公司,你什么也不是。 但是,也有例外,就是另一家公司没有分辨能力,你又特能忽悠。像这位“高管”:假证假名假文凭,小学文化男子应聘入职月薪7万公司高管。 最后,当你思考这个问题时,如果感到害怕,你就要小心了。 忠告:保持独立思考的能力,但隐藏起来 市面上有一些管理者是不允许你和他有不同意见的。通常,独立思考的人凡事都会有自己的看法。而如果你在别人面前和管理者提出不一样的意见,领导会觉得没面子。那么,今后,你可能就没好吃的了。 那么,正确的做法是什么呢?即使大环境下,所有的人都附和管理者,你同样不要被这种环境麻痹自己独立思考的能力。观察你的管理者是开明的人,还是职场“老油条”?选择一个合适的时机说出你的不同意见。 这时,你就知道“察言观色”能力的重要性了。 当存在不同意见的时候,作为组织和管理者需要思考,是不是管理者没有表达清楚,是不是这个“不同意见”更合理,如何说服这个不同意见的人,其他人是不是也有不同的意见? 当然,有些人会觉得这样会导致企业的执行力下降。我想说的是,知识工作者执行任务不像体力劳动者,你告诉他把这个箱子从这里搬到那里,这么准确。任务定义不准确往往是组织管理者自己都还没有想清楚自己到底要什么。最后得不到自己想要的,又反过来说企业的执行力差。 现象:通过建立信息壁垒的手段,保住自己的位置 有一次,我问一个同行:为什么整个系统,这么多个工程,没有一个人知道全景图。(这个系统并不算大,也就30多个子工程)。我们能不能组织所有人建立一个全景图? 他说了:别人是不会告诉你,他自己那块是怎么做的。 我问:为什么呢?有个全景图大家不就可以更好的协作吗?出现问题,也不需要等着某一个人了。 他浅笑,眼看前方:因为如果给你懂了他的那块系统,你就可以替代他了。 这下,我才明白。行业内,还有人通过建立“信息壁垒”,让公司离不开你;让管理者觉得你是有用的。 看懂这点后,你会发现,那些不干“实事”的人,为什么能一直“保住位置”。往往因为他们掌握了信息的源头。 这种协作机制,有好处,比如两个组织之间的对接方式明确,出现问题马上知道找谁解决。坏处一是信息的准确度会在对接人之间严重打折,带来的就是低效率。坏处二就是会滋生建立信息壁垒的职场老油条。 作为个人,我们要问自己,离开当前这家公司,你建立的信息壁垒,还会有价值吗? 作为公司,信息不透明所带来的坏处,我就不想说了。管理企业和管理国家都会遇到这个问题。 忠告:小心那些威胁到别人“KPI”的行为 当公司的IT系统管理员做得不好时,不要直接在公司的大群里说。因为你这样做可能会威胁到他的KPI或他在管理者眼里的印象了。所以,私自跟这位IT系统管理员沟通就好了。 为什么:不管功劳,苦劳,一定要让管理者看到 过年了,相信不少人要开始表现得非常辛苦了。很简单,因为年底了,年终奖的多少就看这一个月了。当然,我说的不是绝对的。但是一定存在这种现象。 这种现象背后的原因是多种的: 管理者对人、工作的判断,依赖的是主观印象,而不是客观因素。 所以,你会经常听到有人在朋友圈、饭局上说自己最近因为工作太猛不舒服、没有时间陪小孩、过劳胖…… 当出现这种现象时,作为管理者就需要反思自己的管理方式了:组织的效率是不是有问题;作为个人,小心使用这种行为,不要让它麻痹了你独立思考的能力。 知识工作者的生产活动存在于大脑中,看不到摸不着。 比如没有好的技术管理的团队,即使你写出优秀的代码,对于你的“年终奖”也没有什么益处。 作为组织,我们需要思考,员工的表现一定要让管理者看到,而不是让所有人都看到。 玩笑:准时下班,肯定是工作不饱和 这是一句玩笑话。但是背后有它道理。 我们知识工作者有一个特点,就是从表面上,你是看不出这个人是否在工作的,因为他的真正工作存在于他的大脑中。他一天坐在那里,你怎么就知道他是否在工作呢?再者,绝大多数人的注意力没法做到连续一小时。所以,公司pay你的一天八小时,是打折的。 然后,我们软件行业里就有了这么一个玩笑话。 事实上,这背后更深层的含义是: 组织、管理者无法评估知识工作者的工作量 组织、管理者还没有理解体力劳动者和知识工作者之间的区别 那怎么知道一个程序员的工作是否饱和了呢?哈哈。这样的好问题,留给喜欢思考的人。P.S. 我不提倡加班文化,让程序员工作饱和的目的是让程序员不加班。 招聘:交叉组织面试是合理的 以前听说腾讯面试,你面试的是A部门,然后企业HR会在某个环节里随机其他部门的人来面试。这种机制能有效避免有人利用手上权利招聘一些利益相关的人。比如把自己的并不能胜任能力的表弟招进来。 而企业中,我发现这种交叉组织面试真的是值得的。 现象:管理者让你把数据拷出来 朋友打电话来诉苦,说他上级要求他把公司的大数据拷出来。这时,你会怎么做呢?我也不知道,说实在的。 但是这个问题是所有企业都会遇到的问题:如何管理无形资产?这个问题有些大。今天不讨论。 小结 其实,还有很多职场经验、组织管理上的思考。这些只是其中一些。其中有些话,是有些绝对,你对号入座了,反正我不负责。 作为一个软件工程师,我是不是有些不务正业?我是不是该执行上级领导给的需求,什么也别想就可以了? 向独立思考者致敬。

2018-01-06 · 1 min · 50 words · 翟志军 Jack Zhai

公交卡带来的管理启示

在管理这个行当里,存在两个基本理论,X理论和Y理论。希望大家认真看一看,这样你就理解了,为什么公司会有这样那样的政策。 X理论 Y理论 一般人的本性是懒惰的,工作越少越好,可能的话会逃避工作。 人们在工作上体力和脑力的投入就跟在娱乐和休闲上的投入一样,工作是很自然的事——大部分人并不抗拒工作。 大部分人对集体(公司,机构,单位或组织等)的目标不关心,因此管理者需要以强迫,威胁处罚,指导,金钱利益等诱因激发人们的工作源动力。 即使没有外界的压力和处罚的威胁,他们一样会努力工作以期达到目的——人们具有自我调节和自我监督的能力。 一般人缺少进取心,只有在指导下才愿意接受工作,因此管理者需要对他们施加压力。 人们愿意为集体的目标而努力,在工作上会尽最大的努力,以发挥创造力,才智——人们希望在工作上获得认同感,会自觉遵守规定。 在适当的条件下,人们不仅愿意接受工作上的责任,并会寻求更大的责任。 许多人具有相当高的创新能力去解决问题。 在大多数的机构里面,人们的才智并没有充分发挥。 | 资料来自维基百科 是的,不少公司的管理人员或多或少基于其中一个理论。有些人在决策时甚至意识不到XY理论的存在。 这两个理论,我都赞同,也都不赞同。就如同我赞同人有善的一面,也有恶的一面。而且,在不同的时候,有不同的一面。 所以,当人们表现为X理论的一面的时候,我不是马上认定这个人100%就是X理论里所说的人。而认为是我们的工作流程或机制的设计出现了问题。 为什么这样说呢?我们先来看看公交卡的设计。我们都知道公交卡可以分为老人卡、学生卡、普通卡。 我们如何避免不是老人的人刷老人卡坐公交呢?可以想象的方法有这些: 很明显,政府出一个“公文”不允许非老人刷老人卡,是最没用的方法。 老人卡使用特殊的颜色,这样刷卡时,司机就可以辨认刷卡人是否为老人。可是广大人民的智慧是无穷,只要加个卡套就好了。P.S. 很少人会想到这样会导致下属人员作假。 在刷卡的地方,加一个专门的人去检查卡人是否一致。这样,大多数人可能上下班可能都会迟到。P.S. 很少人会想到这样还会导致腐败、人与人的矛盾。 不要笑,我们不少公司管理方法的背后的思维模式和这些“方法”的没有多大区别。 如果我们用X理论来度量所有坐公车的人,我们的公车效率就会变得低效。如果我们用Y理论来度量所有坐公车的人,我们的公车效率是好了,但是赚的钱变少了,而且可能亏本。 这就是不少企业经常遇到的问题:抓过紧就死,放太松就散。 公交卡问题如何破局?说到这里,坐过公交车的人已经知道答案了:老人卡刷卡时,语音播报:老人卡。其它特殊的卡依此类推。 很长一段时间,我都在思考:为什么? 后来,我想通了。语音播报时,刷老人卡时,如果这个人不是老人,他一定会脸红(羞耻心)。因为公交上其他人都看到了。语音播报利用了社会人所具有的羞耻心来解决公交卡问题。 回到本文的主题,这样的“公交卡”给我们的管理带来什么启示呢? 一个人不应该用XY理论分类 企业管理做决策时,不能完全基于X理论,也不能完全基于Y理论 利用人性引导人们趋向于Y理论,而不是相反 让信息透明会让我们收益良多 利用人性引导人们趋向于Y理论看似卑鄙,但是总比一些游戏利用人性让你上瘾更让人接受。 信息的不透明是很多管理难题的根本问题所在。以后我们再谈。 小结 公交卡的设计给我带来的不止是启示,更有意义的是背后的思维模式。而思维模式能带给我在任何情况下随机应变的能力。 最后我提个问题,留给读者思考。问题是:如果10人软件开发团队里,服务经常因为开发人员在自己的机器上打包而出现bug,你会如何解决这个问题? 注意,解决这个问题的同时,会反应出你的思维模式。

2017-12-16 · 1 min · 41 words · 翟志军 Jack Zhai

这就是领域驱动设计(DDD)的作用?

面对需求,我们首先想到的是什么 在家电IoT这个领域里,通常都会需要实现家电的分享。比如老婆分享家里的电饭煲给老公,让老公控制电饭煲。 拿到这样一个需求,通常大脑里想到的就是增加一张家电分享表来实现: appliance_user_shared master_user_id shared_user_id appliance_id 然后再修改家电列表的实现,因为需要将别人分享给自己的家电也要能获取到。 同时,别忘记了,我们还要修改所有对于家电的操作的实现。比如业务规则中说明,家电的主人才能对家电的名称进行修改。 就这样,我们实现了用户对于一个家电的分享。这时的业务模型可以表示如下: 过不了多久,产品经理跟你说,如果一个用户家里有10个家电以上,一个个家电的分享,这种体验太糟糕了,我希望将一个家庭分享给其他人,这样,可以将家庭下所有的家庭一下子分享给另一个人了。 当然,我们同样可以将这个需求,看作是添加一个家庭分享表,再修改一下家电列表、家电名称修改、家电控制……这是A方案。 A方案的领域模型表示如下: 但是,我们还有一个B方案。 当我们仔细思考时,我们似乎掉进了产品经理挖的坑:产品觉得通过增加一个“分享家庭”的概念来实现多个家电的分享。 事实上,我们服务器端实现并不一定需要这样做。前端APP可以有一个家电分享的操作界面,但是,服务器在实现这个web api时,只需要在找到这个家庭下的所有家电,然后重用原来单家电分享的概念了,就可以了。 这样做,就非常符合软件设计的开闭原则:对扩展开放,对修改关闭。 基于B方案,我们不需要对家电列表等功能进行修改。同时,你还会发现,某天产品经理抽风,觉得一次性分享所有的家电不好,如果能在一个家庭基础下实现部分家电分享的功能,是不是更好?A方案就头大了。而B方案可以很轻松的应对。 B方案的领域模型表示如下: 说回来,我们应该警惕产品经理或需求人员帮我们做软件设计。 面对需求时,我们的大脑里,第一想到的是数据库表如何设计、如何实现改动最小、是使用微服务呢,还是使用七边形架构……这类技术问题时,我们的设计是技术驱动设计的。 如果我们大脑里第一思考的是什么单家电分享、家庭分享和单家电分享之间是什么关系……这类领域问题,然后基于这些思考,建立一个领域相关的知识体系——以领域模型为体现。如果我们的软件是基于此领域模型进行设计,就是:领域模型驱动软件设计。 按《领域驱动设计》中,作者所说的: 领域驱动设计是一种思维方式,也是一组优先任务。 领域建模 要搞清楚,什么是领域建模,就必须搞清楚什么是软件的核心。 我们来看看《DDD》前言里所写的: 一些设计因素是技术上的。软件的网络、数据库和其他技术方面的设计耗费了人们大量的精力。很多书籍都介绍过如何解决这些问题。大批开发人员很注意培养自己的技术,并紧跟每一次技术进步。 然而很多应用程序最主要的复杂性并不在技术上,而是来自领域本身、用户的活动或业务。当这种领域复杂性在设计中没有得到解决时,基础技术的构思再好也是无济于事。成功的设计必须系统地考虑软件的这个核心方面。 这个核心方面指的就是领域知识。 而领域建模就是消化吸收大量知识(领域相关),最后产生一个反映深层次领域知识并聚集于关键概念的模型。这也就是领域驱动设计的实质。 上文中,关于家电分享的例子,从A方案到B方案,实际上就是随着我们对领域知识的理解更深入,领域建模的一个过程。 小结 就如《DDD》作者所言:很多因素可能会导致项目偏离轨道,如官僚主义、目标不清、资源缺乏,等等。但是真正决定软件复杂性的是设计方法。当复杂性失去控制时,开发人员就无法很好的理解软件,因此无法轻易、安全地更改和扩展它。 领域驱动设计这种思维方式,再加上一整套的设计实践、技术和原则,就能帮助我们控制真正的复杂性。这就是领域驱动设计的作用。 而这种思维要求我们在面对领域问题时,优先考虑的是领域问题,而不是技术问题。 注意,这并不是说我们不考虑技术如何实现。这是优先级问题。 最后,以上举的例子并不是最终的模型。因为家电分享这个概念并不是最根本的概念。更根本概念是家电的权限。这是一个更层次的领域模型:

2017-11-22 · 1 min · 39 words · 翟志军 Jack Zhai

西安火车站旁一小面馆带给我的启示

那一年,我在西安。现在在深圳。但,时常怀念在西安的生活。 每到一个处吃饭(除了星级酒店),不管它是面馆、快餐店、排挡,还是路边小摊,我都会观察它们是如何经营的。 那一年,西安火车站旁,看上去非常普通的面馆,大概60平米左右,却使用了不一样的经营方法。让我一下子感觉发现了新大陆。 当时,在上火车前,想吃点什么。因为没时间,就直接走进了路边的一家面馆。面馆处于火车站正大门前的一个丁字路口边上,人流量自然没得说。 推开门,径直走向前台。可是前台就几个客人,再环视面馆,座位基本都满了。当我走到前台时,那几个客人已经开始找座位。我跟前台说:你好,来碗臊子面。 前台:你自己找个座位先坐下来,然后叫服务员点菜。 我:不用拿号吗? 前台:不用。 然后,我一会儿就找到一个空座位。心中有种侥幸感:还好有座位。即使,我是与一个看起来很凶的大汉共享这张二人桌。 现在想想,这是多年在火车站旁消费带来的条件反射:在火车站旁,有位置就不错了。 桌上有菜单和基本上每个“快餐店”都会有的桌号。 我举手示意服务员,她1分钟左右就过来了,后来观察到,她是专门负责点餐的。 点完就马上付钱。 这位点餐员提醒我:你千万不要乱换座位,要不等下找不到你的。 面也没有等多久就上来了。这时,我才发现,店里,没有我们经常听到的大声吆喝:5号,5号,臊子面……看到送餐员从厨房后面出来,直接就走到了相应的客户桌上,十分精准。 当我吃完,要去赶火车时,我也不担心要排队买单。老板也不用担心我跑单。因为在点餐时已经付过了。 这家面馆,在我看来属于快餐店一类。现在我们来看看这店与一般的快餐店有什么不同: 它没有客户号,只有桌号 这样,送餐时,菜,桌一一对应,节约送餐员的送菜时间,也缩短了客户取餐的时间。 一般的快餐店送餐员全店的找“4号客户”,实在找不到,就大声吆喝,这给我们带来不好的用餐体验不说,我们的快餐店的生意居然寄托于服务员的眼力和短时间记忆力! 客户先找座位,再点餐 做面是需要时间的,并不是你点了,马上就可以拿到。像KFC,在前台完成点餐,取餐,买单所有流程的。在面馆里不适合。 后来,我也就明白了,为什么有些快餐店会把饭类和面类分到不同的点餐通道,我想就是因为饭类和面类之间从点餐到取餐之间的速度是不一样的,需要分开处理。 多说一句,我们做软件架构时,也会把慢速流程和快速流程分开处理。 先付款,后消费 平时,大家都喜欢先消费,后付款。一是不知道还会不会加点,二是,这种消费体验更好。想想哪个高级酒店,不是先消费,后付款。 但是对于一家火车站旁的小快餐店,是不成立的。第一,火车站旁,大多数人,想要的是快点走,点了又点的概率太小;第二,火车站旁,消费者要的是快,而不是“更高级”。 “先付款”节约了完成消费时的计算时间和叫服务员买单时间。最后,节约了客户的时间。至少,我们的生意,也不用寄托于服务员的记忆力。 最后的好处是:火车站,鱼龙混杂,“先付款”,防止了跑单。 给我带来了什么启示 后来,我见识不少火车站旁的快餐店,但是基本上都会有手托的服务员,费时费力的找“客户号”。我知道西安火车站旁的这一小面馆的经营方法,并不是行业的“共识”。虽然每家店都想赚更多的钱。 这家小面馆的经营方法并不一定适合于所有的面馆。况且,世上有没有适用于所有面馆的经营方法,也是个问题。 但是,这家小面馆,一定是看清了自己的价值流:从客户进店,到客户出店。然后,不断优化这个价值流的节点,使其更顺畅,最终实现赚更多的钱。 对于我们做软件产品的呢?我们的价值流又是什么呢?好问题! 另一个问题:发现价值流后,如何持续优化?我的答案是:现场管理。但是软件产品的生产过程,如何做到现场管理呢?好问题! 如果一个不懂软件开发的人,如何管理好软件产品生产过程呢?好问题! 最后提一个问题:这家面馆的经营方法算不算精益? 图片来网络。如果侵权,必删。

2017-10-14 · 1 min · 38 words · 翟志军 Jack Zhai

《精益产品开发》老翟读后感

传统软件开发方法 传统软件开发方法的共同特点是强调计划、管控和结构化的工程方法,并遵循严格的生命周期概念,把软件开发分割为顺序阶段构成的过程,瀑布式开发方法是其中的代表之一。 到了上世纪90年代初,CMMI和PMI项目管理知识体系成为传统产品开发管理方法的典型代表。 我个人认为,传统软件开发方法的假设是:需求确定后就不会变了。然而,时代变了,这个假设是否还站得住脚? 从另一个角度看,我们也就理解了为什么项目经理会对需求变更如此痛恨。你想嘛,项目经理的职责是让项目按时完成(想想KPI怎么定的?),立项后,工期就定死了,我一开始把项目计划做好了,需要变更了,你让我的项目如何按时完成? 所以,具有这样思维模式的项目经理面对敏捷和精益这样的概念时,第一念头就是:它们能帮助让项目按时完成吗? 当然,我并不是说项目按时完成不重要。而是想表达:我们应该清楚自己最终追求的是项目按时完成,还是做好的产品服务用户。 那么,如果“需求确定后就不会变了”这个假设不成立,我们的产品开发应该如何应对呢? 《精益产品开发》 从原则,方法,实施三个方面来说明我们应该如何应对。 产品开发与生产制造的不同 产品开发相对生产有两个最本质的不同:其一,价值的不确定性,它决定我们无法一开始就明确定义价值,或者说“价值定义”的过程应该是一个持续探索的过程,因此才有了精益创业、精益数据分析等实践体系;其二,过程的不确定性,如每个任务的处理时长不等,且可能在过程中发生变化,它决定了价值流动的管理和改进方法不同,如产品开发中看板方法就与生产中的十分不同。 在软件行业,产品开发与生产的本质不同,深有体会啊。生产常常有批量的含义,而产品开发没有,你听说过“批量生产软件”的说法吗? 部署与发布的区别 为更好地管理发布,团队应该区分发布和部署。部署属于技术范畴的概念,发布是属于市场范畴的概念。它们具有如下意义: 部署(deployment):将软件安装到一个特定的环境 发布(release):让一个或一组特性对应用可见和可用。 上家公司时,我们每周会部署两次,没做完的新功能,我们同时会部署上去,只不过,用户是看不到这些功能的,应该feature toggle是off的,偶尔也会向部分用户打开。 等我们确定功能完全OK了,就会把相应的feature toggle完全打开,所有用户就可以看这个新功能了。 这是区分了部署和发布两个概念的做法。 而现在所在家公司由于历史原因,服务器要跟着APP的版本走。APP端的人每个月发布一次,以至于管理人员也认为服务器端也必须一个月发布一次。导致的问题之一就是服务器端一次性部署大量的服务,不论这些服务是否有变更接口外在行为。 这是没有区分部署和发布两个概念的做法。 看板系统的设计、站会的设计 看板系统能全面地反映需求交付过程吗? 瓶颈和问题能在看板墙上得到即时体现吗? 团队可以根据看板墙上的信息协作和做决定吗? 只要问这三个问题,你就知道你的看板系统设计如何。 何勉老师在书提到了一个案例:一家企业网盘的需求被两端——前端和后端——分别实现。团队也按前端和后端来区分。每个团队还有各自的测试人员。 面对这样的情况,我们如何处理,才能更好的交付产品价值呢?我目前所在公司也遇到同样的问题,一个产品的开发甚至涉及到服务器端、APP端、Web端、硬件端。 一个需求同时涉及这么多的端。看板系统如何设计?如何站会?如何测试?好问题。 从这本书里,我得到的答案是: 只要这个需求的涉及人员的任务卡片都应该放在同一个看板上,有时甚至包括市场人员。 站会时,只要这个需求的涉及人员都应该在一起站,有时甚至包括市场人员。 小结 这些只是一部分,书中的很多想法击中了我。因为现实,我就遇到这样那样的问题,苦于不知如何解决。 另,回过头来看,不管传统软件开发方法,精益,还是敏捷,我们都应该始终记得不论开发、测试、项目管理人员,公司决策层,我们的最终目标:为用户提供更好的服务。按时完成任务只是我们达到这个目标的手段。 但是如何才能达到这个共识呢?留给读者一个问题。

2017-10-08 · 1 min · 39 words · 翟志军 Jack Zhai

ChatOps实战

ChatOps概念在国内已经有一些文章谈过,但是都处于理论范畴。而本文则是一篇ChatOps实践的文章。 有必要说明我对ChatOps的理解,ChatOps表面上就是在一个聊天窗口中,发送一个命令给运维机器人bot,然后bot根据我们预定义的操作进行执行,并返回执行结果。至于更深层次的作用,就是将重复性的手工的运维工作自动化了,开发人员、运维人员可以按需执行一些运维操作。 另外,我做到了自动化搭建这一套东西(感谢Github上那么多开源项目,让我少写很多Ansible脚本)。为什么要自动化搭建呢?因为我懒,我不想每次通过一条条shell手工搭建。 本文主题 在RocketChat的聊天窗口中命令Hubot执行一次Jenkins构建任务。 工具介绍 有必要简单说明一下我们此次实现ChatOps的这几个工具。 RocketChat 可以把RocketChat想像成一个具有更多功能的IRC或者微信。它依赖于MongoDB,所以,我们还将自动化安装MongoDB。 如果你了解过Slack的话,它可以作为Slack的开源替代表。 Hubot Hubot是Github出品的一个运维机器人。本质上就是一个接收命令消息,执行预定义操作的一个程序。而接收命令消息的这个组件在Hubot中被称为Adapter。比如我们希望Hubot接收来自RocketChat聊天窗口里的消息,我们就必须为Hubot安装一个RocketChat的Adapter。市面上,已经有很多Adapter了,我们很少需要自己实现自定义Adapter。 那么,Hubot接收到命令消息后,怎么知道执行哪些操作呢?这部分是需要我们实现了。本质上就是通过正则表达式匹配命令消息,然后操作。实际上通过写Coffescript脚本实现。比如: robot.respond /open the (.*) doors/i, (res) -> doorType = res.match[1] if doorType is "pod bay" res.reply "I'm afraid I can't let you do that." else res.reply "Opening #{doorType} doors" Jenkins 就这个就不用多介绍了。值得一提是Github已经有不少自动化搭建Jenkins的Ansible脚本了(完全不需要人工干预),本文使用的是geerlingguy的。 Ansible 能让开发人员快速上手的自动化运维工具。我们使用Ansible实现自动化。想简单了解Anbible,可以看看简单易懂Ansible系列 —— 解决了什么。 准备环境 需要准备几台机器: IP OS 安装 192.168.61.11 CentOS7 Jenkins,Openresty(for Jenkins) 192.168.61.14 CentOS7 Openresty(for RocketChat) 192.168.61.15 CentOS7 RocketChat Server, MongoDB,Hubot 因为我是在本地做实验的,所以需要在本机虚拟化3台机器。我使用Vagrant + VirtualBox的方式来实现。具体Vagrant如何使用,不在本文讨论范围。你也可以手工在VirtualBox或Vmware上创建相应的虚拟机。Vagrant只不过是自动化了这个过程。Vagrant会基于一个称为Vagrantfile的文件来创建机器。 ...

2017-10-08 · 1 min · 205 words · 翟志军 Jack Zhai

简单易懂Ansible系列 —— 实现ssh key主机之间复制

我们在搭建Hadoop完全分布式环境时,Hadoop的name node节点(理解为master节点)需要无密码登录到所有的data node节点。 当然,我们使用手工的方式很容易就实现了: 在name node节点上生成ssh key:ssh-keygen 将public key copy到所有的data node节点上:ssh-copy-id slave1 同时,你还必须设置~/.ssh/config,以防止登录时不停的问yes or no: ```yml Host * StrictHostKeyChecking no ``` 完了,还要设置这个文件的权限为400。 以上步骤当然可以手工一步步执行。但是,总有那么一些人:希望所有的操作都可以版本化,所有的操作都应该自动化。我属于这些人。 再说了,我发现在搭建Jenkins环境时,也遇到了同样的问题:需要将Jenkins master的public key加入到Jenkins agent机器中。 可以预见到将来我还会遇到类似的问题。于是,我找到一个方法来自动化以上操作。 在name node机器上执行task如下 创建用户的时候生成ssh_key: - name: create hadoop user user: name: "{{hadoop_user}}" group: "{{hadoop_group}}" createhome: yes generate_ssh_key: yes ssh_key_bits: 2048 ssh_key_file: .ssh/id_rsa tags: - hadoop 将id_rsa.pub拉取到ansible执行机器上 - name: fetch public key fetch: src: "/home/{{hadoop_user}}/.ssh/id_rsa.pub" dest: /tmp/ flat: yes tags: - hadoop 设置StrictHostKeyChecking no 因为我们只想修改这个用户的ssh行为,所以我们的ssh的配置只是针对当前这个用户的: ...

2017-08-19 · 1 min · 157 words · 翟志军 Jack Zhai

简单易懂Ansible系列 —— 解决了什么

不知什么时候,Ansible的slogan从“IT Automation Software for System Administrators”变成了“AUTOMATION FOR EVERYONE”。 从一个给系统管理员使用的工具变成了给所有人使用的工具。 但是,现实中,发现了解Ansible的人,还是太少了。同时,自己断断续续学习Ansible也有一段时间,希望拿出来和大家交流。所以就决定不定期写写一个关于Ansible的系列。如果你觉得我写得还可以,到文末扫码请我喝杯茶。 此文为“简单易懂Ansible”系列文章的开篇 —— Ansible解决了什么 Ansible解决了什么 首先,它是一个运维工具。当然要解决运维过程中遇到的问题了。运维过程遇到了什么问题? 想像一下,你要在一台新的机器上安装Tomcat,你会怎么样呢,条件反射的: ssh [email protected] wget -c http://apache.fayea.com/tomcat/tomcat-8.5.15.tar.gz tar -zxf apache-tomcat-8.5.15.tar.gz .....省略 好,10分钟后你愉快地完成了老板给你的任务。但是现在你需要给100台机器安装Tomcat呢?手工的重复100次? 而Ansible能让我们只定义一次,理论上可以在无限台机器上执行。换句话:减少运维工作中的重复工作。 同时,如果是人工执行100次,那么失误是难免的!自动化运维工具会严格根据我们所给指令来执行,而不会因为失恋而手抖执行了:sudo rm -rf /。 不少人反对自动化,认为那样太危险,因为一不小心就在上百台机器删错文件。显然,他们没有注意到:自动化实现的是准确地执行指令,解决人类执行任务时存在的指令理解不正确、执行不严格的问题。而机器不会出现这些问题的概念几乎为零。 没有达到预期效果,往往是我们人类下达的指令不正确。 所以,Ansible还解决了人执行指令不准确的问题。 如果使用Ansible来实现上述的运维需求,怎么做呢?你需要做三件事情: 定义目标机器的列表:一种被称为inventory的类ini文件 定义这些机器的配置:使用YAML格式的文件来描述你机器的配置 执行 ansible-playbook -i inventory playbook.yml 以下是inventory文件: [tomcat-servers] 111.111.111.111 112.112.112.112 .... 而这些ip的配置写在一种被称为playbook的YAML文件中: --- - hosts: tomcat-servers tasks: - name: download tomcat get_url: url: http://apache.fayea.com/tomcat/tomcat-8.5.15.tar.gz dest: /tmp - name: unarchive tomcat to /usr/local unarchive: src: /tmp/apache-tomcat-8.5.15.tar.gz dest: /usr/local/ remote_src: true .....省略 如果你想再添加100台机器,你需要做的,也只是在inventory文件里添加100个ip,再执行一遍ansible-playbook命令。 ...

2017-06-12 · 1 min · 123 words · 翟志军 Jack Zhai

即将三十,我不敢说我精通任何一项技术

图片来源:http://www.imdb.com/title/tt0395699/ 回顾自己的技术成长之路,具体技术真心没有一样敢说精通,对于一个像我这样工作6、7年的人来说,实在有些难以启齿。 现在中国整个的技术环境看重的是技术深度,而我从一开始就认为应该先广度再深度,自然在同行中被认为是异类。我没记错的话,大神左耳朵耗子的观点就是深度优先。 为什么要广度优先,而不是深度优先。我有自己理由: 技术变化太快,当你还没有深挖到某一个框架的本质,这个框架就可能已经过时了,特别是JS框架 容易只见树木、不见森林:比如你花很多时间去研究如何分布式存储你业务应用中的文件,但是你可能不知道世界上还有AWS S3这样的东西 手里有把锤子,全世界都是钉子:精通写bash脚本的人,所有的运维工作都倾向于写bash来解决运维问题,不知道世界上还有Ansible这样方便的东西,也不知道有时候根本问题不在运维,而在开发 我说出这些理由,并不是说我们就不需要深入研究某个框架和技术,只是想说明我们的选择的优先级会决定,至少会影响我们的思维方式。 这几年,我开始输出一些体现我思维方式的文章,比如: 《耦合的本质》 《关于自动化配置还有什么好说的呢?》 《也许,这样理解HTTPS更容易》 《Puppet,Chef,Ansible的共性》 (根据自己的一次分享整理) 《信息检索中,索引的本质》 很少人发现这些文章的真正价值,因为看起来和他们的实际工作没有任何关系,这些文章不会告诉你怎么快速搭建好https环境,也不告诉你怎么用Ansible copy一个文件到所有的目标机器上。 在一次面试时一位老架构师两次问我:《耦合的本质》真的是你自己写的?显然他不相信写这篇文章的人30不到。确认之后,他说他不完全认同“耦合的本质是假设”,但是他欣赏这样的思维方式。 我头一回感觉到有人看懂这篇文章。 总的来说,这些文章体现出来思维方式是: 利用概念推导、还原事物的形成过程、找共性这3个手段来找到事物的本质,再从这个本质推导基于此事物的上层建筑。 比如我根据我们实际运维过程所要做的事情,推导出要实现自动化所要解决的问题,然后再通过“找共性”的方法,最终找到了这Puppet,Chef,Ansible 三款工具之间的共性。 但是有什么用呢?其实,找到共性后,当遇到第四种自动化运维工具Salt时,我们就很容易提问了: Salt如何与受控机器通信 如何组织机器的? 使用什么DSL来描述这些机器的配置 最后根据这些问题进行深入地学习,这样我们就可以从被动学习变成主动学习,有方法论的学习方式。甚至找到这些工具的知识边界。 然而这只是我的个人学习方式,不一定适用于所有人。也不代表我的学习方式就是好的。 我只想说明:深度优先和广度优先的选择会改变我们的思维方式。 按道理,使用这样的思维方式(有点像方法论),任何一门技术都可以做到精通,但是我目前就是没做到精通。 因为我排斥用脑袋记东西。我认为记不了的东西或者能不记的东西,它就不值得记忆。比如如何将字符串ip转成一个整型数字、Ansible里某个module的具体用法。 而现实中,我对比其他的运维人员,我发现我用Ansible用得已经非常好了,Ansible里的概念我基本已经理解透了。但是我仍然不敢说精通Ansible。我实在记不了unarchive这个module的所有参数。 所以,即将三十了,我仍然不敢说我精通任何一项技术。这成为我的困境。 这时,很多人就会说了,你应该考虑转管理了。 但是,我要问了:为什么要转管理呢? 不少人的回答: 因为你老了,你没有精力去学习更多的新语言、新框架了,你拼不过小鲜肉了。 这个观点里有,有两个假设:第一,到三十后,你学不会,或学得慢新语言、新框架是因为没有精力;第二,小鲜肉没有能力做管理; 第一点假设不成立,因为那只是借口——不想做的人,会找理由,想做的人,会找办法。第二点假设只是概率性问题,小鲜肉也可以做管理。 转不转管理,决定于你是否真的Ready好了,是否真的喜欢做管理。和你年龄没有任何关系。 说到底,写不写代码,做不做管理,都是个非常私人的问题。我们没必要那么在意别人怎么看。 最后,我深爱着写代码。这不会因为我目前或将来是否精通某项技术而改变。

2017-05-10 · 1 min · 44 words · 翟志军 Jack Zhai

为什么站会会成为形式

图截自:http://agilemanifesto.org/iso/zhchs/manifesto.html 最近,项目上遇到了以前我从来没有遇到的事情:10多个人一个团队(概念上的),要应对9个外部需求提出方;要维护超过10个子系统,这个“大系统”还是从另一个不愿意配合的团队接手过来的;项目管理者中,有倾向于敏捷的,也有倾向于瀑布的;最可怕的是这支团队完成组建才1个多月,只有3个人有站会经验,平均工作经验在7年以上😱。 所有的这些条件混合在一起,管理就变得异常复杂,困难。面对这样复杂的乱麻,谁都很难有勇气一刀切。 然而,事情还要做。比如站会。上周我自荐主持一次站会。说实在,那次站会是失败的,因为期间还是有两个人拿手机来刷。 有人拿手机出来刷,说明站会上的内容和他们无关,进一步说明站会是无效的。 但是,为什么呢?我会后一直都在思考这个问题。 我想起自己一年多前,也是带团队从零开始实践敏捷开发。为什么不会出现这样的情况? 突然,一个词蹦出来:共同语言! 站会成为形式的根本原因,就是整个团队没有共同语言!。没有共同语言使站会沦为形式。 好,现在我必须解释两个问题: 为什么整个团队没有共同语言导致站会成为形式? 为什么整个团队没有共同语言? 我先解释为什么整个团队没有共同语言,再解释为什么没有共同语言的团队站会是形式。 为什么整个团队没有共同语言 团队的沟通模型 第一个使整个团队没有共同语言的因素是:团队的沟通模型。 为了方便讨论,我们假设团队的沟通模型为: 项目管理A,对接需求方1、2、3,然后再将任务拆分给Q、W、E。项目管理B、C依此类推。 这样的沟通模型下,为什么团队成员会没有共同语言? 在这样的沟通模型下,开发人员Q平时只与A沟通需求,尽管可能私底下与其他开发人员沟通一下实现,可以说,开发人员Q与项目管理A才会有共同语言。依此类推,每个开发人员只与他的直接上级有共同语言。 我的结论是:趋向于单向沟通的团队沟通模型决定团队成员之间没有共同语言。而且这种单向沟通的结构时间越长,团队成员之间共同语言就越少!现象是,同处一个团队,你不知道你隔壁坐的同学到底在做什么。 没有统一业务术语 第二个整个团队没有共同语言的因素是:团队内部没有统一业务术语。 我们假设站会时,移动团队里的iOS、Anroid、H5三个小组一起参加同一个站会。而在站会时,iOS针对功能A使用了“激活”业务术语,而Android的同学对同一功能A却使用“上线”业务术语。 不统一业务术语不仅导致成员之间没有共同语言,导致更严重的问题是:沟通效率低下。 为什么整个团队没有共同语言导致站会成为形式 其实道理很简单,你问问自己,你喜欢与自己有更多共同语言的人交谈,还是反之?这是人性! 站会时,我们更倾向于听我们关心的,和我们听得懂的。但是因为没有共同语言,所以,我们即不关心,也听不懂! 站会当然也就是形式而已。 怎么破? 这下肯定会有人问,那为什么要站会?取消不就可以了。问这样的人是因为不了解站会的本质:站会一种团队快速反馈的机制。 至于为什么需要快速反馈,很简单:(真正有效的)每日站会的团队可以每天根据站会内容(反馈)来对人员、需求、发布时间进行调整,调整的时间是以天计。而如果只有周会的团队,那么,这个团队调整的时间是以周计,那你觉得哪种团队面对变化时更敏捷,迅速? 说回来,如何让站会更有效,而不至于成为一种形式呢? 至少可以肯定的是这不是一个主持人就能解决的。 剩下的先留给大家思考,我们下篇文章再讨论。 你也可以先读读我之前写过的文章: 每日站会、代码审查、结对编程 之开源中国实践 反馈机制在企业中的作用? 如何防止程序员上班迟到?

2017-05-07 · 1 min · 40 words · 翟志军 Jack Zhai