2006年11月28日

          論劍歸來(lái)(一)

          應(yīng)朋友邀請(qǐng),周六早從上海出發(fā)往杭州參加阿里巴巴網(wǎng)俠大會(huì)。同行四人,有銳道的macro chen、楊光(還是我?guī)煹埽⒁苿?dòng)的王偉旭(特長(zhǎng)是linux和網(wǎng)絡(luò)安全,也是中國(guó)linux推廣的先驅(qū))。一路上,言談甚歡。老莊給我們訂的票,他一早腸胃有恙,仍然堅(jiān)持把票送到火車站,之后去吊鹽水,下午又出現(xiàn)在會(huì)場(chǎng)。確實(shí)精神可嘉,建議阿里巴巴頒發(fā)“最佳精神獎(jiǎng)”。

          到杭州已是中午,錯(cuò)過(guò)了上午大會(huì)。下午Robbin進(jìn)行Java技術(shù)展望和RoR實(shí)現(xiàn)REST的演講,既然是朋友,肯定是要捧場(chǎng)的。Robbin旁征博引,以其深厚的技術(shù)功底和對(duì)新技術(shù)的敏銳洞察贏得了聽(tīng)眾。

          晚上一堆人去聚會(huì),各路豪杰紛至:有阿里巴巴的,有自己創(chuàng)業(yè)的,有技術(shù)大牛,還有媒體(Infoq),出版社(博文的周總領(lǐng)3員大將赴會(huì))。大家互換名片,認(rèn)識(shí)的不免寒暄幾句,不認(rèn)識(shí)的也很快就熟捻了,還不時(shí)有“原來(lái)你就是×××”的驚呼,原來(lái)網(wǎng)上就“互通心曲”,只是一直沒(méi)機(jī)會(huì)認(rèn)識(shí)罷了。

          席間觥籌交錯(cuò),具體內(nèi)容暫且不表,只說(shuō)一件令我感受頗深之事。一個(gè)阿里巴巴的員工表現(xiàn)出對(duì)公司的無(wú)比忠誠(chéng),講起公司的獎(jiǎng)懲制度,說(shuō)是一個(gè)員工的績(jī)效不僅跟所在項(xiàng)目相關(guān),還與部門、其它部門甚至整個(gè)公司的業(yè)績(jī)相關(guān)。所以只要是對(duì)公司有利的事情,即使與自己現(xiàn)在的工作無(wú)關(guān),他們也會(huì)去做。按常理來(lái)說(shuō),這有點(diǎn)不公平,我只能努力做好自己的事情,而如果別人不努力,我就是白做。但如果大家都努力,又變成了共贏。

          這里讓我講一個(gè)簡(jiǎn)單的博弈問(wèn)題,就是“囚徒困境”。AB兩個(gè)同犯被抓,因?yàn)闆](méi)有其它任何證據(jù)和證人,只能讓2人分別交供。如果AB都矢口否認(rèn),那么兩人無(wú)罪釋放。如果A承認(rèn),B不承認(rèn);A是坦白從寬,判1年;B抗拒從嚴(yán),判5年,反之亦然。如果2人都承認(rèn),ok證據(jù)確鑿,各判2年。如果2人都是理性人,且沒(méi)有互通消息,按照博弈,每個(gè)人的最優(yōu)解就是承認(rèn),也就是各判2年。其實(shí)對(duì)2人真正有利的就是打死不承認(rèn)然后都無(wú)罪釋放,而這種狀態(tài)在理性人的假設(shè)下是很難實(shí)現(xiàn)的--除非有一個(gè)教父,一直灌輸他們不要出賣同伙。

          馬云就是這個(gè)“教父”!

          卡內(nèi)基有篇文章,我總結(jié)成一句話就是:用崇高的理想打動(dòng)別人。據(jù)說(shuō)馬云一直是以個(gè)人魅力及“創(chuàng)造中國(guó)電子商務(wù)的明天”類似的理想,激勵(lì)員工的。有了統(tǒng)一的企業(yè)文化,員工都不計(jì)較個(gè)人得失,努力奮進(jìn),最終企業(yè)和所有員工取得共贏,這絕對(duì)是擺脫“囚徒困境”的典型案例。

          話說(shuō)回來(lái),阿里巴巴能讓你感受到團(tuán)隊(duì)的力量,一群精英在一塊做很有價(jià)值的事情,對(duì)每個(gè)人也是很好的鍛煉。個(gè)人認(rèn)為,如果有吃苦耐勞的打算,眼光放長(zhǎng)遠(yuǎn)點(diǎn),又沒(méi)有其它方面的束縛,阿里巴巴的確是不錯(cuò)的選擇。(得向阿里巴巴收代言費(fèi),呵呵!)

          第二天聽(tīng)了多場(chǎng)論道,主要是SAAS,搜索,分詞方面。結(jié)合阿里巴巴的戰(zhàn)略,我把幾點(diǎn)融合起來(lái)講一下。這個(gè)下篇再細(xì)細(xì)道來(lái)。

           

           

          posted @ 2007-05-21 20:35 pesome 閱讀(1145) | 評(píng)論 (1)編輯 收藏

          sitemesh的問(wèn)題及解決

          再說(shuō) sitemesh 的問(wèn)題,同樣是做 openfans 網(wǎng)摘功能出現(xiàn)的。做好了 IE 插件,有 fans 反饋說(shuō)彈出頁(yè)面太大,這也難怪,用了 sitemesh head footer 都在頁(yè)面上,想縮小頁(yè)面,肯定得把 head footer 都去掉,做個(gè)干凈點(diǎn)的。既然用了 sitemesh 肯定是希望最方便的搞定這個(gè),而不用動(dòng)任何邏輯(包括頁(yè)面邏輯)。這個(gè)好辦,文檔里有說(shuō),通過(guò)在 sitemesh.xml 中增加

          < mapper

          ???????????
          class = " com.opensymphony.module.sitemesh.mapper.ParameterDecoratorMapper " >

          ???????????
          < param?name = " decorator.parameter " ?value = " decorator " ? />

          ???????????
          < param?name = " parameter.name " ?value = " confirm " ? />

          ???????????
          < param?name = " parameter.value " ?value = " true " ? />

          ???????
          </ mapper >

          就能搞定,這樣只需要使用參數(shù)如 saveSnippet.html?decorator=simple&confirm=true ,就能讓它使用指定的 decorator 。然后做一個(gè)去掉 head footer 只保留必要的 js css 引用的 simple.jsp 頁(yè)面,同時(shí)在 decorator.xml 中配

          < decorator?name = " simple " ?page = " simple.jsp " ></ decorator >

          就應(yīng)該可以搞定。

          但怎么測(cè),就是不使用這個(gè) simple decorator 。沒(méi)辦法,只好跟進(jìn) sitemesh 源碼中去調(diào)試,進(jìn)入 ParameterDecoratorMapper 類,它繼承了 AbstractDecoratorMapper 類,然后有一個(gè) init 方法一個(gè) getDecorator 方法。各打一個(gè)斷點(diǎn), init 方法在 tomcat 啟動(dòng)就會(huì)執(zhí)行,也正常初始化了, getDecorator 方法卻始終不調(diào)用,一時(shí)想不出辦法。看到篇文章說(shuō)不自己寫(xiě) sitemesh.xml 而使用自帶的 com/opensymphony/module/sitemesh/factory/sitemesh-default.xml 也可以,于是備份并刪除我寫(xiě)的 sitemesh.xml ,居然成功了。為什么我寫(xiě)的就不行呢?差別一是我的簡(jiǎn)化了很多,只有

          < mapper

          ????
          class ="com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper" >

          ???????????
          < param? name ="config" ?value ="${decorators-file}" ? />

          ???????
          </ mapper >

          和剛加的

          ParameterDecoratorMapper ,二就是順序,我的 ParameterDecoratorMapper 放在了 ConfigDecoratorMapper 后面,會(huì)不會(huì)是順序原因呢,調(diào)換一下,果然成功了。問(wèn)題是解決了,原理呢?再花點(diǎn)時(shí)間跟一下代碼了解下原理,原來(lái)使用了 Factory ,它會(huì)調(diào)用各個(gè)配置的 Mapper init 方法,并放入 map 中,然后到時(shí)選擇一個(gè) Mapper ,如果符合條件就使用,否則繼續(xù)往下找。這里就有了順序的問(wèn)題,因?yàn)槲以?/span> decorator.xml 中使用了
          <decorator?name="default"?page="default.jsp">

          ????????
          <pattern>/*.html</pattern>

          ????
          </decorator>

          ,這樣如果 ConfigDecoratorMapper 放在前面,他就先找這個(gè) Mapper ,一看 saveSnippet.html?decorator=simple&confirm=true ,符合 pattern 啊,就使用它了,另一個(gè) ParameterDecoratorMapper 根本得不到機(jī)會(huì),所以也進(jìn)不了它的 getDecorator 方法。換了順序就是它先進(jìn)去,所以執(zhí)行,其它的 url 也是先找它,但不匹配,就又交給 ConfigDecoratorMapper 了。呵呵,問(wèn)題也解決了,對(duì) sitemesh 的認(rèn)識(shí)又進(jìn)了一步。

          posted @ 2007-03-11 22:54 pesome 閱讀(3006) | 評(píng)論 (0)編輯 收藏

          中文問(wèn)題的解決

          這次給 openfans 做網(wǎng)摘功能,主體程序倒是很快就寫(xiě)完了,另外要做個(gè) IE 插件,卻碰到了不少問(wèn)題。 IE 插件其實(shí)很簡(jiǎn)單,就是用 js 獲得頁(yè)面的標(biāo)題、 url 和選擇的內(nèi)容,然后通過(guò)彈出窗口,將其送到服務(wù)器。這里就有中文的問(wèn)題了,開(kāi)始使用 escape ,如 escape(title) 形式, request.getParameter 碰到中文就為 null ,網(wǎng)上搜了一通,說(shuō)是可以通過(guò) java 編碼搞定,但拿到就為 null 了,還怎么換編碼?忙活了好幾個(gè)小時(shí),又是 alert ,又是 document.write ,看上去也沒(méi)什么問(wèn)題。不 escape ,直接在瀏覽器中輸入帶中文的 url ,拿到的不為 null 了,拿到后,通過(guò) new String(str.getBytes("ISO-8859-1"), "UTF-8"); 還真顯示正常了。但用 window.open 又出亂碼了。看到文章說(shuō)還有 encodeURIComponent 方法可用,就試了下,把 escape 換成 encodeURIComponent 居然搞定了,服務(wù)端還是得用 new String(str.getBytes("ISO-8859-1"), "UTF-8") 進(jìn)行處理。注意這里用的 tomcat ,它的默認(rèn)編碼就是 "ISO-8859-1" ,如果改了編碼程序也得做相應(yīng)的改動(dòng)了。

          posted @ 2007-03-11 22:51 pesome 閱讀(1058) | 評(píng)論 (0)編輯 收藏

          hibernate native sql的小技巧

          為了性能考慮,使用了 native sql 。因?yàn)樾枰猪?yè),需要 2 個(gè) sql ,一個(gè)獲取 list 一個(gè)取得總數(shù)。獲取 list 很好寫(xiě):

          ?

          ?1 private ?List?getListByNativeSQL( final ?Class?cls,? final ?String?sql)? {
          ?2
          ?3 ??????? return ?(List)?getHibernateTemplate().execute( new ?HibernateCallback()? {
          ?4
          ?5 ??????????? public ?Object?doInHibernate(Session?session)
          ?6
          ?7 ?????????????????? throws ?HibernateException? {
          ?8
          ?9 ?????????????? return ?session.createSQLQuery(sql).addEntity(cls).list();
          10
          11 ???????????}

          12
          13 ???????}
          );
          14
          15 ????}

          16

          ?

          獲取總數(shù)查了下 hibernate reference, 試了幾次才明白用法 :

          ?1 private ?BigInteger?getCountByNativeSQL( final ?String?sql)? {
          ?2
          ?3 ??????? return ?(BigInteger)?getHibernateTemplate().execute(
          ?4
          ?5 ?????????????? new ?HibernateCallback()? {
          ?6
          ?7 ?????????????????? public ?Object?doInHibernate(Session?session)
          ?8
          ?9 ????????????????????????? throws ?HibernateException? {
          10
          11 ????????????????????? return ?(BigInteger)?(session.createSQLQuery(sql).uniqueResult());
          12
          13 ??????????????????}

          14
          15 ??????????????}
          );
          16
          17 ????}

          18

          這里的

          sql 是“ select count(*) 開(kāi)頭的”。這里大家可能要問(wèn),為什么要使用 BigInteger ,因?yàn)槿绻?/span> uniqueResult() 默認(rèn)就返回 BigInteger ,而 BigInteger cast Integer 會(huì)出錯(cuò)。那么如果我就是要返回 Integer 呢,可以通過(guò)下面的辦法實(shí)現(xiàn):

          ?1 private ?Integer?getCountByNativeSQL( final ?String?sql)? {
          ?2
          ?3 ??????? return ?(Integer)?getHibernateTemplate().execute(
          ?4
          ?5 ?????????????? new ?HibernateCallback()? {
          ?6
          ?7 ?????????????????? public ?Object?doInHibernate(Session?session)
          ?8
          ?9 ????????????????????????? throws ?HibernateException? {
          10
          11 ????????????????????? return ?(Integer)?(session.createSQLQuery(sql).addScalar( " count " ,?Hibernate.INTEGER).uniqueResult());
          12
          13 ??????????????????}

          14
          15 ??????????????}
          );
          16
          17 ????}

          18

          大家注意粗體的部分,這里是給一個(gè)

          alias 賦予類型,那么 sql 就需要變成以 ”select count(*) as count ” 開(kāi)頭了。

          posted @ 2007-03-02 10:52 pesome 閱讀(5267) | 評(píng)論 (2)編輯 收藏

          php5+mysql5+apache2需要注意的幾點(diǎn)

          今天為了在本機(jī)裝個(gè)wordpress玩玩,搞了搞php5+mysql5+apache2。網(wǎng)上搜了一篇文檔,很快就讓php與apache跑起來(lái)了,但連mysql始終不行。報(bào)錯(cuò):Call to undefined function mysql_connect()。查了一下半天,就是php關(guān)于mysql的ext沒(méi)配好,但我改了php.ini啊,也把"extension=php_mysql.dll"放出來(lái)了。查了好久,看到一篇說(shuō)php5需要加上"extension=php_mysqli.dll",試了下果然好了。
          ???? 然后需要以index.php作為默認(rèn)的welcomefile(不知道怎么叫,web.xml里是這個(gè)),需要在"DirectoryIndex index.html index.html.var"后加上 index.php就行。
          然后飛快的裝了phpmyadmin、dvbbs的php版。發(fā)現(xiàn)php應(yīng)用的安裝的確很是方便,解壓,拷貝到htdocs下,馬上就能運(yùn)行了,比java應(yīng)用簡(jiǎn)單的多,更別提復(fù)雜的要死的企業(yè)應(yīng)用了。這點(diǎn)上java要好好向php學(xué)習(xí)啊。

          posted @ 2007-01-14 17:34 pesome 閱讀(1307) | 評(píng)論 (0)編輯 收藏

          開(kāi)始研究電子支付

          項(xiàng)目需要,開(kāi)始研究電子支付。國(guó)外的電子支付提供商,得好好研究它的文檔和api。全是e文,只能慢慢看了。

          posted @ 2007-01-12 15:41 pesome 閱讀(1305) | 評(píng)論 (1)編輯 收藏

          準(zhǔn)備給openfans添加spring2.0支持

          ? 學(xué)習(xí)了下spring2.0。對(duì)openfans而言,有2個(gè)比較重要的改進(jìn)。首先是aspectj的支持,可以方便的使用aspectj語(yǔ)法定義aspect和pointcut了,openfans準(zhǔn)備在domain object的自動(dòng)注入上和權(quán)限等方面使用aop。另外就是spring form標(biāo)簽庫(kù)的引入,現(xiàn)在springmvc也有自己的標(biāo)簽庫(kù),以前自己給checkbox和radio寫(xiě)的request.getParameter可以改寫(xiě)了。

          posted @ 2006-12-28 15:15 pesome 閱讀(1144) | 評(píng)論 (1)編輯 收藏

          一個(gè)定時(shí)更新cache框架

               摘要: 應(yīng)項(xiàng)目需要做了一個(gè)定時(shí)更新的 cache 框架,采用 spring+quartz 很方便的實(shí)現(xiàn),可以適用任何需要定時(shí)才更新的地方,比如靜態(tài)網(wǎng)頁(yè) cache 等。代碼很簡(jiǎn)單: ---------------------------------QuartzCacheHandler-------------------...  閱讀全文

          posted @ 2006-12-13 14:46 pesome 閱讀(4145) | 評(píng)論 (7)編輯 收藏

          這次做portal的一些總結(jié)(二)

          接著前面的寫(xiě)。上文主要寫(xiě)了 ajax portal 中的使用,這篇寫(xiě)集群方面的體會(huì)。現(xiàn)在比較流行的架構(gòu)就是前端 F5 做負(fù)載均衡,后面 2 臺(tái) websphere server 做成集群,各自都有 HttpServer ,每個(gè) HttpServer 都向 2 臺(tái) was 做轉(zhuǎn)發(fā)。這樣每臺(tái)都能獨(dú)立完成從 HttpServer was 的流程。一臺(tái)出現(xiàn)故障, F5 首先進(jìn)行切換,只向正常 server HttpServer 發(fā)起請(qǐng)求,這臺(tái) HttpServer 再進(jìn)行切換只向同一臺(tái) server 上的 was 做轉(zhuǎn)發(fā)。這次 portal 就是采用的這種架構(gòu),不妨稱為架構(gòu) A

          另一種簡(jiǎn)單點(diǎn)的架構(gòu)就是只做 F5 負(fù)載均衡,不做 was 集群,每臺(tái) websphere server 上的 HttpServer 接受 F5 轉(zhuǎn)發(fā)的請(qǐng)求,只向本 server was 轉(zhuǎn)發(fā)。這樣每臺(tái) websphere server 保持獨(dú)立,相互間沒(méi)有數(shù)據(jù)交換和轉(zhuǎn)發(fā)。不妨稱為架構(gòu) B

          架構(gòu) A B 各有優(yōu)劣,適合不同的需要,下面進(jìn)行些比較:

          ????????? 從應(yīng)用部署上看:

          A 使用了 websphere 集群,由一個(gè) DeployManager 進(jìn)行分發(fā),部署應(yīng)用,只需部署一次,由 DM 分發(fā)到幾個(gè)節(jié)點(diǎn)上。而 B 每個(gè) server 都是獨(dú)立的,部署應(yīng)用只能一臺(tái)臺(tái)部署,如果 server 較少差別還不明顯,如果達(dá)到 10 臺(tái)以上,一臺(tái)臺(tái)部署將是一個(gè)比較痛苦的事情。

          ????????? session 上看:

          A 使用了 websphere 集群,可以使用集群提供的 session 復(fù)制,對(duì)于一些關(guān)鍵應(yīng)用(某臺(tái)服務(wù)器宕機(jī), session 也必須保持的應(yīng)用)很有必要。而對(duì)于一些能夠允許 session 丟失的應(yīng)用,才可以使用 B 。當(dāng)然 A 也可以關(guān)閉 session 復(fù)制,因?yàn)?/span> session 復(fù)制不管是使用數(shù)據(jù)庫(kù)方式還是內(nèi)存方式,總會(huì)消耗一定的性能。具體消耗多少性能,就要看不同的 application server session 復(fù)制方案了,想深入了解,可以看集群方面的文檔,我也只記得一個(gè)比較簡(jiǎn)單的 round robbin 了。

          ????????? 從架構(gòu)復(fù)雜性看:

          B 更為簡(jiǎn)單,因?yàn)闆](méi)有 DM 的概念,每臺(tái) server 都保持獨(dú)立。而使用了 DM 有時(shí)也會(huì)出現(xiàn)莫名奇妙的問(wèn)題,這當(dāng)然是由于不了解 DM 的機(jī)制所致,但總歸也增加了復(fù)雜度,這點(diǎn)在后面的教訓(xùn)中進(jìn)行說(shuō)明。

          ????????? 從水平擴(kuò)展性上看:

          B 肯定更勝一籌。只要 F5 能支持,多少臺(tái) server 都沒(méi)關(guān)系。而 A 多臺(tái) server 做集群,要看 websphere 支持的節(jié)點(diǎn)數(shù)量,應(yīng)該不會(huì)太大。這個(gè)如果哪位同學(xué)知道,敬請(qǐng)告知。

          當(dāng)然 A B 在服務(wù)器較多的情況下是可以共存的,可以考慮幾臺(tái)機(jī)器做集群,然后集群間做負(fù)載均衡,這樣既可以減少部署的復(fù)雜度,又可以帶來(lái)較好的水平擴(kuò)展。由于沒(méi)做過(guò)更大型的項(xiàng)目,這個(gè)也只是我的假象,請(qǐng)做過(guò)的同學(xué)斧正。

          ?

          說(shuō)一說(shuō)集群中碰到的問(wèn)題。

          ????????? 首先是對(duì)各節(jié)點(diǎn)的同步:

          有時(shí)為了方便測(cè)試,我們只對(duì)其中一個(gè)節(jié)點(diǎn)進(jìn)行更改,測(cè)試通過(guò)再放到其它節(jié)點(diǎn)。而如果測(cè)試周期較長(zhǎng),有時(shí)就會(huì)造成節(jié)點(diǎn)的不同步,出現(xiàn)各種各樣莫名其妙的問(wèn)題。一個(gè)經(jīng)驗(yàn)就是:無(wú)論如何,在每天下班前要保證各節(jié)點(diǎn)的同步,不同步的現(xiàn)象不要過(guò)夜。

          ????????? 然后是對(duì) DM 的理解:

          我現(xiàn)在還只是實(shí)踐階段,沒(méi)有看過(guò)相關(guān)文檔。從意義上看,它控制了相關(guān)的配置文件,如果進(jìn)行節(jié)點(diǎn)同步,就會(huì)由它把配置文件同步到它管理的節(jié)點(diǎn)上。這對(duì)配置文件的修改提出了要求。我們開(kāi)始只修改節(jié)點(diǎn)的配置文件而沒(méi)有修改 DM 的,結(jié)果進(jìn)行節(jié)點(diǎn)同步就會(huì)覆蓋修改的配置文件,帶來(lái)很多不必要的工作。經(jīng)驗(yàn)就是:或者修改 DM 的配置文件,然后進(jìn)行節(jié)點(diǎn)同步,或者直接同時(shí)修改所有節(jié)點(diǎn)和 DM 的。

          ????????? 還有關(guān)于 cache 的:

          Cache 是性能優(yōu)化的一個(gè)有效手段。在單機(jī)環(huán)境下,最簡(jiǎn)單的就是內(nèi)存 cache ,使用 static Map 就行。而在集群環(huán)境中, cache 就變的比較復(fù)雜了。首先還是從應(yīng)用需求入手,是否要保持每臺(tái)機(jī)器的 cache 同步。如果只是信息展示等要求不高的 cache ,不需保證 cache 的同步,問(wèn)題也比較簡(jiǎn)單,自己寫(xiě)內(nèi)存 cache ,或者使用開(kāi)源的 cache 組件如 ehcache,oscache 等就可以很好的解決問(wèn)題。而如果需要 cache 在幾個(gè)節(jié)點(diǎn)保持同步,就需要特殊的機(jī)制了, ehcache 等號(hào)稱支持分布式 cache ,但好像需要 jgroup ,配置比較麻煩,我沒(méi)有用過(guò),有用過(guò)的同學(xué)請(qǐng)指教。我本來(lái)想使用 session 保存,然后進(jìn)行 session 同步,后來(lái) IBM 建議使用數(shù)據(jù)庫(kù) cache ,即自己寫(xiě)代碼, cache 在數(shù)據(jù)庫(kù)中。這樣不需要 session 同步,對(duì)象不大,性能也能得到保證,現(xiàn)在用下來(lái)效果還可以。

          ?

          posted @ 2006-12-13 13:39 pesome 閱讀(3822) | 評(píng)論 (9)編輯 收藏

          這次做portal的一些總結(jié)(一)

          這次做 ibm portal ,算是臨危受命。做了幾個(gè)月的 SA 離職,留下一個(gè)功能和性能都有很多問(wèn)題的項(xiàng)目,臨時(shí)讓我頂上。經(jīng)過(guò)一個(gè)多月的緊張工作(經(jīng)常加班,上班上不了網(wǎng),也沒(méi)時(shí)間上網(wǎng)),總算功能和性能上都能達(dá)到客戶要求了。而我也由一個(gè)不懂 portal 的人,經(jīng)過(guò)項(xiàng)目中實(shí)戰(zhàn),不說(shuō)成為高手,一般的概念、開(kāi)發(fā)、配置、優(yōu)化等也都有了很多體會(huì)。

          這次技術(shù)上值得推薦的就是合理的使用 ajax ,既加快了首頁(yè)的 load 速度,又帶來(lái)了很好的用戶體驗(yàn)。開(kāi)始首頁(yè)上所有 portlet 都是串行加載,有的 portlet 比如新郵件,依賴于 mail 系統(tǒng)提供的接口。開(kāi)始這個(gè)接口在較大壓力下就出現(xiàn)性能瓶頸,后在我們的要求下替換了協(xié)議,性能也在 1s-2s 之間。如果采用常規(guī)的辦法,加上 wps 驗(yàn)證、運(yùn)算,顯示主題、皮膚,加載所有 portlet ,響應(yīng)時(shí)間肯定在 10s 以上。

          我在 openfans 中使用了 ajax ,有些經(jīng)驗(yàn),所以決定采用異步加載:首頁(yè) load 時(shí)一些 portlet 直接顯示正在 loading 的字樣,在 body onload 時(shí)再使用 ajax 填充內(nèi)容;使用 iframe portlet ,也是 src 先指向一個(gè)靜態(tài)的正在 loading 頁(yè)面, body onload 時(shí)再替換 src 到實(shí)際地址(這是 ajax 模式的一種)。這樣首頁(yè)登錄實(shí)際上只經(jīng)過(guò) wps 內(nèi)部的驗(yàn)證和顯示,所有業(yè)務(wù)邏輯都是加載成功后再并行進(jìn)行。實(shí)際表現(xiàn)效果就是:頭上的主題很快出來(lái),一塊塊區(qū)域顯示正在 loading 字樣,性能快的 portlet 很快出來(lái),需要幾秒的 portlet 隨后出來(lái),而不是讓用戶傻等 10 s 再一下全部顯示。

          使用 ajax 同時(shí)也能解決頁(yè)面刷新問(wèn)題和獲取返回值的問(wèn)題。比如前面顯示新郵件的 portlet ,用戶點(diǎn)擊了一封郵件,新郵件數(shù)應(yīng)該減 1 ,剛點(diǎn)擊的郵件也應(yīng)該上頁(yè)面上消失。原始的做法就是刷新整個(gè)頁(yè)面,既加大服務(wù)器壓力,又帶來(lái)很差的用戶體驗(yàn)。使用 ajax ,在點(diǎn)擊后 1s (或者更長(zhǎng),這取決于郵件系統(tǒng)對(duì)點(diǎn)擊操作的響應(yīng)快慢)刷新 div 的內(nèi)容,用戶甚至感覺(jué)不到內(nèi)容已經(jīng)更新。其它 portlet 也不需要重新載入,大大減輕服務(wù)器的壓力。有的操作需要提交給其它系統(tǒng),而且可能成功可能失敗,這就需要獲得返回值。如果使用普通的 form 提交,需要更新整個(gè)頁(yè)面。而使用 ajax 提交,可以方便的獲得其返回值,進(jìn)而顯示不同的提示。

          另一個(gè)架構(gòu)上的特點(diǎn)就是 portal 服務(wù)器職責(zé)單一 。開(kāi)始所有的業(yè)務(wù)邏輯都是寫(xiě)在 portlet 里,加重了 portlet 服務(wù)器的壓力。我進(jìn)來(lái)后做的一個(gè)大的規(guī)劃就是,把業(yè)務(wù)邏輯抽離到其它 server 上,然后通過(guò) ajax 加載到 portlet 中。這樣既可以充分利用服務(wù)器資源(新的 server 使用單獨(dú)的內(nèi)存空間和線程池),又使得 portal 服務(wù)器職責(zé)更單一:僅進(jìn)行驗(yàn)證、權(quán)限控制、主題、皮膚和 portlet 的展示。

          先寫(xiě)這么多。因?yàn)槭褂昧?/span> 2 臺(tái) server 做集群,在分布式環(huán)境下,開(kāi)發(fā)也有了更多的要求(比如 cache ),后一篇文章再細(xì)細(xì)道來(lái)。

          posted @ 2006-11-28 14:49 pesome 閱讀(3672) | 評(píng)論 (9)編輯 收藏

          <2006年11月>
          2930311234
          567891011
          12131415161718
          19202122232425
          262728293012
          3456789

          導(dǎo)航

          統(tǒng)計(jì)

          公告

          主要記錄作者在學(xué)習(xí)java中的每一步足跡。除非特別說(shuō)明,所有文章均為本blog作者原創(chuàng),如需轉(zhuǎn)載請(qǐng)注明出處和原作者,如用于商業(yè)目的,需跟作者本人聯(lián)系。
          歡迎大家訪問(wèn):

          常用鏈接

          留言簿(16)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          相冊(cè)

          收藏夾

          java技術(shù)

          人間百態(tài)

          朋友們的blog

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 永修县| 双峰县| 民丰县| 库尔勒市| 突泉县| 富平县| 莱芜市| 大姚县| 平舆县| 博乐市| 大同县| 固始县| 巫山县| 桃园县| 乌什县| 上饶市| 公主岭市| 宣城市| 阜新市| 故城县| 大洼县| 台东县| 沙坪坝区| 崇阳县| 沈阳市| 昂仁县| 象山县| 赤城县| 万盛区| 大同市| 石渠县| 临城县| 昭觉县| 阿城市| 威海市| 天全县| 温宿县| 海淀区| 南靖县| 大冶市| 蕲春县|