2006年11月6日
应朋友邀请,周六早从上海出发往杭州参加阿里巴巴网侠大会。同行四人,有锐道的macro chen、杨光(还是我师弟)、移动的王伟旭(特长是linux和网络安全,也是中国linux推广的先驱)。一路上,言谈甚欢。老庄给我们订的票,他一早肠胃有恙,仍然坚持把票送到火车站,之后去吊盐水,下午又出现在会场。确实精神可嘉,建议阿里巴巴颁发“最佳精神奖”。
到杭州已是中午,错过了上午大会。下午Robbin进行Java技术展望和RoR实现REST的演讲,既然是朋友,肯定是要捧场的。Robbin旁征博引,以其深厚的技术功底和对新技术的敏锐洞察赢得了听众。
晚上一堆人去聚会,各路豪杰纷至:有阿里巴巴的,有自己创业的,有技术大牛,还有媒体(Infoq),出版社(博文的周总领3员大将赴会)。大家互换名片,认识的不免寒暄几句,不认识的也很快就熟捻了,还不时有“原来你就是×××”的惊呼,原来网上就“互通心曲”,只是一直没机会认识罢了。
席间觥筹交错,具体内容暂且不表,只说一件令我感受颇深之事。一个阿里巴巴的员工表现出对公司的无比忠诚,讲起公司的奖惩制度,说是一个员工的绩效不仅跟所在项目相关,还与部门、其它部门甚至整个公司的业绩相关。所以只要是对公司有利的事情,即使与自己现在的工作无关,他们也会去做。按常理来说,这有点不公平,我只能努力做好自己的事情,而如果别人不努力,我就是白做。但如果大家都努力,又变成了共赢。
这里让我讲一个简单的博弈问题,就是“囚徒困境”。A和B两个同犯被抓,因为没有其它任何证据和证人,只能让2人分别交供。如果A和B都矢口否认,那么两人无罪释放。如果A承认,B不承认;A是坦白从宽,判1年;B抗拒从严,判5年,反之亦然。如果2人都承认,ok证据确凿,各判2年。如果2人都是理性人,且没有互通消息,按照博弈,每个人的最优解就是承认,也就是各判2年。其实对2人真正有利的就是打死不承认然后都无罪释放,而这种状态在理性人的假设下是很难实现的--除非有一个教父,一直灌输他们不要出卖同伙。
马云就是这个“教父”!
卡内基有篇文章,我总结成一句话就是:用崇高的理想打动别人。据说马云一直是以个人魅力及“创造中国电子商务的明天”类似的理想,激励员工的。有了统一的企业文化,员工都不计较个人得失,努力奋进,最终企业和所有员工取得共赢,这绝对是摆脱“囚徒困境”的典型案例。
话说回来,阿里巴巴能让你感受到团队的力量,一群精英在一块做很有价值的事情,对每个人也是很好的锻炼。个人认为,如果有吃苦耐劳的打算,眼光放长远点,又没有其它方面的束缚,阿里巴巴的确是不错的选择。(得向阿里巴巴收代言费,呵呵!)
第二天听了多场论道,主要是SAAS,搜索,分词方面。结合阿里巴巴的战略,我把几点融合起来讲一下。这个下篇再细细道来。
这次给
openfans
做网摘功能,主体程序倒是很快就写完了,另外要做个
IE
插件,却碰到了不少问题。
IE
插件其实很简单,就是用
js
获得页面的标题、
url
和选择的内容,然后通过弹出窗口,将其送到服务器。这里就有中文的问题了,开始使用
escape
,如
escape(title)
形式,
request.getParameter
碰到中文就为
null
,网上搜了一通,说是可以通过
java
编码搞定,但拿到就为
null
了,还怎么换编码?忙活了好几个小时,又是
alert
,又是
document.write
,看上去也没什么问题。不
escape
,直接在浏览器中输入带中文的
url
,拿到的不为
null
了,拿到后,通过
new String(str.getBytes("ISO-8859-1"), "UTF-8");
还真显示正常了。但用
window.open
又出乱码了。看到文章说还有
encodeURIComponent
方法可用,就试了下,把
escape
换成
encodeURIComponent
居然搞定了,服务端还是得用
new String(str.getBytes("ISO-8859-1"), "UTF-8")
进行处理。注意这里用的
tomcat
,它的默认编码就是
"ISO-8859-1"
,如果改了编码程序也得做相应的改动了。
今天为了在本机装个wordpress玩玩,搞了搞php5+mysql5+apache2。网上搜了一篇文档,很快就让php与apache跑起来了,但连mysql始终不行。报错:Call to undefined function mysql_connect()。查了一下半天,就是php关于mysql的ext没配好,但我改了php.ini啊,也把"extension=php_mysql.dll"放出来了。查了好久,看到一篇说php5需要加上"extension=php_mysqli.dll",试了下果然好了。
然后需要以index.php作为默认的welcomefile(不知道怎么叫,web.xml里是这个),需要在"DirectoryIndex index.html index.html.var"后加上 index.php就行。
然后飞快的装了phpmyadmin、dvbbs的php版。发现php应用的安装的确很是方便,解压,拷贝到htdocs下,马上就能运行了,比java应用简单的多,更别提复杂的要死的企业应用了。这点上java要好好向php学习啊。
项目需要,开始研究电子支付。国外的电子支付提供商,得好好研究它的文档和api。全是e文,只能慢慢看了。
学习了下spring2.0。对openfans而言,有2个比较重要的改进。首先是aspectj的支持,可以方便的使用aspectj语法定义aspect和pointcut了,openfans准备在domain object的自动注入上和权限等方面使用aop。另外就是spring form标签库的引入,现在springmvc也有自己的标签库,以前自己给checkbox和radio写的request.getParameter可以改写了。
摘要: 应项目需要做了一个定时更新的
cache
框架,采用
spring+quartz
很方便的实现,可以适用任何需要定时才更新的地方,比如静态网页
cache
等。代码很简单:
---------------------------------QuartzCacheHandler-------------------...
阅读全文
接着前面的写。上文主要写了
ajax
在
portal
中的使用,这篇写集群方面的体会。现在比较流行的架构就是前端
F5
做负载均衡,后面
2
台
websphere server
做成集群,各自都有
HttpServer
,每个
HttpServer
都向
2
台
was
做转发。这样每台都能独立完成从
HttpServer
到
was
的流程。一台出现故障,
F5
首先进行切换,只向正常
server
的
HttpServer
发起请求,这台
HttpServer
再进行切换只向同一台
server
上的
was
做转发。这次
portal
就是采用的这种架构,不妨称为架构
A
。
另一种简单点的架构就是只做
F5
负载均衡,不做
was
集群,每台
websphere server
上的
HttpServer
接受
F5
转发的请求,只向本
server
的
was
转发。这样每台
websphere server
保持独立,相互间没有数据交换和转发。不妨称为架构
B
。
架构
A
和
B
各有优劣,适合不同的需要,下面进行些比较:
Ø
从应用部署上看:
A
使用了
websphere
集群,由一个
DeployManager
进行分发,部署应用,只需部署一次,由
DM
分发到几个节点上。而
B
每个
server
都是独立的,部署应用只能一台台部署,如果
server
较少差别还不明显,如果达到
10
台以上,一台台部署将是一个比较痛苦的事情。
Ø
从
session
上看:
A
使用了
websphere
集群,可以使用集群提供的
session
复制,对于一些关键应用(某台服务器宕机,
session
也必须保持的应用)很有必要。而对于一些能够允许
session
丢失的应用,才可以使用
B
。当然
A
也可以关闭
session
复制,因为
session
复制不管是使用数据库方式还是内存方式,总会消耗一定的性能。具体消耗多少性能,就要看不同的
application server
的
session
复制方案了,想深入了解,可以看集群方面的文档,我也只记得一个比较简单的
round robbin
了。
Ø
从架构复杂性看:
B
更为简单,因为没有
DM
的概念,每台
server
都保持独立。而使用了
DM
有时也会出现莫名奇妙的问题,这当然是由于不了解
DM
的机制所致,但总归也增加了复杂度,这点在后面的教训中进行说明。
Ø
从水平扩展性上看:
B
肯定更胜一筹。只要
F5
能支持,多少台
server
都没关系。而
A
多台
server
做集群,要看
websphere
支持的节点数量,应该不会太大。这个如果哪位同学知道,敬请告知。
当然
A
和
B
在服务器较多的情况下是可以共存的,可以考虑几台机器做集群,然后集群间做负载均衡,这样既可以减少部署的复杂度,又可以带来较好的水平扩展。由于没做过更大型的项目,这个也只是我的假象,请做过的同学斧正。
说一说集群中碰到的问题。
Ø
首先是对各节点的同步:
有时为了方便测试,我们只对其中一个节点进行更改,测试通过再放到其它节点。而如果测试周期较长,有时就会造成节点的不同步,出现各种各样莫名其妙的问题。一个经验就是:无论如何,在每天下班前要保证各节点的同步,不同步的现象不要过夜。
Ø
然后是对
DM
的理解:
我现在还只是实践阶段,没有看过相关文档。从意义上看,它控制了相关的配置文件,如果进行节点同步,就会由它把配置文件同步到它管理的节点上。这对配置文件的修改提出了要求。我们开始只修改节点的配置文件而没有修改
DM
的,结果进行节点同步就会覆盖修改的配置文件,带来很多不必要的工作。经验就是:或者修改
DM
的配置文件,然后进行节点同步,或者直接同时修改所有节点和
DM
的。
Ø
还有关于
cache
的:
Cache
是性能优化的一个有效手段。在单机环境下,最简单的就是内存
cache
,使用
static
的
Map
就行。而在集群环境中,
cache
就变的比较复杂了。首先还是从应用需求入手,是否要保持每台机器的
cache
同步。如果只是信息展示等要求不高的
cache
,不需保证
cache
的同步,问题也比较简单,自己写内存
cache
,或者使用开源的
cache
组件如
ehcache,oscache
等就可以很好的解决问题。而如果需要
cache
在几个节点保持同步,就需要特殊的机制了,
ehcache
等号称支持分布式
cache
,但好像需要
jgroup
,配置比较麻烦,我没有用过,有用过的同学请指教。我本来想使用
session
保存,然后进行
session
同步,后来
IBM
建议使用数据库
cache
,即自己写代码,
cache
在数据库中。这样不需要
session
同步,对象不大,性能也能得到保证,现在用下来效果还可以。
这次做
ibm
的
portal
,算是临危受命。做了几个月的
SA
离职,留下一个功能和性能都有很多问题的项目,临时让我顶上。经过一个多月的紧张工作(经常加班,上班上不了网,也没时间上网),总算功能和性能上都能达到客户要求了。而我也由一个不懂
portal
的人,经过项目中实战,不说成为高手,一般的概念、开发、配置、优化等也都有了很多体会。
这次技术上值得推荐的就是合理的使用
ajax
,既加快了首页的
load
速度,又带来了很好的用户体验。开始首页上所有
portlet
都是串行加载,有的
portlet
比如新邮件,依赖于
mail
系统提供的接口。开始这个接口在较大压力下就出现性能瓶颈,后在我们的要求下替换了协议,性能也在
1s-2s
之间。如果采用常规的办法,加上
wps
验证、运算,显示主题、皮肤,加载所有
portlet
,响应时间肯定在
10s
以上。
我在
openfans
中使用了
ajax
,有些经验,所以决定采用异步加载:首页
load
时一些
portlet
直接显示正在
loading
的字样,在
body onload
时再使用
ajax
填充内容;使用
iframe
的
portlet
,也是
src
先指向一个静态的正在
loading
页面,
body onload
时再替换
src
到实际地址(这是
ajax
模式的一种)。这样首页登录实际上只经过
wps
内部的验证和显示,所有业务逻辑都是加载成功后再并行进行。实际表现效果就是:头上的主题很快出来,一块块区域显示正在
loading
字样,性能快的
portlet
很快出来,需要几秒的
portlet
随后出来,而不是让用户傻等
10
多
s
再一下全部显示。
使用
ajax
同时也能解决页面刷新问题和获取返回值的问题。比如前面显示新邮件的
portlet
,用户点击了一封邮件,新邮件数应该减
1
,刚点击的邮件也应该上页面上消失。原始的做法就是刷新整个页面,既加大服务器压力,又带来很差的用户体验。使用
ajax
,在点击后
1s
(或者更长,这取决于邮件系统对点击操作的响应快慢)刷新
div
的内容,用户甚至感觉不到内容已经更新。其它
portlet
也不需要重新载入,大大减轻服务器的压力。有的操作需要提交给其它系统,而且可能成功可能失败,这就需要获得返回值。如果使用普通的
form
提交,需要更新整个页面。而使用
ajax
提交,可以方便的获得其返回值,进而显示不同的提示。
另一个架构上的特点就是
portal
服务器职责单一
。开始所有的业务逻辑都是写在
portlet
里,加重了
portlet
服务器的压力。我进来后做的一个大的规划就是,把业务逻辑抽离到其它
server
上,然后通过
ajax
加载到
portlet
中。这样既可以充分利用服务器资源(新的
server
使用单独的内存空间和线程池),又使得
portal
服务器职责更单一:仅进行验证、权限控制、主题、皮肤和
portlet
的展示。
先写这么多。因为使用了
2
台
server
做集群,在分布式环境下,开发也有了更多的要求(比如
cache
),后一篇文章再细细道来。
难得有空,写篇程序之外的文章,关于压力的,也是自己近来的亲身体会。
众所周知软件这行压力是很大的。各种各样的问题层出不穷,每天上班工作内容都是排的满满的,遇到突发问题就得加班。如果不及时进行疏解,积累到一定的程度,就可能产生一定的负面问题,比如上班精神状态差、注意力不能集中、遇事喜欢逃避等等。我就亲身经历了这样的状况,明知自己工作积极性差、效率很低,但也很难一下子找回自我。
一次偶然的出游让我从中很快走了出来。一个亲戚考上厦大的博士,我请了
2
天的假,利用周末时间顺便去厦门旅游。厦门依山傍海,的确是旅游的好去处。晚上到海边,凉风习习,光脚沿着沙滩走过,任起落的潮水在腿上脚上留下层层薄沙。内心也变得平静,能够感受到海的呼吸。天地间仿佛只剩下我和大海,在进行心灵的交流,俗世烦扰皆抛诸脑后,只剩下对海的依恋。白天去爬南普陀山,并不太高,慢慢爬到山顶,整个思明区尽收眼底,远处一艘快艇在海面掠过,留下一条美丽的浪花。然后顺山而下到植物园,途径无数奇花异草、层天老树,走得累了,找个湖边石凳休息一下,人也觉得轻松愉快。
经过大自然的洗礼,回到单位,人的精神面貌焕然一新,抱着积极的心态处理事情,很多问题迎刃而解。压力测试做的很累,经常要熬夜,但通过一轮轮的测试,逐步定位到性能问题所在,自己也学了不少相关知识,想想也就没那么烦了。
做事的方式,也有了长进。我现在信奉人一时只做一件事效率最高的原则。事情再多,也是一件件做,每天安排好近日的工作,并排个优先级,什么是要亲自处理的,什么是让别人处理的,什么是需要预先通知他人的,需要什么资源,每件事情的预计时间如何,需要如何
check
等等。做好一件事就打个勾,做到心中有数。如果事情有延误,分析是什么原因,该如何补救,而不要有太大的心理负担,自己尽力了就好,是自己的责任就要勇敢扛下,死不了人的。这其实是很简单的原则,谁都能够学会,但的确很管用。
总结:压力是无处不在的,关键在于如何应对和排解。用积极的心态和恰当的方法面对,压力也就没那么大了。感觉压力积累到一定程度,在还未影响正常工作之前就先想办法排解,出去旅游、运动等都是缓解压力的好办法。