<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    paulwong

    #

    ehcache configuration (cluster env)

     <ehcache>

        
    <!-- Sets the path to the directory where cache .data files are created.

             If the path is a Java System Property it is replaced by
             its value in the running VM.

             The following properties are translated:
             user.home - User's home directory
             user.dir - User's current working directory
             java.io.tmpdir - Default temp file path 
    -->
        
    <diskStore path="java.io.tmpdir/service"/>

        
    <cacheManagerPeerProviderFactory
            
    class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
            properties
    ="peerDiscovery=automatic, multicastGroupAddress=230.0.0.3,
            multicastGroupPort=4446, timeToLive=0"
    />
       
        
    <cacheManagerPeerListenerFactory
            
    class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
            properties
    ="hostName=, port=40003,
            socketTimeoutMillis=12000"
    />
                       
        
    <!--Default Cache configuration. These will applied to caches programmatically created through
            the CacheManager.

            The following attributes are required:

            maxInMemory
              - Sets the maximum number of objects that will be created in memory

            eternal
              - Sets whether elements are eternal. If eternal,  timeouts are ignored and the element is never expired.
            
              overflowToDisk
              - Sets whether elements can overflow to disk when the in-memory cache has reached the maxInMemory limit.

            The following attributes are optional:
            timeToIdleSeconds              - Sets the time to idle for an element before it expires.
                                             i.e. The maximum amount of time between accesses before an element expires
                                             Is only used if the element is not eternal.
                                             Optional attribute. A value of 0 means that an Element can idle for infinity.
                                             The default value is 0.
            timeToLiveSeconds              - Sets the time to live for an element before it expires.
                                             i.e. The maximum time between creation time and when an element expires.
                                             Is only used if the element is not eternal.
                                             Optional attribute. A value of 0 means that and Element can live for infinity.
                                             The default value is 0.
            diskPersistent                 - Whether the disk store persists between restarts of the Virtual Machine.
                                             The default value is false.
            diskExpiryThreadIntervalSeconds- The number of seconds between runs of the disk expiry thread. The default value
                                             is 120 seconds.
            
    -->
       
        
    <defaultCache
            
    maxElementsInMemory="1000000000"
            eternal
    ="true"
            overflowToDisk
    ="false"
            diskPersistent
    ="false"
            memoryStoreEvictionPolicy
    ="LRU">
            
    <cacheEventListenerFactory
                
    class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
                properties
    ="replicateAsynchronously=true, replicatePuts=true replicateUpdates=true replicateUpdatesViaCopy=true replicateRemovals=true asynchronousReplicationIntervalMillis=1000"/>
        
    </defaultCache>
       
        
    <cache name="com.ubs.swidGLK.METHOD_CACHE"
            maxElementsInMemory
    ="10000"
            eternal
    ="true"
            overflowToDisk
    ="false"
            diskPersistent
    ="false"
            memoryStoreEvictionPolicy
    ="LRU">
            
    <cacheEventListenerFactory
                
    class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"/>
        
    </cache>
    </ehcache>

    http://www.oschina.net/question/12_3984

    posted @ 2012-01-23 23:22 paulwong 閱讀(338) | 評論 (0)編輯 收藏

    由12306.cn談?wù)劸W(wǎng)站性能技術(shù)

    12306.cn網(wǎng)站掛了,被全國人民罵了。我這兩天也在思考這個事,我想以這個事來粗略地和大家討論一下網(wǎng)站性能的問題。因為倉促,而且完全基于 本人有限的經(jīng)驗和了解,所以,如果有什么問題還請大家一起討論和指正。(這又是一篇長文,只討論性能問題,不討論那些UI,用戶體驗,或是是否把支付和購 票下單環(huán)節(jié)分開的功能性的東西)

    業(yè)務(wù)

    任何技術(shù)都離不開業(yè)務(wù)需求,所以,要說明性能問題,首先還是想先說說業(yè)務(wù)問題。
    • 其一,有人可能把這個東西和QQ或是網(wǎng)游相比。但我覺得這兩者是不一樣的,網(wǎng)游和QQ在線或是登錄時訪問的更多的是用戶自己的數(shù)據(jù),而訂票系統(tǒng)訪問的是中心的票量數(shù)據(jù),這是不一樣的。不要覺得網(wǎng)游或是QQ能行你就以為這是一樣的。網(wǎng)游和QQ 的后端負(fù)載相對于電子商務(wù)的系統(tǒng)還是簡單。
    • 其二,有人說春節(jié)期間訂火車的這個事好像網(wǎng)站的秒殺活動。的確很相似, 但 是如果你的思考不在表面的話,你會發(fā)現(xiàn)這也有些不一樣?;疖嚻边@個事,還有很多查詢操作,查時間,查座位,查鋪位,一個車次不 行,又查另一個車次,其伴隨著大量的查詢操作,下單的時候需要對數(shù)據(jù)庫操作。而秒殺,直接殺就好了。另外,關(guān)于秒殺,完全可以做成只接受前N個用戶的請求 (完全不操作后端的任何數(shù)據(jù), 僅僅只是對用戶的下單操作log),這種業(yè)務(wù),只要把各個服務(wù)器的時間精確同步了就可以了,無需在當(dāng)時操作任何數(shù)據(jù)庫??梢杂唵螖?shù)夠后,停止秒殺,然后批 量寫數(shù)據(jù)庫?;疖嚻边@個豈止是秒殺那么簡單。能不能買到票得當(dāng)時告訴用戶啊。
    • 其三,有人拿這個系統(tǒng)和奧運會的票務(wù)系統(tǒng)比較。我覺得還是不一樣。雖然奧運會的票務(wù)系統(tǒng)當(dāng)年也一上線就廢了。但是奧運會用的是抽獎的方式,也就是說不存在先來先得的搶的方式,而且,是事后抽獎,事前只需要收信息,事前不需要保證數(shù)據(jù)一致性,沒有鎖,很容易水平擴(kuò)展。
    • 其四,訂票系統(tǒng)應(yīng)該和電子商務(wù)的訂單系統(tǒng)很相似,都是需要對庫存進(jìn) 行:1)占住庫存,2)支付(可選),3)扣除庫存的操作。這個是需要有一致性的檢查的,也就是在并發(fā)時需要對數(shù)據(jù)加鎖的。B2C的電商基本上都會把這個 事干成異步的,也就是說,你下的訂單并不是馬上處理的,而是延時處理的,只有成功處理了,系統(tǒng)才會給你一封確認(rèn)郵件說是訂單成功。我相信有很多朋友都收到 認(rèn)單不成功的郵件。這就是說,數(shù)據(jù)一致性在并發(fā)下是一個瓶頸
    • 其五鐵路的票務(wù)業(yè)務(wù)很變態(tài),其采用的是突然放票,而有的票又遠(yuǎn)遠(yuǎn)不夠 大家分,所以,大家才會有搶票這種有中國特色的業(yè)務(wù)的做法。于是當(dāng)票放出來的時候,就會有幾百萬人甚至上千萬人殺上去,查詢,下單。幾十分鐘內(nèi),一個網(wǎng)站 能接受幾千萬的訪問量,這個是很恐怖的事情。據(jù)說12306的高峰訪問是10億PV,集中在早8點到10點,每秒PV在高峰時上千萬。
    多說幾句:
    • 庫存是B2C的惡夢,庫存管理相當(dāng)?shù)膹?fù)雜。不信,你可以問問所有傳統(tǒng)和電務(wù)零售業(yè)的企業(yè),看看他們管理庫存是多么難的一件事。不然,就不會有那么多人在問凡客的庫存問題了。(你還可以看看《喬布斯傳》,你就知道為什么Tim會接任Apple的CEO了,因為他搞定了蘋果的庫存問題)
    • 對于一個網(wǎng)站來說,瀏覽網(wǎng)頁的高負(fù)載很容易搞定,查詢的負(fù)載有一定的難度去處理,不過還是可以通過緩存查詢結(jié)果來搞定,最難的就是下單的負(fù)載。因為要訪問庫存啊,對于下單,基本上是用異步來搞定的。去年雙11節(jié),淘寶的每小時的訂單數(shù)大約在60萬左右,京東一天也才能支持40萬(居然比12306還差),亞馬遜5年前一小時可支持70萬訂單量??梢姡掠唵蔚牟僮鞑]有我們相像的那么性能高。
    • 淘寶要比B2C的網(wǎng)站要簡單得多,因為沒有倉庫,所以,不存在像B2C這樣有N個倉庫對同一商品庫存更新和 查 詢的操作。下單的時候,B2C的 網(wǎng)站要去找一個倉庫,又要離用戶近,又要有庫存,這需要很多計算。試想,你在北京買了一本書,北京的倉庫沒貨了,就要從周邊的倉庫調(diào),那就要去看看沈陽或 是西安的倉庫有沒有貨,如果沒有,又得看看江蘇的倉庫,等等。淘寶的就沒有那么多事了,每個商戶有自己的庫存,庫存分到商戶頭上了,反而有利于性能。
    • 數(shù)據(jù)一致性才是真正的性能瓶頸。有 人說nginx可以搞定每秒10萬的靜態(tài)請求,我不懷疑。但這只是靜態(tài)請求,理論值,只要帶寬、I/O夠強(qiáng),服務(wù)器計算能力夠,并支持的并發(fā)連接數(shù)頂?shù)米?10萬TCP鏈接的建立 的話,那沒有問題。但在數(shù)據(jù)一致性面前,這10萬就完完全全成了一個可望不可及的理論值了。
    我說那么多,我只是想從業(yè)務(wù)上告訴大家,我們需要從業(yè)務(wù)上真正了解春運鐵路訂票這樣業(yè)務(wù)的變態(tài)之處。

    前端性能優(yōu)化技術(shù)

    要解決性能的問題,有很多種常用的方法,我在下面列舉一下,我相信12306這個網(wǎng)站使用下面的這些技術(shù)會讓其性能有質(zhì)的飛躍。
    一、前端負(fù)載均衡
    通過DNS的負(fù)載均衡器(一般在路由器上根據(jù)路由的負(fù)載重定向)可以把用戶的訪問均勻地分散在多個Web服務(wù)器上。這樣可以減少Web服務(wù)器的請求 負(fù)載。因為http的請求都是短作業(yè),所以,可以通過很簡單的負(fù)載均衡器來完成這一功能。最好是有CDN網(wǎng)絡(luò)讓用戶連接與其最近的服務(wù)器(CDN通常伴隨 著分布式存儲)。(關(guān)于負(fù)載均衡更為詳細(xì)的說明見“后端的負(fù)載均衡”)
    二、減少前端鏈接數(shù)
    我看了一下12306.cn,打開主頁需要建60多個HTTP連接,車票預(yù)訂頁面則有70多個HTTP請求,現(xiàn)在的瀏覽器都是并發(fā)請求的。所以,只 要有100萬個用戶,就會有6000萬個鏈接,太多了。一個登錄查詢頁面就好了。把js打成一個文件,把css也打成一個文件,把圖標(biāo)也打成一個文件,用 css分塊展示。把鏈接數(shù)減到最低。
    三、減少網(wǎng)頁大小增加帶寬
    這個世界不是哪個公司都敢做圖片服務(wù)的,因為圖片太耗帶寬了?,F(xiàn)在寬帶時代很難有人能體會到當(dāng)撥號時代做個圖頁都不敢用圖片的情形(現(xiàn)在在手機(jī)端瀏 覽也是這個情形)。我查看了一下12306首頁的需要下載的總文件大小大約在900KB左右,如果你訪問過了,瀏覽器會幫你緩存很多,只需下載10K左右 的文件。但是我們可以想像一個極端一點的案例,1百萬用戶同時訪問,且都是第一次訪問,每人下載量需要1M,如果需要在120秒內(nèi)返回,那么就需要,1M * 1M /120 * 8 = 66Gbps的帶寬。很驚人吧。所以,我估計在當(dāng)天,12306的阻塞基本上應(yīng)該是網(wǎng)絡(luò)帶寬,所以,你可能看到的是沒有響應(yīng)。后面隨著瀏覽器的緩存幫助 12306減少很多帶寬占用,于是負(fù)載一下就到了后端,后端的數(shù)據(jù)處理瓶頸一下就出來。于是你會看到很多http 500之類的錯誤。這說明服務(wù)器垮了。
    四、前端頁面靜態(tài)化
    靜態(tài)化一些不覺變的頁面和數(shù)據(jù),并gzip一下。還有一個并態(tài)的方法是把這些靜態(tài)頁面放在/dev/shm下,這個目錄就是內(nèi)存,直接從內(nèi)存中把文件讀出來返回,這樣可以減少昂貴的磁盤I/O。
    五、優(yōu)化查詢
    很多人查詢都是在查一樣的,完全可以用反向代理合并這些并發(fā)的相同的查詢。這樣的技術(shù)主要用查詢結(jié)果緩存來實現(xiàn),第一次查詢走數(shù)據(jù)庫獲得數(shù)據(jù),并把 數(shù)據(jù)放到緩存,后面的查詢統(tǒng)統(tǒng)直接訪問高速緩存。為每個查詢做Hash,使用NoSQL的技術(shù)可以完成這個優(yōu)化。(這個技術(shù)也可以用做靜態(tài)頁面) 對于火車票量的查詢,個人覺得不要顯示數(shù)字,就顯示一個“有”或“無”就好了,這樣可以大大簡化系統(tǒng)復(fù)雜度,并提升性能。
    六、緩存的問題
    緩存可以用來緩存動態(tài)頁面,也可以用來緩存查詢的數(shù)據(jù)。緩存通常有那么幾個問題: 1)緩存的更新。也叫緩存和數(shù)據(jù)庫的同步。有這么幾種方法,一是緩存time out,讓緩存失效,重查,二是,由后端通知更新,一量后端發(fā)生變化,通知前端更新。前者實現(xiàn)起來比較簡單,但實時性不高,后者實現(xiàn)起來比較復(fù)雜 ,但實時性高。 2)緩存的換頁。內(nèi)存可能不夠,所以,需要把一些不活躍的數(shù)據(jù)換出內(nèi)存,這個和操作系統(tǒng)的內(nèi)存換頁和交換內(nèi)存很相似。FIFO、LRU、LFU都是比較經(jīng)典的換頁算法。相關(guān)內(nèi)容參看Wikipeida的緩存算法。 3)緩存的重建和持久化。緩存在內(nèi)存,系統(tǒng)總要維護(hù),所以,緩存就會丟失,如果緩存沒了,就需要重建,如果數(shù)據(jù)量很大,緩存重建的過程會很慢,這會影響生產(chǎn)環(huán)境,所以,緩存的持久化也是需要考慮的。 諸多強(qiáng)大的NoSQL都很好支持了上述三大緩存的問題。

    后端性能優(yōu)化技術(shù)

    前面討論了前端性能的優(yōu)化技術(shù),于是前端可能就不是瓶頸問題了。那么性能問題就會到后端數(shù)據(jù)上來了。下面說幾個后端常見的性能優(yōu)化技術(shù)。
    一、數(shù)據(jù)冗余
    關(guān)于數(shù)據(jù)冗余,也就是說,把我們的數(shù)據(jù)庫的數(shù)據(jù)冗余處理,也就是減少表連接這樣的開銷比較大的操作,但這樣會犧牲數(shù)據(jù)的一致性。風(fēng)險比較大。很多人 把NoSQL用做數(shù)據(jù),快是快了,因為數(shù)據(jù)冗余了,但這對數(shù)據(jù)一致性有大的風(fēng)險。這需要根據(jù)不同的業(yè)務(wù)進(jìn)行分析和處理。(注意:用關(guān)系型數(shù)據(jù)庫很容易移植 到NoSQL上,但是反過來從NoSQL到關(guān)系型就難了)
    二、數(shù)據(jù)鏡像
    幾乎所有主流的數(shù)據(jù)庫都支持鏡像,也就是replication。數(shù)據(jù)庫的鏡像帶來的好處就是可以做負(fù)載均衡。把一臺數(shù)據(jù)庫的負(fù)載均分到多臺上,同時又保證了數(shù)據(jù)一致性(Oracle的SCN)。最重要的是,這樣還可以有高可用性,一臺廢了,還有另一臺在服務(wù)。 數(shù)據(jù)鏡像的數(shù)據(jù)一致性可能是個問題,所以我們要吧在單條數(shù)據(jù)上進(jìn)行數(shù)據(jù)分區(qū),也就是說,把一個暢銷商品的庫存均分到不同的服務(wù)器上,如,一個暢銷商品有1萬的庫存,我們可以設(shè)置10臺服務(wù)器,每臺服務(wù)器上有100個庫存,這就好像B2C的倉庫一樣。
    三、數(shù)據(jù)分區(qū)
    數(shù)據(jù)鏡像不能解決的一個問題就是數(shù)據(jù)表里的記錄太多,導(dǎo)致數(shù)據(jù)庫操作太慢。所以,把數(shù)據(jù)分區(qū)。數(shù)據(jù)分區(qū)有很多種做法,一般來說有下面這幾種:

    1)把數(shù)據(jù)把某種邏輯來分類。比如火車票的訂票系統(tǒng)可以按各鐵路局來分,可按各種車型分,可以按始發(fā)站分,可以按目的地分……,反正就是把一張表拆成多張有一樣的字段但是不同種類的表,這樣,這些表就可以存在不同的機(jī)器上以達(dá)到分擔(dān)負(fù)載的目的。

    2)把數(shù)據(jù)按字段分,也就是堅著分表。比如把一些不經(jīng)常改的數(shù)據(jù)放在一個表里,經(jīng)常改的數(shù)據(jù)放在另一個表里。把一張表變成1對1的關(guān)系,這樣,你可 以減少表的字段個數(shù),同樣可以提升一定的性能。另外,字段多會造成一條記錄的存儲會被放到不同的頁表里,這對于讀寫性能都有問題。

    3)平均分表。因為第一種方法是并不一定平均分均,可能某個種類的數(shù)據(jù)還是很多。所以,也有采用平均分配的方式,通過主鍵ID的范圍來分表。

    4)同一數(shù)據(jù)分區(qū)。這個在上面數(shù)據(jù)鏡像提過。也就是把同一商品的庫存值分到不同的服務(wù)器上,比如有10000個庫存,可以分到10臺服務(wù)器上,一臺上有1000個庫存。然后負(fù)載均衡。 這三種分區(qū)都有好有壞。最常用的還是第一種。數(shù)據(jù)一量分區(qū),你就需要有一個或是多個調(diào)度來讓你的前端程序知道去哪里找數(shù)據(jù)。把火車票的數(shù)據(jù)分區(qū),并放在各個省市,會對12306這個系統(tǒng)有非常有意義的質(zhì)的性能的提高
    四、后端系統(tǒng)負(fù)載均衡
    前面說了數(shù)據(jù)分區(qū),數(shù)據(jù)分區(qū)可以在一定程度上減輕負(fù)載,但是無法減輕熱銷商品的負(fù)載,對于火車票來說,可以認(rèn)為是大城市的某些主干線上的車票。這就 需要使用數(shù)據(jù)鏡像來減輕負(fù)載。使用數(shù)據(jù)鏡像,你必然要使用負(fù)載均衡,在后端,我們可能很難使用像路由器上的負(fù)載均衡器,因為那是均衡流量的,因為流量并不 代表服務(wù)器的繁忙程序。因此,我們需要一個任務(wù)分配系統(tǒng),其還能監(jiān)控各個服務(wù)器的負(fù)載情況。 任務(wù)分配服務(wù)器有一些難點:
    • 負(fù)載情況比較復(fù)雜。什么叫忙?是CPU高?還是磁盤I/O高?還是內(nèi)存使用高?還是并發(fā)高?你可能需要全部都要考慮。這些信息要發(fā)送給那個任務(wù)分配器上,由任務(wù)分配器挑選一臺負(fù)載最輕的服務(wù)器來處理。
    • 任務(wù)分配服務(wù)器上需要對任務(wù)隊列,不能丟任務(wù)啊,所以還需要持久化。并且可以以批量的方式把任務(wù)分配給計算服務(wù)器。
    • 任務(wù)分配服務(wù)器死了怎么辦?這里需要一些如Live-Standby或是failover等高可用性的技術(shù)。我們還需要注意那些持久化了的任務(wù)的隊列如果轉(zhuǎn)移到別的服務(wù)器上的問題。
    我看到有很多系統(tǒng)都用靜態(tài)的方式來分配,有的用hash,有的就簡單地輪流分析。這些都不夠好,一個是不能完美地負(fù)載均衡,另一個靜態(tài)的方法的致命缺陷是,如果有一臺計算服務(wù)器死機(jī)了,或是我們需要加入新的服務(wù)器,對于我們的分配器來說,都需要知道。 還有一種方法是使用搶占式的方式進(jìn)行負(fù)載均衡,由下游的計算服務(wù)器去任務(wù)服務(wù)器上拿任務(wù)。讓這些計算服務(wù)器自己決定自己是否要任務(wù)。這樣的好處是可 以簡化系統(tǒng)的復(fù)雜度,而且還可以任意實時地減少或增加計算服務(wù)器。但是唯一不好的就是,如果有一些任務(wù)只能在某種服務(wù)器上處理,這可能會引入一些復(fù)雜度。 不過總體來說,這種方法可能是比較好的負(fù)載均衡。
    五、異步、 throttle 和 批量處理
    異步、throttle(節(jié)流閥) 和批量處理都需要對并發(fā)請求數(shù)做隊列處理的。
    • 異步在業(yè)務(wù)上一般來說就是收集請求,然后延時處理。在技術(shù)上就是可以把各個處理程序做成并行的,也就可以水平擴(kuò)展了。但是異步的技術(shù)問題大概有 這 些,a)被調(diào)用方的結(jié)果返回,會涉及進(jìn)程線程間通信的問題。b)如果程序需要回滾,回滾會有點復(fù)雜。c)異步通常都會伴隨多線程多進(jìn)程,并發(fā)的控制也相對 麻煩一些。d)很多異步系統(tǒng)都用消息機(jī)制,消息的丟失和亂序也會是比較復(fù)雜的問題。
    • throttle 技術(shù)其實并不提升性能,這個技術(shù)主要是防止系統(tǒng)被超過自己不能處理的流量給搞垮了,這其實是個保護(hù)機(jī)制。使用throttle技術(shù)一般來說是對于一些自己無法控制的系統(tǒng),比如,和你網(wǎng)站對接的銀行系統(tǒng)。
    • 批量處理的技術(shù),是把一堆基本相同的請求批量處理。比如,大家同時購買同一個商品,沒有必要你買一個我就寫一次數(shù)據(jù)庫,完全可以收集到一定數(shù)量 的 請求,一次操作。這個技術(shù)可以用作很多方面。比如節(jié)省網(wǎng)絡(luò)帶寬,我們都知道網(wǎng)絡(luò)上的MTU(最大傳輸單元),以態(tài)網(wǎng)是1500字節(jié),光纖可以達(dá)到4000 多個字節(jié),如果你的一個網(wǎng)絡(luò)包沒有放滿這個MTU,那就是在浪費網(wǎng)絡(luò)帶寬,因為網(wǎng)卡的驅(qū)動程序只有一塊一塊地讀效率才會高。因此,網(wǎng)絡(luò)發(fā)包時,我們需要收 集到足夠多的信息后再做網(wǎng)絡(luò)I/O,這也是一種批量處理的方式。批量處理的敵人是流量低,所以,批量處理的系統(tǒng)一般都會設(shè)置上兩個閥值,一個是作業(yè)量,另 一個是timeout,只要有一個條件滿足,就會開始提交處理。
    所以,只要是異步,一般都會有throttle機(jī)制,一般都會有隊列來排隊,有隊列,就會有持久化,而系統(tǒng)一般都會使用批量的方式來處理云風(fēng)同學(xué)設(shè)計的“排隊系統(tǒng)” 就是這個技術(shù)。這和電子商務(wù)的訂單系統(tǒng)很相似,就是說,我的系統(tǒng)收到了你的購票下單請求,但是我還沒有真正處理,我的系統(tǒng)會跟據(jù)我自己的處理能力來throttle住這些大量的請求,并一點一點地處理。一旦處理完成,我就可以發(fā)郵件或短信告訴用戶你來可以真正購票了。

    在這里,我想通過業(yè)務(wù)和用戶需求方面討論一下云風(fēng)同學(xué)的這個排隊系統(tǒng),因為其從技術(shù)上看似解決了這個問題,但是從業(yè)務(wù)和用戶需求上來說可能還是有一些值得我們?nèi)ド钊胨伎嫉牡胤剑?

    1)隊列的DoS攻擊。首先,我們思考一下,這個隊 是個單純地排隊的嗎?這樣做還不夠好,因為這樣我們不能杜絕黃牛,而且單純的ticket_id很容易發(fā)生DoS攻擊,比如,我發(fā)起N個 ticket_id,進(jìn)入購票流程后,我不買,我就耗你半個小時,很容易我就可以讓想買票的人幾天都買不到票。有人說,用戶應(yīng)該要用身份證來排隊, 這樣在購買里就必需要用這個身份證來買,但這也還不能杜絕黃牛排隊或是號販子。因為他們可以注冊N個帳號來排隊,但就是不買。黃牛這些人這個時候只需要干 一個事,把網(wǎng)站搞得正常不能訪問,讓用戶只能通過他們來買。

    2)對列的一致性?對這個隊列的操作是不是需要鎖?只要有鎖,性能一定上不去。試想,100萬個人同時要求你來分配位置號,這個隊列將會成為性能瓶頸。你一定沒有數(shù)據(jù)庫實現(xiàn)得性能好,所以,可能比現(xiàn)在還差

    3)隊列的等待時間。購票時間半小時夠不夠?多不 多?要是那時用戶正好不能上網(wǎng)呢?如果時間短了,用戶也會抱怨,如果時間長了,后面在排隊的那些人也會抱怨。這個方法可能在實際操作上會有很多問題。另 外,半個小時太長了,這完全不現(xiàn)實,我們用15分鐘來舉例:有1千萬用戶,每一個時刻只能放進(jìn)去1萬個,這1萬個用戶需要15分鐘完成所有操作,那么,這 1千萬用戶全部處理完,需要1000*15m = 250小時,10天半,火車早開了。(我并亂說,根據(jù)鐵道部專家的說明:這幾天,平均一天下單100萬,所以,處理1000萬的用戶需要十天。這個計算可能有點簡單了,我只是想說,在這樣低負(fù)載的系統(tǒng)下用排隊可能都不能解決問題

    4)隊列的分分式。這個排隊系統(tǒng)只有一個隊列好嗎? 還不足夠好。因為,如果你放進(jìn)去的可以購票的人如果在買同一個車次的同樣的類型的票(比如某動車臥鋪),還是等于在搶票,也就是說系統(tǒng)的負(fù)載還是會有可能 集中到其中某臺服務(wù)器上。因此,最好的方法是根據(jù)用戶的需求——提供出發(fā)地和目的地,來對用戶進(jìn)行排隊。而這樣一來,隊列也就可以是多個,只要是多個隊 列,就可以水平擴(kuò)展了。 我覺得完全可以向網(wǎng)上購物學(xué)習(xí)。在排隊(下單)的時候,收集好用戶的信息和想要買的票,并允許用戶設(shè)置購票的優(yōu)先級,比如,A車次臥鋪買 不到就買 B車次的臥鋪,如果還買不到就買硬座等等,然后用戶把所需的錢先充值好,接下來就是系統(tǒng)完全自動地異步處理訂單。成功不成功都發(fā)短信或郵件通知用戶。這 樣,系統(tǒng)不僅可以省去那半個小時的用戶交互時間,自動化加快處理,還可以合并相同購票請求的人,進(jìn)行批處理(減少數(shù)據(jù)庫的操作次數(shù))。這種方法最妙的事是 可以知道這些排隊用戶的需求,不但可以優(yōu)化用戶的隊列,把用戶分布到不同的隊列,還可以像亞馬遜的心愿單一樣,讓鐵道部做車次統(tǒng)籌安排和調(diào)整(最后,排隊 系統(tǒng)(下單系統(tǒng))還是要保存在數(shù)據(jù)庫里的或做持久化,不能只放在內(nèi)存中,不然機(jī)器一down,就等著被罵吧)。

    小結(jié)

    寫了那么多,我小結(jié)一下:
    0)無論你怎么設(shè)計,你的系統(tǒng)一定要能容易地水平擴(kuò)展。也就是說,你的整個數(shù)據(jù)流中,所有的環(huán)節(jié)都要能夠水平擴(kuò)展。這樣,當(dāng)你的系統(tǒng)有性能問題時,“加3倍的服務(wù)器”才不會被人譏笑。

    1)上述的技術(shù)不是一朝一夕能搞定的,沒有長期的積累,基本無望。

    2)集中式的賣票很難搞定,使用上述的技術(shù)可以讓訂票系統(tǒng)能有幾佰倍的性能提升。而在各個省市建分站,分開賣票,是能讓現(xiàn)有系統(tǒng)性能有質(zhì)的提升的最好方法。

    3)春運前夕搶票且票量供遠(yuǎn)小于求這種業(yè)務(wù)模式是相當(dāng)變態(tài)的,讓幾千萬甚至上億的人在某個早晨的8點鐘同時登錄同時搶票的這種業(yè)務(wù)模式是變態(tài)中的變態(tài)。業(yè)務(wù)形態(tài)的變態(tài)決定了無論他們怎么辦干一定會被罵。

    4)為了那么一兩個星期而搞那么大的系統(tǒng),而其它時間都在閑著,也就是鐵路才干得出來這樣的事了。

    posted @ 2012-01-17 15:23 paulwong 閱讀(679) | 評論 (1)編輯 收藏

    鐵路的售票系統(tǒng)來說明分庫分表對架構(gòu)的影響

    一、問題:鐵路的售票系統(tǒng)的數(shù)據(jù)量是海量嗎?

    不是。因為數(shù)據(jù)量不大,真不大。

    每一個車次與車次間是獨立的,每車次不超過2000張票,一天發(fā)車不超過50萬車次;
    以預(yù)售期15天來講,15*0.1億張不超過1.5億筆的熱線數(shù)據(jù),稱不上海量數(shù)據(jù)的。
    再加上可以按線路分庫,更是不到千萬級的單表容量。已經(jīng)發(fā)車完成的進(jìn)入歸檔分析。
    即數(shù)據(jù)庫按路線使用不同的服務(wù)器,不同的車次放在不同的表中。并發(fā)量鎖真不大。

    當(dāng)然,如果不分庫分表,再加上不歸檔處理,鐵路的售票系統(tǒng)的數(shù)據(jù)量看起來是海量的;
    關(guān)鍵是這海量的數(shù)據(jù)沒有意義。


    二、如何分庫分表?

    2.1 分庫,考慮數(shù)據(jù)間沒有直接關(guān)系和服務(wù)器如何部署

    鐵路的售票系統(tǒng)為例來說,按路線分庫,再按車次分表是合理的。
    設(shè)路線有1萬條,按每1000條需要兩臺服務(wù)器(一臺熱機(jī)沉余),不到20臺服務(wù)器
    如果使用SAN存儲,則使用SAN作為存儲,本機(jī)作為熱機(jī)沉余,只需要10臺。
    當(dāng)然使用mySQL這種經(jīng)濟(jì)型數(shù)據(jù)庫,服務(wù)器需要更多來防災(zāi);
    即可以采用雙寫或多寫的方式來保證數(shù)據(jù)的絕對安全。

    2.2分表,考慮數(shù)據(jù)間不存在重疊,即數(shù)據(jù)滿足二分原則

    鐵路的售票系統(tǒng)的任意兩個車次是沒有關(guān)系的,所以可以分表。
    電信的某個用戶的通話和其它用戶的通話記錄,也是沒有關(guān)系,所以可以分表處理
    (實際上電信的系統(tǒng),分庫分表后也是不大的,難在后臺的計費、結(jié)算等規(guī)則)



    三、數(shù)據(jù)庫訪問接口



    1. 元數(shù)據(jù):如何識別到當(dāng)前要處理的數(shù)量在哪張表?

    鐵路的售票系統(tǒng)會有一個車次管理系統(tǒng),例2012年2月12日 D3206 車次,
    按預(yù)先設(shè)計的在哪臺服務(wù)器的哪個庫,建哪個表。

    2.建立元數(shù)據(jù)的規(guī)則:即具體如何分庫分表的規(guī)則

    這個就是數(shù)據(jù)庫的訪問接口。

    3.數(shù)據(jù)庫訪問接口的透明程度

    即哪個層知道哪些元數(shù)據(jù)信息。
    例,是否讓窗口售票的客戶端來解析元數(shù)據(jù)的規(guī)則然后緩存,還是通過中間件來解析緩存的

    具體各層使用怎樣透明程度,和業(yè)務(wù)性質(zhì)、節(jié)點和數(shù)據(jù)中心的拓?fù)涞扔嘘P(guān)。



    四、歷史數(shù)據(jù)歸檔與分析

    1.使用分庫分表后,數(shù)據(jù)需要歸檔,分析處理的程序變得復(fù)雜,但使聯(lián)機(jī)交易變得簡單
    2.分析:要注意是針對熱線數(shù)據(jù)分析、歸檔數(shù)據(jù)分析、混合分析有關(guān),
    通過分庫分表和歸檔,更方便使用分布式的統(tǒng)計方案。

    具體可以參考,淘寶的開放平臺架構(gòu)師寫的文章:

    結(jié)論:分庫分表跟不分庫分表,整個架構(gòu)是完全不一樣的。

    像鐵票的售票系統(tǒng)、淘寶、電信、銀行等,絕對要采用分庫分表的數(shù)據(jù)存儲方案,

    來解決數(shù)據(jù)量的增長而不影響性能的問題。

    像淘寶等互聯(lián)網(wǎng)應(yīng)用還要解決帶寬即CDN問題。

    posted @ 2012-01-17 13:24 paulwong 閱讀(624) | 評論 (0)編輯 收藏

    JBoss下DataSource加密(下)

    數(shù)據(jù)源文件:my-oracle-ds.xml

    <datasources>
        
    <local-tx-datasource>
            
    <jndi-name>jdbc/my-local</jndi-name>
            <connection-url>
                jdbc:oracle:thin:@10.5.7.30:1521:orcl
            
    </connection-url>
            
    <driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
            <security-domain>EncryptedOracleDbRealm</security-domain>
            
    <exception-sorter-class-name>
                org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter
            
    </exception-sorter-class-name>
            
    <metadata>
                
    <type-mapping>Oracle10g</type-mapping>
            
    </metadata>
            
    <depends>
                jboss.security:service=JaasSecurityDomain,domain=ServerMasterPassword
            
    </depends>
        
    </local-tx-datasource>



        
    <mbean code="org.jboss.security.plugins.JaasSecurityDomain"
            name
    ="jboss.security:service=JaasSecurityDomain,domain=ServerMasterPassword">
            
    <constructor>
                
    <arg type="java.lang.String" value="ServerMasterPassword"></arg>
            
    </constructor>
            
    <!-- The opaque master password file used to decrypt the encrypted
                database password key 
    -->
            
    <attribute name="KeyStorePass">
                {CLASS}org.jboss.security.plugins.FilePassword:${jboss.server.home.dir}/conf/server.password
            
    </attribute>
            
    <attribute name="Salt">abcdefgh</attribute>
            
    <attribute name="IterationCount">13</attribute>
        
    </mbean>

    </datasources>

    在jboss4.3/jboss-as/server/default/conf/login-config.xml中增加節(jié)點:

    <application-policy name="EncryptedOracleDbRealm">
        
    <authentication>
            
    <login-module
                
    code="org.jboss.resource.security.JaasSecurityDomainIdentityLoginModule"
                flag
    ="required">
                
    <module-option name="username">username</module-option>
                
    <module-option name="password">
                    3wW33nIpavHK4pd3qoNTbA
                
    </module-option>
                
    <module-option name="managedConnectionFactoryName">
                    jboss.jca:service=LocalTxCM,name=jdbc/my-local
                
    </module-option>
                
    <module-option name="jaasSecurityDomain">
                    jboss.security:service=JaasSecurityDomain,domain=ServerMasterPassword
                
    </module-option>
            
    </login-module>
        
    </authentication>
    </application-policy>

    以上的password由下面命令得出:

    E:\JBOSS\jboss4.3\jboss-as\server\default\lib>java -cp jbosssx.jar
    org.jboss.security.plugins.PBEUtils abcdefgh 
    13 master mypassowrd
    Encoded password:  2mqrIBSpp8JVWFAqCBklhf

    生成server.password文件:

    E:\JBOSS\jboss4.3\jboss-as\server\default\lib>java -cp jbosssx.jar
    org.jboss.security.plugins.FilePassword abcdefgh 
    13 master server.password

    產(chǎn)生后拷貝到:${jboss.server.home.dir}/conf中。

    posted @ 2012-01-16 18:58 paulwong 閱讀(945) | 評論 (0)編輯 收藏

    Java生成RSA非對稱型加密的公鑰和私鑰(利用java API)

    非對稱型加密非常適合多個客戶端和服務(wù)器之間的秘密通訊,客戶端使用同一個公鑰將明文加密,而這個公鑰不能逆向的解密,密文發(fā)送到服務(wù)器后有服務(wù)器端用私鑰解密,這樣就做到了明文的加密傳送。

    非對稱型加密也有它先天的缺點,加密、解密速度慢制約了它的發(fā)揮,如果你有大量的文字需要加密傳送,建議你通過非對稱型加密來把對稱型‘密鑰’分發(fā)到客戶端,及時更新對稱型‘密鑰’。

    package com.paul.module.common.util;

    import sun.misc.BASE64Decoder;
    import sun.misc.BASE64Encoder;

    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.security.Key;
    import java.security.KeyPair;
    import java.security.KeyPairGenerator;

    import javax.crypto.Cipher;

    public class RSASecurityUtil2 {
        
    /** 指定加密算法為RSA */
        
    private static final String ALGORITHM = "RSA";
        
    /** 密鑰長度,用來初始化 */
        
    private static final int KEYSIZE = 1024;
        
    /** 指定公鑰存放文件 */
        
    private static String PUBLIC_KEY_FILE = "PublicKey";
        
    /** 指定私鑰存放文件 */
        
    private static String PRIVATE_KEY_FILE = "PrivateKey";

        
    /**
         * 生成密鑰對
         * 
    @throws Exception
         
    */
        
    private static void generateKeyPair() throws Exception {
            
    //        /** RSA算法要求有一個可信任的隨機(jī)數(shù)源 */
    //        SecureRandom secureRandom = new SecureRandom();
            
            
    /** 為RSA算法創(chuàng)建一個KeyPairGenerator對象 */
            KeyPairGenerator keyPairGenerator 
    = KeyPairGenerator.getInstance(ALGORITHM);
            
            
    /** 利用上面的隨機(jī)數(shù)據(jù)源初始化這個KeyPairGenerator對象 */
    //        keyPairGenerator.initialize(KEYSIZE, secureRandom);
            keyPairGenerator.initialize(KEYSIZE);
            
            
    /** 生成密匙對 */
            KeyPair keyPair 
    = keyPairGenerator.generateKeyPair();
            
            
    /** 得到公鑰 */
            Key publicKey 
    = keyPair.getPublic();
            
            
    /** 得到私鑰 */
            Key privateKey 
    = keyPair.getPrivate();
            
            ObjectOutputStream oos1 
    = null;
            ObjectOutputStream oos2 
    = null;
            
    try {
                
    /** 用對象流將生成的密鑰寫入文件 */
                oos1 
    = new ObjectOutputStream(new FileOutputStream(PUBLIC_KEY_FILE));
                oos2 
    = new ObjectOutputStream(new FileOutputStream(PRIVATE_KEY_FILE));
                oos1.writeObject(publicKey);
                oos2.writeObject(privateKey);
            } 
    catch (Exception e) {
                
    throw e;
            }
            
    finally{
                
    /** 清空緩存,關(guān)閉文件輸出流 */
                oos1.close();
                oos2.close();
            }
        }

        
    /**
         * 加密方法
         * 
    @param source 源數(shù)據(jù)
         * 
    @return
         * 
    @throws Exception
         
    */
        
    public static String encrypt(String source) throws Exception {
            generateKeyPair();
            Key publicKey;
            ObjectInputStream ois 
    = null;
            
    try {
                
    /** 將文件中的公鑰對象讀出 */
                ois 
    = new ObjectInputStream(new FileInputStream(
                        PUBLIC_KEY_FILE));
                publicKey 
    = (Key) ois.readObject();
            } 
    catch (Exception e) {
                
    throw e;
            }
            
    finally{
                ois.close();
            }
            
            
    /** 得到Cipher對象來實現(xiàn)對源數(shù)據(jù)的RSA加密 */
            Cipher cipher 
    = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            
    byte[] b = source.getBytes();
            
    /** 執(zhí)行加密操作 */
            
    byte[] b1 = cipher.doFinal(b);
            BASE64Encoder encoder 
    = new BASE64Encoder();
            
    return encoder.encode(b1);
        }

        
    /**
         * 解密算法
         * 
    @param cryptograph    密文
         * 
    @return
         * 
    @throws Exception
         
    */
        
    public static String decrypt(String cryptograph) throws Exception {
            Key privateKey;
            ObjectInputStream ois 
    = null;
            
    try {
                
    /** 將文件中的私鑰對象讀出 */
                ois 
    = new ObjectInputStream(new FileInputStream(
                        PRIVATE_KEY_FILE));
                privateKey 
    = (Key) ois.readObject();
            } 
    catch (Exception e) {
                
    throw e;
            }
            
    finally{
                ois.close();
            }
            
            
    /** 得到Cipher對象對已用公鑰加密的數(shù)據(jù)進(jìn)行RSA解密 */
            Cipher cipher 
    = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            BASE64Decoder decoder 
    = new BASE64Decoder();
            
    byte[] b1 = decoder.decodeBuffer(cryptograph);
            
            
    /** 執(zhí)行解密操作 */
            
    byte[] b = cipher.doFinal(b1);
            
    return new String(b);
        }

        
    public static void main(String[] args) throws Exception {
            String source 
    = "恭喜發(fā)財!";// 要加密的字符串
            System.out.println("準(zhǔn)備用公鑰加密的字符串為:" + source);
            
            String cryptograph 
    = encrypt(source);// 生成的密文
            System.out.print("用公鑰加密后的結(jié)果為:" + cryptograph);
            System.out.println();

            String target 
    = decrypt(cryptograph);// 解密密文
            System.out.println("用私鑰解密后的字符串為:" + target);
            System.out.println();
        }
    }


    http://blog.sina.com.cn/s/blog_43b03c72010080t2.html
    http://topic.csdn.net/t/20040510/14/3049788.html
    http://yuanliyin.iteye.com/blog/853334

    posted @ 2012-01-16 00:37 paulwong 閱讀(15003) | 評論 (1)編輯 收藏

    《1億在線背后的技術(shù)挑戰(zhàn)》視頻放出

    2011年10月31日,騰訊即通平臺部高級總監(jiān)莊泗華在北京航空航天大學(xué)的演講《1億在線背后的技術(shù)挑戰(zhàn)》讓許多聽眾變成了莊老師的粉絲。

    騰訊大講堂放出莊泗華的演講視頻,轉(zhuǎn)載請注明來自騰訊大講堂

    演講PPT下載:http://djt.open.qq.com/portal.php?mod=view&aid=19

    視頻:1.4億在線背后的故事

    第1部分:從十萬級到百萬級在線


    第2部分:千萬級在線


    第3部分:億級在線


    第4部分:總結(jié)


    posted @ 2012-01-15 21:40 paulwong 閱讀(387) | 評論 (0)編輯 收藏

    我們應(yīng)當(dāng)怎樣做需求分析(轉(zhuǎn))

    又到新年了,日歷又要從2011年翻到2012年了,這使我有太多的感慨,進(jìn)而勾起了對太大往事的回憶。過去的10年,毫無疑問是中國軟件業(yè)發(fā)展最快的10年。當(dāng)我們剛剛畢業(yè)的時候,還在使用VB、PB開發(fā)一些簡單的數(shù)據(jù)庫應(yīng)用,而現(xiàn)在卻幾乎看不到它們的蹤影,換來的是諸如J2EE和.NET這樣的大型web應(yīng)用。而這期間,RUP、XP、敏捷開發(fā)、持續(xù)集成••••••一個接一個的新概念層出不窮,令人眼花繚亂?,F(xiàn)在想來,恍如隔世。

    但更令我印象深刻而難以忘懷的,是我親自經(jīng)歷的、親眼目睹的、道聽途說的一個又一個的軟件項目,它們有的獲得了成功,但更多的是令人沮喪的失敗。套用一下大文豪托爾斯泰體:幸福的家庭都是一樣的,不幸的家庭卻各有各的不幸;幸福的軟件項目都是一樣的,不幸的軟件項目卻各有各的不幸;或者說,成功的軟件項目都是一樣的,失敗的項目卻各有各的問題。我常常在想,我們的項目開發(fā)到底怎么了,進(jìn)而把它們一個一個的剝開來深入分析,竟然觸目驚心。它們有的是需求的問題,有的是客戶關(guān)系的問題,還有設(shè)計的問題、技術(shù)的問題、時間管理的問題、人員培養(yǎng)的問題••••••但歸根到底更多的還是需求的問題。需求分析既是一份體力活兒,更是一份技術(shù)活兒,它既是人際交往的藝術(shù),又是邏輯分析與嚴(yán)密思考的產(chǎn)物。正是我們在需求分析過程存在的巨大隱患,最終導(dǎo)致了那么多項目的失敗。也許你認(rèn)為我在危言聳聽,好吧,我來舉幾個典型事例分析分析吧。

    我的第一個故事來自大名鼎鼎的東軟。我在2005年接一個項目的時候,聽說這個項目之前是東軟做的。當(dāng)時東軟在做這個項目的時候,整個過程經(jīng)歷了10多次結(jié)構(gòu)性的大變更,局部性的調(diào)整更是不計其數(shù)。據(jù)說某天早上,客戶對某個功能不滿意,他們不得不對幾百處程序進(jìn)行修改。之后客戶對修改的內(nèi)容還是不滿意,又不得不將幾百處修改重新改回來。最后這個項目導(dǎo)致的結(jié)果是,整個這個項目組的所有成員都離開了東軟,并似乎從此不愿涉足軟件開發(fā)領(lǐng)域。多么慘痛的教訓(xùn)??!我常常聽到網(wǎng)友抱怨客戶總是對需求改來改去,但客戶對需求改來改去的真正原因是什么呢?當(dāng)我們對客戶的需求沒有真正理解清楚時,我們做出來的東西客戶必然不滿意。客戶只知道他不滿意,但怎樣才能使他滿意呢?他不知道,于是就在一點兒一點兒試,于是這種反復(fù)變更就這樣發(fā)生了。如果我們明白了這一點,深入地去理解客戶的業(yè)務(wù),進(jìn)而想到客戶的心坎兒上去,最后做出來的東西必然是客戶滿意的。記住,當(dāng)客戶提出業(yè)務(wù)變更的時候,我們一定不能被客戶牽著走,客戶說啥就是啥。我們要從業(yè)務(wù)角度深入的去分析,他為什么提出變更,提得合不合理,我有沒有更合理的方案滿足這個需求。當(dāng)我們提出更加合理的方案時,客戶是樂于接受的,變更也變得可控了。

    第二個故事來自我自己的項目,一個早期的項目。在這個項目中,客戶扔給了我們很多他們目前正在使用的統(tǒng)計報表,要我們按照報表的格式做出來。這些報表都是手工報表,許多格式既不規(guī)范,又很難于被計算機(jī)實現(xiàn)。這些報表令我耗費了不少鬧細(xì)胞,直到最終項目失敗都沒法完成。這件事留給我的深刻教訓(xùn)是,不能客戶怎么說軟件就怎么做??蛻籼岢龅脑夹枨笸遣豢紤]技術(shù)實現(xiàn),基于非計算機(jī)管理的操作模式提出來的。他們提出的很多需求常常比較理想而不切實際,畢竟人家是非技術(shù)的。但我們作為技術(shù)人員,需求分析必須實事求是地、基于技術(shù)可以實現(xiàn)的角度去考慮。那種“有條件要上,沒有條件創(chuàng)造條件”的魯莽行事,結(jié)果必然是悲慘的。所以我們必須要基于技術(shù)實現(xiàn)去引導(dǎo)客戶的需求。同時,計算機(jī)信息化管理就是一次改革,對以往手工管理模式的改革。如果我們上了信息化管理系統(tǒng),采用的管理模式卻依然是過去的手工模式,新系統(tǒng)的優(yōu)勢從何而來呢?因此,我們做需求就應(yīng)當(dāng)首先理解現(xiàn)有的管理模式,然后站在信息化管理的角度去審視他們的管理模式是否合理,最后一步一步地去引導(dǎo)他們按照更加合理的方式去操作與管理。

    2007年,我參與了一個集團(tuán)信息化建設(shè)的項目。這個項目中的客戶是一個龐大的群體,他們分別扮演著各種角色。從機(jī)構(gòu)層次劃分,有集團(tuán)領(lǐng)導(dǎo)、二級機(jī)構(gòu)人員、三級機(jī)構(gòu)人員;從職能角色劃分,有高層領(lǐng)導(dǎo)、財務(wù)人員、生產(chǎn)管理員、采購人員、銷售人員,等等。在這樣一個復(fù)雜場景中,不同人員對這個項目的需求是各自不同的。非常遺憾的是,我們在進(jìn)行需求分析的時候沒有認(rèn)真分析清楚所有類型人員的需求。在進(jìn)行需求調(diào)研的時候,總是集團(tuán)領(lǐng)導(dǎo)帶領(lǐng)我們到基層單位,然后基層單位將各方面的人員叫來開大會。這樣的大會,各類型的人員七嘴八舌各說各自的需求,還有很多基層人員在大會上因為羞澀根本就沒有提出自己的需求。這樣經(jīng)過數(shù)次開會,需求調(diào)研就草草收場。我們拿著一個不充分的需求分析結(jié)果就開始項目開發(fā),最終的結(jié)果可想而知。直到項目上線以后,我們才發(fā)現(xiàn)許多更加細(xì)節(jié)的業(yè)務(wù)需求都沒能分析到,系統(tǒng)根本沒法運行,不得不宣告失敗。一個軟件項目的需求調(diào)研首先必須要進(jìn)行角色分析,然后對不同的角色分別進(jìn)行調(diào)研。需求調(diào)研的最初需要召開項目動員大會,這是十分必要的。但真正要完成需求分析,應(yīng)該是一個一個的小會,1~3個業(yè)務(wù)專家,只討論某個領(lǐng)域的業(yè)務(wù)需求,并且很多問題都不是能一蹴而就完成的,我們必須與專家建立聯(lián)系,反復(fù)溝通后完成。需求分析必須遵從的是一定的科學(xué)方法,而不是盲目的大上快上。

    我的最后一個故事可能典型到幾乎每個人都曾經(jīng)遇到過。我們的項目從需求分析到設(shè)計、開發(fā)、測試都十分順利。但到了項目進(jìn)行的后期,快到達(dá)最后期限時,我們將我們的開發(fā)成果提交給客戶看,客戶卻對開發(fā)不滿意,提出了一大堆修改,而且這些修改工作量還不小。怎么辦呢?加班、趕工,測試時間被最大限度壓縮。最后項目倒是如期上線了,但大家疲憊不堪,并且上線以后才發(fā)現(xiàn)許多的BUG。需求分析不是一蹴而就的,它應(yīng)當(dāng)貫穿整個開發(fā)周期,不斷的分析確認(rèn)的過程。以上這個事例,如果我們提早將開發(fā)成果給客戶看,提早解決問題,后面的情況就將不再發(fā)生。這就是敏捷開發(fā)倡導(dǎo)的需求反饋。敏捷開發(fā)認(rèn)為,需求分析階段不可能解決所有的需求問題,因此在設(shè)計、開發(fā)、測試,直到最終交付客戶,這整個過程都應(yīng)當(dāng)不停地用開發(fā)的成果與客戶交流,及時獲得反饋。只有這樣才能及時糾正需求理解的偏差,保證項目的成功。

    以上的故事各有各自的不幸,各自都在不同的開發(fā)環(huán)節(jié)出現(xiàn)了問題。但經(jīng)過深入的分析,各自的問題最終都?xì)w結(jié)為需求分析出現(xiàn)了問題。為了使我們今后的軟件項目不會重蹈覆轍,似乎真的有必要討論一下我們應(yīng)該怎樣做需求分析。

    posted @ 2012-01-15 20:24 paulwong 閱讀(338) | 評論 (0)編輯 收藏

    [轉(zhuǎn)帖]建設(shè)一個靠譜的火車票網(wǎng)上訂購系統(tǒng)

    轉(zhuǎn)自【 http://www.ifanr.com/68019
    昨天,2012年1月11日,網(wǎng)友 @fenng 寫了一篇文章,批評鐵道部火車票網(wǎng)上訂購系統(tǒng),http://www.12306.cn [1]。同時在新浪發(fā)了一條言辭激烈的微博,“去你的‘海量事務(wù)高速處理系統(tǒng)’”,引起熱議 [2]。

    春節(jié)將到,大家買不著車票,趕不上大年三十與家人團(tuán)聚,急切心情可以理解。但是拍桌子開罵,只能宣泄情緒,解決不了實際問題。 開發(fā)一套訂票系統(tǒng)并不難,難在應(yīng)對春運期間,日均 10 億級別的洪峰流量。日均 10 億級別的洪峰請求,在中國這個人口全球第一大國,不算稀罕,不僅火車票訂票系統(tǒng)會遇到,而且電子商務(wù)在促銷時,也會遇到,社交網(wǎng)站遇到新聞熱點時,也會遇到。 所以,能夠在中國成功運行的云計算系統(tǒng),推廣到全球,一定也能成功。

    但是在美國成功運行的云計算系統(tǒng),移植到中國,卻不一定成功。 如果我們能夠設(shè)計建造一套,穩(wěn)定而高效的鐵路訂票系統(tǒng),不僅解決了中國老百姓的實際問題,而且在全球高科技業(yè)界,也是一大亮點,而且是貼著中國標(biāo)簽的前沿科技的亮點。 于是軟件工程師們獻(xiàn)計獻(xiàn)策,討論如何改進(jìn) 12306 網(wǎng)上購票系統(tǒng) [3]。其中比較有代表性的,有兩篇 [4,5] 網(wǎng)友的評論中,有觀點認(rèn)為,[4] 利用“虛擬排隊”的手段,將過程拉長負(fù)載降低,是網(wǎng)游的設(shè)計思路。而 [5] 利用緩存技術(shù),一層層地降低系統(tǒng)負(fù)荷, 是互聯(lián)網(wǎng)的設(shè)計思路。 個人認(rèn)為,[4] 和 [5] 并不是相互排斥的兩種路線,兩者著重解決的問題不同,不妨結(jié)合起來使用,取長補(bǔ)短。

    下面介紹一下我們的設(shè)計草案,追求實用,擯棄花哨。拋磚引玉,歡迎拍磚。
    圖一。12306.cn 網(wǎng)站系統(tǒng)架構(gòu)設(shè)想圖。
    Courtesy http://i879.photobucket.com/albums/ab351/kan_deng/12306.png

    圖一是系統(tǒng)架構(gòu)圖,典型的“展現(xiàn)層”/ “業(yè)務(wù)層”/ “數(shù)據(jù)層”的三段論。 用戶接入有兩類,一個是運行在電腦里的瀏覽器,例如 IE,另一個是手機(jī)。 無論用戶用電腦瀏覽器,還是手機(jī)訪問 http://www.12306.cn 網(wǎng)站,用戶請求首先被網(wǎng)站的負(fù)載均衡器接收。負(fù)載均衡器連接著一群門戶服務(wù)器,根據(jù)各個門戶服務(wù)器的負(fù)載輕重,負(fù)載均衡器把用戶請求,轉(zhuǎn)發(fā)到某一相對清閑的門戶服務(wù)器。 門戶服務(wù)器的任務(wù)類似于收發(fā)室老頭兒,它只讀每個用戶請求的前幾個 bytes,目的是確定用戶請求的類型,然后把請求投放到相應(yīng)類型的隊列中去。門戶服務(wù)器的處理邏輯非常簡單,這樣做的好處,是讓它能夠快速處理大批量用戶請求。

    根據(jù) [5] 的分析,12306 處理的用戶請求,大致分為三類,
    1. 查詢。用戶訂票前,查詢車次以及余票。用戶下訂單后,查詢是否已經(jīng)訂上票。
    2. 訂票,包括確定車次和票數(shù),然后付款。用戶付款時,需要在網(wǎng)銀等網(wǎng)站上操作。
    3. 第一次訪問的用戶,需要登記,包括姓名和信用卡等信息。

    三類請求的業(yè)務(wù)處理過程,被分為兩個階段,
    1. 運行于緩存中的任務(wù)隊列。設(shè)置隊列的目的,是防止處理過程耗時太長,導(dǎo)致大量用戶請求擁塞于門戶服務(wù)器,導(dǎo)致系統(tǒng)癱瘓。
    2. 業(yè)務(wù)處理處理器,對于每一類業(yè)務(wù),分別有一群業(yè)務(wù)服務(wù)器。不同業(yè)務(wù)的處理流程,各不相同。
    圖二。12306.cn 網(wǎng)站查詢和訂票業(yè)務(wù)流程設(shè)想圖。
    Courtesy http://i879.photobucket.com/albums/ab351/kan_deng/12306-1.png
    圖二描述了查詢和訂票,兩個業(yè)務(wù)的處理流程。登記業(yè)務(wù)流程從略。 查詢的業(yè)務(wù)流程,參見圖二上半部,分五步。
    這里有兩個問題需要注意,
    1. 用戶發(fā)出請求后,經(jīng)過短暫的等待時間,能夠迅速看到結(jié)果。平均等待時間不能超過 1 秒。
    2. 影響整個查詢速度的關(guān)鍵,是“查詢服務(wù)器”的設(shè)計。

    查詢?nèi)蝿?wù)可以進(jìn)一步細(xì)化,大致分成三種。
    1. 查詢車次和時間表,這是靜態(tài)內(nèi)容,很少與數(shù)據(jù)庫交互,數(shù)據(jù)量也不大,可以緩存在內(nèi)存中。 車次和時間表的數(shù)據(jù)結(jié)構(gòu),不妨采用 Key-Value 的方式,開發(fā)簡單,使用效率高。Key-Value 的具體實現(xiàn)有很多產(chǎn)品,[5] 建議使用 Redis。 這些是技術(shù)細(xì)節(jié),不妨通過對比實驗,針對火車票訂票系統(tǒng)的實際流量,以及峰值波動,確定哪一個產(chǎn)品最合適。
    2. 查詢某一班次的剩余車票,這需要調(diào)用數(shù)據(jù)庫中不斷更新的數(shù)據(jù)。 [5] 建議把剩余車票只分為兩種,“有”或“無”,這樣減少調(diào)用訪問數(shù)據(jù)庫的次數(shù),降低數(shù)據(jù)庫的壓力。但是這樣做,不一定能夠滿足用戶的需求,說不定會招致網(wǎng)友的批評譏諷。 [4] 建議在訂票隊列中,增加測算訂票隊列長度的功能,根據(jù)訂票隊列長度以及隊列中每個請求的購票數(shù)量,可以計算出每個車次的剩余座位。如果 12306.cn 網(wǎng)站只有一個后臺系統(tǒng),這個辦法行之有效。 但是假如 12306.cn 網(wǎng)站采用分布式結(jié)構(gòu),每個鐵路分局設(shè)有子系統(tǒng),分別管理各個鐵路分局轄區(qū)內(nèi)的各個車次。在分布式系統(tǒng)下,這個辦法面臨任務(wù)轉(zhuǎn)發(fā)的麻煩。不僅開發(fā)工作量大,而且會延長查詢流程處理時間,導(dǎo)致用戶長久等待。
    3. 已經(jīng)下單的用戶,查詢是否已經(jīng)成功地訂上票。 每個用戶通常只關(guān)心自己訂的票。如果把每個用戶訂購的車票的所有內(nèi)容,都緩存在內(nèi)存里,不僅非常耗用內(nèi)存空間,內(nèi)存空間使用效率低下,更嚴(yán)重的問題是,訪問數(shù)據(jù)庫過于頻繁,數(shù)據(jù)量大,增大數(shù)據(jù)庫的壓力。

    解決上述分布式同步,以及數(shù)據(jù)庫壓力的兩個問題,不妨從訂票的流程設(shè)計和數(shù)據(jù)結(jié)構(gòu)設(shè)計入手。
    假如有個北京用戶在網(wǎng)上訂購了一套聯(lián)票,途經(jīng)北京鐵路局和鄭州鐵路局轄區(qū)的兩個車次。
    用戶從北京上網(wǎng),由北京鐵路局的子系統(tǒng),處理他的請求。
    北京鐵路局的訂票服務(wù)器把他的請求一分為二,北京鐵路局的車次的訂票,在北京子系統(tǒng)完成,鄭州鐵路局的車次在鄭州子系統(tǒng)完成。
    每個子系統(tǒng)處理四種 Key-Value 數(shù)據(jù)組。
    1. 用戶ID:多個 (訂單ID)s。
    2. 訂單ID:多個 (訂票結(jié)果ID)s。
    3. 訂票結(jié)果ID: 一個 (用戶ID,車次ID)。
    4. 車次ID:一個(日期),多個 (座位,用戶ID)。
    北京訂票服務(wù)器完成訂票后,把上述四個數(shù)據(jù)組,寫入北京子系統(tǒng)的數(shù)據(jù)庫,同時緩存進(jìn)北京的查詢服務(wù)器,參見圖二下半部第6步和第7步。
    鄭州訂票服務(wù)器完成訂票后,把上述四個數(shù)據(jù)組,寫入鄭州子系統(tǒng)的數(shù)據(jù)庫,同時緩存進(jìn)北京的查詢服務(wù)器,而不是鄭州的服務(wù)器。 讓訂票服務(wù)器把訂票數(shù)據(jù),同時寫入數(shù)據(jù)庫和查詢服務(wù)器的緩存,目的是讓數(shù)據(jù)庫永久保留訂票記錄,而讓大多數(shù)查詢,只訪問緩存,降低數(shù)據(jù)庫的壓力。
    北京用戶的訂票數(shù)據(jù),只緩存在北京的查詢服務(wù)器,不跨域緩存,從而降低緩存空間的占用,和同步的麻煩。這樣做,有個前提假設(shè),查詢用戶與訂票用戶,基本上是同一個人,而且從同一個城市上網(wǎng)。
     但是這里有個缺陷,某用戶在北京上網(wǎng)訂了票。過了幾天,他在北京上網(wǎng),輸入用戶ID和密碼后,就會看到他訂購的所有車票??墒怯诌^了幾天,他去了鄭州,從鄭州上網(wǎng),同樣輸入用戶ID和密碼,卻看不到他訂購的所有車票。
     解決這個缺陷的辦法并不麻煩,在用戶查詢訂票信息時,需要注明訂票地點,系統(tǒng)根據(jù)訂票地點,把查詢請求轉(zhuǎn)發(fā)到相應(yīng)區(qū)域的子系統(tǒng)。 另外,每次訂票的時候,網(wǎng)站會給他的手機(jī)發(fā)送短信,提供訂票信息,參見圖二下半部第8步和第9步。

    以上是一個初步設(shè)計,還有不少細(xì)節(jié)需要完善,例如防火墻如何布置等等。
    這個設(shè)計不僅適用于單一的集中式部署,而且也適合分布式部署。
    或許有讀者會問,為什么沒有用到云計算?其實上述架構(gòu)設(shè)計,為將來向云計算演變,留下了伏筆。
    在上述架構(gòu)設(shè)計中,我們假定每個環(huán)節(jié)需要用多少服務(wù)器,需要多大容量的數(shù)據(jù)庫,預(yù)先都已經(jīng)規(guī)劃好。
    但是假如事先的規(guī)劃,低于實際承受的流量和數(shù)據(jù)量,那么系統(tǒng)就會崩潰。
    所以,事先的規(guī)劃,只能以峰值為基準(zhǔn)設(shè)立。 但是峰值將會是多少?
    事先難以確定。即便能夠確定峰值,然后以峰值為基準(zhǔn),規(guī)劃系統(tǒng)的能力,那么春運過后,就會有大量資源冗余,造成資源浪費? 如何既能抗洪,又不造成資源浪費?解決方案是云計算,而且目前看來,除了云計算,沒有別的辦法。

    Reference,
    [1] 海量事務(wù)高速處理系統(tǒng)。 http://www.douban.com/note/195179318/
    [2] 去你*的‘海量事務(wù)高速處理系統(tǒng)’。 http://weibo.com/1577826897/y0jGYcZfW
    [3] 火車訂票系統(tǒng)的設(shè)想。 http://weibo.com/1570303725/y0l9Y2mwE
    [4] 鐵路訂票系統(tǒng)的簡單設(shè)計。 http://blog.codingnow.com/2012/01/ticket_queue.html
    [5] 鐵路訂票網(wǎng)站個人的設(shè)計淺見。 http://hi.baidu.com/caoz/blog/item/f4f1d7caee09b558f21fe780.html
    題圖來自 Designyoutrust

    posted @ 2012-01-13 13:39 paulwong 閱讀(323) | 評論 (0)編輯 收藏

    臺灣圖書

     
    http://www.tenlong.com.tw/items/9861811915?item_id=59633
     
    商譽管理─看見危機(jī),穿透危機(jī),決勝於未戰(zhàn)之前
    http://www.tenlong.com.tw/items/9861578269?item_id=375391
     
    全面品質(zhì)管理, 2/e
    http://www.tenlong.com.tw/items/9866184560?item_id=390199
     
    曼陀羅九宮格思考術(shù)─達(dá)成目標(biāo)成功圓夢
    http://www.tenlong.com.tw/items/9866151018?item_id=58621
     
    六個標(biāo)準(zhǔn)差的品質(zhì)管制─ 60 小時學(xué)會實務(wù)應(yīng)用的手冊
    http://www.tenlong.com.tw/items/9572182579?item_id=377554
     
    在失業(yè)中創(chuàng)業(yè):被炒魷魚又怎樣!
    http://www.tenlong.com.tw/items/9868768004?item_id=382010
     
    領(lǐng)導(dǎo)未來的 CEO-12 堂 EMBA 名師的管理必修課
    http://www.tenlong.com.tw/items/9862720581?item_id=383127
     
    早上 3 分鐘變身管理大師, 2/e
    http://www.tenlong.com.tw/items/9866487997?item_id=384625
     
    整合行銷傳播策略與企劃
    http://www.tenlong.com.tw/items/9576598761?item_id=384636
     
    Photoshop 視訊課程合集 (21)
    http://www.tenlong.com.tw/items/4712839503?item_id=385316
     
    DTP 視訊課程合集 (7)
    http://www.tenlong.com.tw/items/4712839503?item_id=385314
     
    3ds Max 視訊課程合集(22)
    http://www.tenlong.com.tw/items/4712839503?item_id=348746
     
    Photoshop 視訊課程合集 (22)
    http://www.tenlong.com.tw/items/4712839503?item_id=395988
     
    Photoshop 視訊課程合集 (21)
    http://www.tenlong.com.tw/items/4712839503?item_id=385316
     
    巴菲特 & 索羅斯聯(lián)手出擊─不看會後悔的投資策略
    http://www.tenlong.com.tw/items/9862572752?item_id=387693
     
    揭開肥貓經(jīng)理人薪酬的黑盒子
    http://www.tenlong.com.tw/items/9862572485?item_id=387694
     
    圖解第一次看懂經(jīng)濟(jì)指標(biāo)就上手
    http://www.tenlong.com.tw/items/9866434192?item_id=389815
     
    把鳥事變好事的神奇手帳術(shù)
    http://www.tenlong.com.tw/items/9862295635?item_id=390569
     
    用 Please 換 Yes 的職場成功學(xué)
    http://www.tenlong.com.tw/items/9866009017?item_id=390570
     
    Pose 這樣擺最 OK ─人像攝影與場景的完美結(jié)合
    http://www.tenlong.com.tw/items/9862015454?item_id=392624
     
    寫給 SA 的 UML / UseCase 實務(wù)手冊
    http://www.tenlong.com.tw/items/9861817786?item_id=51507
     
    Thinking in Java 中文版 (Thinking in Java, 4/e)
    http://www.tenlong.com.tw/items/9861815023?item_id=45896
     
    jQuery 實戰(zhàn)手冊 (jQuery in Action, 2/e)
    http://www.tenlong.com.tw/items/9861811915?item_id=59633
     
    讓人不自覺說 YES 的交涉力
    http://www.tenlong.com.tw/items/9866363368?item_id=54347
     
    翻譯大師教你寫出好句子
    http://www.tenlong.com.tw/items/9577297390?item_id=49007
     
    日本超級店長首次公開讓客戶「好想再見到妳」的心機(jī)說話術(shù)
    http://www.tenlong.com.tw/items/9866097250?item_id=352822
     
    iPhone 基礎(chǔ)程式設(shè)計
    http://www.tenlong.com.tw/items/9866649091?item_id=351448
     
    圖解 NLP 惡魔說話術(shù)─實例篇
    http://www.tenlong.com.tw/items/9866363872?item_id=248045
     
    大膽想 出狠招 (Think Big And Kick Ass In Business And Life) http://www.tenlong.com.tw/items/9866662659?item_id=44764
     
    3ds Max 視訊課程合集 1
    http://www.tenlong.com.tw/items/4712839503?item_id=46426
     
    寫給經(jīng)理人的專案管理發(fā)達(dá)之路-使用 Project 2010
    http://www.tenlong.com.tw/items/9572239325?item_id=371017
     
    軟體測試專案實作-技術(shù)、流程與管理
    http://www.tenlong.com.tw/items/9572239473?item_id=351121
     

    posted @ 2012-01-10 14:55 paulwong 閱讀(234) | 評論 (0)編輯 收藏

    JBoss下DataSource加密(上)

    1.先來看一個普通的數(shù)據(jù)源配置文件
    <?xml version="1.0" encoding="UTF-8"?>
    <datasources>
       
    <local-tx-datasource>
         
    <!-- jndi名字 -->
         
    <jndi-name>MySqlDS</jndi-name>
         
    <!--URL地址 --> 
         
    <use-java-context>false</use-java-context>
         
    <connection-url>jdbc:mysql://10.16.175.137:3306/test</connection-url>
         
    <!-- 驅(qū)動 --> 
         
    <driver-class>com.mysql.jdbc.Driver</driver-class>
          
    <!-- 用戶名 --> 
         
    <user-name>root</user-name>
          
    <!-- 密碼 --> 
        
    <password>123456</password>
        
    <exception-sorter-class-name> org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter </exception-sorter-class-name> 
         
    <metadata> 
            
    <type-mapping>mySQL</type-mapping> 
         
    </metadata>
       
    </local-tx-datasource>
    </datasources>


    看一下這個文件,里面用戶名與密碼都是以明文方式存儲的,這樣子對系統(tǒng)的安全而言帶來了極大的威協(xié)。所以我們要為我們這個明文的密碼加一下密,這就是本文的目的.

    2.說到密碼加密,這里我們用到了JBoss下的一個類org.jboss.resource.security.SedureIdentityLoginModule,看看我們該如何用它來幫我們的密碼加密。
    先看個配置數(shù)據(jù)源的例子(mysql-ds.xml)

    <?xml version="1.0" encoding="UTF-8"?>
    <datasources>
    <local-tx-datasource>
    <jndi-name>MySqlDS</jndi-name>
    <use-java-context>false</use-java-context>
    <connection-url>jdbc:mysql://192.168.1.91:3306/atteam</connection-url>
    <driver-class>com.mysql.jdbc.Driver</driver-class>
    <!--這里不用寫上你的用戶名與密碼了,我們可以在login-config.xml里做點手腳,就OK了 -->
    <security-domain>EncryptDBPassword</security-domain>
    <exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name>
    <metadata>
    <type-mapping>mySQL</type-mapping>
    </metadata>
    </local-tx-datasource>
    </datasources>

    接著我們修改server\default\conf\login-config.xml文件,加上下面這一段配置文件

    <application-policy name="EncryptDBPassword">
    <!--這里的name應(yīng)該是你在配置數(shù)據(jù)源時寫的security-domain里的字符串-->
    <authentication>
    <login-module code="org.jboss.resource.security.SecureIdentityLoginModule" flag="required">
    <!-- 數(shù)據(jù)庫的用戶名 -->
    <module-option name="username">test</module-option>
    <!--數(shù)據(jù)庫的密碼,不過是加密過的了 -->
    <module-option name="password">64c5fd2979a86168</module-option>
    <!-- 注意name等于你的數(shù)據(jù)源的jndi-name,這里是MySqlDS -->
    <module-option name="managedConnectionFactoryName">jboss.jca:service=LocalTxCM,name=MySqlDS</module-option>
    </login-module>
    </authentication>
    </application-policy>

    3.補(bǔ)充一下,這個加密的密碼是哪來的

    java -cp "D:\TDdownload\jboss-4.2.0.CR1\jboss-4.2.0.CR1\lib\jboss-jmx.jar;D:\TDdownload\jboss-4.2.0.CR1\jboss-4.2.0.CR1\lib\jboss-common.jar;D:\TDdownload\jboss-4.2.0.CR1\jboss-4.2.0.CR1\server\default\lib\jboss-jca.jar;D:\TDdownload\jboss-4.2.0.CR1\jboss-4.2.0.CR1\server\default\lib\jbosssx.jar" org.jboss.resource.security.SecureIdentityLoginModule 123456 Encoded password: 64c5fd2979a86168

    posted @ 2012-01-09 00:51 paulwong 閱讀(626) | 評論 (0)編輯 收藏

    僅列出標(biāo)題
    共115頁: First 上一頁 90 91 92 93 94 95 96 97 98 下一頁 Last 
    主站蜘蛛池模板: 爱情岛论坛免费视频| 国产亚洲精aa在线看| 一区二区三区免费视频网站| 在线免费观看毛片网站| 亚洲大尺码专区影院| 精品无码人妻一区二区免费蜜桃| 亚洲人成色777777在线观看| 亚洲精品资源在线| mm1313亚洲国产精品无码试看| 三年片在线观看免费大全| 亚洲精品美女久久久久| 蜜桃视频在线观看免费视频网站WWW | 久久久久亚洲Av无码专| 免费视频精品一区二区三区 | 免费国产成人午夜电影| 久久精品熟女亚洲av麻豆| 在线视频免费观看www动漫| 亚洲а∨天堂久久精品9966| 免费可以看黄的视频s色| 国产成人亚洲精品青草天美| 亚洲精品无码日韩国产不卡av| 在人线av无码免费高潮喷水| 亚洲国产日韩在线人成下载| 免费成人福利视频| 亚洲福利一区二区精品秒拍| 国产黄色免费网站| 亚洲av无码片在线观看| 久久免费国产视频| 亚洲伊人久久综合影院| 一区二区在线免费视频| 91麻豆精品国产自产在线观看亚洲| 国产免费伦精品一区二区三区 | aⅴ免费在线观看| 亚洲制服丝袜在线播放| 国产精品无码免费播放| 亚洲中文无码永久免费| 国产精品久久久久影院免费| avtt天堂网手机版亚洲| 毛片免费在线播放| 国产精品亚洲专区无码唯爱网| 免费不卡中文字幕在线|