放翁(文初)的一畝三分地

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            210 隨筆 :: 1 文章 :: 320 評論 :: 0 Trackbacks

          #

                 兩個半小時之后,我和BlueDavy大叔回到了杭州,一個忙碌而充實的周末就這么過去了。回到家已經1點多了,洗了個澡,精神又來了,想把這個充實的周末寫下來,做個紀念。

          緣起

                 幾周前,受到了普元的邀請,去三亞參加一個SOA的技術交流會,原本以為是因為在他們的論壇同時更新了一些文章所以被邀請一起去參加產品部活動,開始不是很想去,畢竟廠商出錢多半就是讓你去聽聽他們的產品,一個周末飛來飛去的也累,但淘寶的BlueDavy大叔要去,順便也叫我一起去熱鬧熱鬧,那么就決定去湊這個熱鬧。周五下班以后背了個包就直奔機場了,結果到了機場才發現辦護照的時候身份證放在家里了,幸好機場還有個臨時身份證明辦理的便民業務,總算順利的上了飛機。

          人物

                 第一天到場,第一個環節就是自我介紹,江湖中人就悉數登場了。Robbin,白衣,俞黎敏,小剛,楊戈,InfoQ中文站的主編霍泰穩和其他幾個編輯,灰狐的主創:銀狐999,程勇,普元的老大Chris以及普元的很多技術架構師牛人。陳勇的一句話就把我們這批人概括了一下,其實大家都是江湖中人,平時混各個堂口的,今天在普元召集的這么一次活動,有機會能夠匯聚一起,談天說地。

          活動

                 第一天上午有兩個Topic關于SOA的市場價值,下午也有兩個Topic關于SOA的企業架構,主講的都是我們這些外部請來的人。上午下午有很多時間是自由討論,每個人都有機會發表自己的意見,應該是算圓桌會議,所以你要發言隨時隨地都可以直接說,不需要顧忌什么,只要覺得要說,該說,就能說。這一天碰撞出不少火花。晚上邊吃燒烤邊聊,后面去沙灘上繼續討論技術圈的構建(不過這個到了最后也沒有一個很好的解決方案)。

                 第二天主要是普元分享了他們對于SOA技術的理解和具體的實現,從實際角度去展示了一個SOA的實實在在的成果。

          收獲

                 其實這部分才是我要寫得重點。一部分一部分來說吧。

          首先是識人,這次在會上看到了很多都是自己曾經蠻佩服的國內開源技術論壇或者社區的創辦者,其實從他們身上除了看到技術人員本身所特有的對于技術的追求更多的是對于新事物的理性的學習和分析。其實我一直覺得有一點對于一個架構師或者一個優秀的開發人員來說很重要的特質就是開放的去學習和接受新事物,有一個包容的心態去看待每一個陌生的新生事物,那么才能不斷地進步。而排斥和固步自封,只能最后束縛了自己的腳步,慢慢的落后與他人。SOA這個概念提出來很多年了,炒作到實質性的轉變也就在這一兩年,具體的實踐還需要后面幾年的實施和驗證。所以到場的每一位沒有一個敢說自己完全了解SOA是什么,絕大部分都是抱著希望了解SOA實際上究竟是什么的想法而來。在討論的過程中大家就很直白的說出了SOA是否還是一個虛概念,過去的EAI,BPM以及現在的EBI的區別。沒有絕對的否定,只有探討,學習和交流。我是第一認識他們,而他們之間已經相互很熟悉,但是和他們交流并不存在任何障礙,沒有說牛人就是一個圈子,基本很難接觸的那種感覺。我想也正是一種Open的心態才能讓人進步得更快。

          再則談談接觸普元的朋友。和普元的朋友交流的機會不算很多,不過在第一天的休息的時候和幾個主要的技術人員作了交流。因為其實我做SCA也還算比較早,所以對于SCA還是比較熟悉的,同時普元又是SCA中國區的推廣者,所以和他們的架構師交流SCA很容易,不像在單位里面基本就是寫好使用文檔給開發者看,如果要談具體的原理,基本沒有人看過SCA規范,我是在SCA0.96版本上作了穩定版本的,現在解析使用Tuscany,再次組裝是自己做的,一來早期的Tuscany對于兩個級別的ServiceReference沒有做級別控制,二來包括WS模塊以及其他模塊有很多的Bug,所以作了再次的開發和封裝以適應業務開發的需求,其實在我們的研討會上也說了,開源的缺點就是不穩定,不一定適應商業開發,如果商業開發的話,一般是需要穩定在某一個版本上。同時由于SCA本身的模塊化特點,所以部分升級和開發十分方便。這些思想和概念以及遇到的問題和普元的開發團隊遇到的一些問題都十分相似,特別是在WS上面,我一度也應為搞不定某些特殊的類型想去使用SDO,不過最后還是直接修復SCAWS組件搞定了,也就沒有使用SDO。不過第二天的普元的服務管理和監控讓我還是眼前一亮,這個對我來說可能也是后續在服務框架中需要考慮和搭建的,因為如果要采取Service API Mashup Platform,那么這部分內容勢必是必須的。同時,普元的很多高手都是SCA組織的成員,這也是我蠻羨慕的,有機會還是要和他們多多學習和交流,雖然后續我的工作重點不是在SCA上了,不過ASF的工作以及SCA的持續學習也是自己“私活”之一。總的感覺來說,普元的技術人員雖然話不多,但是內功深厚,有很多可以去學習和切磋的。

          最后就是關于SOA的一些感觸。第二天中午最后一點時間是給大家講關于這一天半的討論和交流以后對于SOA的收獲,由于時間關系,到我們的時候大家盡量簡短發言,我也就說了自己的兩點想法:1.先學在干在學在干。2.開發人員是我們的客戶,不要讓我們的客戶因為使用我們的產品而痛苦不堪,應該讓我們的客戶在使用了產品以后提高了生產效率。第一點什么意思呢?在我做服務框架以前,先去研究過OSGI,然后又接觸了SOA,最后接觸到了SCA。花了1個多禮拜把SCA規范啃了幾遍以后,找到了使用SCA實現服務框架的優勢以后,就開始搞服務框架了,看了Tuscany的源碼與設計思想,做了修改和封裝,第一階段的SCA服務框架就這么出來了。曾一度寫了關于SCA如何讓SOA落地的一些感想文章,但是后來自己都開始有些迷惑,究竟SOA是什么,僅僅就是用SCA去實現WS來互聯互通么?這時候去看了很多關于SCASOA的資料和文章,突然發現又陷入到了一個開發者的角度去審視SOA的陷阱。很多人說SOA只是一種概念,沒錯,其實就是概念,那么這個概念有什么價值?其實這就是一個思考的過程。參加了BEA2007大會,雖然沒有實質性的一些Topic讓我有所收獲,但是在主題演講的時候讓我突然開了竅。其實任何技術都是有延續性的EAISOA有什么區別,可能很快有人站出來給你一大堆的技術變革,告訴你區別大了去了,但其實SOA的真正價值不是在于說和過去的技術有什么區別,而是它的一種開放,協同的思想,這種思想其實更具各個行業來說都是不同的。這次去普元的交流會上,很明顯的可以看出普元是定位在企業級應用的開放協同角度去考慮SOA的價值以及解決方案和實現手段。而我從大會回來,從新考慮了在阿里軟件SAAS平臺模式下我所關注的SOA的價值以及解決方案,就好比現在我一直在考慮的Service Mashup Platform,這是基于互聯網應用的一種角度的思考。同樣不同行業的人可能都會有不同的一種思考,但都是基于SOA的一種開放,協同的思想來更具具體的使用場景來考慮。所以如果你拋開業務場景去空想SOA,那么結果就會讓自己陷入技術陷阱,用技術的不同來生硬的解釋SOA,這種就好比過去講的笑話,盲人摸象。第二點是我自己在推廣我的ASF的一點經驗,在普元演示產品的時候看到了他們的studio作的很好,但是對于單元測試以及部分組件的集成測試卻做得還不是很夠,同時studio是否能夠讓程序員有便利感(我們很多在場的寫慣了程序的人都覺得程序員不寫幾行代碼,就會沒有創造感),這些可能會影響客戶(開發人員)。其實在我推廣ASF的時候有很多的架構師都反對,頂著壓力死推,最后救了我的是那些開發人員,一份匿名使用反饋加上性能測試,功能測試,最終還是堅持了下來,并被逐步接受。那么對我來說我能夠繼續做好的就是加強文檔的豐富性,測試的簡單性,部屬的方便性,以及開發配置的簡便性(由于很多是配置型的文件,因此采用schema來做提示和交驗我就覺得夠了,至于studio是否需要,如果能夠做得很完美當然最好了)。

          最后其實對于這次活動來說其實我覺得就是一次技術人員的SOA,不同的公司,不同的職業,不同的職位,協同,開放的在一起發表自己的意見來互相學習和交流,本來也就是一種SOA。這兒感謝一下普元,活動本身來說雖然沒有對SOA做出很明確的定義,但是其實讓每一個人能夠去思考,其實問題只有一個答案卻可以有千千萬萬,每個人的角度不同看到的就有不同的內涵。就好比InfoQ主編說的每一個海灘上的沙子都有自己一個唯一標識,我們每一個江湖人士都有自己一個堂口,一個觀點一個看法。

          開放的心態去學習和交流,我要走路還有很長一段。

          花絮:

                 白衣不小心摔了一跤,眼鏡掉到海里了,我們說是觀音大士讓他把眼鏡作為紀念留在了海南。

                 畢玄同學在上岸之前換鞋子的時候,由于不買一個小MM的貝殼,被小MM一直稱作大叔,因此我們笑說畢玄就是到了大叔的年紀了。

          歡迎訪問我的blog:http://blog.csdn.net/cenwenchu79/
          msn:cenwenchu_1979@hotmail.com

          posted @ 2008-03-03 03:36 岑文初 閱讀(1607) | 評論 (6)編輯 收藏

                 SOA的基礎技術實現方式中WebService占據了很重要的地位,通常我們提到WebService第一想法就是SOAP消息在各種傳輸協議上交互。近幾年REST的思想伴隨著SOA逐漸被大家接受,同時各大網站不斷開放API提供給開發者,也激起了REST風格WebService的熱潮。

                 在收到新需求Email之前,我對REST的理解僅僅是通過半懂不懂的看了FieldingREST博士論文,說實話當時也就是希望了解這么一個新概念,對于其內部的思想只是很膚淺的了解了一下。

                 ASF的最新需求就是可能需要實現REST風格的WebService集成,因此不得不好好的去看看REST的真正思想含義以及當前各大網站的設計方式。后面所要表述的也是我這個初學者的一些看法和觀點,拋磚引玉,希望在我將REST融入到ASF之前能夠獲得更多的反饋和意見。

          SOAP

                 什么是SOAP,我想不用多說,google一把滿眼都是。其實SOAP最早是針對RPC的一種解決方案,簡單對象訪問協議,很輕量,同時作為應用協議可以基于多種傳輸協議來傳遞消息(Http,SMTP等)。但是隨著SOAP作為WebService的廣泛應用,不斷地增加附加的內容,使得現在開發人員覺得SOAP很重,使用門檻很高。在SOAP后續的發展過程中,WS-*一系列協議的制定,增加了SOAP的成熟度,也給SOAP增加了負擔。

          REST

                 REST其實并不是什么協議也不是什么標準,而是將Http協議的設計初衷作了詮釋,在Http協議被廣泛利用的今天,越來越多的是將其作為傳輸協議,而非原先設計者所考慮的應用協議。SOAP類型的WebService就是最好的例子,SOAP消息完全就是將Http協議作為消息承載,以至于對于Http協議中的各種參數(例如編碼,錯誤碼等)都置之不顧。其實,最輕量級的應用協議就是Http協議。Http協議所抽象的get,post,put,delete就好比數據庫中最基本的增刪改查,而互聯網上的各種資源就好比數據庫中的記錄(可能這么比喻不是很好),對于各種資源的操作最后總是能抽象成為這四種基本操作,在定義了定位資源的規則以后,對于資源的操作通過標準的Http協議就可以實現,開發者也會受益于這種輕量級的協議。

                 自己理解的將REST的思想歸結以下有如下幾個關鍵點:

          1.面向資源的接口設計

          所有的接口設計都是針對資源來設計的,也就很類似于我們的面向對象和面向過程的設計區別,只不過現在將網絡上的操作實體都作為資源來看待,同時URI的設計也是體現了對于資源的定位設計。后面會提到有一些網站的API設計說是REST設計,其實是RPC-REST的混合體,并非是REST的思想。

                 2.抽象操作為基礎的CRUD

                 這點很簡單,Http中的get,put,post,delete分別對應了read,update,create,delete四種操作,如果僅僅是作為對于資源的操作,抽象成為這四種已經足夠了,但是對于現在的一些復雜的業務服務接口設計,可能這樣的抽象未必能夠滿足。其實這也在后面的幾個網站的API設計中暴露了這樣的問題,如果要完全按照REST的思想來設計,那么適用的環境將會有限制,而非放之四海皆準的。      

                 3Http是應用協議而非傳輸協議

                 這點在后面各大網站的API分析中有很明顯的體現,其實有些網站已經走到了SOAP的老路上,說是REST的理念設計,其實是作了一套私有的SOAP協議,因此稱之為REST風格的自定義SOAP協議。

          4.無狀態,自包含

          這點其實不僅僅是對于REST來說的,作為接口設計都需要能夠做到這點,也是作為可擴展和高效性的最基本的保證,就算是使用SOAPWebService也是一樣。

          REST vs SOAP

          成熟度:

          SOAP雖然發展到現在已經脫離了初衷,但是對于異構環境服務發布和調用,以及廠商的支持都已經達到了較為成熟的情況。不同平臺,開發語言之間通過SOAP來交互的web service都能夠較好的互通(在部分復雜和特殊的參數和返回對象解析上,協議沒有作很細致的規定,導致還是需要作部分修正)

          REST國外很多大網站都發布了自己的開發API,很多都提供了SOAPREST兩種Web Service,根據調查部分網站的REST風格的使用情況要高于SOAP。但是由于REST只是一種基于Http協議實現資源操作的思想,因此各個網站的REST實現都自有一套,在后面會講訴各個大網站的REST API的風格。也正是因為這種各自實現的情況,在性能和可用性上會大大高于SOAP發布的web service,但統一通用方面遠遠不及SOAP。由于這些大網站的SP往往專注于此網站的API開發,因此通用性要求不高。

          ASF上考慮發布REST風格的Web Service,可以參考幾大網站的設計(兄弟公司的方案就是參考了類似于flickr的設計模式),但是由于沒有類似于SOAP的權威性協議作為規范,REST實現的各種協議僅僅只能算是私有協議,當然需要遵循REST的思想,但是這樣細節方面有太多沒有約束的地方。REST日后的發展所走向規范也會直接影響到這部分的設計是否能夠有很好的生命力。

          總的來說SOAP在成熟度上優于REST

          效率和易用性:

                 SOAP協議對于消息體和消息頭都有定義,同時消息頭的可擴展性為各種互聯網的標準提供了擴展的基礎,WS-*系列就是較為成功的規范。但是也由于SOAP由于各種需求不斷擴充其本身協議的內容,導致在SOAP處理方面的性能有所下降。同時在易用性方面以及學習成本上也有所增加。

                 REST被人們的重視,其實很大一方面也是因為其高效以及簡潔易用的特性。這種高效一方面源于其面向資源接口設計以及操作抽象簡化了開發者的不良設計,同時也最大限度的利用了Http最初的應用協議設計理念。同時,在我看來REST還有一個很吸引開發者的就是能夠很好的融合當前Web2.0的很多前端技術來提高開發效率。例如很多大型網站開放的REST風格的API都會有多種返回形式,除了傳統的xml作為數據承載,還有(JSON,RSS,ATOM)等形式,這對很多網站前端開發人員來說就能夠很好的mashup各種資源信息。

                 因此在效率和易用性上來說,REST更勝一籌。

          安全性:

                 這點其實可以放入到成熟度中,不過在當前的互聯網應用和平臺開發設計過程中,安全已經被提到了很高的高度,特別是作為外部接口給第三方調用,安全性可能會高過業務邏輯本身。

                 SOAP在安全方面是通過使用XML-SecurityXML-Signature兩個規范組成了WS-Security來實現安全控制的,當前已經得到了各個廠商的支持,.net php java 都已經對其有了很好的支持(雖然在一些細節上還是有不兼容的問題,但是互通基本上是可以的)。

                 REST沒有任何規范對于安全方面作說明,同時現在開放REST風格API的網站主要分成兩種,一種是自定義了安全信息封裝在消息中(其實這和SOAP沒有什么區別),另外一種就是靠硬件SSL來保障,但是這只能夠保證點到點的安全,如果是需要多點傳輸的話SSL就無能為力了。安全這塊其實也是一個很大的問題,今年在BEA峰會上看到有演示采用SAML2實現的網站間SSO,其實是直接采用了XML-SecurityXML-Signature,效率看起來也不是很高。未來REST規范化和通用化過程中的安全是否也會采用這兩種規范,是未知的,但是加入的越多,REST失去它高效性的優勢越多。

          應用設計與改造:

                 我們的系統要么就是已經有了那些需要被發布出去的服務,要么就是剛剛設計好的服務,但是開發人員的傳統設計思想讓REST的形式被接受還需要一點時間。同時在資源型數據服務接口設計上來說按照REST的思想來設計相對來說要容易一些,而對于一些復雜的服務接口來說,可能強要去按照REST的風格來設計會有些牽強。這一點其實可以看看各大網站的接口就可以知道,很多網站還要傳入function的名稱作為參數,這就明顯已經違背了REST本身的設計思路。

                 SOAP本身就是面向RPC來設計的,開發人員十分容易接受,所以不存在什么適應的過程。

          總的來說,其實還是一個老觀念,適合的才是最好的

                 技術沒有好壞,只有是不是合適,一種好的技術和思想被誤用了,那么就會得到反效果。RESTSOAP各自都有自己的優點,同時如果在一些場景下如果去改造REST,其實就會走向SOAP(例如安全)。

                 REST對于資源型服務接口來說很合適,同時特別適合對于效率要求很高,但是對于安全要求不高的場景。而SOAP的成熟性可以給需要提供給多開發語言的,對于安全性要求較高的接口設計帶來便利。所以我覺得純粹說什么設計模式將會占據主導地位沒有什么意義,關鍵還是看應用場景。

                 同時很重要一點就是不要扭曲了REST現在很多網站都跟風去開發REST風格的接口,其實都是在學其形,不知其心,最后弄得不倫不類,性能上不去,安全又保證不了,徒有一個看似象摸象樣的皮囊。

          REST設計的幾種形式

          參看了幾個大型網站的REST風格的API設計,這里做一下大致的說明:

          FaceBook:

          請求消息:

                 URI設計上采取了類似于REST的風格。例如對于friends的獲取,就定義為friends.get,前面部分作為資源定義,后面是具體的操作,其他的API也是類似,資源+操作,因此就算使用httpget方法都可能作了update的操作,其實已經違背了REST的思想,但是說到,其實那么復雜的業務接口設計下,要通過RUCD來抽象所有的接口基本是不實際的。在URI定義好以后,還有詳細的參數定義,包括類型以及是否必選。

          響應消息:

                 有多種方式,XML,JSONXMLXSD作為參考。有點類似于沒有HeadSOAP,只不過這里將原來可以定義在WSDL中的XSD抽取出來了。

          Flickr:

                 請求消息:

                 http://api.flickr.com/services/rest/?method=flickr.test.echo&name=value

                 這里就可以很明顯看出它所定制的REST請求其實和RPC沒有什么太大的區別。

                 消息返回:

          正確處理返回

          <?xml version="1.0" encoding="utf-8" ?>

          <rsp stat="ok">

                   [xml-payload-here]

          </rsp>

          錯誤處理返回

          <?xml version="1.0" encoding="utf-8" ?>

          <rsp stat="fail">

                   <err code="[error-code]" msg="[error-message]" />

          </rsp>

                 根據返回可以看出已經違背了REST的思想,還是把Http協議作為傳輸承載協議,并沒有真正意義上使用Http協議作為資源訪問和操作協議。

                 總的來說,只是形式上去模仿REST,自己搞了一套私有協議。

          Ebay

                 請求消息:

                 采用xml作為承載,類似于SOAP,不過去除SOAP消息的封裝和包頭,同時在請求中附加了認證和警告級別等附加信息。

                 消息返回:

                 類似于SOAP消息,不過刪除了SOAP的封裝和包頭,同時在返回結構中增加了消息處理結果以及版本等附加信息。

                 這個很類似于當前Axis2框架的做法,將SOAP精簡,同時根據自身需求豐富了安全,事務等協議內容。

          Yahoo Maps

                 請求消息:

                 http://local.yahooapis.com/MapsService/V1/geocode?appid=YahooDemo&street=701+First+Ave&city=Sunnyvale&state=CA

                 采用REST推薦的方式,URI+Parameters

                 返回消息:

          <?xml version="1.0" encoding="UTF-8"?>

          <ResultSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

          xmlns="urn:yahoo:maps"

          xsi:schemaLocation="urn:yahoo:maps http://local.yahooapis.com/MapsService/V1/GeocodeResponse.xsd">

           <Result precision="address">

              <Latitude>37.416384</Latitude>

              <Longitude>-122.024853</Longitude>

              <Address>701 FIRST AVE</Address>

              <City>SUNNYVALE</City>

              <State>CA</State>

              <Zip>94089-1019</Zip>

              <Country>US</Country>

           </Result>

          </ResultSet>

          SOAP的精簡xml返回,其他信息,例如出錯碼等信息由Http協議頭來承載。

          YouTube

          請求消息:

          http://www.youtube.com/api2_rest?method=youtube.users.get_profile&dev_id=YOUR_DEV_ID&user=YOUTUBE_USER_NAME

          可以看到對于資源操作的URI定義也是參數的一部分。

          返回消息:

          <?xml version="1.0" encoding="utf-8"?>

          <ut_response status="ok">

              <user_profile>

                  <first_name>YouTube</first_name>

                  <last_name>User</last_name>

                  <about_me>YouTube rocks!!</about_me>

                  <age>30</age>

                  <video_upload_count>7</video_upload_count>

              </user_profile>

          </ut_response>

                 自定義的類SOAP消息。

          Amazon

                 請求消息:

                 https://Amazon FPS web service end point/?AWSAccessKeyId=Your AWSAccessKeyId

                &Timestamp=[Current timestamp] &Signature=[Signature calculated from hash of Action and Timestamp]

                &SignatureVersion=[Signature calculated from hash of Action and Timestamp]

                &Version=[Version of the WSDL specified in YYYY-MM-DD format] &Action=[Name of the API]

                &parameter1=[Value of the API parameter1] &parameter2=[Value of the API parameter2]

                &...[API parameters and their values]

                 返回消息:

                 類似于SOAP的自有協議,消息體中包含了消息狀態等附加信息。

          總結:

                 看了上面那么多網站的設計,總結一下主要有這么幾種設計方式。

          請求消息設計:

          1. 基本符合REST標準方式:資源URI定義(資源操作)+參數。這類設計如果濫用get去處理其他類型的操作,那么和2無異。

          2. REST風格非REST思想:資源URI定義+參數(包含操作方法名)。其實就是RPCREST跟風。

          3. 類似于SOAP消息,自定義協議,以xml作為承載。(可擴展,例如鑒權,訪問控制等),不過那就好比自己定義了一套SOAPSOAP extends。大型的有實力的網站有的采取此種做法。

          響應消息設計:

          1.       REST標準方式,將Resource State傳輸返回給客戶端,Http消息作為應用協議而非傳輸協議

          2.       XML作為消息承載體,Http作為消息傳輸協議,處理狀態自包含。

          3.       自定義消息格式,類似于SOAP,提供可擴展部分。

          作為遵循REST的理念來看我的選擇是響應1和請求1的設計。

          RESTASF的集成

          ASF要集成REST就現在來看有兩種比較合適的方法。

          一.就是采用Axis2REST實現,這種方式的好處就是開發周期短,容易集成,但是請求和響應的格式無法改變,資源URI設計受限,Axis2REST其實就是將SOAP消息精簡,請求的時候刪除了SOAP的頭,響應的時候僅僅返回資源信息,如果提供xsd就可以被各種客戶端所解析。并非真正的REST

          二.就是采用Restlet開源框架,將Restlet開源框架集成到ASF中,由于Restlet本身就是可內嵌的應用框架,因此集成不成問題,同時Restlet框架只是API結構框架,因此實現和定義完全分開,集成Restlet以后可以自己實現其中的解析引擎也可以采用默認提供的引擎,同時對于內嵌Jetty等多種開源項目的支持,將更多優勢融入到了Rest中。看了一下國內也有很多朋友已經關注Restlet開源項目,看了它的架構設計,個人覺得還是比較靈活和緊湊的。

          題外話

                 在寫這篇文章以前寫了一篇調研報告群發給各個架構師們參考,期待反饋。下午正好和我們的首席架構師聊了一會兒。其實我和他的感覺是一樣的,REST是否真的在我們現有的服務框架中需要集成,理解了REST的思想再去看應用場景,那么可以發現如果要完全遵循REST的設計理念來設計接口的話,那么強要去改變現有已經存在的或者還未開發的接口就會落入為了技術而技術,為了潮流而跟風的近地。當然并不否認REST的好,其實我們兄弟公司的一些業務場景有部分的接口十分合適這類設計,面向資源,高效,簡潔,易用都能夠體現出它的價值。我們將會和我們的兄弟公司合作,也會參考他們的設計理念,在參考當前各個網站的實現情況下,部分的采用這類形式的發布,提供給第三方的ISV,無疑是我現在把REST融入到ASF中最好的理由。

                 有了需求去做才不會陷入為了技術而技術,畢竟技術是由商業價值驅動的,同樣社會上充斥著各種技術的鼓吹,如果稍不留神就會陷入跟風的潮流中。

          歡迎訪問我csdn的blog:http://blog.csdn.net/cenwenchu79/,也歡迎和我做交流,msn:cenwenchu_1979@hotmail.com,關于SOA,REST,SAAS。

          posted @ 2008-02-22 08:45 岑文初 閱讀(4288) | 評論 (1)編輯 收藏

           

          JVM優化配置

                 這里首先要說明的是這里提到的JVMSunHotSpot JVM 5和以上的版本。性能優化在應用方面可以有很多手段,包括Cache,多線程,各種算法等等。通常情況下是不建議在沒有任何統計和分析的情況下去手動配置JVM的參數來調整性能,因為在JVM 5以上已經作了根據機器和OS的情況自動配置合適參數的算法,基本能夠滿足大部分的情況,當然這種自動適配只是一種通用的方式,如果說真的要達到最優,那么還是需要根據實際的使用情況來手動的配置各種參數設置,提高性能。

                 JVM能夠對性能產生影響的最大部分就是對于內存的管理。從jdk 1.5以后內存管理和分配有了很多的改善和提高。

          內存分配以及管理的幾個基本概念和參數說明:

          Java Hotspot Mode

          server client兩種模式,如果不配置,JVM會根據應用服務器硬件配置自動選擇模式,server模式啟動比較慢,但是運行期速度得到了優化,client啟動比較快,但是運行期響應沒有server模式的優化,適合于個人PC的服務開發和測試。

          Garbage Collector Policy

                 Jdk 1.5的時候已經提供了三種GC,除了原來提供的串行GCSerialGC)以外,還提供了兩種新的GCParallelGCConcMarkSweepGCParallelGC采用了多線程并行管理和回收垃圾對象,提高了回收效率,提高了服務器的吞吐量,適合于多處理器的服務器。ConcMarkSweepGC采用的是并發方式來管理和回收垃圾對象,降低垃圾回收產生的響應暫停時間。這里說一下并發和并行的區別,并發指的是多個進程并行執行垃圾回收,那么可以很好的利用多處理器,而并行指的是應用程序不需要暫停可以和垃圾回收線程并發工作。串行GC適合小型應用和單處理器系統(無需多線程交互,效率比較高),后兩者適合大型系統。

                 使用方式就是在參數配置中增加-XX:+UseParallelGC等方式來設置。

                 對于這部分的配置在網上有很多的實例可以參考,不過最終采用哪一種GC還是要根據具體的情況來分析和選擇。

          Heap

                 OOM的各種經歷已經讓每一個架構師開發人員看到了了解Heap的重要性。OOM已經是Heap的臨界點,不得不引起注意,然而Heap對于性能的潛在影響并未被引起重視,不過和GC配置一樣,在沒有對使用情況作仔細分析和研究的情況下,貿然的去修改Heap配置,可能適得其反,這里就來看一下Heap的一些概念和對于性能的影響。

                 我們的應用所能夠得到的最大的Heap受三部分因素的制約:數據處理模型(32位或者64位操作系統),系統地虛擬內存總數和系統的物理內存總數。首先Heap的大小不能超過不同操作系統的進程尋址范圍,當前大部分系統最高限度是4GWindows通常是2GLinux通常是3G。系統的虛擬內存也是分配的依據,首先是不能超過,然后由于操作系統支持硬盤來做部分的虛擬內存,如果設置過大,那么對于應用響應來說勢必有影響。再則就是要考慮同一臺服務器上運行多個Java虛擬機所消耗的資源總合也不能超過可用資源。就和前面OOM分析中的一樣,其實由于OS的數據處理模型的限制,機器本身的硬件內存資源和虛擬內存資源并不一定會匹配,那么在有限的資源下如何調整好資源分配,對于應用來說尤為重要。

          關于Heap的幾個參數設置:

                 說了Heap的有限資源問題以后,就來看看如何通過配置去改變JVM對于Heap的分配。下面所說的主要是對于Java Heap的分配,那么在申請了Java Heap以后,剩下的可用資源就會被使用到Native Heap

                 Xms: java heap初始化時的大小。默認情況是機器物理內存的1/64。這個主要是根據應用啟動時消耗的資源決定,分配少了申請起來會降低啟動速度,分配多了也浪費。

                 Xmx:java heap的最大值,默認是機器物理內存的1/4,最大也就到1G。這個值決定了最多可用的Java Heap Memory,分配過少就會在應用需要大量內存作緩存或者零時對象時出現OOM的問題,如果分配過大,那么就會產生上文提到的第二類OOM。所以如何配置還是根據運行過程中的分析和計算來確定,如果不能確定還是采用默認的配置。

                 Xmn:java heap新生代的空間大小。在GC模型中,根據對象的生命周期的長短,產生了內存分代的設計:青年代(內部也分成三部分,類似于整體劃分的作用,可以通過配置來設置比例),老年代,持久代。每一代的管理和回收策略都不相同,最為活躍的就是青年代,同時這部分的內存分配和管理效率也是最高。通常情況下,對于內存的申請優先在新生代中申請,當內存不夠時會整理新生代,當整理以后還是不能滿足申請的內存,就會向老年代移動一些生命周期較長的對象。這種整理和移動會消耗資源,同時降低系統運行響應能力,因此如果青年代設置的過小,就會頻繁的整理和移動,對性能造成影響。那是否把年青代設置的越大越好,其實不然,年青代采用的是復制搜集算法,這種算法必須停止所有應用程序線程,服務器線程切換時間就會成為應用響應的瓶頸(當然永遠不用收集那么就不存在這個問題)。老年代采用的是串行標記收集的方式,并發收集可以減少對于應用的影響。

                 Xss:線程堆棧最大值。允許更多的虛擬內存空間地址被Java Heap使用。

          以下是sun公司的性能優化白皮書中提到的幾個例子:

          1.對于吞吐量的調優。機器配置:4G的內存,32個線程并發能力。

          java -Xmx3800m -Xms3800m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20

                 -Xmx3800m -Xms3800m 配置了最大Java Heap來充分利用系統內存。

                 -Xmn2g 創建足夠大的青年代(可以并行被回收)充分利用系統內存,防止將短期對象復制到老年代。

              -Xss128 減少默認最大的線程棧大小,提供更多的處理虛擬內存地址空間被進程使用。

              -XX:+UseParallelGC 采用并行垃圾收集器對年青代的內存進行收集,提高效率。

              -XX:ParallelGCThreads=20 減少垃圾收集線程,默認是和服務器可支持的線程最大并發數相同,往往不需要配置到最大值。

           

          2.嘗試采用對老年代并行收集

          java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseParallelOldGC

          -Xmx3550m -Xms3550m 內存分配被減小,因為ParallelOldGC會增加對于Native Heap的需求,因此需要減小Java Heap來滿足需求。

          -XX:+UseParallelOldGC 采用對于老年代并發收集的策略,可以提高收集效率。

           

          3.提高吞吐量,減少應用停頓時間

          java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:ParallelGCThreads=20 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:SurvivorRatio=8 -XX:TargetSurvivorRatio=90 -XX:MaxTenuringThreshold=31

           

          -XX:+UseConcMarkSweepGC -XX:+UseParNewGC 選擇了并發標記交換收集器,它可以并發執行收集操作,降低應用停止時間,同時它也是并行處理模式,可以有效地利用多處理器的系統的多進程處理。

          -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=31 表示在青年代中Eden和Survivor比例,設置增加了Survivor的大小,越大的survivor空間可以允許短期對象盡量在年青代消亡。

           

          -XX:TargetSurvivorRatio=90 允許90%的空間被占用,超過默認的50%,提高對于survivor的使用率。

           

          類似的例子網上很多,這兒就不在列下來了,最終是否采取自己配置來替換默認配置還是要根據虛擬機的使用情況來分析和配置。

          posted @ 2008-01-23 16:16 岑文初 閱讀(2971) | 評論 (2)編輯 收藏

                 OOM這個縮寫就是Java程序開發過程中讓人最頭痛的問題:Out of Memory。在很多開發人員的開發過程中,或多或少的都會遇到這類問題,這類問題定位比較困難,往往需要根據經驗來判斷可能出現問題的代碼。原因主要是兩個:對象沒有被釋放(多種情況引起,往往是比較隱蔽的引用導致被Hold而無法被回收)。另一種就是真的Memory不夠用了,需要增加JVMHeap來滿足應用程序的需求。最近有同事發的關于解決OOM的問題,讓我了解了原來OOM除了在JVM Heap不夠時會發生,在Native Heap不夠的時候也會發生,同時JVM HeapNative Heap存在著相互影響和平衡的關系,因此就仔細的去看了關于OOMJVM配置優化的內容。

          OOM

                 在其他語言類似于C,Delphi等等由于內存都是由自己分配和管理,因此內存泄露的問題比較常見,同時也是很頭痛的一件事情。而Java的對象生命周期管理都是JVM來做的,簡化了開發人員的非業務邏輯的處理,但是這種自動管理回收機制也是基于一些規則的,而違背了這些規則的時候,就會造成所謂的“Memory Leak”。

          OOM(Java Heap)

                 錯誤提示:java.lang.OutOfMemoryError

          這類OOM是由于JVM分配的給應用的Heap Memory已經被耗盡,可能是因為應用在高負荷的情況下的卻需要很大的內存,因此可以通過修改JVM參數來增加Java Heap Memory(不過也不能無限制增加,后面那種OOM有可能就是因為這個原因而產生)。另一種情況是因為應用程序使用對象或者資源沒有釋放,導致內存消耗持續增加,最后出現OOM,這類問題引起的原因往往是應用已不需要的對象還被其他有效對象所引用,那么就無法釋放,可能是業務代碼邏輯造成的(異常處理不夠例如IO等資源),也可能是對于第三方開源項目中資源釋放了解不夠導致使用以后資源沒有釋放(例如JDBCResultSet等)。

                 幾個容易出現問題的場景:

                 1.應用的緩存或者Collection:如果應用要緩存Java對象或者是在一個Collection中保存對象,那么就要確定是否會有大量的對象存入,要做保護,以防止在大數據量下大量內存被消耗,同時要保證Cache的大小不會無限制增加。

                 2.生命周期較長的對象:盡量簡短對象的生命周期,現在采用對象的創建釋放代價已經很低,同時作了很好的優化,要比創建一個對象長期反復使用要好。如果能夠設置超時的情景下,盡量設置超時。

                 3.類似于JDBCConnection Pool,在使用Pool中的對象以后需要釋放并返回,不然就會造成Pool的不斷增大,在其他Pool中使用也是一樣。同樣ResultSetIO這類資源的釋放都需要注意。

                 解決的方法就是查找錯誤或者是增加Java Heap Memory。對于此類問題檢測工具相當多,這里就不做介紹了。      

          OOM(Native Heap)

          錯誤提示:requested XXXX bytes for ChunkPool::allocate. Out of swap space

                 Native Heap MemoryJVM內部使用的Memory,這部分的Memory可以通過JDK提供的JNI的方式去訪問,這部分Memory效率很高,但是管理需要自己去做,如果沒有把握最好不要使用,以防出現內存泄露問題。JVM 使用Native Heap Memory用來優化代碼載入(JTI代碼生成),臨時對象空間申請,以及JVM內部的一些操作。這次同事在壓力測試中遇到的問題就是這類OOM,也就是這類Memory耗盡。同樣這類OOM產生的問題也是分成正常使用耗盡和無釋放資源耗盡兩類。無釋放資源耗盡很多時候不是程序員自身的原因,可能是引用的第三方包的缺陷,例如很多人遇到的Oracle 9 JDBC驅動在低版本中有內存泄露的問題。要確定這類問題,就需要去觀察Native Heap Memory的增長和使用情況,在服務器應用起來以后,運行一段時間后JVM對于Native Heap Memory的使用會達到一個穩定的階段,此時可以看看什么操作對于Native Heap Memory操作頻繁,而且使得Native Heap Memory增長,對于Native Heap Memory的情況我還沒有找到辦法去檢測,現在能夠看到的就是為JVM啟動時候增加-verbose:jni參數來觀察對于Native Heap Memory的操作。另一種情況就是正常消耗Native Heap Memory,對于Native Heap Memory的使用主要取決于JVM代碼生成,線程創建,用于優化的臨時代碼和對象產生。當正常耗盡Native Heap Memory時,那么就需要增加Native Heap Memory,此時就會和我們前面提到增加java Heap Memory的情況出現矛盾。

          應用內存組合

                 對于應用來說,可分配的內存受到OS的限制,不同的OS對進程所能訪問虛擬內存地址區間直接影響對于應用內存的分配,32位的操作系統通常最大支持4G的內存尋址,而Linux一般為3GWindows2G。然而這些大小的內存并不會全部給JVMJava Heap使用,它主要會分成三部分:Java HeapNative Heap,載入資源和類庫等所占用的內存。那么由此可見,Native Heap Java Heap大小配置是相互制約的,哪一部分分配多了都可能會影響到另外一部分的正常工作,因此如果通過命令行去配置,那么需要確切的了解應用使用情況,否則采用默認配置自動監測會更好的優化應用使用情況。

                 同樣要注意的就是進程的虛擬內存和機器的實際內存還是有區別的,對于機器來說實際內存以及硬盤提供的虛擬內存都是提供給機器上所有進程使用的,因此在設置JVM參數時,它的虛擬內存絕對不應該超過實際內存的大小。

          待續……


          JVM
          優化配置


          更多內容可訪問:http://blog.csdn.net/cenwenchu79/
          posted @ 2008-01-22 16:54 岑文初 閱讀(2829) | 評論 (2)編輯 收藏

          Author: wenchu.cenwc

          Email: wenchu.cenwc@alibaba-inc.com

          Memcached 介紹與分析

                 Memcached是一種集中式Cache,支持分布式橫向擴展。總結幾個它的特點來理解一下它的優點和限制。

                 Memory:內存存儲,不言而喻,速度快,對于內存的要求高,不指出的話所緩存的內容非持久化。對于CPU要求很低,所以常常采用將Memcached服務端和一些CPU高消耗Memory低消耗應用部屬在一起。(作為我們AEP正好有這樣的環境,我們的接口服務器有多臺,接口服務器對于CPU要求很高(由于WS-Security),但是對于Memory要求很低,因此可以用作Memcached的服務端部屬機器)

                 集中式Cache:避開了分布式Cache的傳播問題,但是需要非單點保證其可靠性,這個就是后面集成中所作的cluster的工作,可以將多個Memcached作為一個虛擬的cluster,同時對于cluster的讀寫和普通的memcached的讀寫性能沒有差別。

                 分布式擴展:Memcached的很突出一個優點,就是采用了可分布式擴展的模式。可以將部屬在一臺機器上的多個Memcached服務端或者部署在多個機器上的Memcached服務端組成一個虛擬的服務端,對于調用者來說完全屏蔽和透明。提高的單機器的內存利用率,也提供了scale out的方式。

                 Socket通信:傳輸內容的大小以及序列化的問題需要注意,雖然Memcached通常會被放置到內網作為CacheSocket傳輸速率應該比較高(當前支持Tcpudp兩種模式,同時根據客戶端的不同可以選擇使用nio的同步或者異步調用方式),但是序列化成本和帶寬成本還是需要注意。這里也提一下序列化,對于對象序列化的性能往往讓大家頭痛,但是如果對于同一類的Class對象序列化傳輸,第一次序列化時間比較長,后續就會優化,其實也就是說序列化最大的消耗不是對象序列化,而是類的序列化。如果穿過去的只是字符串,那么是最好的,省去了序列化的操作,因此在Memcached中保存的往往是較小的內容。

                 特殊的內存分配機制:首先要說明的是Memcached支持最大的存儲對象為1M。它的內存分配比較特殊,但是這樣的分配方式其實也是對于性能考慮的,簡單的分配機制可以更容易回收再分配,節省對于CPU的使用。這里用一個酒窖比喻來說明這種內存分配機制,首先在Memcached起來的時候可以通過參數設置使用的總共的Memory,這個就是建造一個酒窖,然后在有酒進入的時候,首先申請(通常是1M)的空間,用來建酒架,酒架根據這個酒瓶的大小分割酒架為多個小格子安放酒瓶,將同樣大小范圍內的酒瓶都放置在一類酒架上面。例如20cm半徑的酒瓶放置在可以容納20-25cm的酒架A上,30cm半徑的酒瓶就放置在容納25-30cm的酒架B上。回收機制也很簡單,首先新酒入庫,看看酒架是否有可以回收的地方,如果有直接使用,如果沒有申請新的地方,如果申請不到,采用配置的過期策略。這個特點來看,如果要放的內容大小十分離散,同時大小比例相差梯度很明顯,那么可能對于使用空間來說不好,可能在酒架A上就放了一瓶酒,但占用掉了一個酒架的位置。

                 Cache機制簡單:有時候很多開源的項目做的面面俱到,但是最后也就是因為過于注重一些非必要性的功能而拖累了性能,這里要提到的就是Memcached的簡單性。首先它沒有什么同步,消息分發,兩階段提交等等,它就是一個很簡單的Cache,把東西放進去,然后可以取出來,如果發現所提供的Key沒有命中,那么就很直白的告訴你,你這個key沒有任何對應的東西在緩存里,去數據庫或者其他地方取,當你在外部數據源取到的時候,可以直接將內容置入到Cache中,這樣下次就可以命中了。這里會提到怎么去同步這些數據,兩種方式,一種就是在你修改了以后立刻更新Cache內容,這樣就會即時生效。另一種是說容許有失效時間,到了失效時間,自然就會將內容刪除,此時再去去的時候就會命中不了,然后再次將內容置入Cache,用來更新內容。后者用在一些時時性要求不高,寫入不頻繁的情況。

                 客戶端的重要性:Memcached是用C寫的一個服務端,客戶端沒有規定,反正是Socket傳輸,只要語言支持Socket通信,通過Command的簡單協議就可以通信,但是客戶端設計的合理十分重要,同時也給使用者提供了很大的空間去擴展和設計客戶端來滿足各種場景的需要,包括容錯,權重,效率,特殊的功能性需求,嵌入框架等等。

                 幾個應用點:小對象的緩存(用戶的token,權限信息,資源信息)。小的靜態資源緩存。Sql結果的緩存(這部分用的好,性能提高相當大,同時由于Memcached自身提供scale out,那么對于db scale out的老大難問題無疑是一劑好藥)。ESB消息緩存。

          集成設計

                 為什么需要集成?直接使用現有的兩個Java實現Memcached是否就可以了?

                 當前集成主要為了兩方面考慮,首先是方便的配置使用,如何將Memcached內嵌到類似于ASF以及其他框架中去,并且通過配置文件方便使用,這就需要作部分的集成工作,這部分工作主要是定義了配置文件以及通過Stax去解析配置的功能。然后是如何管理Memcached,這部分內容包括了初始化,運行期檢測,資源回收的工作。最后是擴展,這里的擴展分成兩部分(功能的擴展以及框架實現的擴展),功能擴展例如當前擴展了虛擬的cluster,可以讓多個memcached Client組成一個虛擬的cluster,如果通過放入cluster的方式放入到其中一個Cache Client中的話,那么就可以在整個cluster都作好備份,這樣其實可以根據memcached的單機多實例以及多機多實例作交互備份,提高可靠性。當然后續還有很多可以擴展的內容,這里只是一個開頭。框架實現的擴展指的是這里采用了類似于JdkJAXP的框架設計,只是規定了框架API結構,至于實現者動態載入,這個和ASF等現在可擴展的框架一樣,提供了很方便的擴展點,后續的設計中會提到。

          接口設計類圖:

          1 Cache接口包類圖

                 ICacheIMemcachedCache實現的是最基本的Cache的功能,只是IMemcachedCache有所增強,提供了對于虛擬的Cluster的操作,批量操作,統計的功能。ICacheManagerIMemcachedCacheManager分別是對于上面兩個Cache的管理類,根據配置文件解析,初始化客戶端池,建立虛擬集群,銷毀客戶端池等工作。

          2 Memcached 實現包

                 省略了一些輔助類定義。這部分是具體的實現,同時可以在圖上看到spi包內的CacheManagerFactory就是用來提供擴展使用的接口。只需要定義在jarMETA-INF下面建立services目錄,建立兩個名為:com.alisoft.xplatform.asf.cache.IMemcachedCacheManagercom.alisoft.xplatform.asf.cache.spi.CacheManagerFactory的文件就可以替換MemcachedCacheManagerCacheManagerFactory的實現類,從而改變Memcached Client實現機制。如果沒有這兩個文件在Classpath目錄下面,那么默認將會使用當前框架中的兩個實現。

          3 Memcached的結構圖

                 Memcached Server就是部署在不同服務器或者在同一臺服務器上的Memcached實例,一般采用后臺守護進程方式運行。SocketPool是客戶端連接到服務端的Socket通信層,Memcached Client可以歸屬為虛擬的ClusterMemcachedCacheManager作用是管理ClusterCache。從這個結構圖可以看出客戶端的每一層都是很獨立,這樣有利于層次的交互,以及組合擴展。

          測試與使用

          1. 配置:

          需要有一個名為memcached.xml的文件在classpath中,可以在jar里面也可以在任意classpath可以找的到的地方,需要注意的是,CacheManager實現了對于多個memcached.xml merge的功能。

          具體的配置內容如下:

          <?xml version="1.0" encoding="UTF-8"?>

          <memcached>//總標簽

            //memcached Client的配置,也就是一個IMemcachedCache的配置。Name必須填,表示Cache的名稱,socketpool必須填,表示使用的遠程通信連接池是哪一個,參看后面對于socketpool的定義。后面都是可選的,第三個參數表示傳輸的時候是否壓縮,第四個參數表示默認的編碼方式

          <client name="mclient1" socketpool="pool1" compressEnable="true" defaultEncoding="UTF-8" >

                  <!--errorHandler></errorHandler-->//可定義錯誤處理類,一般不需要定義

              </client>

              <client name="mclient2" socketpool="pool2" compressEnable="true" defaultEncoding="UTF-8" >

              </client>  

               //socketpool是通信連接池定義,每一個memcached Client要和服務端交互都必須有通信連接池作為底層數據通信的支持,name必填,表示名字,同時也是memcached client指定socketpool的依據,failover表示對于服務器出現問題時的自動修復。initConn初始的時候連接數,minConn表示最小閑置連接數,maxConn最大連接數,maintSleep表示是否需要延時結束(最好設置為0,如果設置延時的話那么就不能夠立刻回收所有的資源,如果此時從新啟動同樣的資源分配,就會出現問題),nagleTCP對于socket創建的算法,socketTOsocket連接超時時間,aliveCheck表示心跳檢查,確定服務器的狀態。Serversmemcached服務端開的地址和ip列表字符串,weights是上面服務器的權重,必須數量一致,否則權重無效

              <socketpool name="pool1" failover="true" initConn="10" minConn="5" maxConn="250" maintSleep="0"

                  nagle="false" socketTO="3000" aliveCheck="true">

                  <servers>10.0.68.210:12000,10.0.68.210:12222</servers>

                  <weights>5,5</weights>

              </socketpool>  

              <socketpool name="pool2" failover="true" initConn="10" minConn="5" maxConn="250" maintSleep="0"

                  nagle="false" socketTO="3000" aliveCheck="true">

                  <servers>10.0.68.210:22000,10.0.68.210:22222</servers>

                  <weights>5,5</weights>

              </socketpool>

              //虛擬集群設置,這里將幾個clientcache設置為一個虛擬集群,當對這些IMemcachedCache作集群操作的時候,就會自動地對集群中所有的Cache作插入,尋找以及刪除的操作,做一個虛擬交互備份

              <cluster name="cluster1">

                  <memCachedClients>mclient1,mclient2</memCachedClients>

              </cluster>            

          </memcached>

          2. 測試代碼,這里就附帶一個單元測試類的代碼就可以很清楚的知道使用方法。


          后話

          沒有不好的,只有不適合的,適合的場景使用,根據場景適合的使用,才是提高性能的最有效手段。后需要根據所需的應用場景繼續對這部分集成內容作完善,實踐完善設計。

           
          posted @ 2008-01-02 22:58 岑文初 閱讀(2076) | 評論 (1)編輯 收藏

               周四下午聽了一節課就提早回來了,周五身體不好也就沒有去公司,也沒有寫關于第二天的一些所見所聞,其實第一天的啟發也并非完全是參加了大會的感觸,只是正好和自己目標有些碰撞,感覺還有一些可寫的。第二日,早晨的內容其實昨天已經也略有所聞,但是可能更為詳細一些,下午的內容就基本沒怎么聽了,因為唯一一個感覺還算是比較務實的課堂連載給我的感覺就是“空”,也可能是因為時間都只有一個小時,所以基本那些演講人翻翻ppt就來不及了,也沒什么可以細致的解答的,而提問的同學聽來聽去就是問一個問題:“實施SOA怎么做?”老師能給的一個答案就是“不同的情況又不同的處理辦法吧”。既然寫了,那么還是流水的記錄一下這一天的所見所聞。

                 早晨還是主題演講,和昨天一樣,也是技術+實踐。一共分成了五部分:1.提高企業生產效率:企業社會計算與業務流程管理。2.中國生活網項目介紹。3.極速虛擬化。4.東軟的演講。5.BEA咨詢副總裁的實施創新。這五部分內容,第一部分還是有一些其啟發的內容,因此最后介紹一下。

          中國生活網,東軟的演講就像給我blog留言的一個同樣去了BEA2007的朋友說的一樣,商業推廣大于技術創新推廣。

          極速虛擬化主要介紹的是BEAVMWare公司合作的一種應用服務部署模式,將原來的服務器+OS+VM+WEBContainer+App改變成為服務器+LiquidVM+WLS-VE+App,省略了原來的OS,同時通過虛擬層的優化,將硬件服務器由單機獨立部署,轉變成為硬件資源池,軟件負載均衡動態部署應用,提高服務器的利用率,將軟件抽象出來與底層硬件分離。由于這部分內容和底層硬件優化比較緊密,和上層軟件架構不是很相關,因此對我來說能夠實踐的機會比較少。

          BEA咨詢副總裁講的實施創新,一開始就以當前最為火熱的幾個web2.0的網站作為切入點,講述了一下這些網站成功就是在與創新,后面就是推廣性的介紹了一下當前互聯網應用的情況,并沒有提到如何去創新。赫赫,不過如果說出來了,就不叫作創新了,創新還是要根據每個人的商業嗅覺,當有了技術的支持以后,如何變技術為社會價值,并將其社會價值最大化,那就依賴于個人創新能力體現了。

          最后談談上午第一個主題演講:提高企業生產效率:企業社會計算與業務流程管理。這個主題其實針對的客戶群應該不是類似于我這樣的應用平臺開發架構師,而是國有大中型企業的IT技術經理。這部分內容其實應該是涉及到了SOA的應用,將SOA+Web2.0結合應用到了企業級信息管理中。不過同一本佛經,不同的和尚悟出的道理也是不同的,給出下面幾個重點詞,做一下解釋和自己的一些分享(這里只是從自己的角度去看待主題中的一些關鍵內容)。

          Key point:資產管理的演變

          Detail企業的資產管理由Capital的管理àInformation管理àInteraction管理。其實第一步就是我們過去說的最原始的ERP風潮的進化,而第二步其實是在當前Web2.0的啟發下,企業內部管理的再次變革,當然這次變革是跟隨當前互聯網Web2.0的技術變革而產生的。一個領域的變革,能夠啟發另一個領域的變革。當企業內部由有形資產比例占據絕對優勢逐漸轉變成為人力資源等無形資產占據絕對優勢以后,企業管理的手段以及方式都將作很大的改變,而一個企業和一個互聯網應用一樣,如果想要不斷發展,那么就不能僅僅依靠兩三個管理者的智慧,而是要依靠企業員工所構筑的企業內社會網絡來不斷提供新鮮血液。這點也就是Web2.0的重要特性之一,社區概念和群眾參與。將每一個個體的生產率轉變成為企業生產率。而完成這一點當前能夠采取的有效手段,就是通過SOA+BPM在企業中的實施來達成。構建信息共享網絡(現在可比以前豐富多了,blog,rss,wiki等等,在回來的時候我們幾個還談論了可以構建企業內部的交友社區,解決大齡男女的終身大事問題)。管理的交互策略:將流程,人員,信息提供給每一個企業員工,員工可以參與流程的制定,以及及時反饋企業流程問題。

          My option企業是否需要SOA來完善自身信息化,還是根據各自的情況和財力而定。對我的架構設計來說,其實可以同樣推出這么一個觀念,架構設計需要能夠融入創新,可以靈活擴展,提倡每個開發工程師和架構設計師貢獻ideasolution,這也是SCA的一個亮點和根基所在。

          Key point:企業社會計算+BPM+SOA = 提升生產效率

          Detail首先說一下三部分的各自功能。企業社會計算的功能:1.參與者驅動的協作工具。2.社會搜索與專業知識的發現。3.組裝與Mashup(后面會談以下關于Mashup的一些了解)。BPM的功能:1.連接到交互與協作的工具。2.建立專門的協作模型(終端)。3.使企業流程民主化。SOA的功能:1.服務創建與啟用。2.服務的動態發現。3.普遍的安全訪問。這三部分如何提升企業生產率呢?企業社會計算是以用戶為中心,那么個人的智慧就能夠最大限度的貢獻并且提升成為企業智慧。BPM提供了實時業務可視和控制,能夠及時地糾正問題,并且快速做出響應。SOA將活動和數據轉換為可重用和松耦合的服務,提高了業務開發速度,降低了開發成本,最大限度地利用已有資源。

          My option其實這三點就是昨天BEA對于創世紀平臺的構想,將Web2.0思想+BPM可視化工具+SOA模塊化服務三者結合起來,最大限度地挖掘互聯網應用的價值,提高靈活快速的開發和響應模式,滿足客戶需求,最終達到業務級別的敏捷。說到這兒,其實我發現那么多的概念,思想和規范,最終的目標歸結起來就是阿里巴巴的考核第一條:客戶第一。互聯網應用的客戶就是無數的網民,每個人的需求不同,每個人的喜好不同,如何開發出在這么一個廣闊的客戶群體中能夠長期生存的應用,只能夠不斷地根據用戶反饋來分析,創新,改變,那么應用的設計,開發都需要敏捷。Java世界中,初學者會使用Jdk提供了很多API包,成熟的開發人員可以根據很多開源項目來構建自己所需要的應用。而到了今天,其實需要更高層次的封裝和構建,也就是業務級別的封裝和構建,使得互聯網應用開發能夠基于這些服務組件自由組裝,拼裝出客戶所需要的應用,極端一點說,可能客戶通過一個工具就可以訂制出自己所需要的一個組合應用。用個形象的比喻,就好比量體裁衣式的一對一的模式已經不能夠適合這個飛速發展的互聯網時代,需要的是可定制化的模版式設計,客戶只需要將自己喜歡的上衣,褲子,帽子搭配好,根據自身尺寸就可以定制到自己喜歡的套裝,快速便捷。有人可能會問,那么大家都穿成一樣豈不是很沒有個性。兩個方面看這個問題:首先看看快餐的啟發,為什么人們那么容易接受快餐?在效率和可用性上如果能夠滿足的情況下,每個月快餐店推出的一款新產品就足以讓現代人覺得有新鮮感。(周日中午和老婆去爸爸媽媽家吃飯,聽到了樓下有喊磨剪刀戧菜刀,爸爸說這也就這邊小鎮上才有的風景了。老婆問,那么城里面刀鈍了怎么辦?赫赫,大家都一個反應,真的不行就換一把唄。)另一個方面就是個性化,其實在SAAS模式下多租戶的個性化也是和重要的一點,我們需要批量定制,同時需要個性化服務,不存在矛盾,如果覺得矛盾了,那么架構設計需要考慮是否能夠有更好的優化。在BEA的不同角色多視圖的演示中,就是展現的這么一點,其實個性化的并不是底層的應用服務,而是在同一層的應用服務池中,用Mashup的方式來結合客戶端的精彩技術構建出豐富多彩的個性化界面,滿足用戶地個性化需求,說到底也就是以業務組件抽象為基礎,多角度展現應用。

          上面第二點好像談的越來越與主題無關了,其實本來就是非針對我的課題,我自然就會遐想到其他地方去了。早晨就這么過去了,中午吃過飯,和同事去黃埔江邊逛了一下看看時間尚早,就去了一樓的廠商參展區,昨天晚上也去了一下,不過因為太晚,很多廠商都收拾走了,也沒有太多收獲,今天正好去看看。由于當前比較關心Web Service安全性能方面的問題,因此特意去了BEA的展臺看看是否有收獲,開始看到了BEA的安全介紹展臺,和展臺的朋友聊了一陣,發現大家的角度不同,他主要是側重于用戶鑒權和資源訪問控制這部分的安全策略,BEA對于用戶鑒權和資源訪問控制提供了數據庫設計和對應的API,也沒有仔細了解就轉去了另外地方看看。走了幾步看見了一個BEA的展臺正在給幾個朋友看SOAP消息,這下我就來勁了,馬上走過去看看,果然這個展臺是我想去的展臺,正好那兩個看的人都沒有興趣走開了,我一對一的和工作人員交流,問起了BEA現在對Web Service所采用的安全策略是什么?SAML2.0。性能怎么樣?(因為我這邊作的壓力測試web service在附帶了WS-Security Signature以后對于CPU的消耗高了幾倍)沒做過測試,因為剛剛開發出來一個月。兼容性如何(對于Php,.net)?沒有做過測試。那位工作人員不是負責這個模塊開發的,所以也不是很了解,我請他幫忙到時候給我一些SAML 2的資料,并留了我的card給他,他也很友好的答應給我回復。有一點點的失望,不過畢竟開發人員工作可能都很忙,這種展會都是推廣的多。

          轉眼看了看表就到了140分了,趕緊去了三樓參加下午的培訓,結果那個教室一早滿員,我只好站在邊上聽,巧的是正好有個人走了,我就安心的座了下來聽,看過BEA World2007的分會場安排的朋友就會知道,其實每一個會場兩天下午安排的都是系列性的講座,也就是每一個會場每天多節課都是相互關聯的,我選擇的這個是比較適合架構師和PM聽的結合概念,設計和實踐的系列講座,所以次次人滿為患,但是今天下午聽了一節課以后,加之昨天下午的兩節,我提早和我同事說還是早點走吧。

          就這樣結束了我2天的BEA SOA之旅,慶幸的是還是有不少的收獲,不論是否是大會給我的啟發。前一陣子給自己的blog以及所有的IM都改了一個名字,叫做:做塊石頭沉下去。因為覺得做一個技術人員(個性使然,目標是做一個大P),應該像一塊石頭一樣沉在下面,踏踏實實的做事,經得起成功,也經得起失敗。不過今天早晨跑步的時候又覺得,其實做技術的人,應該做一塊可以浮起來也能夠沉的下去的石頭,去參加這樣的技術大會,就是抱著浮起來的心態,去看看新的世界,接受新的思想,石頭沉的太深太久會被淤泥掩埋,同樣會因為閉塞而止步不前。當然浮起來就是為了去更好的地方沉下去,河流那么大,要學的還有很多很多。
              更多分享在我的csdn的blog:http://blog.csdn.net/cenwenchu79

          附加:今天早晨還看了關于mashup的兩篇文章,很不錯,也受益匪淺。

          http://www.ibm.com/developerworks/cn/webservices/ws-soa-mashups/?S_TACT=105AGX52&S_CMP=content

          posted @ 2007-12-17 11:56 岑文初 閱讀(1128) | 評論 (2)編輯 收藏

           

          BEA World 2007 SOA第一日手記

                 前一陣子工作忙,去北京參加CSDNweb2.0的機會錯過了,這次我正好處與服務框架第一階段總結期,同時測試部的資深總監受到BEA的邀請,可以帶上架構師一起去,所以有機會去上海參加BEA World 2007 SOA大會。說起來我們老大說這次會議的主題和我也算是“專業對口”,不是一直在說SCASOA落地么,那么就去看看BEA怎么讓SOA走的踏踏實實的。

                 會議一共分成了兩天,這兩天上午都是主題演講,下午和其他的年度大會一樣,分成很多分會場,自己可以根據自己的興趣去選擇所要聽的主題。因為也沒有太多時間去看電子郵件中的會刊,所以對主題都還不清楚,早晨起床就粗粗瀏覽了一下上午的主題,一共分成了四塊:1.超越SOA:技術融合與動態應用。2.江蘇電力SOA實踐。3.基礎架構新探索。4.鑄就面向客戶的英國航空公司。正好是技術與實踐相結合,兩個技術案例,兩個商業案例。9點左右,大廳門一開,大家魚貫而入,選了貴賓席后面的第二排,就開始了我這上午半天的BEA SOA之旅。我想看我blog的多半是技術人員,我們就不講關于BEA公司的宣傳內容,直接進入主題,首先是總的談談這幾部分具體介紹的內容,然后談談我這個半吊子的SOA學習者的一些感觸。

                 超越SOA:技術融合與動態應用:

          既然是BEA公司的SOA年度會議,那么自然會將BEA公司對于SOA的解決方案和產品推向我們每一個人。這次BEA推出的是他們的SAAS的平臺Genesis(創世紀),SAAS今年很熱,當然我們自己公司也是基于SAAS理念來構筑我們的電子商務平臺,BEA是將三個熱門的思想(WEB2.0 SAAS SOA)結合在了一起,放在這個創世紀平臺上,這三部分任何一項都可以作為互聯網應用開發的新理念來指導新一輪的互聯網運動浪潮,不過結合起來是否能夠達到想象的效果,這還需要實踐來檢驗。BEA為我們演示了一個關于模擬汽車銷售,服務,研發以及客戶多角色共同參與的項目實踐,在同一個業務系統中,角色的不同所看到的視圖不同,同時不同角色可以相互溝通,更甚者客戶可以對于設計者提出設計需求,同時銷售可以觀察客戶行為,主動地推薦產品。同時BPM的流程管理靈活性也在這個展示中成為了靈活適應需求的一個亮點。

          江蘇電力SOA的實踐:

          一個感覺,畫圖的水平不錯,滿眼的線路圖。

          基礎架構新探索:

          這部分內容其實是對于第一部分的介紹做了部分的系統架構介紹,也就是對于剛在的Genesis平臺作了一個總體的概述,以及一個遠景規劃。闡述了Genesis平臺的層次結構設計,主要分成四個層次:

          User Interaction

          Business Process

          Service Network

          Hosting

          最低下一層叫作Hosting,并不是我們常規考慮的硬件Hosting,而是指的我們各個業務系統原來的各種實現,也就是我們常說的各種信息孤島或者就是不同的遺留應用或者針對SAAS來說就是ISV的應用,這些Hosting常常技術實現不同,但是希望能夠被融合起來,發揮更大的價值。Service NetworkSOA概念中的Service Domain,這一層往往來說是我們現在比較關注去實現的一層,因為這層是SOA是否能夠真正達到服務融合,服務復用的基礎,如何讓服務注冊,路由,交互,為上層提供靈活組合的基礎,是一個關鍵性的問題。Business Process層的作用主要是通過BPM來將下層的Service串起來,發揮服務靈活響應需求變化的要求。User Interaction這層次屬于比較高要求的層次,其實也就是結合了Web2.0的一個特性,那就是客戶參與和貢獻,使得產品更加具有活力。

          英國航空公司的案例:

          另一個感覺,好多數字展示了英航在互聯網信息化的成就。

          以上是我上午聽了四個主題講座的如實感受和介紹,后面把我自己的一些新的體會感悟說一下。

                 前面說了,ASFSCA-based Application Service Framework)第一期正好告一段落,其實在周二來上海之前,我正在畫第一期的結構圖以及后續需要規劃和完善的功能圖,當時其實有一些迷惘,作為我來說,不能和Tuscany一樣做純粹架構設計和實現,我需要關心業務部門的需求,根據需求來考慮框架功能實現優先級。根據首架的需求,我的第二期內容在年內暫時大部分內容是對于前期框架Web Service安全性能優化,多種分布式場景技術實現及測試,跨平臺客戶端兼容性的測試,最后一點就是ISV服務互通的架構支撐預研。總結了前期的工作,同時把一些新的功能點做了羅列(對于基礎框架生命周期的維護和監測,擴展點的增加),同時也對性能優化方案作了初步的制定,但是總感覺好像有些迷失方向的感覺,難道按照現有需求就只需要完成這些就達到了我們ASF的階段性交付了么,對于ISV服務互通采用什么策略呢?正好周二也要來上海,也沒有再多想,不過雖然剛才說了早晨的演講就這么些,但是對我腦子里那些問題倒是正好給了一些spark,下面就將這些spark一一道來。

                 SPARK OneDBA。不要誤會,不是我們公司的DBA,呵呵,是Dynamic Business Application的縮寫。這個詞匯是我第一次聽到,也是BEA公司給我的一個新的概念,叫做動態業務應用。它的概念其實就是指服務于服務之間組成了業務應用可以根據用戶需求靈活變化,成為動態而非過去,由需求,建模,概要設計,詳細設計,編碼實現而產生出來的傳統商業應用。應為傳統應用最大的弱點就是固化和僵硬,面對現在互聯網應用的多變性和客戶化,傳統的設計理念和模式已經很難適應這種應用場景,因此需要一種敏捷的開發模式,面向服務+BPM+ESB,可能這些技術早就都已經存在并且也都曾經被廣為推崇,但是結合起來所能達到的效果確不是1+1+1=3的效果。同時結合Web2.0的特質,倡導參與貢獻多于遵循使用,這種靈活的框架模式無疑成為應用平臺很好的一個理念。此時我回顧了我這段時間SCA的一些工作,當前的服務框架已經能夠做到讓開發者不用過多關心業務邏輯以外的內容,業務模塊化和面向服務交互的理念已經深入開發過程中,但是考慮一下提到的以后ISV應用的互通解決策略,就可以發現,其實由于當前我們所開發的系統首先都是新系統,采用同樣的技術架構,雖然ISV和我們的交互已經是異構環境,但是我們系統之間處于業務流程相對來說比較固定,服務組裝交互實現可以定義好的情況,也就是說是一種服務靜態組裝的過程。但是對于未來我們的ISV應用來說,首先都是異構的實現,然后就是在ISV之間串聯未必可以通過靜態配置和設計事先確定,同時針對用戶行為分析是否可以及時動態調整服務流程,都是一個動態的過程,這也給我一個啟示,那就是第二期的互通,需要量體裁衣(最后會提到為什么要用這個詞),來構造適合的Service Network Business Work Flow。當然這個過程還是和我先前說的一樣,按照需求的優先級逐步實現,按需而進。

                 Spark TwoUser Interaction。其實這個概念應該是我在我同事北京帶回來程序員web2.0增刊中所看到的一個理念。我想現實生活中其實這類工作老早開展起來了,就好比你去商場買東西給你一個反饋表,讓你填寫一下,那么那個產品會根據客戶的反饋作一定的改進。只是今天BEA給我展示的時候,通過不同角色所看到的用戶操作界面的個性化和專業化,讓User Interaction這個概念在技術上有了實實在在的表現,同時在基于剛才提到的DBA基礎上,客戶的反饋在最最極端的情況下都可以直接主導流程(即客戶可以修改流程),不過BEA也說了這還是需要安全策略的配置允許的。那么作為我們未來互聯網應用的場景下,這種面向客戶的交互其實對于互聯網應用來說無疑是很有吸引力的。

                 Spark Three:社會計算。這個詞很新鮮,也是今天第一次聽到,下午也在一個分會場站了50分鐘(會場太小,走錯以后再回來就只能站著了)。社會計算和Web 2.0中的Social networking有一定的概念上的類似,其實就是溝通,也就是團體的溝通,個體的溝通,通過什么樣的有效手段來溝通,rss,mash up,blog,都是一種手段,在上面的例子里面,買車子的客戶可以通過blog反饋給DesignerSales可以push給客戶一個小短片來展示給客戶看新的產品,這些都是一些很有效的溝通手段,其實溝通就是為了雙贏,互聯網貿易除了安全這個大問題以外,剩下的最大問題就是如何讓買賣雙方因為溝通問題導致交易受挫。同時社區化是應用的互通價值最大化的有效生態環境保證。

                 Spark Four:客戶行為分析。其實也是一種手段,不過指的是自學習的一種行為分析,類似于Google對于客戶行為分析。如果留意一下,我們在日常搜索中如果搜索的內容經常會出現,那么Google就會智能化的提高客戶體驗。

                 其實,對我最有啟發的還是第一點,同時對于我來說有很多的問題需要去深入了解和分析,同時結合當前框架以及業務場景做量體裁衣,這么說的目的其實在于聽過了BEA的創世紀平臺規劃后,整個框架設計和理念都是讓人覺得很有創新和價值的,但是BEA規劃到了2009年,他的功能點和橫向縱向切面都作了規劃,但是這么一個龐然大物對于ASF來說并不合適,ASF也并不需要朝著這個方向發展。阿里的人都喜歡用武俠小說來打比方,我就打個比方,BEA為韋小寶提供了一套盔甲的解決方案,不論從外觀和安全性上來說都是完美無缺的,不過韋小寶其實需要的是一件金絲甲,輕輕薄薄的,跑路快,又可以刀槍不入。同時有什么問題隨時可以修補增改。框架設計的敏捷性和框架問題相應的敏捷性是同樣重要的,龐大的項目版本周期長,為了不同客戶訂制困難,那么就是另一個固化和僵硬的體現。當然設計框架幾個關鍵點需要把握:擴展性,規范通用性(不要用私有的協議),學習基礎上的創新。

                 上面是上午的內容,其實為什么花了那么多字寫了上午的內容,其實是下午的內容沒什么好說了^_^

                 下午一共參加了四個分會場,一個就是剛才提到的站了50分鐘的社會計算和Web2.0的講座,概念性的介紹,不過擴展了思路。Liquid Infrastructure for Enterprise Java Application,這個課程名字不錯吧,流動性的框架針對企業及的java應用,結果去了一聽,是談到使用vmware的產品,如何在服務器池中部署企業應用,提高效率和節約成本,晚上吃飯的時候和我們的測試部老大談起了這個,他剛進公司就做了這樣的實施,得卻對于效能有一定的幫助,不過對我原先的理解就偏差大了,早知道仔細看看簡介了。最后兩節課是SOA一個培訓的聯系課程,今天下午四節,明天下午4節,我今天下午就參加了兩節,最后兩節,一節是談到了關于SOA的治理,一位香港的朋友介紹的,聽了一節課,就知道他最后一句說出了他SOA治理的名言:SOA治理最難的就是搞定內部關系,技術從來就不是問題。赫赫,這句至理名言好象在很多行業中盛行。第二節課是對SOA技術的一個匯總,講師開始整一個介紹了Web Service的框架,最后才提了一句孤立的Web Service不是SOA,真是畫龍點睛啊,要是沒有這句話,我真的要為他捏把汗了,不過他發的BEA對于SOA的最后幾個領域模型介紹還是應該蠻有幫助的,不過因為時間緊迫,他沒有講這些重點,而是把時間讓給了最后BEA認證介紹的講師。我么,提起包包,吃晚飯去了。

                 這就是我第一天BEA的手記,明天是否會下午全部聽完,這就要看我們同行老大的安排了,不過還是期待明天上午的主題演講能夠有一些Spark,讓我也能有所收獲。這次也看見一些同行的朋友提問,有些是技術型的,但是聽那兩個SOA講座的有不少還是理論先行的,這感覺SOA又開始在這兒“漂浮”起來。

                 總的來說,其實參加這樣的大會我也早就有心理準備,未必能夠真的了解很多核心的解決方案,只是可以接觸一些新的思想,新的碰撞可能會給自己的工作帶來一些靈感和啟發,后續周末或者下周就可以把第一階段總結和第二階段的思考再從新規劃一下。轉眼就11點半了,洗澡睡覺,期待明天的碰撞,不論是否有火花。

          posted @ 2007-12-13 20:38 岑文初 閱讀(1047) | 評論 (0)編輯 收藏

          SSL &WS-Security--Web Service安全保障

                 今天早晨看了一下blog的留言,發現有位朋友給我留了言,提到了他正在研究SCA,同時也有些困惑,當在異構分布式環境的情況下,不論是否使用SCA規范來實現,都采用Web Service來完成面向服務的服務調用,覺得SCA沒有什么優勢可言。其實這是一個誤解,SCA框架規范并不是一個具體的業務場景解決實施規范,它是一種框架結構性規范,它的精華部分主要在于:一.將抽象和封裝由對象提升到了業務組件模塊 .框架的可擴展性(也就是因為沒有實現的約束,才會能夠易于擴展)。當然這兩點所帶來的好處那就是在這么一個精煉的框架核心規范下,不斷融入了外界的各種好的技術和理念,就好比現在的Web2.0最重要的一點特質,規范的只是接口(用于統一交互的管理),開放的是接口下的任何貢獻,主動參與和主動的集成將會使得框架越來越有活力,Spring就是很好的例子。而SCASpring的差異我也早在前面的文章中說過,SCA和其他的規范一樣,并不是一個橫空出世的規范,是積累在過去的失敗中沉積的產物。最后打了個比方,SCA規范好比一本菜譜,至于采用什么鍋子,用哪里產的材料都是由廚師自己掌握,這也是架構師和程序員需要共同努力將這個規范實踐的原動力,正確的做事和做正確的事是成敗的兩個關鍵。言歸正傳,繼續這次的主題。

          在前面的服務框架工作中,對于Web Service的支持成為了這段時間的重點工作,從開始的壓力測試,Java客戶端的兼容性測試到.net,php客戶端的兼容性測試,WS-Security的集成,服務框架對于Web Service的支持在需求中逐漸增強。AEP第一期基本完成準備上線,第二期的需求也已經在醞釀中,ASF的第二期功能需求也逐漸的被提出來了,有一點看上去優先級比較高,因此我就開始動手先做,那就是SSL。一開始的時候對于SSL需求有些誤解,以為是要做Web 服務器端的SSL,其實我們需要做的是硬件的SSL,只不過“首架”的意思是需要對SSL模式下的客戶端調用作準備(的確,客戶端在SSL不論是硬件還是軟件模式下都需要作一定的工作)。后續將講述一下我在做Web 服務器端SSL平臺集成的工作和SA專家交流了解的硬件SSL的架構策略。

          What is SSL

                 雖然以前也對SSL有所聞,也常看到IE突然蹦出一個安全提示框,但是對于SSL的具體原理以及結構沒有仔細看過。既然要用了,還是那個原則,先把原理搞清楚,然后再去實踐。

                 SSL(Secure Socket Layer)是一種通信交互協議,由Netscape公司在1994年制定,主要目的就是確保在web 服務器和瀏覽器之間數據傳輸安全。SSL協議層是在TCP/IP層和應用層之間。當前TLS(Transport Layer Security)正在逐漸替代SSL(最新版本v3)

                 SSL協議分成以下幾部分:

                 Record ProtocalSSL的基礎層,SSL所有的上層操作都是基于這個層次,這層主要負責消息內容的分段,壓縮,加密和數字摘要等操作。

                 Handshake Protocal故名思義就是握手協議,也是在正式應用數據傳輸前雙方交換加密設置以及認證的流程規范協議。

                 Change Cipher Spec Protocol是基于record協議層通知遠端服務器修改record協議層中安全設置的協議。

                 Alert Protocol是基于record協議發送警告到遠端服務器的協議。

          SSL的具體流程圖:

           

                 SSL的流程也體現了對于對稱性密鑰和非對稱性密鑰的使用,由于對稱性密鑰加密比非對稱性密鑰加密要快1000倍,那么對稱性密鑰被用來做對內容的加密,而非對稱性密鑰用來做傳遞對稱性密鑰的加密手段。

                 服務端所需要具備的是一個擁有服務端的標示,公鑰私鑰對的證書。在握手的流程中,服務端將帶有公鑰的證書抽取出來發送給客戶端,客戶端就首先可以判斷證書頒發者是否屬于本機受信的CA,如果不是,就會類似于IE跳出提示,如果通過了這部分CA認證,雙方就可以通過非對稱性加密算法來交換客戶端生成的臨時對稱密碼,進行安全加密信息交互。

          軟件SSL的實踐

                 因為當前所有的單元測試都是通過我提供的ASF模板類,所以啟動的Web Service都是服務框架中Jetty發布的Web Service,很輕量級,沒有以往測試Web應用的復雜,不需要單獨去啟動一個Web Container。前期對于WS-Security的集成已經使得單元測試可以支持帶WS-SecurityWeb Service的測試。

                 抱著試一試的心理,直接用服務框架發布了SSLWeb Service,客戶端調用了一下,沒有成功,但是錯誤還不能定位是客戶端還是服務端的問題,因此首先去外部配置了Tomcat來建立了一個SSL服務端。

          Tomcat SSL服務端的配置:(只需要修改一個文件conf/server.xml

              <Connector port="8443" maxHttpHeaderSize="8192"

                         maxThreads="150" minSpareThreads="25" maxSpareThreads="75"

                         enableLookups="false" disableUploadTimeout="true"

                         acceptCount="100" scheme="https" secure="true"

                         clientAuth="false" sslProtocol="TLS" keystoreFile="D:/work/asf/webservice/src/conf.test/keys/alisoft.jks"

                         keystorePass="alisoft" keystoreType="jks" truststoreFile="D:/work/asf/webservice/src/conf.test/keys/alisoft.jks"

                         truststorePass="alisoft" truststoreType="jks"/>

          clientAuth沒有必要配置成為true,不需要重復反向再認證。如果這個值設為false。其他幾個值就是生成的服務端證書庫位置及密碼。這里所要注意的就是要求keystore密碼和私鑰密碼一樣,因為只有一個配置密碼的地方,這在生成公鑰密鑰對時兩者密碼寫成一致。這樣就OK了,直接訪問8443端口就能作為https來訪問服務了。

          采用XFire客戶端來做單元測試,代碼如下:

          public static void SSLSecurityTest()

                   {

                             Service serviceModel = new ObjectServiceFactory().create(IAccountService.class);

                             //https的客戶端代碼需要增加的

                             System.setProperty ( "java.protocol.handler.pkgs" , "com.sun.net.ssl.internal.www.protocol" );

                             System.setProperty ( "javax.net.ssl.keyStore" , "D:/work/asf/webservice/src/conf.test/keys/myisvdemo.jks" );

                             System.setProperty ( "javax.net.ssl.keyStorePassword" , "myisvdemo" );

                             System.setProperty ( "javax.net.ssl.trustStore" , "D:/work/asf/webservice/src/conf.test/keys/myisvdemo.jks" );

                             System.setProperty ( "javax.net.ssl.trustStorePassword" , "myisvdemo" );

                             System.setProperty ("java.protocol.handler.pkgs","com.sun.net.ssl.internal.www.protocol");

                             Security.addProvider ( new com.sun.net.ssl.internal.ssl.Provider());

                            

                            

                             String serviceUrl = "http://localhost:8080/axis2/services/AccountService";

                             String serviceHttpsUrl = "https://localhost:8443/xfire/services/AccountService";

                             String serviceHttpsUrl2 = "https://localhost:8443/axis2/services/AccountService";

                            

                             try

                             {

                                      IAccountService service = (IAccountService)serviceFactory.create(serviceModel,serviceHttpsUrl2);

                                     

          //WS-Security所需要的配置

                                      Client client = ((XFireProxy)Proxy.getInvocationHandler(service)).getClient();

                                      client.addOutHandler(new DOMOutHandler());

                                      Properties properties = new Properties();

                                      properties.setProperty(WSHandlerConstants.ENABLE_SIGNATURE_CONFIRMATION, "false");

                                      properties.setProperty(WSHandlerConstants.ACTION, WSHandlerConstants.SIGNATURE);

                                      //properties.setProperty(WSHandlerConstants.ACTION, WSHandlerConstants.TIMESTAMP);

                                      properties.setProperty(WSHandlerConstants.SIG_PROP_FILE, "keys/client.properties");

                                      //properties.setProperty(WSHandlerConstants.USER, "myisvdemo");

                                      properties.setProperty(WSHandlerConstants.USER, "wenchu");

                                      properties.setProperty(WSHandlerConstants.PW_CALLBACK_CLASS, ClientUtPasswordHander.class.getName());

                                      //properties.setProperty(WSHandlerConstants.SIG_KEY_ID, "IssuerSerial");//"DirectReference","IssuerSerial","SKIKeyIdentifier"

                                      properties.setProperty(WSHandlerConstants.SIG_KEY_ID, "SKIKeyIdentifier");

                                      client.addOutHandler(new WSS4JOutHandler(properties));

                                      AccountBean[] result = service.getUserAccountList("te", "ta");

                                      System.out.println(result.length);          

                             }

                             catch(Exception ex){ex.printStackTrace();}

                   }

                 這樣保證了客戶端的配置已經沒有問題了,因此就主要將ASF框架中的SSL集成進去。由于ASF中集成的是Jetty,因此只需要在Jetty動態建立Mapping Server的時候,Serverconnector為以SslSocketConnector類型來構造,這樣就可以響應https的部分了,同時也可以在其它端口發布成為不需要SSL的服務。這里細節就略去了,改造不是很復雜,只需要對Jetty較為了解即可。不過這里還是要贊一下Jetty,真是輕量級的好東西啊。集成以后再次作單元測試,OK,測試通過。

          .Net的客戶端測試

                 最后就需要對.netSSL的測試,由于.net客戶端已經在上次配置了policy作為WS-Security的配置,按照常理來說應該不需要再配置證書之類的東西了,就嘗試著做了一下,在建立Web Reference的時候會有提示說證書授權的認證不符合要訪問的地址的身份,這個可以忽略。然后接下去測試了一下,就總是提示無法建立TLS/SSL的交互通道,查了一下,只需要加入下面一句話即可:

          System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

          它的作用就是接受所有的證書,也就是在我們SSL中的流程中,檢查證書CA是否受信這部分省略,就好比我們訪問一些非受信證書的網站跳出的提示框我們點擊確認一樣。

          到此為止,應用服務器的SSL配置和測試就基本結束了。后面要談到的就是硬件SSL的結構和設計。

          硬件SSL結構設計

                 首先為什么要使用SSL來加密呢,干脆用WS-Security就好了,而且WS-Security有著很多SSL所無法做到的特性(不基于傳輸層,保障非點對點的安全傳輸,部分加密等等)。但是在前面的壓力測試中明顯可以看到還沒有用到加密,僅僅是簽名服務器的CPU消耗就成倍的增長,可見對于性能的影響。同時上面提到的應用服務器SSL,其實也是類似于WS-Security,消耗比較大。因此就提出了硬件SSL的設計。

                 這里主要提了兩種,第二種也是現在SA比較推薦的。

          一.              為應用服務器增加獨立的SSL加速卡,例如roadcom CryptoNetXM卡,SSL加速卡的作用在于能夠將應用服務器處理SSL的工作獨立完成,讓應用服務器專心處理應用請求,使得應用服務器性能不受影響。

           

          SSL加速卡部署圖

                 由于許多服務器使用的是不同的加密數據,因此管理這樣一個Web服務器組會花費比較大并且復雜。同時傳統的負載均衡陣列中每一個處理加密服務器要求有一個SSL加速卡和數字證書,而證書是被CA簽署過的一個電子認證標識,在加密通信方面提供了一致性的驗證,這樣對于CA的電子認證標識管理也是很復雜的一件事,因此產生了第二種設計模式。

          二.              SSL基礎結構與BIG-IP結合

          BIG-IP是一個運行有BIG-IP負載均衡軟件的服務器,它通過SSL加速卡實現了SSLoff-loading,同時還可以實現應用層和IP層的負載均衡。通過SSL終結,前端的BIG-IP負責SSL的集中處理以及同時將處理后的請求負載均衡到各個應用服務器上,這樣既降低了SSL證書管理成本,也減少了Web服務器組的管理復雜性。

           



           

          Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1926332

          posted @ 2007-12-10 08:56 岑文初 閱讀(2602) | 評論 (1)編輯 收藏

           

                 上周周四快速了結了對于搜索引擎的集成以后,又從新回到對ISV WebService接口集成和測試的支持中。測試部發現了一個很棘手的問題,將WS-Security集成到了ASF(應用服務框架)中以后,接口中如果出現中文,就會導致異常拋出。這個問題相關的同事已經跟蹤了12天了,但是還是沒有頭緒,離周末還有一天,我趕緊接手,希望能夠趕在測試部下周整體測試前修復這個問題。其實前面做了那么多工作,如果一旦這個問題被卡住,那么就會前功盡棄了。

                 首先工作就是要確定,究竟是加了WS-Security導致中文問題,還是本來WS的中文返回就有問題。簡單的做了單元測試驗證了一下,確認了的卻是增加了WS-Security導致的中文作為參數或者作為返回值都回拋出異常。根據異常的翻譯來看,就是因為在消息體中出現了非法字符。前幾天一位同事讓我幫忙看WS的一個中文問題時發現,在Http頭上對方返回的編碼方式是utf-8而在SOAP消息體中,XML的編碼方式卻寫著gbk,所以客戶端解析器在解析SOAP消息中的xml時候采用的是Utf-8的編碼方式,解析出來的中文自然是不對的。同時翻閱了一下資料,在xml  1.0的內部二進制嵌入必須用base64編碼一下,否則是不允許出現非法字符,在xml 1.1已經對這部分作了擴展。所以這次集成了WS-Security產生的問題,可能就會因為這兩種原因造成的。

                 但是事實上并不是這兩方面的原因造成,Axis2和當前很多Web Service框架都采用了Stax方式的Jaxp(Java API for xml processing),在帶WS-Security和不帶的兩種流程中,所用的Jaxp的讀寫解析器采用的是不同的解析器,所以才會出現了上面的問題,因此還是要從根本上去了解Stax模式的Jaxp框架結構及工作模式。

          Stax(Streaming API for XML)

          背景

          Stax不是很新的概念了,在2002年就被提出,在2004年被JCP作為編號為173JSR正式發布。因此在我們日常開發中如果說到Jsr 173就是關于Streaming API for XML的內容,同時,在lib中如果列了jsr-173.jar或者stax-api.jar也就是對于Streaming API for XML的接口定義包,同時這個包內只是定義框架接口,并沒有具體的實現,JSR 173是接口定義規范,各個開源組織或者廠商都可以根據規范實現自身的Stax,這個后面的結構介紹中就會提到。Stax的創始者是BEA的兩位系統工程師,所以在我們日后的出錯中,如果類似于com.bea.xml.stream.XXX  Class not found 等錯誤,多半是在所有的lib庫中沒有對應的Stax的具體實現,只有接口定義。當前支持JSR的實現有Sun,Bea,Oracle,Breeze Factor和其他的一些開源項目(最出名的就是codehauswoodstox)。

          Jdk 1.6種已經把Stax集成到了內部(javax.xml.transform.stax),順便說一句的就是,在jdk1.5中,范型和對于Collection的增強是很成功的,而在jdk1.6中雖然沒有1.5的很多新特性的融入,但是仔細觀察一下就可以發現,其實對于xmlweb service的處理和支持作了不少的增強,其實也是針對當前SOA的大趨勢作的技術方面的增強,很多概念和實現其實很早就在我們的應用開發中得到體現,個人覺得這也是Sun在開源后的最大受益之處(利用開源來匯集更多的亮點和精華),包括對于1.7OSGI的暢想,其實都是大勢所趨。這讓我想起了昨天看程序員增刊第一部分對于Web2.0中的特質的一項描述,利用集體智慧,有所放棄有所收獲,放棄了獨享的知識專利(當然核心部分可以保留),獲得的是廣泛的集體參與所帶來的智慧亮點。

          Stax結構體系和功能描述

          Stax的提出開始,其本身就只是一個框架性的規范,并沒有具體的實現約束,這也為各個開發商和開源組織認可這個規范提供了一個最基本的優勢條件。這點也是當前所有的有生命力的框架或者系統所具備的最基本的特點之一,開放性,制定接口,規范流程,但是不約束具體的實現。

          功能描述:

                 這是我第一次去看JSR的描述,JSRJava Specification Request的縮寫,也就是規范申請,其中所需要填的描述中就詳細的寫出了申請為JSR的目的(這比類似于國內申請專利之類的,不過感覺更為簡潔和開放)。

                 Streaming API for XML 描述的是一種基于javapull方式來處理XMLAPIStreaming API通過暴露簡單的Iterator模式API提供給開發者處理XML的控制權。同時當前兩種關于XML的規范,JAXBJAX-RPC也十分需要通過Stax模式來處理xml

                 其實早在Stax出現之前,jdk中的已經有了jaxp家族,saxdom,這兩種API分別針對不同的應用場景作了很好的封裝。SAX是用于處理XML的事件驅動方法,由很多的回調函數組成。而DOM則是將XML解析成為內存中的樹狀結構,然后通過API來對XML中的元素和標簽進行分析。SAX速度快,需要的內存小,但是無法修改XML,而DOM可以提供對于XML任意節點的訪問,同時也可以寫入內容到XML,但是缺陷就是速度慢,消耗內存大,需要把XML全部解析完以后才能夠繼續操作。

                 網上對于Stax的好處有很多很詳細的文檔,就我自己的學習理解來看,比較重要的幾點就是:1.pull方式替代了pushStax從名字上就可以看出和SAX十分相像,其實很大的一點不同就是在于Pull替代了PushSax可以實現很多固定的回調函數,然后在執行XML解析的過程中不斷的被調用和處理,但是缺點很明顯,首先被動回調導致開發者無法根據場景來動態選擇如何裁減事件處理需求,同時無法同時處理多個XML2.StaxSAX可以更靈活定制事件處理條件。3.Stax可以寫入XML4.Stax除了和SAX提供了一樣的API模式的處理方式,還封裝了Event模式的對象處理方式。5.StaxDOM性能高,應用場景廣泛,特別是當前很多應用處理xml數據流時都需要邊讀邊分析,當流結束以后就自動關閉了,此時可能已經將流釋放,然而此時在作DOM分析已經無法實現,而Stax正好滿足了這種需求。因此對于Stax適用范圍的描述如下:需要清晰,有效的pull-parsing模式分析XML,另一方面也需要靈活的對XML Stream進行讀寫操作,需要創建新的事件類型和擴展XML的文檔類型以及屬性的情況。

          Stax體系結構:

                 下圖中是Stax接口部分的類圖,基本上已經包括了Stax規范中的大部分接口定義。


          Stax接口類圖

           

           

          兩類API設計接口:Cursor APIIterator API

                 Cursor API的兩個接口定義為:XMLStreamReaderXMLStreamWriter。這部分接口提供了類似于游標方式的方法定義,能夠在XML解析過程中,從XML文檔流獲取或者寫入信息,同樣也類似于游標讀取信息一樣,只能前進不能后退,在任意一個時刻能夠返回XML中的部分信息片斷。

                 Iterator API的兩個接口定義為:XMLEventReaderXMLEventWriterIterator APIXML輸入流看作了一組離散的事件對象,這些XML流讀入并被Parser分析,然后被解析成為這類事件對象,在開發者的應用程序中,可以主動的Pull(拉)出需要處理的事件對象。

          對于這兩種API的選擇基于下面幾點:

          1.內存有限類似于J2ME可以選擇使用cursor API

          2.性能是第一優先級,創建底層的庫或者框架結構時使用cursor API更有效。

          3.如果需要類似于管道處理XML,使用Iterator API

          4.如果想要修改事件流,使用Iterator API

          5.如果需要應用能夠處理可插入的處理流程,使用Iterator API

          6.總的來說,如果你對性能要求不是很高,建議使用Iterator API,因為它更靈活和易擴展。

          工廠類

          Stax采用的是抽象工廠模式來動態的根據環境配置加載不同的Stax的實現。在我原先查找問題的時候看來也是產生WS-Security中文問題的根源,當帶WS-Security的時候對于XML流分析和讀寫采用了codehauswoodstox包中針對StaxCursor API實現,而不帶WS-Security時對于XML流分析和讀寫采用的是axis2中實現的Cursor API 

          工廠類都是抽象類,因此都需要實例來繼承實現,如何選取工廠類的實現,并且通過工廠類來生成兩套API的實現,按照以下的規則來載入:(以XMLInputFactory為例)

          1.       讀取系統屬性,看配置中是否有javax.xml.Stream.XMLInputFactory等配置的描述。

          2.       讀取Jrelib/xml.stream.properties文件來讀取配置。

          3.       從可讀取的Jar中讀取在META-INF/services/javax.xml.stream.XMLInputFactory文件來判斷載入哪一個的工廠類實現。

          4.       使用默認的XMLInputFactory實例。

          其他接口的說明

                 XMLResolver接口可以在分析XML的過程中對于某些資源解析定位到定義和實現的方法上。

                 XMLReporter接口用于報告所有的非致命的錯誤,致命錯誤通過XMLStreamException來報告。

          對于接口使用細節可以參看sun公司的webservice tutorial


          WS-Security中文問題解決

                 在對新一代的Jaxp做了基本學習以后,那么對于axis2如何處理SOAP消息有了基本的了解,在跟蹤了代碼調試以后,發現問題主要是出在axis2rampart模塊的Axis2Util類,其中的兩個方法getDocumentFromSOAPEnvelope(SOAPEnvelope env, boolean useDoom)getSOAPEnvelopeFromDOMDocument(SOAPEnvelope env, boolean useDoom)。在有WS-Security和沒有的不同情況下,傳入的參數useDoomtruefalse,導致走了兩個不同的解析流程。當useDoomtrue的時候,axis2通過SOAPEnvelope對象和axis2Streaming parser來解析和構建Dom Document。當useDoomfalse的時候,首先將SOAPEnvelope對象讀入字節數組流,然后在根據Stax工廠生成實例,并且構造出StAXSOAPModelBuilder,然后返回通過StAXSOAPModelBuilder獲得的Dom Document對象。

                 察看了一下調用者傳入參數的地方,其實是通過MsgContext的參數配置來確定采取什么策略,因此只需要將axis2.xml中配置增加一個parameter,設置useDoomtrue即可。或者就是做一個handle或者phaseInflowoutflow中配置這個參數即可。

                 搞了那么久也就是修改一個配置,如果光從結果看,花了兩天時間真是比較浪費,但是如果從過程來看,那么這兩天時間所學到的那還是比較值的。

                 由于第二天是周日,問題解決了也就沒有再繼續細究。但是周日早晨晨跑的時候,給自己列了三個疑問,首先為什么走系統獲取的Stax會有問題,再則如果我用sunjaxp實現來替換是否能夠解決此問題而不需要配置useDoomuseDoom兩種處理模式究竟有什么區別。

          問題的再次細究

                 周一上班的時候還是記得周日早晨提出的三個問題,因此就仔細的再分析了一下這三個問題。

          首先是采取sunjaxp替換,這個實現在sunjwsdp中已經包含了,替換以后然后強制在jre的配置文件中指定使用,出現了異常,看來直接使用還不行,需要針對一些參數作配置,特別是對namingspace的解析,同時也沒有花更多時間去細研究。

          再則,仔細回想了一下我在定位這個問題的時候做的實驗,我曾經試圖將中文先用Base64編碼,然后服務端接收到以后回傳,客戶端再用Base64解碼,沒有任何問題。有時候換一個中文或者中文前后有字母數字,也可以正常處理,同時在跟蹤代碼過程中看過SOAP消息中的內容,內容是亂碼。這讓我有點啟發,例如我輸入參數為“岑文初”每次始終都會出錯,如果輸入為“岑文”,就沒有問題,看了看內存內的變量,發現,原來如果是“岑文初”的時候SOAP消息中的標簽封閉被破壞,如果是“岑文”,雖然是亂碼,但是沒有破壞標簽的封閉。

          仔細看了看上次提到的兩個流程,其實兩個流程除了parser不同以外,對于SOAPEnvelope的處理也是不一樣的,走UseDoom的是直接將分析好的Dom對象返回,不做附加的處理,只是根據Envelope生成了SOAP的解析器以及配置了StaxCursor的兩個接口實現類。不走UseDoom的情況則是完全將SOAPEnvelope再次序列化并且通過外部的Stax實現來解析和處理,但是問題就出在對象到字節流的序列化過程,默認的是使用了SOAP規定的utf-8編碼方式,因此在這個過程中有些中文的內容就破壞了SOAP的消息包XML的標簽合法性,導致外部解析器分析出現問題。如果將傳入和傳出的中文都編碼成utf-8沒有任何問題。

          問題總結就是其實根源在于對于內容中的中文字符編碼時采用Utf-8破壞了xml的封閉性,而我開始采用的useDoom正好規避了這個過程,也就自然通過了。但是就其設計本身來說,rampart應該是贊同使用useDoomfalse的方式,這才是真正的Stax的模式,同時有很好擴展性。另一方面個人覺得類似于這種抽象工廠機制來說,最好不要在系統變量或者jre中強制指定,這樣會導致一些意想不到的問題,雖然是規范,但是細節實現畢竟有差異,因此一些特殊的開源框架的一些莫名其妙的xml解析問題也常常由于這些引起。

          幾點感悟

                 靈活的SPIService Provider Interface)模式是當前框架設計以及底層設計的必要特質,開放才會發展得更好。

                 靈活是把雙刃劍,在遇到一些靈活的框架設計時,首先必須了解其原理和結構,然后根據實踐來驗證問題的緣由。

                 抽象工廠還是有適用場景的,類似于JaxpSCA等框架的實現,抽象工廠以及利用JarMETA-INF/services來載入SPI的實現是IOC的一種很好的補充。


               更多內容請訪問我的blog:http://blog.csdn.net/cenwenchu79

          posted @ 2007-12-04 16:10 岑文初 閱讀(1365) | 評論 (3)編輯 收藏

          和第三部分同樣,這部分內容其實應該在后面才對,不過當前工作既然做了,也需要寫下來分享,那么就提前插隊到成長記錄當中吧。看了這篇文章以后,可能給人的感覺是有點偏離服務框架的內容。的卻,如果純粹從技術方面來說,這部分應該不屬于服務框架范疇。拿杭州作個例子,杭州是全國唯一一個景點不但不漲價,反而免門票的地方,原因何在,無非是管理者看得遠,景點的門票收益看得到,但是是小頭,免去門票帶來的商機那才是金礦。框架其實也是這樣,如果客戶用起來不方便,甚至都不能用,那么框架再好,也會有人笑話你是個高高在上的理論主意者,這種框架適合于教學,而非實用。現在也是在邁出平臺服務框架兼容性的第一步,那天和同事們開玩笑說,以前聯通移動的wap業務,好在大家的開發語言都相似,isp只需要兼容各種手機客戶端,我們現在要做的就是兼容各種不同開發語言,平臺,以后甚至瀏覽器,我們這種全部都搞通的人出去,那就真的是搶手貨了。

          周一測試部和ISV support小組的日報反映,.net的客戶端對于復雜對象數組返回有問題,緊接著就是.net客戶端對于web servicewsse無法調試通過。我以前沒有接觸過.net,沒辦法,硬著個頭皮裝了個vs2005WSE 3。前面一個問題就是我前面半周間斷性的解決的問題,在第三篇記錄中也寫了。后面的問題比較緊急,也比較嚴重,因為如果wsse不能順利調試通過,那么將會直接影響我們后續將wsse全面部署的計劃,同時ISV已經跟在后面作測試了。看了看時間進度表,下周要進入平臺搜索引擎增強的開發和WSSE性能優化(WSSE對于CPU的消耗真是厲害),因此也就只有兩天,周四和周五。昨天晚上調試到了很晚(我說的很晚可能有些朋友覺得很早,不過對于我這種早睡早起的人來說,真的算晚了),雖然盡力了,但是還是卡在了最后的部分(服務端返回內容的驗證解析),周五一大早到公司就開始繼續調試,一直到了下午5點鐘,我的神哪,讓我看到那個斷點不再跳出一個令我已經看到都反胃的出錯提示框(順便說一下,微軟的vs出錯提示框作的蠻精致,不過再好看都是出錯,2天內看到了不下數百次,再好看也讓人反胃了),最后在群里面大大的發泄了一把,公司一堆人覺得莫名其妙,不知道我受了什么打擊,就搞通一個東西能夠壓抑成這樣,其實這其中的苦也就自己知道,還是那句話:“在沒有調試過.net的程序以前不知道開源的好啊,能看到源碼是多么開心的一件事情啊,整一個在替微軟作白盒測試,連google都被我翻爛了,也就只看到幾個老外在Q,而沒有人在那兒A”。廢話說了那么多,言歸正傳,實踐是建立在理論基礎上的,那么先系統性的來介紹一下關于WSSE的內容(如果概念已經十分熟悉了,跳過即可),以及如何解決.net客戶端無法調試Java發布的web service的問題。

          在互連網應用中Web Service已經得到了廣泛的認同,同時也是因為這種廣泛的應用,使得Web Service在規范化方面越來越成熟。企業和企業之間的信息交互,很重要一點就是信息的安全性,電子商務等互連網應用這方面的需求更為突出,如果沒有安全的保證,沒有客戶或者企業愿意將信息在網上交互,同時也不會信任任何接受到的信息。然而,作為SOA的有效技術手段,Web Service的動態性很強,服務的開發者無法預料到服務將在什么環境下被使用,因此服務的安全性變得更加復雜。

          在考慮安全性方面主要有三個關鍵性的概念:

          機密性(Confidentiality),完整性(Integrity,身份鑒別(Authentication)。

          機密性:除了指定的接受者,其他人無法查看消息的內容。通常會使用密鑰(對稱或非對稱)對消息加密,從而保證消息的機密性。
              完整性:確保消息在傳輸的過程中沒有被修改。即保證消息的接收者接收到的消息與消息發送者最初發送的消息完全一致。通常會對消息做摘要(Digest),再使用密鑰(對稱,非對稱)加密摘要,從而保證消息的完整性。   

          身份鑒別:確保消息發送者的身份與消息中所聲稱的用戶身份一致。最簡單的做法就是讓用戶同時發送用戶名和密碼,服務方確認密碼的有效性從而判斷該用戶身份是否與用戶名所代表的一致。然而在實際的應用中的做法通常不會如此簡單,此時往往會使用密鑰對一段信息加密,服務方通過解密此信息確認用戶的身份。

          那么如何選擇使用對稱密鑰還是非對稱密鑰?什么時候使用公鑰,什么時候使用私鑰?首先由于對稱密鑰的加密解密速度比非對稱的密鑰快很多(大約1000倍),所以在加密消息的時候一般都使用對稱密鑰。但是有一個問題就是對稱密鑰又如何發布呢?網絡上兩個沒有聯系的用戶如何建立起一個共享的密鑰?這時就需要PKI來幫助我們將這個共享的密鑰建立起來,即利用非對稱密鑰中的公鑰來加密那個共享密鑰,傳遞到私鑰的擁有方。由此可以知道:對稱密鑰加密普通信息,非對稱密鑰加密對稱密鑰。

          Integrity,使用非對稱密鑰的私鑰加密摘要,得到的東西是一個廣為人知的東西—Digital Signature(數字簽名). 而使用對稱密鑰加密摘要得到的是HMAC(Hash message authentication codes)。他們在保證消息完整性的同時,都具有身份鑒別的功能,不過前者還有一個功能---抗否認性。值得注意的是在Confidentiality中,使用非對稱密鑰方法是用公鑰加密,私鑰解密,而在Integrity中使用非對稱密鑰的方法恰恰相反。

          在當前的安全策略上很多時候會使用到SSLVPN,他們的好處和缺點網上都有評論,但作為和傳輸層無關的安全策略,WS-Security規范無疑是最具廣泛的應用。IBMBEA,Microsoft共同制定了WS-Security規范,解決了安全的三個基本問題:機密性、完整性、身份鑒別,在Web Services使用SOAPXML 格式)作為消息封裝協議的背景下,標準化組織分別制定了XML EncryptionXML Digital Signature、與SAML(XML格式的Security Token)三套規范,WS-Security則是規定了如何將以上規范組合起來以滿足Web Services安全需求的一套規范。

          XML Signature規范是將數字簽名和XML組合而成的產物,不要以為XML Signature僅僅是將數字簽名技術應用于XML文件。

          XML Signature包括以下的功能:

              1XML Signature可以對任何能夠以URI形式(uniform resource identifier)定位的資源做簽名。既包括與簽名同在一個XML文件中的元素,也包括其他XML文件中的元素,甚至可以是非XML形式的資源(比如一個圖形文件),只要能被URI定位到的資源都可以應用XML Signature. 這也代表了XML簽名的對象可以是動態的變化。

              2XML Signature可以對XML文件中的任一元素做簽名,也可以對整個文件做簽名。

              3XML Signature 既可以用非對稱密鑰做簽名(Digital Signature),也可以用對稱密鑰做簽名(HMAC)

          具體的標簽以及含義就不做解釋了,不過如果要做簽名策略配置,需要熟悉這些標簽,這也會影響到后續開發中遇到的各種問題。另外兩個規范這邊就不做說明了,因為現在服務框架暫時只是提供了Signature的要求,如果內容需要加密,那么對于應用來說性能可能是不可接受的,因此需要的是利用SSL和簽名結合的策略來實現完整的安全機制。

          對于WSSE的支持

                 ASF這部分是改造了TusncayWeb Service子項目,Tuscany子項目內部集成的web service的開源框架是axis2,雖然很多朋友評價xfire好于axis2,不過個人在使用過程中感覺其實兩者各有所長,只是說如何在適當的場合使用,如果需要和Spring很好的集成,那么xfire當然是最好的選擇,如果需要能夠有很好的wsse以及其他開源支持,那么axis2應該是個很不錯的選擇,畢竟apache組織下的開源項目眾多,自家人集成起來更是得心應手,特別是wss4jaxis2的集成,axis2addressrampart兩個子插件模塊使用起來十分方便,同時在框架的可插入性和模塊化上,覺得axis2要好過xfire。不過axis2的客戶端比xfire要麻煩得多,xfire封裝的好多了,這也是很多人喜歡xfire的緣故了(不過再傻瓜也抵不過.net客戶端的傻瓜,不過這個傻瓜模式無法讓人測試,那么就真的被當成傻瓜了),畢竟易用性往往是吸引到第一批客戶的重要特質,這也是后續做ASF所需要考慮的問題。

                 使用Axis2的框架結合Jetty這個輕量級內嵌容器作為Web Service發布框架(不得不提的是,在作web service的性能測試的過程中,公司的測試資深人員對于ASFweb service性能作了肯定,其實這和使用Jetty也有一定的關系,現在越來越多的開源框架都使用了Jetty作為內置web輕量級容器,很靈活,同時也可以達到很好的性能要求,在后面工作中對于hessian集成到服務框架中來,也是采用了Hessian+Jetty),并且通過Axis2rampart集成了wss4j,提供了WSSE的增強功能。

          對于認證模式場景需求問題的解決

                 ASF對于Web Service Security這部分只是要求了Signature,而對于Signature需要提供兩種方式,UserNameTokenX.509證書。前者提供給內部的一些應用使用,后者提供給外部ISV使用,兩者主要差別也就是在性能上,后者經過測試,在CPU的使用上,是6-8倍于不帶SignatureWeb Service

                 UserNameToken這種模式很簡單,就很類似于我們平常的用戶認證,用戶名和密碼作為明文或者加密,嵌入在Soap Header中即可,客戶端根據本地保存的受信用戶記錄來交驗是否是合法用戶。

                 X.509就比較特殊一些,所謂的證書,其中包括了公鑰私鑰對(作為簽名和認證使用),證書頒發者的信息(可能是一些CA機構或者是用本地的證書生成工具自己生成),證書擁有者的身份信息,以及一些導入的受信第三方的公鑰證書。當前的證書方式的簽名認證主要有兩種模式,一種是雙方證書都是由第三方CA認證,同時雙方都將對方的CA作為可信的CA,那么請求發起方將會把自己的證書放入到Soap Header中,接受方接受到請求以后,獲取證書,發現是受信的CA,那么就認為請求發起方身份可信,同時在作完整性摘要校對。另一種模式就是雙方的證書可以沒有任何權威的CA作保證,但是雙方首先就需要將附帶自己公鑰的證書發送給對方,對方將這附帶有公鑰的證書分別導入到證書管理庫中(java是某個JKS.netwindows的當前用戶或者本機的證書管理文件)。雙方交互的時候不需要將證書置入Soap Header中,但是需要將證書的引用標示(序列號或者是X.509 SubjectKeyIdentifier)傳遞給服務端,服務端根據標示在本地的證書庫中查找并且校驗,這種模式的好處就是不需要CA的認證(省錢)同時傳遞的時候不需要將證書帶入到Header中,節省了傳遞報文的大小,缺點就是雙方需要互相保存對方的公鑰證書到本地的證書庫中,同時這種模式也為跨平臺帶來了很多問題,后續的互通中就會提到。

                 ASF的證書認證模式中采用了后者,因為要求每個ISV去有一個第三方CA作為授權不是很可行,但是問題就是如果ISV需要導入我們的公鑰證書比較方便,但是我們需要管理那么多ISV的證書,同時又需要動態上傳修改保存證書那么就不能用原有的手動導入的模式,同時由于到時候部署的服務器集群不可能都維護一份本地的證書庫,因此需要用數據庫手段來維護,但是在應用啟動以后再要新增或者修改證書,將會比較麻煩,因此采取了擴展wss4j的策略讀取方式來適應新的應用場景。

          擴展的CrytoProvider類圖

          擴展后的keystore初始化以及signature部分流程圖

                   這部分設計主要是擴展了WSS4JCrytoProvider,擴展后的CrytoProvider重載了獲取X509證書的幾個方法,這里類似于AOP,通過提供ICertsLoaderHandler接口來回調獲取其它存儲內的certs構建 visual keystore,同時在作signature的時候,如果發現ISVcert不存在于當前的visual keystore 中根據CrytoProvider的接口實現,來決定是全部刷新還是部分獲取刷新當前的visual keystore中的certs。這樣就可以達到了動態裝載和刷新certs的要求,同時根據性能要求選擇配置和實現不同的CrytoProvider

          .NetJava的互通

                 Java 的客戶端和服務端Security互通很快就搞定了,只是對于一些應用場景做證書管理的擴展。然而,在經歷了.net客戶端調用Java發布的ws返回數組對象類型的問題以后,又一個大難題擺在了我的面前,ISV support小組和測試部的日報上把.net客戶端無法在wsse的模式下調用Java 發布的 Web Service作為了重點問題,需要我支持,那么當然當仁不讓的接下來盡快搞定了,雖然對.net來說,我算是新手中的新手,不過經過兩天的測試,讓我總結出了.net調試的技巧,那就是截包分析(感覺又回到我前幾年在通信行業干活時的狀況,對于對方協議不了解,又沒有源碼可看,那么就截報文來分析么)。開始挺樂觀的,想著WS-Security微軟也是參與者么,應該會嚴格遵守的,估計一天搞定,結果活活的折騰了兩天,下面所描述的如何互通可能總的看起來應該不是很復雜,不過摸索的過程可真是很費事,google的每一條老外的信息都被我看過了,但是QuestionAnswer少。廢話不多說,進入正題。

                 首先不管是什么客戶端調用什么服務端,都需要先做一件事情,準備key pairs。在Java中證書管理庫可以通過Jdk提供的key tools這個工具生成jks格式的Java Key Store,可以將公鑰導出,或者將公鑰導入,同時可以生成秘鑰對保存在證書中。在.net中可以通過makecert的工具來生成符合Public Key Cryptography Standards #12PKCS#12標準定義,包含了公鑰和私鑰的二進制格式的證書形式,以pfx作為證書文件后綴,同時可以通過mmcwindows的證書存儲區進行管理,導入或者導出證書。其實.netjava的互通關鍵問題就是出在證書格式不同以及獲取證書的算法上。下面就具體的描述一下如何從Java的開發者來做好Java WebService.net互通的工作。

                  更多內容請參見:http://blog.csdn.net/cenwenchu79
          posted @ 2007-11-26 00:43 岑文初 閱讀(2965) | 評論 (0)編輯 收藏

          僅列出標題
          共12頁: First 上一頁 4 5 6 7 8 9 10 11 12 下一頁 
          主站蜘蛛池模板: 武冈市| 洛浦县| 苍南县| 佛山市| 彭山县| 鄂托克前旗| 宜章县| 卢湾区| 江孜县| 布尔津县| 荃湾区| 巴楚县| 称多县| 延边| 柳河县| 湖州市| 焦作市| 仙游县| 芦溪县| 浦江县| 彰化市| 安多县| 富顺县| 五莲县| 涟源市| 周宁县| 衡水市| 巩留县| 田林县| 东至县| 罗甸县| 馆陶县| 加查县| 闵行区| 成都市| 吴忠市| 三门县| 合肥市| 建湖县| 桐城市| 长兴县|