许超前的博客 - A longker in the Earth

August 18, 2010

2010,上半年志

Filed under: Daily Life — 许超前 @ 10:30 pm

DAL2.2发布。
这是一个较为成熟的大版本。在我心里,我的使命到此也就结束了。

离开手机之家。
最终还是做了这个选择。现在这个项目由增禄接手。我有理由相信增禄能够继续推动DAL向前发展,并取得更大的成绩。
手机之家曾经是我心灵的归宿。我想,不管以后身在何方,手机之家都将是我美好的记忆。

登了一回泰山。
登泰山的想法由来已久,却一直不能实现。这回终于圆梦了。遗憾的是没有看到日出,更糟的是还被淋了一身雨。是的,人生本来就是充满着缺憾的。

去了一趟武汉。
毕业几年后,放下忙碌的工作和紧张的生活,突然有一种被掏空的感觉。也许,只有重新回到起点,才能看清自己的终点。去了学校,还去了东湖,依然是那样得美好。

加入百度。
这个选择,我想几年过后再来评价,会更加客观准确。

小外甥考上山东大学。
金榜题名时,很高兴,呵呵。在这祝愿他学业有成吧。大学只是刚刚开始,不要虚度光阴。

也学车了。
参加驾校培训一个多月了。再过一个多月,就能拿到c1驾照了。学车的理由很简单,待2012到来时,自己能跑得快些。

。。。。。。

结束了,也开始了,下半年会有哪些变化、提高和突破?拭目以待。

April 3, 2010

数据库技术大会结束,<<数据访问层开发实践>>演讲PPT下载

Filed under: Daily Life — 许超前 @ 10:13 pm

April 2, 2010

Dal2.2.8发布了,开始支持分布式事务(遵循XA规范)

Filed under: Daily Life — 许超前 @ 12:10 am

在团队全体成员经过3个月的努力后,Dal2.2系列的一个重要迭代版本Dal2.2.8终于发布了。

在这要说一声,增禄和大庆,你俩辛苦了。

为了支持分布式事务,我们着实费了一点功夫。因为Dal向外提供的特性必须都是语言中立、数据库中立的。所以,我们需要考虑不支持join/suspend/resume等子句的数据库。

MySQL就是这样一个对XA仅提高有限支持的数据库:
For XA START, the JOIN and RESUME clauses are not supported;
For XA END, the SUSPEND [FOR MIGRATE] clause is not supported.
详见:http://dev.mysql.com/doc/refman/5.1/en/xa-restrictions.html

同时,我们还要充份考虑因各种原因造成的状态扰乱问题。还好,最后我们通过嵌套事务扁平化、XA START/XA END命令配对、数据库链接作用域去重叠及链接事务范围内独占来解决这一切问题。

至此,Dal不但继续擅长于提升web2.0+系统的承载能力,而且也适用于保证那些重要系统的关键数据的完整性和安全性。

晚些时候,大庆做了个简单的benchmark,发现在系统复杂度上升、dal-core接口更加易用的情况下,仍然保持和Dal2.1系列一样的性能表现。虽然有些小小的失落(预期是更好),但是也算还好吧。

明天继续灌数据,看看在缓存数据量增大(以触发JVM进行垃圾回收)的情况下的表现吧,顺便profile看看。

April 1, 2010

4月3号参加数据库技术会议,演讲主题是:数据访问层开发实践

Filed under: Daily Life — 许超前 @ 12:12 am

话题还是和Dal有关。

Dal2.0发布到现在已经有半年的时间了。这半年来,我们对数据访问层的认识有了不少的变化,Dal整个软件的结构和特性也已经发生了变化。

这次话题,主要是和大家分享和探讨过去的经验、现在的见解及未来的规划等。望有兴趣的同行前往批评指正。

November 24, 2009

用Hudson+Subversion+Maven搭建持续集成(Continuous Integration, CI)环境

Filed under: Daily Life — 许超前 @ 10:05 pm

为了让接下来的研发工作能更顺利地开展,花了点时间给新团队搭建了个持续集成环境。这里用到的工具主要有:HudsonSubversionMaven等等。

关于持续集成这个概念,有兴趣的可以参考Martin Fowler的一篇文章:Continuous Integration

之前,对那些JAVA编写的服务程序,我们采用的构建方式很原始:手动写Shell脚本,把SVN中的JAVA源码编译成JAVA字节码。应该说,在团队规模较小(不需要太多的协同工作)、部署环境单一(我们之前只部署在Linux环境当中)的时候,这种方式还是不错的,起码两年以来,我们并没有遇到什么问题。

那现在为什么要来搭这个环境?持续集成带来的好处有很多。。。在这我只说说我们这么做的主要原因:
一、进度控制力度增强了,需要快速迭代,也需要更快地看到结果。
二、可测试性要求提高了,所有的代码必须是自测试的。
三、对外发布的不再是源代码,而是可执行文件了。
四、给团队成员一个全新的体验,走正规化开发道路。
。。。

以下是搭建好的持续集成环境的结构图:
Continuous Integration

—The end.

November 17, 2009

试用Google Closure Compiler的API

Filed under: Daily Life — 许超前 @ 7:22 pm

原来的JS压缩服务采用的是YUI Compressor,一年下来表现还算稳定。

今天老高说想尝试一下Google Closure Compiler,翻了翻文档,看看有没API能直接用的:传一个原始字符串,返回一个压缩后的字符串。找了半天,没有此类的例子(看来设计者认为像我们这样直接采用API而不是使用命令行的用户不多)。

查看JavaDoc,定位到com.google.javascript.jscomp.Compiler,有如下描述:
Compiler (and the other classes in this package) does the following:
* parses JS code
* checks for undefined variables
* performs optimizations such as constant folding and constants inlining
* renames variables (to short names)
* outputs compact javascript code
看来就是这个了。

相中方法: Result compile(JSSourceFile extern, JSSourceFile input, CompilerOptions options) 。
input和options容易理解,extern是什么?其实类的描述里也稍微提了下:
External variables are declared in ‘externs’ files. For instance, the file may include definitions for global javascript/browser objects such as window, document.
很显然可以没有extern(但不能为NULL,设置方法参看底下的代码)。

按道理,编译后返回的result里应该就有我想要的结果了吧,结果出乎意料。Result只有编译状态的描述。难道此路不通?

又从JAR包的META-INF看到入口类是CompilerRunner,一路追踪下去。。。中间省略文字几千字。绕了半天,得出的结论是:和CompilerRunner相关的几个类很难复用,想用的方法要么是不可见,要么是包可见,要么是子类可见。代理来继承去,眼看就OK了,又发现很多状态居然是static的,这使得程序的状态是迭加的。看来此路也不通。。。又绕回Compiler。晕,原来Compiler有一个方法toSource()就是返回压缩化的代码的。

这下好办了。主要代码如下:
final ByteArrayOutputStream err = new ByteArrayOutputStream();
final PrintStream errWrapper = new PrintStream(err);
final Compiler compiler = new Compiler(errWrapper);

final ByteArrayInputStream bais = new ByteArrayInputStream(codeBytes);

final CompilerOptions options = new CompilerOptions();
final CompilationLevel level = CompilationLevel.SIMPLE_OPTIMIZATIONS
level.setOptionsForCompilationLevel(options);

final Result status = compiler.compile(JSSourceFile.fromCode("extern", ""), JSSourceFile.fromInputStream("input", bais), options);
System.out.println(compiler.toSource);

把代码布上后,测试通过。本来这是一件小事,没必要以此作为BLOG的内容。但是这件事也是给了我几个感触,觉得有必要说一说:
一、文档很重要。简单的几句话,也许就能让用户少走很多弯路。DAL后面一定要多写文档,特别是使用手册。
二、API设计要符合直觉。不符合直觉的设计会造成大量的困扰。当年Lucene的delete操作,用脚跟想想就应该放在IndexWriter里,可设计者却把它放在IndexReader里,结果邮件列表里经常出现此类的问题。当然,后续版本已经做了修改(IndexWriter有了delete方法)。用户不会关心你为什么这么做;新用户要抛弃你只要点一下鼠标就可以了;而老用户选择离开只需要皱一下眉头。
三、时间管理很重要。任何事情都应该在任务框架里进行;否则,很多东西可能会失控。

—The end.

October 24, 2009

SD2China大会演讲结束,<<手机之家的数据访问层实践>>PPT下载

Filed under: Daily Life — 许超前 @ 5:22 pm

今天去的比较晚,12点20分才到会议中心。那时还没吃早饭(刚买的一杯豆浆还很烫),已经饿得发慌了,于是去了食堂,吃了一个馒头,喝了一碗粥。

到会场12点30分左右。工作人员也到场了。放上PPT,我也坐到旁边和同事聊了会。这时发现会议室里已经坐満了人,还有因没位置站着的朋友。

演讲从下午1:00点开始,一直到下午2:10,总共需时70分钟。在演讲进行到一半的时候,我已经明显感觉到自己的肚子在叫了:)

整个演讲过程,勉强过得去,我打60分。
因为时间有限,我无法去谈一些过于细节的东西,只能是说说思路。不过其实我们做开发有时候缺的就是思路,不是吗?
对于这些,还希望当时在场的朋友多多包含,如果有比较模糊的地方,可以给我发邮件,再进行交流。

感谢我的家人和同事,感谢各位支持我的朋友,谢谢。

以下是这次演讲的PPT,点此下载

October 23, 2009

参加SD2China大会,演讲主题是:手机之家的数据访问层实践

Filed under: Daily Life — 许超前 @ 9:37 pm

演讲主题改了好几回,最后还是选了这个,简单、朴实。
和大家分享的是:DAL从无到有的演变过程,以及在此过程当中我们所获得的经验和教训,还有一些总结性的经过证明的知识点,最后是DAL的未来规划。欢迎各位朋友前来一同探讨。

地点:北京温都水城会议中心3层第32会议室
时间:2009年10月24日下午第一场
交通:乘坐地铁5号线或其他线路在崇文门、东单、雍和宫、惠新西街南口、立水桥站换成地铁5号线在天通苑北下车,出战乘坐会务组班车到达温都水城。

October 18, 2009

出差长沙第7天,所见所闻所行所思

Filed under: Daily Life — 许超前 @ 12:46 pm

算上今天,来长沙已经7天了。

此行来长沙的目的,是改造DAL以支持Oracle数据库。
由于之前在开发DAL的时候,在支持多数据库机制上面做了充分的考虑,改动起来还比较顺利。

现在想起来,如果当时不那么坚持,那这次就不是三两天能搞定的事了。“人无远虑,必有近忧”,是矣。

现在,似乎有一个风气,那就是“敏捷为王”。东西先跑起来再说,后面再慢慢改进。有人甚至主张Just-In-Time Architecture,对此,我持保留意见。也许某些领域,应该这么做;但有些领域,若是这么做,可能会产生无法预计的后果。有些东西一旦成形,才想到要除掉它,那将是成倍的代价,很难。

这种风气已经蔓延到其它领域。我就经常发现,有些产品经理对于自己提出来的需求往往是没有经过仔细思考的、没做过调查的,不管用户到底是不是真的需要,不用任何科学的分析手段,就那么一拍脑袋,“喂,那个谁,你给我改改,急用”。现代人,谁不急?

极端要不得。一个度字。不同的人,不同的角度,不同的认知,会触发不同的行为,最终产生不同的结果。

DAL的开发,暂告一个段落。最近杂事很多,对DAL的投入明显没有之前那么多了。
上次接受JavaEye采访,很多朋友对我每周工作80个小时觉得诧异。我要说的是,有段时间我每周工作的时间达到100个小时以上。
其实,之前一个长周期的项目已经让我身心俱疲了,在这种情况下了,我接下了设计和开发DAL2.x的任务,着实是出自于职业操守,而非兴趣。DAL1.0由我开发,我知道其中的问题,如果不把这些问题解决,我睡不着觉。这关乎手机之家1000万用户的使用体验。
DAL1.0到DAL2.x的跨度非常大(包括代码和思想),同时又要保证平滑升级(不改应用程序的逻辑),当然还要保证数据的一致性,关键数据一旦出错,后果很难想象。
有心人应该能了解这其中的工作量了吧。到了后期,完全是凭自己的意志在坚持了。

家里人有时候也会责备,问这么做到底是为了啥?图个啥?

一个中国的开发人员,他热爱自己的职业,他有着一个10年的梦想,他坚信自己能开发出一个有用的软件,他坚信自己能和国外的优秀同行做得一样好。这就是坚持的理由。

在长沙出差这几天,总体还过得去(在这要感谢长沙的新同事)。这里气候比北京要湿润的多,饮食也还适应,睡觉也还习惯。走在园区的小路上,还能闻到阵阵桂花香。这让我想起当年在桂子山上上学的情形,满山的桂子花,而我就在树下的凳子上读书,在林荫小道上慢悠悠地骑车。

呜忽,皆往矣。

光阴无法倒转,人得往前走、向前看。感激、赞美身边的每一个人,活在当下!

再过3天,我就要回北京了。北京虽然气候恶劣,但在北京,我有一种归属感。
赶回去有三个原因,一是长沙这边的事已经差不多了,第二是家里有一堆事,等着我回去处理。最后一个是要回去参加CSDN举办的SD2China大会,做主题演讲。不知道到时候会不会遇到老同学?

过后,就是今年的最后一个季度了。要怎么过,得想一想了。

—The End.

September 12, 2009

终于把搜索更新改成基于MQ(Message Queue, 消息队列)的方式了

Filed under: Daily Life — 许超前 @ 1:45 am

经过同事们的一番努力,终于把搜索更新改为基于MQ的方式了,大家(特别是增禄和大庆)辛苦了。

搜索更新早就想改了,因为种种限制,无法实施。这些限制如下:
一)手机之家采用混合编程(主要是PHP+JAVA)。
二)JAVA调用PHP显然不是好方法。
三)用PHP做异步触发很困难。
四)用PHP写驻留程序很困难。
五)要让PHP在消费消息失败时回滚很困难。
六)基于这些限制,DAL1.0最后用PHP和数据库实现了一个不太可靠的消息队列。这显然不太好。
“旧”更新方式如下图所示:
Screenshot-001

DAL升级到2.x后,之前的种种限制已经消失了,搜索更新一下子有了很大的改进空间。具体改进如下:
一)引入双队列,为的是能异步触发,从而节省内存、降低CPU占用率,进而提高负载能力。DAL2.x内置队列写消息非常快,写一条消息耗时不到1微秒(不是毫秒,了解个大概,省略测试环境)。
二)(部分)拉改成了推,“近实时“更新有了可能性。时间关系,留待下一步继续改进。
“新”更新方式如下图所示:
Screenshot-002

接下来可能会抽个时间试试以下的方式(废弃Crond,主要是为了减少更新延迟):
Screenshot-003

注:图中提到的M3,是Massive Message Manager的简称,是我们的大庆在近期开发的作品,在此鼓励一下:)。

—The End.

Older Posts »

Powered by WordPress, 京ICP备09047672号