前些天在抓虾老同事的群里聊些话题,才发现在抓虾的日子竟然已经过去十年了。如今还会有人提到抓虾,但往往是把它当成徐易容的一次创业失败的教训。但是对亲身参与的人来说,那段经历并不只是“一次失败的教训”。
我和抓虾网的缘分,得从2006年说起。当时我正在如日中天的IT新闻(江湖)站点Donews供职。那时候的“IT圈”名副其实,Donews很像“江湖”上的“聚贤庄”,每周五晚上还有定期的聚会。我虽然只是个程序员,但也因此有机会近距离观察李想、王志东、李开复等等IT大佬。这样的机会刷新了我的很多认识,也让我掌握到不少“小道消息”,我第一次听说抓虾和徐易容,就是在聚会上。
大概从2006末年开始,聚会上谈得更多的话题就不再是IT,而是房市、股票(Keso当时也在,他前段在一篇文章里也谈到这点)。Donews本身也发生了些变故,我当时混得还不算差,但也在考虑下份工作了。
有一天,老大转来一封邮件让我去接洽。原来是徐易容希望开展内容合作,用RSS输出定制内容给抓虾。因为之前做过RSS相关的开发,这方面我确实比较擅长。
如今很多网民大概不知道什么叫RSS了,RSS也确实没落了。但是在十年前,RSS绝对算开天辟题的技术,即便在今天也有很多启发意义。所以,我在这里多作些讲解。
简单说,RSS就是进行站点内容分发的“开放API”,而且是“洗剥干净”的纯内容。普遍的做法是,由内容提供方按照RSS规范,把最单纯最核心的内容(去掉了广告之类无关的内容)用XML格式输出来,由其他人抓取。
这种技术如今看来不可思议,当时却是价值非凡。在我看来,原因由好几点。
第一,当时的抓取技术远没有如今这么先进,想在繁杂的网页中准确提取原文相当困难,甚至许多网站的数据库里存储的都是混杂在一起的内容,RSS推动了数据和表现的彻底分离;第二,当时大家都在努力获得流量,通过提供RSS输出“纯”内容,很容易把自己的内容推送到各个平台,建立众多触达入口;第三,或许也是最重要的,RSS提供了“合烧”的功能,因为各站点都提供了分门别类的RSS输出,你很容易把信息重新组织聚合,“简单拼拼XML”就可以把新浪体育、搜狐体育、网易体育的内容集合到一起,这可以算作如今大红大紫的个性化阅读的先驱;第四,你不再需要频繁刷新网页去看更新了,RSS阅读器可以定期检查更新,提醒读者。
正是因为RSS有诸多优点,大家很快发现,有了RSS,就不用大费周折去浏览一个个网站了。或许,这就是未来的方向?
我记得第一次收到易容的短信是个周六的下午。当时天气很好,我正在二环边修自行车,忽然接到一条礼貌而客气的短信,于是约好第二天上午见面。
第二天我特意提早出发,因为听说徐易容特别守时,说几点就必然是几点。到了抓虾以后见到两个人,热情开朗的是徐易容,同样热情的是合伙人谌振宇(还是我的湖南老乡),印象里他好像还留长发。当时主要聊了聊技术合作的事情,大家很快就敲定了合作方案,输出哪些频道的内容,怎样输出,因为大家都是做技术的,所以沟通相当愉快。
等周一上班了我就开始计划开发,很快就开发完成,对接成功,易容还发了个恭敬客气的邮件专门表示感谢——当时抓虾是小站点,内容合作算是借Donews的光。事情到此,就算告一段落了。
不久,易容又给我发了个邮件,说要再约吃饭聊聊。我虽然感觉有点奇怪——合作已经完成了。不过易容说“感觉大家还不熟,多聊聊就熟了嘛”,所以我欣然答应。
这次吃饭还是易容和振宇做东,聊的话题更多了些。顺带他们也介绍了自己在做的事情,抓虾未来要做的事情。我本来也比较感兴趣,所以就这么一直聊下去。
然而话锋突变,易容和振宇对视一眼,然后站起探身过来,拉住我的胳膊说:我们觉得你挺合适,想请你加入,不知道你是什么意见?
虽然我当时在考虑看其它的工作,但易容这个举动还是让我大感意外(在我以后的工作中,也再没有过这样的经历)。但是我又想到,他们说得这么直接,态度又那么真诚,于是答应回去认真考虑下。没几天我就下定决心加入了。那时候大家都很爽快,我还没有提离职,振宇给我发短信说“你的工位和电脑都已经准备好了,就等你来了”。
刚加入抓虾的时候,整个团队已经有十多人了。技术团队里,除了两位创始人,还有几位工作了五六年的同事:昌乐、明珠,分别负责后端和前端。再就是像我这样刚工作三四年的,崇利、王曦、永辉、一弢。再往下就都是在校的实习生了:刁、陈凯、路明、国栋、永超等等。当时负责UI的是潇潇,后来是新浪来的王达。比我稍晚一点,又来了海鹏、熹熹(姜志熹)、朱荣等人。再晚点,又来了实习生陈拓。总的来说,团队很年轻,活力十分充沛,相处也很融洽。
我当时印象比较深的是实习生。我自己到了毕业那年费了不少周折才找到工作,想起来要庆幸运气不错。而像国栋、永超都是北大计算机系的,基础相当好,工作也很卖力。我这才发现,实习原来不是外界传说的“廉价劳动力”,对实习生来说能提前体验职业和职场,对公司来说能提前锁定优秀的在校生——原来,好苗子还在大二大三就已经被瓜分完毕了呢。
从我后来的经历来看,或许北京在这方面有得天独厚的优势。无论在长三角、珠三角,都很难有“名校高材生愿意去前途未卜的创业公司实习”的普遍氛围。无论在哪里,这样的孩子们可选的去处都很多,但只有在北京,会有相当部分的人不怎么考虑生活的压力,投身去做自己想做的、有意思、但前途还不明确的事情。但是话说回来,“改变世界”这回事,很多时候确实不是靠算计,而是靠情结和信念来完成的。
当然,这或许也和那些年北京的气氛有关。我曾经和很多在北京的朋友讨论过,什么时候的北京最可爱。比较普遍的答案是,06年到08年那一段。虽然大家没有什么钱(我每次从朝阳门去保福寺都是骑自行车),但那个时候的北京有无比的包容感,加上各方面的管制都在逐渐放松,人人都有点“美好前途全力创”的感觉。
我自己感觉也是如此,那段日子真让人怀念。记得我刚工作不久,听说德国人开发了一种新的Web服务器,叫Lighttpd,于是找来研究了一番,写了点东西放在网上。过了不久,有人联系我希望聊聊Lighttpd,见面了才知道,这个人是豆瓣的创始人阿北。今天想来似乎不可思议,但当时却是“意料之外、情理之中”的事情。
这样的经历还有不少。06年有一天晚上我和韩磊、霍炬、朱辉龙一起在簋街喝酒到很晚,这时候来了两位流浪歌手,于是我们也跟着一起唱。唱着唱着,店家又给上了很多啤酒。我们都觉得很奇怪,一问才知道,大堂对侧另一桌的朋友虽然不认识我们,但觉得唱得不错,所以给我们点了一打啤酒。于是,大家端杯走向那桌不认识的朋友,一边连声说“谢谢”,一边喝了几杯,这样就算尽了礼数。
07年夏天我设了个饭局,谁会来完全不知道,只靠朋友口耳相邀。结果,一开始来了个挺斯文的年轻人,自我介绍说“我松鼠会的姬十三”……过会儿又来了个家伙,一问原来是DBA Notes的冯大辉。过会儿,李笑来老师、博文视点的周筠老师也陆续来了。很多朋友之前都没有见过面,只是在网络上听说过。当面见了,轮流做个自我介绍,谁也没什么架子,大家一边吃一边聊。现在我已经离开北京很多年了,
回来说抓虾的团队。这个团队就是在那样的年代,由一群热情洋溢的年轻人组成,所以虽然说不上多么严谨专业,但感觉是幸福的。办公室的二楼有供加班休息用的房间和小床,虽然卫生很糟总是臭气熏天,但大伙就靠这张床(还有漱口水),熬过了很多不眠之夜。
吃午饭这件事也很能体现团队的风格。当时抓虾是包午饭的,定点在华清嘉园附近的一个饭店,从保福寺走过去大概要二十分钟。每天吃饭的程序都是异步沟通,确保高效:首先打电话过去点菜,然后等电话通知上菜时间,估摸着快到了,组队去吃饭。走进饭店通常所有菜刚刚摆上桌,大家就坐之后一顿猛吃,通常桌子刚转两圈就吃完了,前后不到10分钟。有一次,易容有事来晚了五六分钟,结果被告知“你们的人都走了,桌子都收拾完了”。这种作风有深刻的后遗症,我离开抓虾之后,陆续被很多人说起“吃饭速度好快”。
同样有意思的是团建。07年组织了一次自驾去河北涞源和空中草原,露营的那天晚上,男生挤的那张帐篷里臭气弥漫,等我早上起来已经有好几个人受不了气味,跑去看日出了。那天晚上易容也没仔细看防潮垫下面的情况,据他说睡的那块地方下面正好有一大块马粪,导致他胃受寒了好些天。回程我们在八达岭高速遇上特大堵车,从中午12点到夜里8点基本没动地方。这是我第一次在高速上的汽车里过夜,半夜我还拿三脚架和单反出来拍了不少高速夜景。夜里有好几次前面疏通了一两公里,坐在副驾驶的我醒来就喊“易容,可以走了”,于是他发动汽车往前开一段,接着又睡着。第二天早上8点多我们才回到北京,结果是皆大欢喜:当天不上班,全员多休息一天。我还追问易容记不记得前天晚上我叫他开车的事情,他竟然完全没有印象。
当然,对于公司来说,团队年轻,气氛好,只是一个方面。团队年轻就意味着可能犯错,需要严格要求、反复锤炼。尤其是因为没有大公司成套的规章制度,这方面需要付出的努力就更多。后来我每次回想,都觉得这方面易容和振宇肯定花了很多心思,没有靠打鸡血也没有靠蛮力逼迫,就能保持整个团队的技术追求和信任保持在很高的水平。就我所见,真正能做到这一点的人,着实不多。
我记得有一次偷空看到海鹏的代码,惊异发现内部管理系统也写得那么漂亮,真是自愧不如,这才相信他之前呆的IBM并不只有笨拙死板的流程,还会培养良好的规范意识和职业素养,自己之前真是知道得太少了。当然我也是只有佩服其他人的份,有次我花了些心思写了个周边的小模块,也被同事称赞“写得真漂亮”,当时真是心花怒放。滋养技术追求,并且这种追求会被明确肯定,对良好的技术氛围功不可没。 实习生陈拓来的第一天就说,他的电脑不要装Windows,直接装Linux,真是让我吃了一惊。许多年后我和他在长沙见面聊起此事,他嘿嘿一笑说“其实我Linux不怎么熟悉的,但是当时看身边的人一个个都用命令行,再用Windows肯定说不过去”。
或许正是因为有这样的团队和这样的气氛,所以后来我回忆起自己在抓虾的经历,也深刻觉得在技术上获益匪浅。
有几个例子我印象很深。第一是整个抓取的任务分派系统。因为要抓取的RSS Feed(内容源,也可以理解为某个URL地址对应的XML)很多很多,如何高效调度它们,保证尽快抓到更新,又不能做太多的无用功,就成了大问题。新闻的更新时间比较好预测,但还有大量的RSS来自博客,博客的更新时间往往取决于作者心情,完全没有规律,什么算法都不好用。这个问题采取了一个非常取巧的办法来解决:从读者出发。只要发生读者登录事件,就检查这个读者订阅的RSS Feed,如果对应的Feed上次的抓取时间在半小时之前,就立刻触发再抓一次。
换句话说,重要的不是技术要做到无所不能,而是要给读者“抓得够多够快”的感觉,真正的问题是用有限的资源实现最佳的效果。后来在很多工作中我发现,技术人员往往忽略了这点,明明可以用很低成本实现的效果,非要去钻牛角尖。或许,这并不是因为他们笨,只是因为没有见过让人“开窍”的例子。
第二是抓虾的存储。为了保证阅读效果,抓虾抓来的内容都需要存储在本地,几百万Feed每天产生的数据量相当可观。那时候HDFS之类的东西根本没有成气候,更谈不上云计算、云存储了。如果数据量大了,充其量是使用Tokyo Cabinet之类的类库来完成,但这种东西本身又不甚可靠,工业上使用总是问题多多。
抓虾解决这个问题也是用的简单粗暴的方式。把内容用Gzip压缩成二进制存到MySQL的表里,只提供ID和GUID的查询。这样单张表可以存放3亿的数据,分表的规则也相当简单。
这种方案听起来有些土也不可思议,但当时确实解决了问题,而且依托MySQL现成的主从复制,数据的一致性也有很好的保障。正好那一年《容量规划的艺术》中文版面世,我找来一边读,一边思考MySQL的存储方案,深刻体会到一个道理:方案本身并没有绝对的优劣, 根据实际情况提炼关键指标,综合考虑各种变量,通过分析、估算、设计、验证,得出合适的方案,到后来能把各种约束、条件、关注点烂熟于胸,这才是工程的真正含义。
这或许是那个年代技术人员的“通病”。因为没有那么多现成的类库和框架,大家只能因陋就简,靠内家功夫取胜。最近讨论技术方案时,我提出了一个看起来简陋直接,与“高大上”一点关系都没有的办法,大家细看之后觉得确实可行。我说,“我们那个年代成长起来的技术人员,一般都会这样的思考”。
上面说的还只是刚去抓虾的印象,随着工作时间的增常,我也见到、学到了更多让我印象深刻的东西。
在去抓虾以前,我的关注点主要集中在开发上。写好代码,能跑起来,工作就算完成了。但是去了抓虾之后我才发现,工业级的程序不是这么玩的。首先所有的服务程序都有专门的启动程序,保证真正的程序不死,死了也能迅速重启。同时,所有的程序运行的状态,也必须一目了然,不但要有实时查看,还要有日报、周报等等各种报表。
这相当于一边写程序一边问自己:我的程序里应当提供哪些关键信息,通过它们就可以鉴别程序的状态,这些信息通过什么途径可以访问——这是一个“元设计”的过程,促使我们更深层次地思考我们的工作。我也深刻领会到了“输出给程序处理的信息应该是什么样”,它和给人看的信息有哪些差别。
可惜到如今,我发现还有大量的程序员从来不思考这样的问题,自己的程序在跑着,既看不到实时的状态,也不提供每天的统计。出现问题只能通过肉眼排错,不但意识不到效率的低下,反而乐于扮演“救世主”的角色。这些,其实都是缺乏严格训练的表现。回想我们都离职之后,服务器“裸奔”了大半年竟然没有出问题,靠的都是之前在工程上做的各种努力。
值得一提的还有“负责任的精神”。当时有一些基础的模块是振宇早期写的,当时抓虾有著名的十大谎言,第一大谎言就是“振宇的程序没有bug”,每次说起这个振宇都是笑笑,“这不是谎言嘛”。结果有天中午吃饭时聊到程序,似乎振宇的程序逻辑真的有个bug,只见他神色凝重,立刻放下筷子回去了,把这个bug修好了才算解脱。其实那个bug并没有立刻的重大的影响,而且振宇已经很忙了,但是他仍然保持着对质量和技术的执着追求,让我汗颜,也让我佩服。
这种汗颜和佩服是有理由的。有一次线上出现了bug,我两三天也没有解决,每次被问起来就说“正在解决”。直到有一天振宇问我,我才承认“我调不出来”,敷衍等到明天再说。我记得他当时神情一变,凛然正色道:“不可能,我不相信有调不出来的bug”。然后拉着我一起调试。多机器、多线程的系统,本来调试就很复杂,但他就靠着GDB,蹬着转椅在几台电脑前晃悠,从吃过晚饭一直调到深夜,我们终于定位、解决了问题,出公司回家已经是星斗漫天,一看表已经三点了。我总觉得IT行业虽然年轻,还是可以从传统的师徒制借鉴很多的。起码,后来我自己带领技术团队时,我也有好几次说“不可能,我不相信有调不出来的bug”,然后拉椅子现场坐下来证明我说的对。
抓虾在技术上要求很严格,但不死板。很多时候都是“任务式管理”,你领到的是个抽象的任务,并没有限制解决的办法,但要求实现最终的效果。这样看起来很自由,真正解决起来很痛苦,但也锻炼人。
在我入职后不久,就有博客作者反馈抓虾的抓取比较慢,他们自己新发表一篇博客,其它在线阅读器可能半小时就抓到了,我们却要一个小时。当时在我看来这是小概率事件(几十万种子里有个案抓取慢而已),意义不大。但是,连着几次开周会的时候易容都在强调这件事情,我不得不顶着巨大的压力去解决“怎样能在抓取速度上全面超过竞争对手”,绞尽脑汁想了各种办法,终于算是解决了问题。在那之后,我开始领悟到什么是“解决复杂问题”了。
还有一次,因为抓取程序的频率调整机制失控,新浪微博把我们的抓取服务器IP给屏蔽了。我还记得当时振宇给我发了条短信“今天必须把新浪的事情搞定”,没有任何关于方法的指示。我找到之前在新浪工作过的朋友,辗转打了二十多个电话,终于联系到执行屏蔽的技术人员。在我确认承诺修正程序,以后不超负荷抓取之后,封锁的问题终于得到了解决。
这件事也给了我很多启发:当时有一种建议是找大批代理服务器来抓,但我没有采取这种办法。技术产生的问题当然可以用技术解决,但是这不是唯一的途径,我们也可以靠沟通来解决,而且也应当靠沟通来解决。明白了这个道理,我在后来的工作中受益很多,甚至在求职中也受益很多。从抓虾离职后,有次面试中HR让我举例说明自己的专业素质,我举的就是这个例子。从最终的结果来看,这个答案应该是不错的。
我本来以为十年前的故事应当很容易写完,但今天真正坐下来动笔,才发现根本不能一一记录。虽然已经过了十年,那些记忆还那么真切。十年前的每一个傍晚,我在保福寺高高的写字楼上看到四下居民区的灯渐次亮起,入夜再渐次熄灭,然后自己才下班,那画面仿佛就在昨天。无论今天的人如何评说,那段经历已经和自己融铸为一体,无可剥离,也无可冷冰冰地“客观”看待。
年轻的时候,我们往往会被成功的故事所激励,被“出类拔萃”、“与众不同”、“卓尔不群”的话语所感动,最终却发现,自己很可能只不过是“类”、“众”、“群”的一份子而已。但是谁又能说,这一定不是好事呢?