为什么极力支持测试驱动开发TDD

国内的一个很流行的博客上面讨论了TDD的一些问题,并且顺带批评了某咨询公司的咨询师不够脚踏实地。我在那个博客留言表达过我的不同意见,前几天随着另外一篇对TDD质疑的文章发表我和文章的作者在Twitter上论战了一番,不过论战是不能解决问题的(之前InfoQ上的虚拟讨论也没有解决问题),所以我再简单的整理一下我的意见。

首先,我声明我是一个笃信极限编程对『编程』有巨大价值的人。而TDD是极限编程XP里面的实践之一,在讨论XP的过程中我们一般都倾向于使用『实践(practice)』这个词,而不是『方法论(methodology)』,原因是极限编程描述的这些『方法』实际上是很多做事的具体方式,而不是一种『理论』。

我不应该咬文嚼字,不过有些时候这很重要。我需要从极限编程这个名字开始讨论这个问题。以前的一次OpenParty上,o6z问我『你知道极限编程为什么叫极限编程么?』,我当时真的不知道答案,只是隐约觉得极限编程的很多个体实践都是一种极限的挑战。而后o6z说『其实极限编程就是指程序员公认一些最佳实践,他们致力于不断的改进、优化这些最佳实践,最后把他们推向极致,这就叫极限编程』。这个答案可能是官方的,也可能是坊间流传的,不过我觉得它特别贴切,解释了极限编程的价值观。我当前公司的CEO上次调侃过『价值观』这个词,他说价值观说出来就不灵了,就成狗屁了……他说真正的价值观体现在你做每个决策的时候左右你的那种抽象的直觉。极限编程的每个写下来的『实践』其实就是写下来的价值观的体现,在实践的过程中最重要的就是不断的去磨练你的直觉,让价值观内在化。OK,极限编程我说道这里。

TDD,测试驱动开发。我们按照刚才阐述极限编程的涵义推演一下TDD是怎么来的。我们在写程序的时候发现不对程序进行细粒度的验证就很容易产生Bug,逐渐的整个编程社区有了一个最佳实践『单元测试』,我们也知道『单元测试』是相对于『集成测试』和『系统测试』的,我们提高程序内在质量的时候这些测试工具我们都要使用,只是有时其它测试会通过那种被叫做QA的程序员编写。为了不扯到另外一个话题,我们继续,当大家公认测试是最佳实践的时候,极限编程社区把测试推向极致。极致的测试应该具有细的粒度,高的覆盖率,有意义的验证条件,全面的边界条件,不脆弱等等,这些指标单个都不产生价值,但是在某个平衡的状态它具有最高的价值。极限的TDD的目的就是找到那个平衡。

我们退一步说,其实目前我们的程序员社区绝大部分人面临的都不是是否可以做好TDD,找到那个最佳的平衡点的问题。现在的主要问题还是是否可以写出有意义的测试,如何写测试的问题。其实质疑TDD的朋友经常的理由是『只要写好单元测试就可以了』,这其实正是我现在说的我们大多数程序员的困惑。也就是说『使用TDD』的对面是『能够写好单元测试但是不做TDD』,我认为这是一个伪命题。因为TDD的目的就是把测试这种最佳实践推向极限,这是一个过程,我可以把它分成两个阶段:

  • 第一个阶段是通过TDD强制从不写测试向写测试转变,因为绑定了写测试和写代码的节奏,它可以保证你写出的代码是可以测试的;
  • 第二阶段是通过不断实践和优化TDD让你能够写好测试。因为测试不只是有单元测试,还有系统测试和集成测试,随着对TDD的熟悉你会发现可以用不同层级的测试来驱动你的设计。使用越高层级的测试越有难度,这也是极限的一种体现。现在比较普遍的BDD其实就是将领域模型驱动DDD这种建模的方式与TDD结合的产物, Spec的描述形式让它不仅可以组织好单元测试,也可以组织好系统测试(如验收测试驱动设计,ATDD)。第二个阶段可以一直优化,永远没有极限,这个过程是最有价值的;

这种阶段化的实践其实内置了一些积极的意图:

  • 先写测试后写实现其实是把同时写测试和实现更近一步的产物。同时写测试的一种形容就是『可测试性驱动程序开发』,前几年老赵就写过这方面的博文,并且从可测试性上论证了TDD的积极意义。因为只有同时写测试和实现才能最好的保证你的代码是可测试的。而解决可测试性的难题的关键点是有可以检查验证条件(而不是足够细的粒度,细粒度既不是充分条件也不是必要条件,只是细粒度容易找到验证条件而已),也就是测试结果需要可验证。如果没有已知的可检查验证条件,那么可测试性就无法保证。所以先构思一个测试验证点再写代码是这个逻辑的体现。
  • 测试准备耗时费事,但是如果我们偷懒不做,那么后期可能面临的是完全无法做。保证测试容易准备需要在设计上多加考虑,如慎用Singleton等。这些思考可以影响你的设计,帮助你着力思考系统中的哪些状态是可变的,哪些是不变的,帮助你强化设计出无副作用或者少副作用的代码(因为有副作用的代码更难准备测试环境,环境的组合会多变),这帮助你函数化思考。
  • 红绿的节奏和小步前进可以帮助你减少对调试的依赖。调试和测试都是我们验证Bug的工具,不过我们最好在难以复现的场景使用调试这种终极武器,在编码阶段反复的进入调试说明你的测试有问题。编码阶段调试的常见原因就是测试没有跟上,因为我们知道最最常见的代码错误就是拼写错误。测试和调试找到拼写错误的代价是完全不同的。小步前进配合现代版本控制工具可以让我们完美的通过折半查找找到出问题的代码所在,如果有自动化测试套件的话折半查找还会事半功倍。这一条是说TDD的节奏所鼓励的小步前进的好处。
  • 测试驱动的测试需要有一个明确的名字。在寻找名字的过程你会重新思考这条验证的目的,让你整理需求的思路,也就是提醒你经常的问『为什么?』。细粒度的问为什么,并且为这些需求设计测试场景,这对每个想要贯彻『具体问题具体分析』的程序员非常重要。

这样的王婆卖瓜的理由我还有很多,多说无益。其实这里有一个关键的问题需要澄清,我们说TDD有这么多积极的意义,但是我们不能说『所有的代码都要TDD』,因为它很容易让TDD成为不现实的『生产力毒药』。当初比我经验丰富的一位同事就和我说『Spike(技术验证)的时候不需要TDD』,我发现在需要自由翱翔的时候放弃TDD的确是很舒服的事情,不过每当我们看这些Spike产生的代码时我们会发现TDD的重要性。因为这些 Spike出来的代码经常惨不忍睹。另外一位资深的同事就又和我说『Spike完成后,你应该删掉那些代码。然后重新TDD去实现它们,因为严格测试、精心设计过的代码才是为生产环境准备的』。我举的这个例子不能绝对化,不过我想表达的是,如果你想知道不做TDD的后果,那么一定要先做好TDD,回去对比观察没有TDD代码的不是。大部分关于TDD的批评大都来自那些还没有完全掌握TDD的人,工作流还没有很好的优化,此时对比『写单元测试』的自己就开始觉得TDD让自己混身不适了,『把最佳实践推向极限这个行为』要在完全掌握『最佳实践』的前提下才可以继续修炼。

我这里放一个比喻,我不知道是否贴切:有一种修行是爬看不到顶峰的山,视力可及的半山腰上有一片开满鲜花的平台。有些人爬到平台就下结论『爬到山顶也不过如此,也许还没有这么多鲜花呢』。但是另外一些人则继续攀登,以致山下都看不到他们的身影了。半山腰的人也许会开始质疑那些继续攀登的人的动机,说这完全是一种宗教。对于继续攀登的人来说,的确是一种信仰让他们坚持下去,那就是极限编程。关键的问题在于,对于那些山脚下的『沉默的大多数』人而言他们应该听谁的呢?是应该相信半山腰的人说『那些持续攀登的人走火入魔了,其实半山腰这里就最好了』?还是跟随那些持续攀登的人所走过的路走下去?其实,持续攀登的人会告诉所有山下的人你随时可以转身回到那个平台去,所以我们的行为是安全的,不过如果你持续攀登,那山上一定有一个更好的世界。有些人听了前者的话停留在山下徘徊,因为他们绝得那半山腰也不过如此,山下的日子很好过。但是有些人听了后者的话爬上了半山腰,还有一些也成为了后者。

这种比喻可以写的很华丽,不过这不是什么论据,它只是一种修辞而已。《思考的技术》这本书的第二章叫「逻辑打动人心」,我摘一些句子:

“但是”、“然而”这种话,对于改善经营而言,有白害而无一利

这是借口中常用的词,它会给出一个反面的评价,而后是中庸的『具体问题具体分析』。极限编程不是这样,它是单向的夸张,把最佳实践推向极限。所谓『写好单元测试就好了,要具体问题具体分析』其实是不写测试的一个好借口。如果你想让自己积极的去实践,请给自己一个极限的理由,当然,你随时都可以转身回到那个平台的。

如果给客户的药方,只是没有什么感觉的营养剂,客户的经营状况将无法改善

这是我想说明极限编程的极限的意义。这些推向极限的过程不是邪教,让你以为最后可以看到神迹而葬身途中,它的目的是给你一剂猛药,让你更好的走到那个平台,甚至到下一个层次上去(第一个平台的人兴许都不知道后面还有其它平台吧?)。

其实说到这里咨询公司的秘密也揭开了。咨询公司的医生不是包治百病的,他们的大部分都是希望给你一个最佳的『盗梦空间中的术语,植入想法,Inception』,期望这个植入可以帮助你向积极的方向前进,不过你的行为依然是你自己控制的。好的咨询公司不会利用这个机会『洗脑』,因为他们自己也在不断追求极致的过程中。这更像把酿造啤酒的技术推向极致的修士们(Trappist,非常著名的修道院啤酒的修士们通过几代人不断的优化酿造他们认为完美的啤酒,具有稳定而微妙的口味)所做的修行,他们自己在不断优化自己所做的事情,并通过咨询把这些Inception植入客户的思想。这里还要澄清一个问题,不是修道院中的所有修士都有崇高理想,有些新进来的修士不会酿酒,有些隐藏在修士中的南郭先生可能没有追求极致的精神,这非常正常,我们都是不完美的,我们的组织也不会完美,不过我们依然可以有追求完美的组织。

写到这里,我重复一下我在OpenParty的朋友中经常说的一句话『要把积极的影响施加给身边的朋友们』,我不像Cleverpig信仰巴哈依教,不过我坚持积极做人,积极影响人。极限编程和其中的TDD都出于同样的动机,施加给所有的程序员积极的愿望,不断的优化自己的工作流,以期达到最终的『极致』。谢谢观赏。

内文的一些链接我会稍后添加

后记:最近工作家里都忙,有了一个小公主需要伺候,所以没有太多时间更新Blog。我写博客不是让人围观的,而是写给自己和我所爱的家人朋友。我在Twitter上口水战还有写这篇博文主要是『质疑TDD和某咨询公司』与我的价值观冲突,所以我才不得不写这篇博文表达我的观点。我和我的朋友们还在努力组织好OpenParty的Unconference活动,我们的理想主义可以在这个活动上得到满足,我们给大家一个自由的分享与获取知识的机会,并且更重要的是我们要把积极的态度植入到参与活动的朋友的意识中,我想这是让我们生活更美好的最佳途径。

The value of reading news

Recently I found I’m addicted on reading news, including gadget news, social headlines and hacker news. Today, I’m thinking why I read so much news? What’s the value of reading news?

The news include content and context, but there are more things underneath. When we read news, we got a story of what just happend, but this is not very valuable. The content and context is history journal, we just put some sentence and images into our memory. This is no difference with a comupter, and computer is good at recording things, it never changes or forgets. We are human, we have non-linear thinking machine, which give us some outputs after thinking. I think there are 3 main elements for human, thinking, feeling and memory, reading news just give us some outputs of memory and feeling, those things construct a timeline in our brain. And when we have spare time, the brain thinks in right mode, and it may give us idea at anytime. Acctually, the most value part is making a point of view, so we determine which part we should stand for this piece of news. This judgement can be irational, I means the reason and the result may has no direct connection, we just jump to a conclution. I think we can call it taste. And I remember this quote “The only thing you can trust is your taste”. This irational process of making judgement is our taste.

We should split news into two categories. One is a report of a story, it tells us what just happend, like a statement, we just recieve it and store. Another is a comment of something, so there will be some personal judgement or ideas come from reviewer. They already stand on a side of this story, and we will recieve this comments and record the direct feeling of there comment. For example, the techmeme always tell us the breaking headline of different news source, but most of which is plain story. The other example is hacker news, it contains lots of blog post about someone’s opinion, those report is more like sharing taste of those things. I prefer the deep analysis of news, like hacker news’ style. They put non-linear reason and result together, help us organizing out thoughts in reviewer’s points of view. This thinking practice helps us make our own taste.

If we only store news, it’s a huge waste. I we just day dreaming, it’s useless too. Reading some news, and corresponding analysis is good for us. This may be the real value of reading news.

Don’t waste too much time on reading news, most of them are fast food. You should do long reads too, long articles are more nutritious. Magazines are way between long reads and online fragment reading, whe should balance the ratio of them. Keep processing langurages and images in our memory is important, it’s your privilege, it helps you find your real taste.

诚信

怪诞行为学》的第八章“性本善还是性本恶”里面说了诚信的重要性。里面有一些关于诚信的试验,大意是说诚信和道德约束有关系,当一个行为不符合某个人道德约束,并且这个人此时意识到了这个道德约束(一些因素会影响这种意识的强烈程度),那么他就会选择放弃不诚信的行为。里面写到:

诚实为什么重要?一个理由是,我们别忘记美国在当今世界上占据经济强国的位置,就是因为(起码我们认为),在企业管制标准上,它是世界上最诚实的国家之一。

今天早上听《锵锵三人行》,这一期正好也说的是诚信。诚信可以分解为两个部分,诚实和信任。因为互相诚实才会互相信任。这在我们现代的中国,是严重缺失的,社会上大量的热点事件和诚信的缺失相关。每次提到缺乏诚实,都会提到所谓的“厚黑学”对我们社会道德的影响,我们的生活圈子里面的确因此有很多人推崇“术”和“礼”,所有的事情都需要讨论一下如何“经营”。这一方面说明我们善于思考,知道如何通过一些行为来影响事情的发展,以保持自己的利益。很少有绝对诚信的团体,但是有些团体更诚信一些。我非常希望生活在更诚信的团体中。

我们朋友间经常评价某人是否“靠谱”。我想“靠谱”的朋友大部分是真诚对待我们的人。我不是说一个人对所有人真诚是“靠谱”,我指的是他对我们诚实,所以对我们这个小群体来,他/她是可信的,那么我们就把这个人归做“靠谱”的人。

要想表现的诚实,需要一个起码很小的可信的环境,也就是说如果一个最小的可信任环境都没有的情况下,诚实是做不到的。我们身上可能都发生过这样的事情,某人在路上把你拦下,说路上发上了什么意外或者迷路了,希望跟你要一些零钱回家。在第一次遇到这样的故事的时候,我们小时候学到的乐于助人的道德标准会鼓励你给他们一些钱,你给了以后心里还甜滋滋的。这里面有个条件,要钱的那个人的“表演”一定要非常的真诚,让你相信他/她,你们之间有一个很小的诚信环境,所以你的道德约束就可以起作用。但是,事实是,这种情况几乎全部都是骗局(女巫店的《机场奇谭录》),朋友亲人的教导还有再次遇见这种表演会让你知道这是不可信的。这时你在遇到这种事情的发生的时候,你和骗子之间是没法形成一个诚信环境的,此时道德约束就会变得如鸿毛一样轻了。这无数次的失望形成了我们社会中诚信的缺失。

怪诞行为学》中还提到了制度约束不如道德约束。比如迟到:以前在ThoughtWorks的时候,没有人记考勤,但是迟到行为需要向捐款箱投钱,数量不顾定,一些团队可能会要求迟到的人买冰激淋请客。现在工作的公司有严格的考勤制度,迟到1-2分钟也要用1小时的加班抵扣,否则就会扣工资,定这些制度的人会说制度是平等的,但是造成的结果确实大家藐视迟到,想办法申请更多的加班。《怪诞行为学》里面讨论“罚款对杜绝迟到有效么?”提到社会规范强于市场规范:

罚款的效果并不好,事实上它还会带来长期的负面效应。

社会规范(例如共同创业的兴奋)强于市场规范(例如薪金随晋升而增加)时,员工能为公司(特别是那些刚起步的公司)创造的价值的确令人瞩目。

实际上,他们会认识到社会规范可以简历忠诚,更重要的是,它使人们自我发展,达到如今企业的要求:实行弹性工作制,关心公司,并且积极参与公司事务。这正是社会性关系带来的。

王晓明同学讲《价值驱动的组织结构转型》的时候提到了价值驱动的可评估的组织结构转型,我听完很受启发。不过ZoomQuiet同学以前曾经用过这样一个签名“组织结构转型就是催生靠谱的人的组织”。这两个说法都强调了组织结构转型是一个制度和人的优化过程,其中制度是所谓的市场规范,制度规范的修改要放权于靠谱的人。而人的建设是整个过程中最重要的,人要靠谱,也就是说真诚的实现承诺,构建一个充分互信的环境。所以王晓明同学提到在做组织结构转型的时候要注意不要存侥幸心里,做过程改进试验的时候要通知上级和下面的团队,达到共识以后再实践。在企业内部形成信任链条,大家都诚信的工作,才可以让社会规范充分的发挥作用,达到促进企业健康发展的目的。这个过程也就呼应了ZoomQuiet同学所说的“催生靠谱的人”,有能力又诚实的人一起工作,形成诚信环境,也就形成了一个靠谱的人的集合,那样就有了靠谱的人的组织,组织结构转型就会成功。

所以我想这样定义:

靠谱
诚实,可靠(可以达成目标)

最后,说说OpenParty。和冰云聪明的猪一起聊,开始有了组织OpenParty这样一个活动的想法。原因是我们希望各个社区里面靠谱的人可以在一起真诚的交流,交流的内容不设限制。因为当时的很多公司赞助的技术活动里面有很浓的商业味道,让一些话题变成了软文的宣讲会,这样大家活动起来很不舒服,在这个角度上来说就是缺乏“真诚”。我们组织活动的方式选择了Unconference,自助会议。活动的时候个人是没法影响活动的走向的,大家在一起通过民主的方式选择要听什么、要讲什么。到现在好像快有30期了,我们发现随着活动的不断积累(口口相传),来参加活动的人越来越“靠谱”,很多社区的大腕在现场和参与者真诚交流,听话题的朋友给演讲者真诚的反馈。这样真诚的环境就形成了一个小范围的信任。Terry Zhu来我们活动的时候说美国的湾区(美国的创新发动机)有很多类似OpenParty这样的开放会议,大家都很真诚的交流,所以形成了湾区那样的环境。朋友从美国旅游回来说三藩那里充满微笑,但并非美国所有的城市都是那样。可以说,由于湾区城市大部分的人的真诚,形成了城市良好的诚信环境,这样的环境会让更多的靠谱的人聚集过去。OpenParty只是一个很小很小的活动,它只能形成一个很小很小的诚信环境,但是这是一种努力。我们希望这种努力可以把诚信带到更大一些的环境(参与者所在的公司),延长到更久的时间(朋友在活动以后的深入交流),能够聚合更多的靠谱的人。

用真诚换信任。希望我们不要总是面对艰难的囚徒困境就好。

links:

怪诞行为学
怪诞行为学
锵锵三人行
锵锵三人行
女巫店的《机场奇谭录》
女巫店的《机场奇谭录》
ThoughtWorks
ThoughtWorks
价值驱动的组织结构转型
价值驱动的组织结构转型
ZoomQuiet
ZoomQuiet
OpenParty
OpenParty
冰云
冰云
聪明的猪
聪明的猪
Terry Zhu
Terry Zhu
囚徒困境
囚徒困境

在VPS上装东西优先参考它们的wiki

有个朋友问我装OpenVPN哪个教程好,可那是很久以前搭的所以我不记得是用的哪篇教程了。还好,在Ubuntu的linode上面搭OpenVPN基本上没什么障碍。据我的经验,在VPS上面装任何软件最好的方式就是看注明VPS的wiki:

这两个都很不错,可以优先看看这里是否有需要的教程。

VPN还有其它选择,如PPTP和L2TP,它们在桌面和移动平台基本上都可以用,不像OpenVPN由于授权问题在一些封闭的移动系统里面不可以用。不过最好……你的VPS三种VPN都部署上,以备不时之需。

我最喜欢的电台是什么?当然是北京FM91.5轻松调频啦。 What’s you…

我最喜欢的电台是什么?
当然是北京FM91.5轻松调频啦。
What’s your favorite radio station?
It’s definitely Beijing FM 91.5 EasyFM

在iPhone上我可以订阅EasyFM的一些Podcast,还可以通过WunderRadio收听在线的版本。iPod nano可以收到,AIWA的收音机可以受到,家里现在有个大收音机解决了信号不好的问题。That’s so cool!

I subscribed some podcast from EasyFM, and I also listen EasyFM online by WunderRadio on my iPhone. I can receive EasyFM radio through my wife’s iPod nano, a old portable AIWA FM radio reciever and a advanced big radio receiver at home ,it fixed the bad signal issue. Sweet!

Inception

盗梦空间 Inception

道姆·柯布(莱昂纳多·迪卡普里奥 Leonardo DiCaprio 饰)与同事阿瑟(约瑟夫·戈登-莱维特 Joseph Gordon-Levitt 饰)和纳什(卢卡斯·哈斯 Lukas Haas 饰)在一次针对日本能源大亨齐藤(渡边谦 饰)的盗梦行动中失败,反被齐藤利用。齐藤威逼利诱因遭通缉而流亡海外的柯布帮他拆分他竞争对手的公司,采取极端措施在其唯一继承人罗伯特·费希尔(希里安·墨菲 Cillian Murphy 饰)的深层潜意识中种下放弃家族公司、自立门户的想法。为了重返美国,柯布偷偷求助于父亲迈尔斯(迈克尔·凯恩 Michael Caine 饰),吸收了年轻的梦境设计师艾里阿德妮(艾伦·佩吉 Ellen Page 饰)、梦境演员艾姆斯(汤姆·哈迪 Tom Hardy 饰)和药剂师约瑟夫(迪利普·劳 Dileep Rao 饰)加入行动。在一层层递进的梦境中,柯布不仅要对付费希尔潜意识的本能反抗,还必须直面已逝妻子梅尔(玛丽昂·歌迪亚 Marion Cotillard 饰)的处处破坏,实际情况远比预想危险得多…… 

我仅借上这么个引子,是说我的老婆和我的故事。

这段时间老婆睡眠不好,经常有噩梦,甚至有时半夜会哭醒。我最为丈夫当然要细心开导。我这个人很信任心理暗示的作用,所以就希望通过心里暗示的方法让老婆给自己植入一个想法,客服噩梦带来的麻烦。

老婆最近的噩梦有两种主题(这个其实是我老婆的隐私,不过说来无妨):

  • 梦到小的时候上课老师让回答问题,被刁难,或者考试有难题做不出来,非常着急和委屈。
  • 梦到长相可怕的人吓唬她

因为老婆对我总是很信任,并且觉得我很聪明,所以我就想以此作为基础让她对自己有心理暗示。主题就是这样:“无论何时Tin都会在我身边帮助我的。” 结果还真的不错,老婆后面一周的睡眠恢复了很多:

  • 第一种梦境她会梦到我告诉她如何回答,然后进很自豪了。考题的时候她会梦到我回家给她讲题。这些场景就基本上不会成为噩梦了,而是一种有压力但是最后会缓解的场景。而且这个时候她基本上会意识到自己在做梦了。
  • 第二种情况因为她基本上都能梦到我在身边,所以很少梦到遇到长相恐怖的人的梦境了。

我还满心欢喜这Inception植入的不错。但是,电影里面就说过,一个看似聪明的Inception总是会被做梦者潜意识的保护所破坏,最终的结果就是通过另外一个梦把做梦者带回原来相似的困境中,也就是噩梦。我们尝试的这个心理暗示,最后果真还是被另外一个梦弄得失效了,而且这次又把我亲爱的老婆吓醒了,对她的打击似乎比上次还要严重。所以这已经在警告我不要尝试通过暗示的方式让Inception影响你的梦,这种Lucid dream其实更真实也就更可怕。

我老婆梦到了什么呢?简单来说就是她梦到她非常信任的我出了问题。她梦见我变得非常落魄和消瘦,但是依然甜蜜的迎接她回家,这个场景让她很难受。其实这就是对我们尝试暗示给自己的东西的一个反驳,因为每次用了很强烈的意识说我是保证她的梦安全的人,但是如果我出了问题,那么这个梦就崩溃了。

我现在真的很后悔自己干预她的梦。而且也许我们要通过调节睡眠节奏的方式来减少做噩梦的情况了。现在观察的结果就是白天睡眠过多或者睡前喝水太多容易引发这种强烈的梦。所以我们准备从这方面解决问题。不能再尝试通过暗示的方式来做了,那样最后我们两个都心疼了。

这篇blog献给我亲爱的老婆

最简单的说,最有用的是这篇教程《Debian上安装l2tpd/IPSec VPN…

最简单的说,最有用的是这篇教程《Debian上安装l2tpd/IPSec VPN服务》
在Linode的Ubuntu 9.04 (jaunty)上面安装L2TP,由于参考了apple4.us的这篇文章《如何在 Debian / Ubuntu 服务器上架设 L2TP / IPSec VPN》,所以没有配置成功,主要原因是ubuntu上面的openswan版本和这个配置不相符,强行配置是会失败的,照猫画虎难度很大(而且我现在用的jaunty的openswan根本就配不通)。
主要卡在sudo ipsec vierify上的两个disable上面:
Checking for RSA private key (/etc/ipsec.secrets) [DISABLED]
ipsec showhostkey: no default key in “/etc/ipsec.secrets”

Opportunistic Encryption Support [DISABLED]
后面的这个Opportunistic Encryption因为oe=off这个配置不对,所以总是提示很多问题。
后来经过了很多无助的搜索才发现了这篇《l2tp vpn搭建总结(linode ubuntu)》,解释了这个不要紧:

其中需要注意两项:Checking for RSA private key和Opportunistic Encryption Support,第一项其实你大可不必管他,disable或者ok都行。如果你实在要解决,可以:

ipsec newhostkey –file /root/tmpkey
cat /root/tmpkey >> /etc/ipsec.secrets
rm /root/tmpkey

然后,疑问都解决了发现没有仔细阅读《Debian上安装l2tpd/IPSec VPN服务》,人家说

如果客户端连接显示“server did not respond”,通常说明openswan的版本不对,Debian Lenny自带的版本貌似有些问题。在命令行运行如下命令,即可安装openswan-2.6.24:

sudo aptitude install libgmp3-dev gawk flex bison
wget http://www.openswan.org/download/openswan-2.6.24.tar.gz
tar xf openswan-2.6.24.tar.gz
cd openswan-2.6.24
make programs
sudo make install
sudo apt-get remove openswan
sudo /etc/init.d/ipsec restart

卸载openswan并自己编了新的版本后果然就OK了。注意调试的时候应该看/var/log/syslog和/var/log/auth.log。

登root的时候发现: You have new mail in /var/ma…

登root的时候发现:
You have new mail in /var/mail/root
原来是有很多root邮件没有传递,查了一下可以这样做,修改/etc/aliases:
root: your.gmail.account@gmail.com
然后sudo postalias /etc/aliases就好了,root邮件就会被传递到你的gmail邮箱。当然我的情况是在ubuntu下使用postfix,否则修改的位置略有不同,谷歌一下。

昨天调试服务器上的L2TP,sudo -i了一下,发现root根目录有好多好多的…

昨天调试服务器上的L2TP,sudo -i了一下,发现root根目录有好多好多的wp-cron留下的垃圾文件,原来是我的crontab写的有问题:

*/5 * * * * /usr/bin/wget http://www.ermiao.com/wp-cron.php?doing_wp_cron >> /home/public_html/ermiao.com/log/wp-cron.log 2 >> /home/public_html/ermiao.com/log/wp-cron.err

因为默认情况下wget会把文件下载到home目录下,而且它还会自动重命名,结果文件越来越多……

解决方法就是增加下载后删除的参数,并且让它quiet运行。

*/5 * * * * /usr/bin/wget -q --delete-after http://www.ermiao.com/wp-cron.php?doing_wp_cron >> /home/public_html/ermiao.com/log/wp-cron.log 2 >> /home/public_html/ermiao.com/log/wp-cron.err

OpenParty的新网站的Django项目使用了South这个migratio…

OpenParty的新网站的Django项目使用了South这个migration工具。可是刚才增加了一个Model以后却无论如何都无法生成这个migration。

./manage.py schemamigration core --auto

上面这个命令每次都提示:

Nothing seems to have changed.

很郁闷。试验了看是否是South或者Django的版本问题,都升级到最新版依然有这个问题。看了google groups里面也没有人报有这个问题。于是仔细搜索问题的来源,最终发现是这个原因:

class Meta:
app_label = 'core'

上次我们Team重构项目的时候去掉了项目的openparty前缀,使用相对路径import,结果造成”core”项目实际上是存在”apps.core”下面的。所以,需要用Meta类告诉Django实际上对应的app名称。结绳记事。