刚和墨菲定律信息合作,求介绍新建应用的流程?

注册 | 登录
用故事,讲道理。cunzai
零基础学产品,BAT产品总监带,2天线下集训+1年在线课程,全面掌握优秀产品经理必备技能。
秩序从混乱中产生了出来。——弥尔顿
本文记录笔者总结的工作原则27则,涵盖了一个业务/需求从评估,到立项、策划设计、沟通协作,直到完成的整个流程,每天进入工作前默读两遍,用以警示自己,希望对你有启发。
最重要的是信息。
产品经理:咦?我感觉B活动更适合下周的新年活动啊。
运营:A活动要明显优于B活动,你看昨天我们做了A活动,参与用户比B活动的人数多了2倍!
真相——昨天是圣诞节,活跃用户数量达到20万,是平时的5倍,而B活动是2个月前日活2万的时候做的。A活动的参与率只有B活动的20%。
原则:不要轻易相信,要收集更多信息再做判断
对于产品经理来说,做判断是要比做原型、写文档、跟项目都要重要的事情,而做出好的判断的必要前提是:要掌握足够充分的信息。
需求方:我们的超市今年又再创佳绩!但是无人便利店恐怕会在未来威胁到我们。
产品经理:呵呵,防盗怎么办?无人便利店绝对开不起来!
真相——亚马逊、阿里巴巴还有国内的数十家无人便利店企业拔地而起,发展迅猛。
原则:接纳未知,不轻言否定
作为一个有着常识,基本逻辑的人,面对那些跳脱常识的观点,不免第一反应就是“不可能”。然而世事如风云,变幻莫测,不可能在以以往想象不到的速度变成现实。
产品经理:我们新推出的功能您觉得怎么样,是不是解决了您的问题?好用吗?
用户:嗯嗯。
真相——用户数据完全没有上涨,很快竞争对手推出了另一种解决方案,大受欢迎。
原则:做一个冷眼看客
观察,应该尽量不要影响到事物原本的样子,如果带这主观情绪去询问用户,那么用户很可能会迎合你的情绪;如果亲身跟进到流程中去,那么流程中的人和事可能会发生变形。
用户:我觉得你们这个特别不好用,因为我经常……
产品经理:嗯,我们现在做了优化,在新版本里我们做了A,B,C,D…
用户:可是我还是觉得不好用啊!
产品经理:怎么会呢?那一定是您不会用,我来教您……
真相——用户之所以认为不好用,其实他是想实现另外一个类似的需求,而现在的解决方案并没有注意到那个新需求。
原则:倾听
记住,在现阶段,你的目的是了解用户的需求,而不是去解决某个用户的问题,更不要急迫地想要让用户爱上你的产品。
客户:新版本没有满足我的需求!
产品经理:怎么会呢,我可是按照需求评审会上你的要求做的!
真相——当初客户举例说要在线协调100人,产品经理就真的做成了最大100人的网络,可是客户实际上偶尔也会有协调好几千人的需求。
原则:多想,多问
在需求没有得到最终认可之前,每一个细节都有可能隐藏着陷阱和机遇,因此你需要事事留意,多想多问,不要把它当成一件苦差,因为它完全可以升华意义。
精益求精。
老板:我发现有很多客户对海外品牌很有兴趣,而那些做代购的良莠不齐,正是我们的好机会!
产品经理:是的呢。
真相——海外建仓,加关税,还要另外搭建新的供应链、库存管理、客服系统导致实现周期极长,而且利润率大大低于代购。
原则:做投入产出分析
信息足够丰富的情况下,经验丰富的产品经理,应该能够对业务实现的投入产出进行大致判断,如果做的仅仅是一件“65+50=70”的事情,那么就应该好好考虑了。
运营:你不能因为你不喜欢,就不做这个功能,这对公司来说非常重要。
产品经理:好吧,但是我真的不喜欢这种做法。
真相——产品经理曾经看过类似的失败案例,但是已经不记得了,只是潜意识在让他抗拒这个做法,最终该功能也因为上线后出现了一些用户的不满,因此被产品经理当做借口下掉了。
原则:不做让自己不高兴的事
所有的理性分析,都离不开情感。
我们常说的产品感,就像是救生员的救生直觉,艺术家口中的灵光乍现,其实是平时积累的东西,在潜意识的呈现,如果你经验足够丰富,遇到一件让人极不舒服的事件,那很有可能你是对的。
如果你已经完全理解了原理,还是单纯地不喜欢它,那么将它转交给其他人吧,它有可能会因为你的喜好而被冷落。
老板:我觉得微信的会员卡功能很好,我们也有这么多的用户,照抄一个微信的吧!
产品经理:好的,我觉得我们应该在个人中心增加一个入口,采用……
真相——老板做会员卡的目的只是想让用户了解自己的权限,问题在于当前的用户对特权的感知不强,老板认为用户有了会员卡之后就会仔细研究权限。
原则:先考虑能不能不做
当我们接触到一个新的业务/需求时,怎么才能考虑的更清楚呢?如果仅仅是去考虑它如何实现,实现之后带来的好处,那就相当于一开始就为自己准备了一个狭小的套子,最终也往往是狭隘的。
考虑不做,能够让自己的思考范围从“做”的极端到“不做”的极端,因此思考的可能性就更多。
老板:XX直播的形式很好,我们也需要用户更强的互动,我们也能够做直播吧?
开发:是的,我们能够做的。
产品经理:好的,我也就安排。
真相——公司是做共享充电宝的,用户到app上唯一理由是没电了充电,用完即走。
原则:应该做,而不是可以做
其实不仅仅是在需求,因为“可以做”而盲目去做的人随处可见。笔者就因为会做数据分析,会做测试,会写文案,而被老板、同事理直气壮的要求各种打杂。
放大到业务/需求上,做了不应该做但是可以做的事情,不仅事倍功半,甚至可能会带来用户认知的丧失,给产品带来致命打击。
运营:我们需要一个第二件半价的营销活动。
产品经理:好的,第一件原价,第二件五折,下周实现。
真相——运营在接下来的日子里又提出了第二件6折、买二送一、满100减10等等活动,产品开发每次都临时开发,运营、开发相互抱怨,苦不堪言。
原则:解决一类事,而不是一件事
很多人在去解决一件事的时候,真的就是在解决这么一件事,下一次哪怕只有少许改动,他们也会从头开始再来一遍,更可悲的是,自始至终他们都没有发现这些事情很类似,如果把这类事的原理告知他们,他们也能够想到解决方案,可惜他们就是不能发现。
这其实就要求产品经理具有较强的抽象分析能力,能够理解到事物的本质,一次性解决类似的事情。如果只是一件,一件的去解决,不仅效率低下,也会让人丧失成就感,终日重复着简单、低效的工作。
不仅仅是解决方案。
市场:这个需求对我们来说很重要,希望尽快实现!
产品经理:好的,我们会按照精益思路,先做用户访谈,然后设计MVP,再灰度发布……
市场:???听不懂,反正尽快上线就好了!
真相——需求本身的确对用户来说是有用的,但是市场主要是想要有相关的宣传物料给他们做市场拓展,顺便提升下自己的业绩,对于这个功能最终实现的效果如何,市场根本不关心。
原则:了解需求,也了解关键人的诉求
许多时候,业务部门会跟产品开发对立,抱怨产品开发不能体谅他们,而产品开发也振振有词的表示为用户考虑。但或许并不冲突,处理需求的时候也站在需求人的立场,思考“为什么是他提需求?”,“需求满足后对他会有什么好处”,这样我们在处理需求时也能够更好的把握需求的实现顺序。
开发:我们的新后台打通了A系统和B系统!
产品经理:那太好了,我们可以将麻烦的X后台迁移到新后台!
真相——麻烦的X后台的主要目的就是为了联系A、B系统,而现在这件事已经被新后台做了,X后台已经没有存在的必要。
原则:牢记目的,反复零秒思考
当我们深入细节,往往会忘记初衷,把注意力集中在一个个细分的点上,甚至问题已经不存在了,我们还醉心于研究解决方案中的细节。
零秒思考,是日本麦肯锡合作人赤羽雄二发明的一种思考方法,它可以让你自由翱翔在自己的思绪,去深入思考问题的方方面面,这是我常用的思考方法,推荐了解。
需求方:我要的商务合作的页面做好了吗?
产品经理:嗯,已经加入了排期。不过我想了想,既然做了商务合作,那么对用户也不能吝啬,所以我准备做意见反馈,但是有些简单问题让用户等待实在是体验太差了,所以我研究了一下在线客服系统,还挺好的,可以接入。产品要成长,所以我们要鼓励用户反馈,因此要用积分奖励他,我准备做个积分系统,顺便做个有吸引力的用户等级……
结果——产品经理将这些需求提出来,市场表示他们只需要商务合作,运营表示没资金准备积分奖励,开发表示没时间,客服表示听不懂,老板表示产品经理可以去财务那结下薪水。
原则:保持专注
产品经理常常以脑洞大自傲,但想太多也有可能意味着难以专注,做一个业务/需求,总是患得患失,思绪万千,其实这很有可能是目标不清晰,逻辑混乱的表现。我们要尽量以全局视角观察业务/需求,明确它的目的、职责,保持专注。
需求方:用户扫描领取会员卡的需求做好没有,急着用!
产品经理:还不行,H5的图做的没有体现我们的品牌,资料填写的表格不能判断输入的格式,填写完成之后居然不能够直接跳到应用市场下载app……我们要做就要做好。
结果——第二天果然没有上线,需求方到老板面前声泪俱下,老板批评了产品经理和技术团队,技术团队和需求方对产品经理十分不满。而产品经理一再坚持,终于上线了一个华丽的解决方案,但是一段时间之后,用户似乎无动于衷。
原则:完成&完美&完整
本人是精益创业的拥趸,在满足需求的前提下,越简单的实现就越能被我接受。如果一个需求和它的解决方案被用户认可,那么它才值得被完美,被完整,否则只是劳民伤财。
你以为的,不一定是你以为的。
需求方:圣诞活动测试完了吗?我们已经在用户群里做了预热,反响强烈。
产品经理:哦,上周我们评估了一下,认为这个活动太老套了,实现起来也挺麻烦的,就取消了。
结果——需求方到老板面前声泪俱下,老板批评了产品经理,最终需求方厚着脸皮去向用户解释,需求方不再相信产品经理。
原则:及时反馈
产品经理往往同时面对很多需求方,很多信息,我们常常刻意或者不自觉的将这些需求方和需求做优先级分类,对于信息的变更,也常常认为理所当然,熟不知对需求方来说,这些需求可能非常重要,反馈晚了,就可能会犯下严重的错误。
需求方:你是这个想法啊,可是来到这一步的用户之前就看过这些信息,有必要再看一遍吗?
产品经理:需要的,因为特别重要。
真相——产品经理在需求方表达的同时就意识到了问题,为了维持形象,因此不顾众人反对,坚持上线。后面在用户访谈中,也有用户表达不满,产品经理最终迫于压力改成了自己也认可的方案。
原则:承认错误
许多产品经理认为自己是业务/需求、用户体验方面的专家,听一些“一秒钟变小白”之类的段子,就把其他人都当成小白,不懂装懂,作出一副权威专业的姿态。这样不仅让自己吞下苦果,更会加大自己与用户的距离,变得更加不能理解用户。
合作方:你们要求的,做成跟滴滴一样的模式,我们下周技术对接吧。
产品经理:嗯…行吧。
真相——合作是领导牵线的,希望做到跟滴滴一样的接单模式,产品经理意识到接单模式其实不止一种,但是领导都谈好了,总是没错的吧,而且都准备对接了,现在才来问这种问题,岂不是让人看轻自己?还是算了吧。结果,合作方理解的一样的模式果然是跟产品经理理解的不一样,甚至跟领导理解的也不一样,对接了1个半月的合作来这么浑浑噩噩的结束了,合作方将公司列入了黑名单。
原则:充分表达
不要过分高估了其他人,也不要让不好意思害了自己,把自己踩在脚底下才能更接地气。有疑问就提,有想法就表达,这样能够换取更多未知的信息,对于产品工作,它的作用比你想象中更大。
需求方:我有一个想法,为什么不能做一个定时的引导呢,如果用户停住5秒钟不操作,就弹出提示?
产品经理:这样做会吓到用户的,属于预期之外的事情,还是我这种在页面中增加提示按钮的做法合理。
真相——产品经理意识到那个做法是更好的,但是怎么能让需求方占了上风呢?小小提示无关紧要,这可关系到脸面呢。产品经理坚持的解决方案上线了,但是用户还是一直投诉不知道怎么用,产品经理很后悔。
原则:采纳最好的想法
虽然并非人人都是产品经理,但每个人都有解决方案的能力,采纳最好的想法,不仅会让产品更好,也能够让其他人投入到产品设计中,从而更加认可你的工作。
产品经理:什么情况?这么多BUG,主流程都没有实现?不是让你们好好测吗?
开发:是好好测了呀,测不出来也没办法嘛。
真相——产品经理并没有给出明确的标准,直说“好好测”,开发只是随便点了几下,并没有用心思考。产品经理对开发更不信任了。
原则:一定要有标准
人是感性的动物,绝大多数时候大脑都会选择最节省能量的方式——感觉,去应对问题。所以我们常常会用“我觉得”、“大多数都是”、“可能”、“用心”这种不明确的词语,但当我们去推进事件时,不能够给出明确的标准,会让被推动方感到无从下手,甚至钻空子。而有了明确的,可量化的标准,不仅有助于事件的推动,也能够让我们更有掌控力。
开发:我这已经有很多需求了,时间不多,你这个需求有要求吗?
产品经理:这个需求非常紧急、重要,你们越快越好啊。
真相——开发将需求逐一加入了日程,对这个“越快越好”的需求,由于没有deadline,被开发扔到了一个叫做“零散需求”的地方,直到很久以后产品经理火冒三丈地过来质问。
原则:一定要有deadline
跟需求方呆久了,就会发现对于他们来说,绝大多数需求都是“重要”又“紧急”的,而且要求都是尽快完成。对于这种情况,我向来是不置可否,要求他们给出一个准确的时间。
而自己作为需求方时,为承接方设定明确的deadline,能够避免我们对于项目进展的失控。
产品经理A:我们这次做的会员体系,跟用户的个人中心关系比较大,这是我的方案。
产品经理B:你这个改法有点问题,优惠券不应该弱于会员,毕竟优惠券一直是我们的核心。
产品经理C:我正在做个人中心的优化,改动比较大,你们说的我可都不知道啊,不准改。
结果——产品经理A、B直接对开发团队发起了需求变更,开发一片混乱,好不容易达成一致,产品经理C的改版方案获得了通过,之前所做的工作将全部被推翻。
原则:责任分明
工作中,职责不明确的事情屡见不鲜,有些人因为自己熟悉某些工作就指手画脚,而公司内部还乐在其中,以为这是“开放的全民参与”。这样会带来信息的过载,影响到许多人的判断,更会丧失其他人对于产品经理的认知。
产品经理:怎么跟阿里奶奶的技术对接还没完成,市场那边就已经向客户推广了?
开发:我怎么知道,我们还以为是你安排的呢!
真相——产品经理将工作安排给开发后,就撒手不管了,而需求方向市场直接下达了任务,最终公司不得不向已经签约的用户致歉,并作出补偿。
原则:跟进到底,确保始终有第一负责人
许多产品经理把自己定义成一个接需求,做方案,推开发的内部产品开发的管理者,对于相关的合作、市场、运营的工作不闻不问,甚至抗拒,而其他人对产品经理的定义理解不清,就会很容易第一负责人的丧失,导致项目失控。如果产品经理并不想做主要负责人,或者在某些工作环节与多人对接时,确保有责任人,并确保大家都知道他是责任人。
开发:又是XX提的需求?前两次都是没搞清楚情况就火急火燎的来提需求,这次你调研了没?
产品经理:前两次我都跟他讲明白了,相信他这次不会继续犯错了。
结果——需求人这次依然在犯错,而且出现的问题比之前更大,他也不以为意,让产品经理去收拾烂摊子了。
原则:不要相信一个犯错两次的人
同样的错误,如果两次发生在同一个人身上,那么我会认为这个人是不用心的,不靠谱的,以后需要谨慎防范的,甚至使用一些可以规范他思维的方式,比如需求提出文档、交互检查清单等,去帮助他发现自己的错误。(仅代表个人观点)
设计:这种交互虽然还很新潮,但是在欧美年轻人那里已经很受欢迎了,我们也尝试尝试嘛~
产品经理:看在你这么热情的份上,就这么做吧。
结果——新版本上线之后,用户并不接受,吐槽“越改越差”,迫于压力,产品经理又将其改回了老版本的样子,设计师反而也瞧不起产品经理了。
原则:只做事,不做人
当遇到想法不一致时,很多人不仅考虑事情,还受到人情事故的影响,生怕惹他人不高兴。产品经理作为各方的枢纽,这种事情就更多了,我们的确是要站在其他人的立场考虑,但不应该因为照顾某些人而去做不对的事情,坚持自己的立场,只做事,不做人,或许事情也没你想象中严重。
产品经理:我故意做成这种简单的原型,就是想让你们设计师好好发挥想象力与审美能力。
设计师:该你想的你不想,还让我来帮你想,你是产品经理还是我还是啊!我不管,反正你原型什么样我就做成什么样!
真相——设计师以前都是由需求方给出图,然后将其上色,改成高保真,对于交互设计也并没兴趣,认为产品经理应该做出高保真和交互效果。产品经理苦心劝导无果,反而被设计师告到老板那里说“不懂脑子,推卸责任”。
原则:区分对待,赋能与把控
赋能,给一个目的,让执行人自由发挥;把控,明确做法、步骤、目的、时间,让执行人严格执行。自谷歌提出赋能后,国内大大小小公司都提出了各种赋能,我也很喜欢给同事赋能,但事实证明,很多人不理解,不接受,不能承受赋能,把控对他们才是有效的。
观察你的合作伙伴,根据情况赋能与把控,让他们都进入到更舒服的状态。
开发:这个功能做的不彻底啊,为什么不一次性开发完?
产品经理:哦,你们一直说时间紧,任务重,所以我故意做简单点,以后有时间了再补充。
真相——一次性开发完并不比现在麻烦多少,开发很高兴对别人说时间紧、任务重,讨厌外行评估他们的工作。
原则:不了解别人的立场,就别自以为是对别人好
作为同理心强的产品经理,我们常常为其他人考虑,做我们认为对他们好的事情,但是其他人似乎并不领情。这是因为“为你好”与“站在你的立场”是不同的,如果不能理解别人的立场,那么千万别自以为是对别人好。
开发:这里漏了一个逻辑,如果用户是先买东西后取消订单,这个商品会对他15分钟内不可见!
产品经理:还好,用户都取消了就不太可能再买了,还是上线重要!
真相——这是电商购物的一个很正常的现象,出现的概率还是有的。上线之后,投诉电话如潮水般涌来,用户流失率飙升,产品经理不得不跟开发一起,通宵修复BUG,并做用户道歉。
原则:相信墨菲定律,不抱侥幸心理
写这最后一条,其实是用来警示自己,除了做事不要抱有侥幸心理外,对于以上的26条原则也不能随意违反,事情都是从不紧急变成紧急的,问题都是从小问题变成大问题的。
#专栏作家#
朝聆夕改,人人都是产品经理专栏作家。移动应用客户端产品经理,关注移动社交、教育等领域;拒绝空谈的行动派,爱深度研究。
本文原创发布于人人都是产品经理。未经许可,禁止转载。
题图来自 Unsplash,基于 CC0 协议
赞赏是对原创者的最大认可
赞赏6人打赏
收藏已收藏 | 206赞已赞 | 43
用故事,讲道理。cunzai
产品经理群
运营交流群
品牌营销群
文案交流群
Axure交流群
关注微信公众号
大家都在问
5个回答8人关注
5个回答8人关注
129个回答178人关注
56个回答63人关注
15个回答44人关注
19个回答42人关注Docker和PID 1僵尸进程问题
当构建Docker 容器时,需要注意PID 1 僵尸回收问题,那个问题会在你最不期望出现问题的时候,导致一些不期望的结果和看起来很困惑的问题。本文解释了PID 1问题,解释怎样解决它,并
当构建Docker 容器时,需要注意PID 1 僵尸回收问题,那个问题会在你最不期望出现问题的时候,导致一些不期望的结果和看起来很困惑的问题。本文解释了PID 1问题,解释怎样解决它,并且作为一个预先构建的方案--可以作为一个基本的Docker镜像来使用。
当上面的问题解决了,你可能会想去读&
大概一年前-回溯到Docker0.6 的时期-我第一次介绍。这是为了对Docker友好而修改的最小的Ubuntu 基础镜像。其他人可以 并且把它作为他们自己镜像的基础镜像。
我们是早期的Docker使用者,用Docker来持续集成并且在Docker达到1.0版本之前,用作搭建开发环境的方式。为了解决一些使用 Docker能够解决的问题,我们开发了docker基础镜像。例如,Docker不会在某个恰当处理子进程的初始化进程下运行进程。以至于容器有可能结 束导致各种各样的问题僵尸进程。Docker 也不会做任何事情,以至于让重要的消息能够正常的被处理等等。
然而,我们已经发现很多人对我们解决的问题理解上有问题。Granted,是Unix操作系统底层很少人知道和理解的系统级机制。所以在本文中我们将会详细描述这个我们已经解决了的最重要的PID 1僵尸进程问题。
我们发现:
我们解决的问题适用于很多人
大多数人甚至没有意识到这些问题,所以很多事情会以意想不到的方式被打断(墨菲定律)
如果每个人都一遍又一遍的重复解决这些问题是低效率的。
所以我们在空闲时间,把解决方案提取为每个人可以复用的基础镜像:Baseimage-docker.这个镜像也加入了一些有用的,相信大多数Docker镜像开发者都需要的工具。我们把Baseimage-docker作为我们所有Docker镜像的一个基础镜像。
社区看起来喜欢我们所做得事情:我们是Docker注册处最流行的第三方镜像。只是排在了官方的Ubuntu和CentOServer镜像下面。
PID 1 问题: 进程僵尸
回想一下Unix的进程是一个有序的树。每个进程可以派生子进程,每个进程具有一个除了最顶层以外的父进程。
这 个最顶层的进程是init进程。它是当你启动系统时由内核启动。这个init进程负责启动系统的其余部分,如启动SSH服务,从启动Docker 守护进程,启动Apache / Nginx的,启动你的GUI桌面环境,等等。他们每个进程都可能会反过来派生出更多的子进程。
到目前为止还没有什么特别的。但考虑到如果一个进程终止会发生什么。比方说,bash(PID 5)进程终止。它变成了一个所谓的&停止活动的进程&,也称为&僵尸进程&。
为什么会这样?这是因为Unix被设计为这样一种方式,父进程必须明确地&等待&子进程终止,以便收集它的退出状态.。僵尸进程一直存在,直到父进程已经执行该操作,使用系统调用函数。我从手册页引用
&一个子进程终止了,但一直被等待就变成了&僵尸&。内核维护了一组关于僵尸进程最小的信息列表(PID,终止状态,资源使用信息),为了让父进程以后进行等待时,能够获取有关子进程的信息。&
在日常的语言中,人们认为&僵尸进程&是会造成严重破坏的混乱进程。但正式的说 - 从Unix操作系统观点 - 僵尸进程有一个非常明确的定义。他们是已经终止,但没有(还)被他们的父进程等待的进程。
大多数时间这都不是问题,在子进程上调用waitpid()的动作是为了消除它的僵死进程,这就是所谓的&收割&。许多应用正确的收割它们的子进程。在上 面的例子中用的是sshd,如果bash终止了然后操作系统将会向sshd发送一个SIGCHLD信号把它唤醒。sshd注意到了这个信号后就收割子进 程。
但是有个特殊情况,假设父进程终结了,或者是故意的(因为程序逻辑决定该退出系统了)或者是用户的操作导致的(例如用户将这个进程杀死了)。这个父进程的子进程将会发生什么?他们不再有父进程了,所以他们变成了&孤儿&(这是实际的专业术语)。
这就是init进程起作用的地方。init进程--PID 1--有一个特殊的任务。就是&接收&孤儿进程(注意,这是实际的技术术语)。这就意味着init进程变为了这些进程的父进程。尽管这些进程从来都没有被init进程直接创建。
拿Nginx作为例子,默认是作为后台守护进程。它是这么工作的。第一,Nginx创建一个子进程。第二,原始的Nginx进程退出了。第三,Nginx子进程被init进程给接收了。
你可能知道我将要表达什么。操作系统内核自动的处理收容,所以这就意味着内核期望init进程要有一个专门的职责:操作系统也期望init进程收割被接收的孤儿进程。
这是Unix系统中一个非常重要的职责。它是如此基础的职责以至于很多很多软件的都利用了这一点。所有的守护软件非常期望被守护的子进程都被init进程收容和收割。
尽管我用守护进程作为例子,但不限于守护进程。每当一个进程退出了,虽然它还有子进程存在。这是因为它们期待init进程稍后来清理。这些已经详细的在这两本书中描述了:&著&Silberschatz等和&著&Stevens 等。
为什么僵尸进程是有害的
即使他们终止了进程,为什么僵尸进程是一件坏事&? 原始应用程序的内存已经被释放,对啊?这不仅仅是一个条目,你在ps中看到它了吗?
你是对的,原始应用程序的内存已经被释放。&但事实上,你还看到它在ps中,这意味着它仍然占用一些内核资源。 :
&只要一个僵尸进程通过等待没有在系统中被移除,&它就会在内核进程表中消耗一个位置,并且要是这个表被填满,那它就没办法创建一个新的进程。&
与Docker的关系
那么这怎么涉及到Docker?我们看到很多人在他们的容器里只运行一个进程,他们认为运行单进程,他们的工作就结束了。但是,这个进程写出来并不是为了 完全像init进程的行为。也就是说,非但没有恰当的收割被收容的孤儿进程,反而没准它还期望其他的init进程来正确地做那样的工作。
让我们来看看具体的例子.假设你的容器运行了一个web服务器,web服务器运行一个CGI,它是用bash写的脚本。CGI脚本调用grep.然 后web服务器决定CGI脚本运行的时间太长了并且杀死了这个脚本,但是grep 没有受影响并继续运行。当grep结束了,它成为了僵尸并且被PID 1收容(web服务器)。web服务器不知道grep,所以web容器不收割它,然后grep僵尸进程停留在系统中了。
这个问题也适用于其他状况。人们经常为第三方应用创建Docker容器--比如PostgreSQL--并且把这些应用当做灵魂进程在容器中运行。当你正 运行其他人的代码,你能确保这些应用接下来不会大量产生僵尸进程吗?如果你运行你自己的代码,并且你审计了类库。没发现问题。但是通常情况下还是应该运行 一个适当的init系统进程来阻止问题发生。
但是运行一个全初始化系统不会让container重量级并且像一个虚拟机吗?
一个初始化系统没有必要是重量级的,你可能很轻易地就想到了Upstart,Systemd,SysV等初始化系统。可能你认为完整的系统需要在容器中被启动。其实不是这样的。我们所说的&全初始化系统&,是没有必要的也不是令人满意的。
我所谈论的初始化系统是小的,它的唯一职责就是启动你的应用,并且收割收容的子进程。使用如此简单的初始化系统是完全符合Docker的哲学的。
一个简单的初始化系统
是否已经存在一个能够运行其他应用并且能够同时收割收容的子进程的软件?
有一个几近完美的解决方案,每个人都有--它是简单陈旧的bash. Bash正确的收割收容的子进程。Bash能够运行任何事。所以不是要把这些放到你的Dockerfile中...
CMD [&/path-to-your-app&]
&&你可能有兴趣用这个替代:
CMD [&/bin/bash&, &-c&, &set -e && /path-to-your-app&]
(-e 指令阻止bash把这个脚本当做简单的命令直接执行exec())
这回导致如下处理层次结构:
但是不幸的是,这个程序有一个致命问题,它没有正确处理信号!假设你用kill发送SIGTERM信号给bash.Bash终止了,但是没有发送SIGTERM给它的子进程!
当bash结束了,内核结束整个容器中的所有进程。包扩通过SIGKILL信号没有被干净的终结的进程。SIGKILL不能被捕获,所以进程是没有办法干 净的终结。假设你运行的应用程序正忙于写文件;在写的过程中,应用被不干净的终止了这个文件可能会崩溃。不干净的终止是很坏的事情。很像把服务器的电源给 拔掉。
但是为什么要关心init进程是否被SIGTERM给终结了呢?那是因为docker stop 发送 SIGTERM信号给init进程了。&docker stop& 应该干净的停止容器,以至于稍后你能够用&docker start&启动它。
Bash专家现在可能会有兴趣写一个EIXT处理器,它简单的发送信号给子进程,像这样:
#!/bin/bash
function cleanup() {
local pids=`jobs -p`
if [[ &$pids& != && ]]; then
kill $pids &/dev/null 2&/dev/null
trap cleanup EXIT
/path-to-your-app
不幸的是,这个不解决问题。仅仅是给子进程发送信号是不够的:init进程在终结自己前必须等待子进程终结。如果init进程过早的结束了,所有的子进程又没有干净的被内核终结。
所以明显的一个更加复杂的解决方案是需要的。但是一个全初始化系统像 Upstart,Systemd 和SysV init对于轻量级的Docker容器来说就是赶尽杀绝。幸运的是,Baseimage-docker有一个解决方案。我们已经写了一个自定义的,轻量级 的初始化系统。特别是在Docker容器内。由于缺少一个好的名字,我们把这个程序叫做,一个350行最小资源使用率的Python程序。
my_init的一些关键特性:
收割收容的子进程
&执行子进程
&等待直到所有的子进程都终结了才结束自己,并且用最大超时时间。
记录活动到&docker日志文件&。
Docker会解决这些吗?
理想的,这个PID1问题是被Docker本地解决的。如果Docker提供一些内嵌初始化系统能够正确收割被收容的子进程那将是很伟大的事情。但是直到 2015年一月,我们也没有注意到Docker团队为解决这个问题付出任的何努力。这不是苛求--Docker是非常有雄心的,并且我相信Docker端 对有更大的事情需要关心,比如进一步开发它们的编配工具。PID1问题在用户层面是可以解决的。所以在Docker官方解决这个问题之前,我们建议人们自 己通过使用恰当的和上面描述的行为一样的初始化系统来解决这个问题。
这真是问题吗?
从这一点来说,这个问题可能听起来仍然不真实。如果你从来没有在容器中看到过任何僵尸进程,那么你可能倾向于认为所有的事情都很正常。但是唯一让你认为这 个问题从来没有发生过的方式,是当你已经评审完你所有的代码,类库代码,以及类库依赖的类库代码。除非你已经那样做了,否则有些通过上面描述的方式产生进 程的代码,他们随后可能会成为僵尸进程。
你可能会认为,我从来没有看到它出现,所以机会是很小的。但是墨菲定律说道,当事情可能会出错,那么它们就会出错。
除了僵尸进程持有内核资源这个事实外,僵尸进程的不离开也会干扰那些检测进程是否存在的软件。例如&管理进程。 它重启那些崩溃的进程。崩溃监测通过分析 ps&的输出实现和发送0信号到进程ID实现的。僵尸进程是通过ps 和对0信号的响应来显示的,所以Phusion 乘客认为这个进程依然存活,尽管他已经终止了。
再想想取舍。阻止僵尸进程的发生这个问题的发生,你所需要做的就是花5分钟,或者使用docker基础镜像,或者导入& &到你的容器中。内存和磁盘占用很小:只占用内存和硬盘几MB空间就能够阻止墨菲定律发生。
所以PID 1 问题是需要注意的的问题。一个方法就是使用Dock基础镜像。
是否Dock基础镜像是唯一的解决方式?当然不是,Dock基础镜像的主旨是:
1.使人们书一道一些重要Docker容器的警告和缺陷。
2.提供一些预先解决方案方便其他人使用,以至于其他人不至于针对此问题重新发明解决方案。
这也意味着多种解决方案的存在,一旦他们解决了我们描述的这个问题。你可以自由的重新用C,Go,Ruby 或者其他什么语言来实现该解决方案。但是我们已经提供了一个很好的解决方案了,你为什么还要这样呢?
可能你不想使用Ubuntu作为基础镜像。可能你会使用CentOS。 但是不要停止使用image-docker所给你带来的好处。 举例来说,我们的& 项目使用CentOS容器。 我们简单地提取了基础的image-docker的my_init并且将其引入。
因此,即使你不使用, 或者不想要使用Baseimage-docker,好好看看我们描述的问题,考虑你能做什么来解决这些问题。
快乐的Dockering.
第二部分: 我们将讨论这一现象,很多人将Baseimage-docker与&胖容器&联系起来。 Baseimage-docker根本不是关于胖容器的,&那么他是什么? 参看
原文:http://www.oschina.net/translate/docker-and-the-pid-1-zombie-reaping-problem
转载请保留固定链接:
------分隔线----------------------------
fail2ban是由Python语言开发监控软件,通过监控系统日志(Debian/...
Linux在4.9版本的内核新增了一款TCP拥塞控制技术:BBR, Linode 最新...
概述 RabbitMQ是一个开源的AMQP实现,服务器端用Erlang语言编写,支...
概述 RabbitMQ是一个开源的AMQP实现,服务器端用Erlang语言编写,支...
一、使用背景 当生产环境有很多服务器、很多业务模块的日志需...
What is the opcode cache? When the interpreter to complete the analysis of script...

我要回帖

更多关于 墨菲 的文章

 

随机推荐