透明思考


Transparent Thoughts


  1. DevOps来了

    (本文系InfoQ中文站电子期刊架构师[2011年四月刊]之主编寄语 )

    经过几年的酝酿,敏捷和运维这两个领域终于各自受到了足够的重视,并顺理成章地有了交集。从2009年起,一阵被称为”DevOps”的风潮从欧洲发端,迅速席卷了北美和澳洲──现在以Flickr、Twitter为代表的一干互联网公司竞相以快速发布、频繁发布为荣:这厢Flickr做个PPT叫”每天10次部署”,那边Twitter就在演讲里有意无意地说”每天部署几十次”。一说起做互联网,你要是还在走俩月一个版本的发布周期呀,你都不好意思跟人打招呼──等你做出新版本,用户都跑竞争对手那儿去啦。

    顾名思义,”DevOps”就是开发和运维要搞到一块去──每天部署十几次,这两组人是得搞到一块去,不然光是填流程单的时间都不够。凡是参与过流程改进的人都知道,”搞到一块去”这事永远都是说起来容易做起来难。开发和运维,工作的环境不同,沟通的方式不同,使用的工具不同,通常还隶属不同部门,没有点方法套路,说一句”你们要紧密协作”半点用都顶不上。不过,办法总比困难多:流程、技术、工具三管齐下,一点点改进现状,最终达到交付与运维紧密无间的企业文化,至少已经有先例告诉我们是可行的。

    IT技术的潮流,向来是澳洲比英美慢两三年,中国又比澳洲慢两三年。于是很自然地,当别人开始热火朝天地讲DevOps,咱们这儿”敏捷运维”还是几家互联网巨头的王谢堂前燕。不过正因为这个潮流时差,也不难预测,两三年后”敏捷运维”一定会像今天的”敏捷”一样飞入百姓家。所以呢,咱们得从现在开始早做准备──比如看看本期《架构师》精选的几篇文章,先大概了解一下这”敏捷运维”讲的到底是个啥,然后开始做一点思考和分享。等更多企业开始意识到敏捷运维的重要性,咱不就已经成竹在胸了么。


  2. 光与暗的一体两面

    最近两天,看了一些颇丑陋的事,给新同事介绍咨询业务也讲了一些挺灰暗的东西,又看到云风回忆他的网易十年也不尽是情意绵绵。可能这就是年纪大一点的好处:能明白所有鲜衣怒马的下面总会有几块或痛或痒的疮疖,也能勉强接受而不至于马上就要拂袖而去。

    但是同时也不会因为阴暗面的存在就放弃做些有意义的事。大概这是一体两面:曾经在不那么干净的环境(或者干脆就是焦油坑)里努力尝试过,就会懂得阴影总是会在的,光线也总是可以追求的。不仅学着君子远危墙,也学着知其不可为而为,这样算是更好的中庸吧。毕竟乘桴浮于海总是容易的,难事又留给谁来做呢?

    在机场读完了Xiao转发的讨论串。每个精彩传奇的背后总有些狗血的破事,但毕竟不是每坨狗血的破事都能成就一个精彩的传奇。所以,还是只管"GOTEAM"吧。

    (谨以此文答myan问)


  3. Collaborate with Monitors

    ( Copied fromContinuous Delivery)

    Every operations team has some way of monitoring their production environments.They might have OpenNMS, or one of the alternatives such as Nagios orHP’s Operations Manager. Perhaps they have created their own custom monitoringsystem. Whichever system they use, they will want your application to hookinto it so that they know the moment any error condition occurs, and where tolook for more details to determine what has gone wrong.

    It is important to find out, right at the beginning of the project, how theoperations team expects to monitor your application, and make it part of yourrelease plan. What do they want to monitor? Where are they expecting your logsto be? What hooks should your application use to notify operations staff ofmalfunctions?


  4. 代码风险分级

    (本文基本上出自FindBugs

    阻碍风险

    逻辑正确性风险

    这些缺陷模式的出现可能意味着程序员错误地描述了代码逻辑,从而导致程序行为出错。例如:

    • 不可能的类型转换。
    • 永远为假的instanceof操作
    • null调用equals方法
    • 对不同类型的对象进行相等性比较

    多线程正确性风险

    这些缺陷模式的出现可能意味着程序员对多线程环境编程不熟悉,在程序运行中可能随机引发错误。例如:

    • Boolean值同步可能导致死锁
    • notify()wait()不配对
    • readObject()方法同步
    • 错误的静态变量缓式初始化

    关键风险

    易受恶意代码攻击

    这类缺陷模式表示代码没有足够的封装或是放松了已有的封装,在极端情况下可能遭受恶意代码的攻击,或引入不易诊断的错误。例如:

    • 以返回可修改对象的形式暴露内部细节
    • public访问级的finalize()方法
    • final的成员变量
    • 在成员变量中保存可修改的容器

    安全性风险

    这类缺陷模式可能意味着程序员没有充分考虑安全性需求,可能降低系统的安全性水平。例如:

    主要风险

    性能风险

    这类缺陷模式可能导致系统性能水平不必要地降低。例如:

    • 不必要的原生变量装箱/拆箱
    • 显式调用垃圾收集
    • 调用低效的浮点数构造器
    • URL的性能缺陷

    不佳编程实践

    这类缺陷模式指示出不够好的编程习惯,会给维护带来困难,特殊情况下有可能导致程序行为错误。例如:

    • ==!=进行字符串比较
    • clone()方法没有调用super.clone()
    • 丢弃异常
    • removeAll()方法清空容器


  5. 太阳底下没有新雪

    胡凯说,他用了五年时间从纸卡回归纸卡

    用胡凯惯有的乐观态度,这事情是一个学习思考和成长的过程。

    用我惯有的悲观态度,这就是个傻逼事情。人家老早跟你说过了,你不听,绕个大圈子终于绕回来。好不好早点听老人劝呢?

    我惯有的悲观态度之关键在于:大师们当初那样说,其实早就考虑到了各种情况。只是你不知道。你以为自己有了新想法。你以为自己在创新在改进。其实呢,太阳底下没有新雪。过了很久以后你才明白,其实你想的那些,大师们都想过了,想过了才跟你那样说的。你只是自己折腾着玩。

    真正不幸的是我每每看到的创新思维无非分成两类:
    • 跟大师们说的一样。很遗憾,你只是想明白了人家二十年前就说过的事。
    • 跟大师们说的不一样。很遗憾,你搞错了。

    考虑到比如穆斯林从两千年前就在打仗直到今天还在打仗这种事情,这世界还真是令人感到可悲啊。


  6. 转战西安

    上周末公司AwayDay,所有人来了西安。去兵马俑,唯一的乐趣就是拍一大堆同事的人像。然后就留在西安了。

    据说按照招聘网站的职位搜索,DevOps是2010年的大热门:虽说经常跟“Java”、“C”、“Ruby”之类的词汇同时出现,但“DevOps”是2010年增长最快的职位描述关键词。

    然则,为什么OPs的书我还是读不出乐趣来呢?ITIL这样的流程框架读起来实在是味同嚼蜡啊…

    而且据@DEVOPS_BORAT说,每个优秀的DevOps背后,都藏着一个被热妞拒绝的悲催故事。

    凌晨三点起来恢复系统有木有!!!新版本上线就当机有木有!!!敏捷!!!敏捷你妹啊!!!OP都是折翼的天使啊!!!你伤不起啊!!!伤不起啊!!!

    周六在西安OpenParty做了一个简单的DevOps介绍,还偶遇了鲍老师。其实说到DevOps的“怎么做”,很常用的引入变化的技巧仍然适用:

    • Start small and build on trust and safety
    • Create champions
    • Use metrics to build confidence
    • Celebrate success
    • Exploit compelling events

    有235人在用1.HourFor.Me,我也小celebrate一下。也~~


  7. DevOps- How To Start

    (Stolen fromEvan Bottcher)

    How to assess the current situation?

    I would start by drawing a big visual map of the path from developer check-in to production,including the likelyintegration of multiple streams of work. Have the teams estimate the time taken in each stage,likely delaysetc. This can be quite enlightening when seen from a total value-stream view – as few peoplewill have thewhole picture at present.

    Categorise time and effort as ‘value-add’ vs ‘non-value-add’. E.g. time inmanuallytesting from scripted scenarios is non-value-add as a computer could do it more quickly. Manualtesting forexploratory testing is probably value-add, if it is genuinely finding defects.

    Metrics would be build times, deployment time, how long does it take to configure an environment. Howmanydefects are found, how many are true defects, how many are configuration and environment?

    How to shape an improvement plan for “last mile”?

    Need to prioritise areas of concern from your map of the path to production. Root cause analysisshould be doneto understand the cause of delays and defects. Spend some time setting a vision for what the bestpath toproduction would look like for the customer, and build out a set of steps to implement thosechanges. E.g.“shift to trunk development”, “train staff in continuous integration”,“automateself-service production-like environment”.

    Who is able to do this?

    Need to quickly understand the source control, development practices, deployment environment andarchitecture insufficient detail to be able to understand how to improve things. If it’s a unix targetenvironment, bestto understand something of that environment.

    A generalised set of tools/tech/skills:

    • automation (e.g. capistrano, ruby, bash, powershell etc.)
    • source control, and methods to do trunk development and deployments (feature toggles and branchbyabstraction)
    • configuration management – chef, puppet, whatever you can apply to windows servers if that’sinscope
    • understand the ops perspective – tools for monitoring, logging, plotting systemperformance andstability over time (nagios, ganglia, cactii in the open source area)


  8. 关于追求这件事

    有些事虽然你一直都知道它存在,但亲眼见到还是不一样,亲身感受到还是不一样。

    比如说,一家标普300指数的IT企业,它的研发组织要求严格的TDD,要求100%的测试覆盖率,要求严苛的重构,连JavaScript都必须符合编码规范。它的运维团队使用Chef和EC2。它的测试团队进行端到端的自动化测试。它的业务主管们跟程序员坐在一起画界面原型和定迭代计划。

    简而言之,他们做那些我们一直都知道是正确的事,并且坚持做,不找借口。

    这才叫有所追求。

    做能赚钱的事是不需要说的。谁都知道饿了要吃饭。所谓“以交付为核心”、“以达成任务为核心”这些话根本就是可笑:如果连交付都做不到,我为什么还要拿我的那份薪水?做到本来就理所应当被做到的事,不是有追求。

    做正确的事当我能看到收益的时候,这也是不需要说的。地上掉了钱谁都知道要拣起来。只要吃下药去就能治病,这个时候不吃的人是傻子。仅仅不做傻子,不是有追求。

    (当然还有一种可爱的态度是:做不到、做起来有困难的事就赶快贴上个“不可能”的标签然后心安。之所以它是可爱的,因为那不像成年人应该有的态度。)

    所谓有追求,就是即使这件事做下去不会马上看到收益,甚至收益都不会体现在自己身上,但我知道这件事是对的,我就应该坚持做,不找借口。做不到的时候就承认做不到,然后向别人学习,希望自己下次能做到。

    说到底,交付这件事,据说是只要有一帮中专生到北大青鸟培训六个月就可以干的。那么不追求把代码写写好,我去谈什么“以交付为核心”到底有什么意思呢?

    就像我跟小朋友说的,如果你只想满足于交付收钱的话,那你真的会有麻烦,因为中国会写程序会交付的人有太多而且他们比你便宜太多。


  9. 这个春天,我感觉运维们鸭梨很大

    壹、穷人的EC2自动快照

    用两个简单的shell脚本加一个crontab就能每周(如果你愿意的话,每天也可以)备份EC2的机器。今天在Ubuntu上玩各种东西把环境玩复杂化以后,发现这个脚本蛮有用。

    话说,实在没有什么理由,不到EC2搞台机器放自己的博客兼作翻墙梯啊…

    贰、挪亚,不是方舟

    这位John Vincent同志写了一篇博客论述…嗯,为什么有Chef和Puppet还不够。

    Chef和Puppet管理有计划的变更,但你经常会做无计划的偶发变更,而且你不太希望每次变更重启都得重启服务。所以,Vincent桑说,你需要…

    Distributed coordination, dynamically reconfigurable code, elasticity and environment-awareapplications.

    然则,看完Noah的README就知道了。这就是RESTful的RMI…好吧,正确的思想永远都用得上,而且RESTful总比RMI要好那么一点点。

    叁、飞禽走兽们

    Nagios是老牌的监控工具,十多年历史了。

    Hadoop这里好玩的东西不少,分布式文件系统MapReduce,还有重新发明轮子的ZooKeeper

    Sinatra,快速做一个web server,不需要Rails那么庞大,比WEBrick容易写。

    Redis,又一个key-value store。加上Ohm,好了,NoSQL的对象持久化。

    看一遍Noah的使用场景,感到运维们鸭梨很大。

    (还有一本Hadoop的书可我今天看不着…等明天翻墙再说吧。)

    肆、来点音乐

    Music as Datais a live programming language/environment based on Processing.org written in Clojure. It’ssomething likeSuperCollider or Chuck but aims to be easier to hack/experiment live.

    我喜欢他的网站。简约而不简单。


  10. Chef学习手记之叁:红宝石菜谱

    有了一台基本的服务器,现在我就要在上面配置Rails服务器。当然这件事已经有人干过了,但我不想用别人的菜谱,再怎么说我也是RubyWorks的开发者…

    (还有,我觉得Fedora还是不如Ubuntu好用,所以我偷偷把EC2的机器换成了Ubuntu 10.04。)

    新建一个菜谱真容易,用knife一下子就搞定了:

    $ knife cookbook create my_rails_gig

    菜谱放在 #{chef-repo}/cookbooks/my_rails_gig 下面。首先要看的是 recipes/default.rb,缺省菜色的做法就写在里面。在我开始做自己的配置之前,我得先保证Apache和Passenger都配好了。

    # default.rbinclude_recipe “passenger_apache2::mod_rails”

    然后涅,我要用“railsapp”这个用户来部署Rails应用──不可以用root来跑服务。所以我得确保有这个用户(以及它独占的一个组)。

    # default.rbgroup ‘rails’ dogroup_name ‘rails’action :createenduser ‘railsapp’ dousername ‘railsapp’action :createend

    接下来,按照我们RubyWorks的传统,Rails应用应该部署在 /var/rails 目录下面。所以要确保有这个目录。

    # default.rbdeploy_to = ‘/var/rails’directory deployto doowner “railsapp”group “rails”mode “0755”action :createend

    现在是最挑战的部分:配置Passenger…但是只要是像我一样经验丰富的Rails服务器管理员,这个也小菜一碟Apache2那本菜谱讲了怎么在Apache里做web_app,你只要调用就行:

    # default.rbweb_app ‘rails_app’ dotemplate “rails_app.conf.erb”docroot “#{deploy_to}/current/public”server_name “#{MY_COOL_HOSTNAME}”rails_env ‘production’end

    唯一的trick就是rails_app.conf.erb这个template:我需要把它放在 templates/default 目录下(规则和Rails有点像)。别的么…就再没啥啦~~(不信就看代码)噢对了,别忘了在这台机器的角色里加上新的菜色:

    “run_list”: [“recipe[passenger_apache2::mod_rails]”,”recipe[my_rails_gig]”],

    噢也~菜谱写完开始做菜~先把菜谱上传到服务器:

    $ knife cookbook upload my_rails_gig

    再跑到我的服务器上执行一下 chef-client …这就好了。用 railsapp 用户到 /var/rails/current 下面建一个应用(为什么要“current”?问Capistrano)。浏览器访问80端口,看后台日志,Rails已经开始工作了。

    嗯,虽说写自己的菜谱挺好玩的,不过这个菜谱很值得学习──其实很多菜谱都值得学习,所以…

    (未完待续)