2007年5月21日
應朋友邀請,周六早從上海出發往杭州參加阿里巴巴網俠大會。同行四人,有銳道的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,搜索,分詞方面。結合阿里巴巴的戰略,我把幾點融合起來講一下。這個下篇再細細道來。
2007年3月11日
這次給
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"
,如果改了編碼程序也得做相應的改動了。
2007年3月2日
2007年1月14日
今天為了在本機裝個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學習啊。
2007年1月12日
項目需要,開始研究電子支付。國外的電子支付提供商,得好好研究它的文檔和api。全是e文,只能慢慢看了。
2006年12月28日
? 學習了下spring2.0。對openfans而言,有2個比較重要的改進。首先是aspectj的支持,可以方便的使用aspectj語法定義aspect和pointcut了,openfans準備在domain object的自動注入上和權限等方面使用aop。另外就是spring form標簽庫的引入,現在springmvc也有自己的標簽庫,以前自己給checkbox和radio寫的request.getParameter可以改寫了。
2006年12月13日
摘要: 應項目需要做了一個定時更新的
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
同步,對象不大,性能也能得到保證,現在用下來效果還可以。
?
2006年11月28日
這次做
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
),后一篇文章再細細道來。