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

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

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

    paulwong

    #

    Ehcache分布式緩存

    從1.2版本開(kāi)始,Ehcache可以使用分布式的緩存了。

    分布式這個(gè)特性是以plugin的方式實(shí)現(xiàn)的。Ehcache自帶了一些默認(rèn)的分布式緩存插件實(shí)現(xiàn),這些插件可以滿(mǎn)足大部分應(yīng)用的需要。如果需要使用其他的插件那就需要自己開(kāi)發(fā)了,開(kāi)發(fā)者可以通過(guò)查看distribution包里的源代碼及JavaDoc來(lái)實(shí)現(xiàn)它。

    盡管不是必須的,在使用分布式緩存時(shí)理解一些ehcahce的設(shè)計(jì)思想也是有幫助的。這可以參看分布式緩存設(shè)計(jì)的頁(yè)面。
    以下的部分將展示如何讓分布式插件同ehcache一起工作。

    下面列出的是一些分布式緩存中比較重要的方面:

    你如何知道集群環(huán)境中的其他緩存?分布式傳送的消息是什么形式?什么情況需要進(jìn)行復(fù)制?增加(Puts),更新(Updates)或是失效(Expiries)?采用什么方式進(jìn)行復(fù)制?同步還是異步方式?

    為了安裝分布式緩存,你需要配置一個(gè)PeerProvider、一個(gè)CacheManagerPeerListener,它們對(duì)于一個(gè)CacheManager來(lái)說(shuō)是全局的。每個(gè)進(jìn)行分布式操作的cache都要添加一個(gè)cacheEventListener來(lái)傳送消息。

    正確的元素類(lèi)型

    只有可序列化的元素可以進(jìn)行復(fù)制。

    一些操作,比如移除,只需要元素的鍵值而不用整個(gè)元素;在這樣的操作中即使元素不是可序列化的但鍵值是可序列化的也可以被復(fù)制,

    成員發(fā)現(xiàn)(Peer Discovery)

    Ehcache進(jìn)行集群的時(shí)候有一個(gè)cache組的概念。每個(gè)cache都是其他cache的一個(gè)peer,沒(méi)有主cache的存在。剛才我們問(wèn)了一個(gè)問(wèn)題:你如何知道集群環(huán)境中的其他緩存?這個(gè)問(wèn)題可以命名為成員發(fā)現(xiàn)(Peer Discovery)。

    Ehcache提供了兩種機(jī)制用來(lái)進(jìn)行成員發(fā)現(xiàn),就像一輛汽車(chē):手動(dòng)檔和自動(dòng)檔。

    要使用一個(gè)內(nèi)置的成員發(fā)現(xiàn)機(jī)制要在ehcache的配置文件中指定cacheManagerPeerProviderFactory元素的class屬性為net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory。

    自動(dòng)的成員發(fā)現(xiàn)

    自動(dòng)的發(fā)現(xiàn)方式用TCP廣播機(jī)制來(lái)確定和維持一個(gè)廣播組。它只需要一個(gè)簡(jiǎn)單的配置可以自動(dòng)的在組中添加和移除成員。在集群中也不需要什么優(yōu)化服務(wù)器的知識(shí),這是默認(rèn)推薦的。

    成員每秒向群組發(fā)送一個(gè)“心跳”。如果一個(gè)成員 5秒種都沒(méi)有發(fā)出信號(hào)它將被群組移除。如果一個(gè)新的成員發(fā)送了一個(gè)“心跳”它將被添加進(jìn)群組。

    任何一個(gè)用這個(gè)配置安裝了復(fù)制功能的cache都將被其他的成員發(fā)現(xiàn)并標(biāo)識(shí)為可用狀態(tài)。

    要設(shè)置自動(dòng)的成員發(fā)現(xiàn),需要指定ehcache配置文件中cacheManagerPeerProviderFactory元素的properties屬性,就像下面這樣:

    peerDiscovery=automatic multicastGroupAddress=multicast address | multicast host name multicastGroupPort=port 
    # (timeToLive屬性詳見(jiàn)常見(jiàn)問(wèn)題部分的描述)
    timeToLive=0-255

    示例

    假設(shè)你在集群中有兩臺(tái)服務(wù)器。你希望同步sampleCache1和sampleCache2。每臺(tái)獨(dú)立的服務(wù)器都要有這樣的配置:
    配置server1和server2

    <cacheManagerPeerProviderFactory
    class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
    properties
    ="peerDiscovery=automatic, multicastGroupAddress=230.0.0.1,
    multicastGroupPort=4446, timeToLive=32"
    />

    手動(dòng)進(jìn)行成員發(fā)現(xiàn)

    進(jìn)行手動(dòng)成員配置要知道每個(gè)監(jiān)聽(tīng)器的IP地址和端口。成員不能在運(yùn)行時(shí)動(dòng)態(tài)地添加和移除。在技術(shù)上很難使用廣播的情況下就可以手動(dòng)成員發(fā)現(xiàn),例如在集群的服務(wù)器之間有一個(gè)不能傳送廣播報(bào)文的路由器。你也可以用手動(dòng)成員發(fā)現(xiàn)進(jìn)行單向的數(shù)據(jù)復(fù)制,只讓server2知道server1而server1不知道server2。

    配置手動(dòng)成員發(fā)現(xiàn),需要指定ehcache配置文件中cacheManagerPeerProviderFactory的properties屬性,像下面這樣:

    peerDiscovery=manual rmiUrls=//server:port/cacheName, 
    rmiUrls配置的是服務(wù)器cache peers的列表。注意不要重復(fù)配置。

    示例

    假設(shè)你在集群中有兩臺(tái)服務(wù)器。你要同步sampleCache1和sampleCache2。下面是每個(gè)服務(wù)器需要的配置:
    配置server1

    <cacheManagerPeerProviderFactory
    class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
    properties
    ="peerDiscovery=manual,
    rmiUrls=//server2:40001/sampleCache11|//server2:40001/sampleCache12"
    />

    配置server2
    <cacheManagerPeerProviderFactory
    class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
    properties
    ="peerDiscovery=manual,
    rmiUrls=//server1:40001/sampleCache11|//server1:40001/sampleCache12"
    />

    配置CacheManagerPeerListener

    每個(gè)CacheManagerPeerListener監(jiān)聽(tīng)成員們發(fā)向當(dāng)前CacheManager的消息。
    配置CacheManagerPeerListener需要指定一個(gè)CacheManagerPeerListenerFactory,它以插件的機(jī)制實(shí)現(xiàn),用來(lái)創(chuàng)建CacheManagerPeerListener。

    cacheManagerPeerListenerFactory的屬性有:
    class – 一個(gè)完整的工廠類(lèi)名。
    properties – 只對(duì)這個(gè)工廠有意義的屬性,使用逗吃分隔。

    Ehcache有一個(gè)內(nèi)置的基于RMI的分布系統(tǒng)。它的監(jiān)聽(tīng)器是RMICacheManagerPeerListener,這個(gè)監(jiān)聽(tīng)器可以用RMICacheManagerPeerListenerFactory來(lái)配置。

    <cacheManagerPeerListenerFactory
    class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
    properties
    ="hostName=localhost, port=40001,
    socketTimeoutMillis=2000"
    />

    有效的屬性是:
    hostname (可選) – 運(yùn)行監(jiān)聽(tīng)器的服務(wù)器名稱(chēng)。標(biāo)明了做為集群群組的成員的地址,同時(shí)也是你想要控制的從集群中接收消息的接口。

    在CacheManager初始化的時(shí)候會(huì)檢查hostname是否可用。

    如果hostName不可用,CacheManager將拒絕啟動(dòng)并拋出一個(gè)連接被拒絕的異常。

    如果指定,hostname將使用InetAddress.getLocalHost().getHostAddress()來(lái)得到。

    警告:不要將localhost配置為本地地址127.0.0.1,因?yàn)樗诰W(wǎng)絡(luò)中不可見(jiàn)將會(huì)導(dǎo)致不能從遠(yuǎn)程服務(wù)器接收信息從而不能復(fù)制。在同一臺(tái)機(jī)器上有多個(gè)CacheManager的時(shí)候,你應(yīng)該只用localhost來(lái)配置。

    port – 監(jiān)聽(tīng)器監(jiān)聽(tīng)的端口。
    socketTimeoutMillis (可選) – Socket超時(shí)的時(shí)間。默認(rèn)是2000ms。

    配置CacheReplicators

    每個(gè)要進(jìn)行同步的cache都需要設(shè)置一個(gè)用來(lái)向CacheManagerr的成員復(fù)制消息的緩存事件監(jiān)聽(tīng)器。這個(gè)工作要通過(guò)為每個(gè)cache的配置增加一個(gè)cacheEventListenerFactory元素來(lái)完成。

    <!-- Sample cache named sampleCache2. -->
    <cache name="sampleCache2"
    maxElementsInMemory
    ="10"
    eternal
    ="false"
    timeToIdleSeconds
    ="100"
    timeToLiveSeconds
    ="100"
    overflowToDisk
    ="false">
    <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
    properties
    ="replicateAsynchronously=true,
    replicatePuts=true, replicateUpdates=true, replicateUpdatesViaCopy=false, replicateRemovals=true "
    />
    </cache>

    name:緩存名稱(chēng)。通常為緩存對(duì)象的類(lèi)名(非嚴(yán)格標(biāo)準(zhǔn))。

    maxElementsInMemory:設(shè)置基于內(nèi)存的緩存可存放對(duì)象的最大數(shù)目。

    maxElementsOnDisk:設(shè)置基于硬盤(pán)的緩存可存放對(duì)象的最大數(shù)目。

    eternal:如果為true,表示對(duì)象永遠(yuǎn)不會(huì)過(guò)期,此時(shí)會(huì)忽略timeToIdleSeconds和timeToLiveSeconds屬性,默認(rèn)為false;

    timeToIdleSeconds: 設(shè)定允許對(duì)象處于空閑狀態(tài)的最長(zhǎng)時(shí)間,以秒為單位。當(dāng)對(duì)象自從最近一次被訪問(wèn)后,如果處于空閑狀態(tài)的時(shí)間超過(guò)了timeToIdleSeconds屬性值,這個(gè)對(duì)象就會(huì)過(guò)期。當(dāng)對(duì)象過(guò)期,EHCache將把它從緩存中清空。只有當(dāng)eternal屬性為false,該屬性才有效。如果該屬性值為0,則表示對(duì)象可以無(wú)限期地處于空閑狀態(tài)。

    timeToLiveSeconds:設(shè)定對(duì)象允許存在于緩存中的最長(zhǎng)時(shí)間,以秒為單位。當(dāng)對(duì)象自從被存放到緩存中后,如果處于緩存中的時(shí)間超過(guò)了 timeToLiveSeconds屬性值,這個(gè)對(duì)象就會(huì)過(guò)期。當(dāng)對(duì)象過(guò)期,EHCache將把它從緩存中清除。只有當(dāng)eternal屬性為false,該屬性才有效。如果該屬性值為0,則表示對(duì)象可以無(wú)限期地存在于緩存中。timeToLiveSeconds必須大于timeToIdleSeconds屬性,才有意義。

    overflowToDisk:如果為true,表示當(dāng)基于內(nèi)存的緩存中的對(duì)象數(shù)目達(dá)到了maxElementsInMemory界限后,會(huì)把益出的對(duì)象寫(xiě)到基于硬盤(pán)的緩存中。

    class – 使用net.sf.ehcache.distribution.RMICacheReplicatorFactory

    這個(gè)工廠支持以下屬性:
    replicatePuts=true | false – 當(dāng)一個(gè)新元素增加到緩存中的時(shí)候是否要復(fù)制到其他的peers. 默認(rèn)是true。
    replicateUpdates=true | false – 當(dāng)一個(gè)已經(jīng)在緩存中存在的元素被覆蓋時(shí)是否要進(jìn)行復(fù)制。默認(rèn)是true。
    replicateRemovals= true | false – 當(dāng)元素移除的時(shí)候是否進(jìn)行復(fù)制。默認(rèn)是true。
    replicateAsynchronously=true | false – 復(fù)制方式是異步的(指定為true時(shí))還是同步的(指定為false時(shí))。默認(rèn)是true。
    replicateUpdatesViaCopy=true | false – 當(dāng)一個(gè)元素被拷貝到其他的cache中時(shí)是否進(jìn)行復(fù)制(指定為true時(shí)為復(fù)制),默認(rèn)是true。

    你可以使用ehcache的默認(rèn)行為從而減少配置的工作量,默認(rèn)的行為是以異步的方式復(fù)制每件事;你可以像下面的例子一樣減少RMICacheReplicatorFactory的屬性配置:

    <!-- Sample cache named sampleCache4. All missing RMICacheReplicatorFactory properties default to true -->
    <cache name="sampleCache4"
    maxElementsInMemory
    ="10"
    eternal
    ="true"
    overflowToDisk
    ="false"
    memoryStoreEvictionPolicy
    ="LFU">
    <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"/>
    </cache>

    常見(jiàn)的問(wèn)題Windows上的Tomcat

    有一個(gè)Tomcat或者是JDK的bug,在tomcat啟動(dòng)時(shí)如果tomcat的安裝路徑中有空格的話(huà),在啟動(dòng)時(shí)RMI監(jiān)聽(tīng)器會(huì)失敗。參見(jiàn)http://archives.java.sun.com/cgi-bin/wa?A2=ind0205&L=rmi-users&P=797和http://www.ontotext.com/kim/doc/sys-doc/faq-howto-bugs/known-bugs.html。

    由于在Windows上安裝Tomcat默認(rèn)是裝在“Program Files”文件夾里的,所以這個(gè)問(wèn)題經(jīng)常發(fā)生。

    廣播阻斷

    自動(dòng)的peer discovery與廣播息息相關(guān)。廣播可能被路由阻攔,像Xen和VMWare這種虛擬化的技術(shù)也可以阻攔廣播。如果這些都打開(kāi)了,你可能還在要將你的網(wǎng)卡的相關(guān)配置打開(kāi)。

    一個(gè)簡(jiǎn)單的辦法可以告訴廣播是否有效,那就是使用ehcache remote debugger來(lái)看“心跳”是否可用。

    廣播傳播的不夠遠(yuǎn)或是傳得太遠(yuǎn)

    你可以通過(guò)設(shè)置badly misnamed time to live來(lái)控制廣播傳播的距離。用廣播IP協(xié)議時(shí),timeToLive的值指的是數(shù)據(jù)包可以傳遞的域或是范圍。約定如下:

    0是限制在同一個(gè)服務(wù)器
    1是限制在同一個(gè)子網(wǎng)
    32是限制在同一個(gè)網(wǎng)站
    64是限制在同一個(gè)region
    128是限制在同一個(gè)大洲
    255是不限制

    譯者按:上面這些資料翻譯的不夠準(zhǔn)確,請(qǐng)讀者自行尋找原文理解吧。

    在Java實(shí)現(xiàn)中默認(rèn)值是1,也就是在同一個(gè)子網(wǎng)中傳播。改變timeToLive屬性可以限制或是擴(kuò)展傳播的范圍。

    原文地址為 http://ehcache.sourceforge.net/documentation/distributed_caching.html

    posted @ 2012-02-14 15:46 paulwong 閱讀(9004) | 評(píng)論 (2)編輯 收藏

    更改MAVEN默認(rèn)使用的JDK版本

    需填加PLUGIN:
      <build>  
        
    <plugins>  
          
    <plugin>  
            
    <groupId>org.apache.maven.plugins</groupId>  
            
    <artifactId>maven-compiler-plugin</artifactId>  
            
    <configuration>  
              
    <source>1.6</source>  
              
    <target>1.6</target>  
            
    </configuration>  
          
    </plugin>  
        
    </plugins>  
    </build>
    再UPDATE PROJECT CONFIGURATION

    posted @ 2012-02-14 14:36 paulwong 閱讀(3613) | 評(píng)論 (0)編輯 收藏

    我們應(yīng)當(dāng)怎樣做需求調(diào)研:迭代

    前面我一直在反復(fù)強(qiáng)調(diào)這樣一個(gè)觀點(diǎn),需求分析不是一蹴而就的,是一個(gè)反復(fù)迭代的過(guò)程。它將從第一次需求分析開(kāi)始,一直持續(xù)到整個(gè)項(xiàng)目生命周期。為什么這樣說(shuō)呢?讓我們一起來(lái)分析分析。

    在第一次的需求分析階段,我們?cè)谝欢螘r(shí)期內(nèi)需要與客戶(hù)進(jìn)行反復(fù)地討論,這個(gè)過(guò)程往往是這樣一個(gè)反復(fù)循環(huán)的過(guò)程:需求捕獲->需求整理->需求驗(yàn)證->再需求捕獲••••••

    需求捕獲,就是我們與客戶(hù)在一起開(kāi)研討會(huì),討論需求的活動(dòng)。客戶(hù)可能會(huì)描述他們的業(yè)務(wù)流程,這時(shí)我們?cè)诩埳侠L制簡(jiǎn)單的流程草圖,及時(shí)地記錄下來(lái);客戶(hù)在描述業(yè)務(wù)的同時(shí),可能會(huì)反復(fù)提到一些業(yè)務(wù)名詞,詳細(xì)詢(xún)問(wèn)這些名詞的含義,以及它們與其它名詞的關(guān)系,用類(lèi)圖或者對(duì)象圖繪制簡(jiǎn)單的草圖;客戶(hù)在描述業(yè)務(wù)的同時(shí),還會(huì)提出今后的軟件希望實(shí)現(xiàn)的功能,如能夠展示某個(gè)報(bào)表、能夠?qū)С鑫募孕枨罅斜淼男问接涗浵聛?lái)。一個(gè)功能,在需求列表中會(huì)有多個(gè)需求,而每個(gè)需求應(yīng)當(dāng)能夠用1、2句話(huà),在20個(gè)字以?xún)?nèi)就可以描述清楚。需求列表是客戶(hù)提出的最最原始的需求,他不摻雜任何分析設(shè)計(jì),是我們的每項(xiàng)功能必須實(shí)現(xiàn)的內(nèi)容。需求列表是需求驗(yàn)證以及日后的用戶(hù)驗(yàn)收測(cè)試的依據(jù),不論我們今后如何分析和設(shè)計(jì)這些功能,都要能如實(shí)地實(shí)現(xiàn)這個(gè)列表中提出的需求。(需求列表應(yīng)當(dāng)如何編寫(xiě),將在后面的章節(jié)詳細(xì)描述。)

    需求整理,就是在需求研討會(huì)后,需求分析人員對(duì)研討內(nèi)容的分析和整理的過(guò)程。首先,需求分析人員應(yīng)當(dāng)通過(guò)用例模型,劃分整個(gè)系統(tǒng)的功能模塊,以及各個(gè)模塊的業(yè)務(wù)流程。用例模型分析是一個(gè)由粗到細(xì)的過(guò)程,這樣一個(gè)過(guò)程也是符合人類(lèi)認(rèn)識(shí)世界的思維習(xí)慣的一個(gè)過(guò)程。最先,我們應(yīng)當(dāng)對(duì)整個(gè)系統(tǒng)繪制用例圖,設(shè)計(jì)用例場(chǎng)景,并依次對(duì)這些用例進(jìn)行用例描述、流程分析、角色分析等分析過(guò)程。當(dāng)然,在整體用例分析的同時(shí),我們還應(yīng)當(dāng)進(jìn)行一個(gè)整體的角色分析,繪制一個(gè)角色分析圖,進(jìn)行一個(gè)流程分析,繪制一個(gè)流程分析圖(可以是傳統(tǒng)的流程圖、UML中的行動(dòng)圖,甚至一個(gè)簡(jiǎn)單的示意圖,等等)。

    然后,我們?cè)僭谡w用例圖的基礎(chǔ)上,依次對(duì)每個(gè)用例繪制用例圖。每個(gè)用例圖中,會(huì)更細(xì)致地劃分出多個(gè)用例,并依次進(jìn)行用例描述、流程分析、角色分析等分析工作。如此這般地不斷細(xì)化,直到我們認(rèn)為需求已經(jīng)描述清楚為止。

    在一個(gè)系統(tǒng)中,用例需要細(xì)化幾次,是由這個(gè)用例的業(yè)務(wù)復(fù)雜程度決定的。對(duì)于一個(gè)簡(jiǎn)單的用例,只需要細(xì)化一次就夠了;而對(duì)于比較復(fù)雜的用例,則需要細(xì)化2~3次,甚至更多。

    用例分析的過(guò)程,之所以稱(chēng)之為分析,它摻入了很多需求分析人員對(duì)業(yè)務(wù)的理解與設(shè)計(jì):模塊如何劃分、流程如何設(shè)計(jì)、業(yè)務(wù)如何轉(zhuǎn)換,等等。用例分析,還需要讓需求分析員與架構(gòu)師、設(shè)計(jì)師等技術(shù)人員共同協(xié)作來(lái)完成,因?yàn)橛美治鲞€包含對(duì)業(yè)務(wù)需求的技術(shù)可行性分析。只有一份可行的需求分析,才能為后續(xù)的設(shè)計(jì)開(kāi)發(fā)掃清障礙,有效降低項(xiàng)目風(fēng)險(xiǎn)。最后,需求分析員應(yīng)當(dāng)將需求列表中的內(nèi)容,逐一地與用例進(jìn)行核對(duì),以避免分析人員忽略用戶(hù)的某項(xiàng)業(yè)務(wù)需求。(后面將詳細(xì)描述用例模型的搭建過(guò)程。)

    在用例分析的同時(shí),需求分析人員還需要對(duì)業(yè)務(wù)中的相關(guān)事物,制作領(lǐng)域模型。領(lǐng)域模型,是對(duì)用戶(hù)業(yè)務(wù)領(lǐng)域中相關(guān)事物、相互關(guān)系、相互行為操作的描述,它是以對(duì)象圖和類(lèi)圖的形式表達(dá)的。需求人員對(duì)領(lǐng)域模型的分析,對(duì)業(yè)務(wù)理解的深度,對(duì)日后軟件的設(shè)計(jì),以及軟件的功能擴(kuò)展、升級(jí)演化,都起到了至關(guān)重要的作用。(后面將更加詳細(xì)地講述領(lǐng)域模型。)

    最后,當(dāng)我們完成了一系列的分析整理并形成文檔以后,應(yīng)當(dāng)對(duì)及時(shí)地與客戶(hù)進(jìn)行反饋,確認(rèn)我們的理解是否正確,也就是需求驗(yàn)證工作。需求驗(yàn)證工作應(yīng)當(dāng)貫穿整個(gè)研發(fā)周期,并且在不同時(shí)期表現(xiàn)出不同的形式。首先,在需求分析階段,需求驗(yàn)證工作表現(xiàn)為對(duì)需求理解是否正確的信息反饋。需求分析人員與客戶(hù)再次坐在一起,一項(xiàng)一項(xiàng)描述我們對(duì)需求的整理和理解,客戶(hù)則時(shí)不時(shí)地對(duì)一些問(wèn)題進(jìn)行糾正,或者更加深入地加以描述。我們則認(rèn)真地記錄,回來(lái)整理,并等待下一次的驗(yàn)證。在需求分析后期,我們還可以制作一些簡(jiǎn)單的原型,更加形象地描述我們對(duì)需求的理解,會(huì)使我們與客戶(hù)的溝通更加順暢。隨后的設(shè)計(jì)開(kāi)發(fā)階段,我們則應(yīng)當(dāng)以迭代開(kāi)發(fā)的形式進(jìn)行。每開(kāi)發(fā)完一個(gè)迭代周期,將開(kāi)發(fā)的成果與客戶(hù)反饋。這樣做的結(jié)果是,客戶(hù)可以及時(shí)地提出我們對(duì)需求理解的偏差,或者及時(shí)提出對(duì)我們?cè)O(shè)計(jì)不滿(mǎn)意的地方,使我們存在的問(wèn)題得到及時(shí)地發(fā)現(xiàn)與解決。問(wèn)題及時(shí)的解決,使我們修復(fù)問(wèn)題的代價(jià)得以降至最小。之后,當(dāng)開(kāi)發(fā)進(jìn)入到驗(yàn)收測(cè)試階段,我們則是與客戶(hù)一道,一項(xiàng)一項(xiàng)地驗(yàn)證我們的軟件是否滿(mǎn)足需求列表中要求的業(yè)務(wù)需求。最后,當(dāng)軟件迎來(lái)下一次升級(jí)開(kāi)發(fā)時(shí),我們將開(kāi)啟另一次輪回。

    因此,需求分析就是按照這樣的過(guò)程,每次多理解一些,再多理解一些,更多理解一些,逐漸深入的過(guò)程。每深入一步,我們的軟件就更接近客戶(hù)的滿(mǎn)意。

    我們應(yīng)當(dāng)怎樣做需求分析
    我們應(yīng)當(dāng)怎樣做需求調(diào)研:初識(shí)
    我們應(yīng)當(dāng)怎樣做需求調(diào)研:拜訪
    我們應(yīng)當(dāng)怎樣做需求調(diào)研:研討會(huì)
    我們應(yīng)當(dāng)怎樣做需求調(diào)研:需求研討
    我們應(yīng)當(dāng)怎樣做需求調(diào)研:迭代
    (續(xù))

    posted @ 2012-02-14 01:12 paulwong 閱讀(548) | 評(píng)論 (0)編輯 收藏

    Hadoop集群環(huán)境搭建

    通常,集群里的一臺(tái)機(jī)器被指定為 NameNode,另一臺(tái)不同的機(jī)器被指定為JobTracker。這些機(jī)器是 masters。余下的機(jī)器即作為DataNode 也作為T(mén)askTracker。這些機(jī)器是 slaves\ 官方地址:(http://hadoop.apache.org/common/docs/r0.19.2/cn/cluster_setup.html)
    1 先決條件確保在你集群中的每個(gè)節(jié)點(diǎn)上都安裝了所有必需軟件:sun-JDK ,ssh,Hadoop
    JavaTM1.5.x,必須安裝,建議選擇Sun公司發(fā)行的Java版本。
    ssh 必須安裝并且保證 sshd一直運(yùn)行,以便用Hadoop 腳本管理遠(yuǎn)端Hadoop守護(hù)進(jìn)程。
    2 實(shí)驗(yàn)環(huán)境搭建2.1 準(zhǔn)備工作操作系統(tǒng):Ubuntu
    部署:Vmvare
    在vmvare安裝好一臺(tái)Ubuntu虛擬機(jī)后,可以導(dǎo)出或者克隆出另外兩臺(tái)虛擬機(jī)。
    說(shuō)明:
    保證虛擬機(jī)的ip和主機(jī)的ip在同一個(gè)ip段,這樣幾個(gè)虛擬機(jī)和主機(jī)之間可以相互通信。
    為了保證虛擬機(jī)的ip和主機(jī)的ip在同一個(gè)ip段,虛擬機(jī)連接設(shè)置為橋連。

    準(zhǔn)備機(jī)器:一臺(tái)master,若干臺(tái)slave,配置每臺(tái)機(jī)器的/etc/hosts保證各臺(tái)機(jī)器之間通過(guò)機(jī)器名可以互訪,例如:
    10.64.56.76 node1(master)
    10.64.56.77 node2 (slave1)
    10.64.56.78 node3 (slave2)
    主機(jī)信息:

    機(jī)器名IP地址作用
    Node110.64.56.76NameNode、JobTracker
    Node210.64.56.77DataNode、TaskTracker
    Node310.64.56.78DataNode、TaskTracker
    為保證環(huán)境一致先安裝好JDK和ssh:
    2.2 安裝JDK
    #安裝JDK
    $ sudo apt-get install sun-java6-jdk1.2.3
    這個(gè)安裝,java執(zhí)行文件自動(dòng)添加到/usr/bin/目錄。
    驗(yàn)證 shell命令 :java -version 看是否與你的版本號(hào)一致。
    2.3下載、創(chuàng)建用戶(hù)$ useradd hadoop
    $ cd /home/hadoop
    在所有的機(jī)器上都建立相同的目錄,也可以就建立相同的用戶(hù),最好是以該用戶(hù)的home路徑來(lái)做hadoop的安裝路徑。
    例如在所有的機(jī)器上的安裝路徑都是:/home/hadoop/hadoop-0.20.203,這個(gè)不需要mkdir,在/home/hadoop/下解壓hadoop包的時(shí)候,會(huì)自動(dòng)生成)
    (當(dāng)然可以安裝/usr/local/目錄下,例如/usr/local/hadoop-0.20.203/
    chown -R hadoop /usr/local/hadoop-0.20.203/
    chgrp -R hadoop /usr/local/hadoop-0.20.203/

    (最好不要使用root安裝,因?yàn)椴煌扑]各個(gè)機(jī)器之間使用root訪問(wèn) )

    2.4 安裝ssh和配置1) 安裝:sudo apt-get install ssh


    這個(gè)安裝完后,可以直接使用ssh命令 了。
    執(zhí)行$ netstat -nat 查看22端口是否開(kāi)啟了。
    測(cè)試:ssh localhost。
    輸入當(dāng)前用戶(hù)的密碼,回車(chē)就ok了。說(shuō)明安裝成功,同時(shí)ssh登錄需要密碼。
    (這種默認(rèn)安裝方式完后,默認(rèn)配置文件是在/etc/ssh/目錄下。sshd配置文件是:/etc/ssh/sshd_config):

    注意:在所有機(jī)子都需要安裝ssh。

    2) 配置:
    在Hadoop啟動(dòng)以后,Namenode是通過(guò)SSH(Secure Shell)來(lái)啟動(dòng)和停止各個(gè)datanode上的各種守護(hù)進(jìn)程的,這就須要在節(jié)點(diǎn)之間執(zhí)行指令的時(shí)候是不須要輸入密碼的形式,故我們須要配置SSH運(yùn)用無(wú)密碼公鑰認(rèn)證的形式。
    以本文中的三臺(tái)機(jī)器為例,現(xiàn)在node1是主節(jié)點(diǎn),他須要連接node2和node3。須要確定每臺(tái)機(jī)器上都安裝了ssh,并且datanode機(jī)器上sshd服務(wù)已經(jīng)啟動(dòng)。
    ( 說(shuō)明:hadoop@hadoop~]$ssh-keygen -t rsa
    這個(gè)命令將為hadoop上的用戶(hù)hadoop生成其密鑰對(duì),詢(xún)問(wèn)其保存路徑時(shí)直接回車(chē)采用默認(rèn)路徑,當(dāng)提示要為生成的密鑰輸入passphrase的時(shí)候,直接回車(chē),也就是將其設(shè)定為空密碼。生成的密鑰對(duì)id_rsa,id_rsa.pub,默認(rèn)存儲(chǔ)在/home/hadoop/.ssh目錄下然后將id_rsa.pub的內(nèi)容復(fù)制到每個(gè)機(jī)器(也包括本機(jī))的/home/dbrg/.ssh/authorized_keys文件中,如果機(jī)器上已經(jīng)有authorized_keys這個(gè)文件了,就在文件末尾加上id_rsa.pub中的內(nèi)容,如果沒(méi)有authorized_keys這個(gè)文件,直接復(fù)制過(guò)去就行.)
    3) 首先設(shè)置namenode的ssh為無(wú)需密碼的、自動(dòng)登錄。
    切換到hadoop用戶(hù)( 保證用戶(hù)hadoop可以無(wú)需密碼登錄,因?yàn)槲覀兒竺姘惭b的hadoop屬主是hadoop用戶(hù)。)
    $ su hadoop
    cd /home/hadoop
    $ ssh-keygen -t rsa


    然后一直按回車(chē)
    完成后,在home跟目錄下會(huì)產(chǎn)生隱藏文件夾.ssh
    $ cd .ssh
    之后ls 查看文件
    cp id_rsa.pub authorized_keys
    測(cè)試:
    $ssh localhost
    或者:
    $ ssh node1

    第一次ssh會(huì)有提示信息:
    The authenticity of host ‘node1 (10.64.56.76)’ can’t be established.
    RSA key fingerprint is 03:e0:30:cb:6e:13:a8:70:c9:7e:cf:ff:33:2a:67:30.
    Are you sure you want to continue connecting (yes/no)?
    輸入 yes 來(lái)繼續(xù)。這會(huì)把該服務(wù)器添加到你的已知主機(jī)的列表中
    發(fā)現(xiàn)鏈接成功,并且無(wú)需密碼。


    4 ) 復(fù)制authorized_keys到node2 和node3 上
    為了保證node1可以無(wú)需密碼自動(dòng)登錄到node2和node3,先在node2和node3上執(zhí)行

    $ su hadoop
    cd /home/hadoop
    $ ssh-keygen -t rsa
    一路按回車(chē).
    然后回到node1,復(fù)制authorized_keys到node2 和node3
    [hadoop@hadoop .ssh]$ scp authorized_keys node2:/home/hadoop/.ssh/
    [hadoop@hadoop .ssh]$ scp authorized_keys node3:/home/hadoop/.ssh/

    這里會(huì)提示輸入密碼,輸入hadoop賬號(hào)密碼就可以了。
    改動(dòng)你的 authorized_keys 文件的許可權(quán)限 [hadoop@hadoop .ssh]$chmod 644 authorized_keys

    測(cè)試:ssh node2或者ssh node3(第一次需要輸入yes)。
    如果不須要輸入密碼則配置成功,如果還須要請(qǐng)檢查上面的配置能不能正確。
    2.5 安裝Hadoop#切換為hadoop用戶(hù)
    su hadoop
    wgethttp://apache.mirrors.tds.net//hadoop/common/hadoop-0.20.203.0/hadoop-0.20.203.0rc1.tar.gz
    下載安裝包后,直接解壓安裝即可:
    $ tar -zxvfhadoop-0.20.203.0rc1.tar.gz


    1 ) 安裝Hadoop集群通常要將安裝軟件解壓到集群內(nèi)的所有機(jī)器上。并且安裝路徑要一致,如果我們用HADOOP_HOME指代安裝的根路徑,通常,集群里的所有機(jī)器的
    HADOOP_HOME路徑相同。
    2 ) 如果集群內(nèi)機(jī)器的環(huán)境完全一樣,可以在一臺(tái)機(jī)器上配置好,然后把配置好的軟件即hadoop-0.20.203整個(gè)文件夾拷貝到其他機(jī)器的相同位置即可。
    3 ) 可以將Master上的Hadoop通過(guò)scp拷貝到每一個(gè)Slave相同的目錄下,同時(shí)根據(jù)每一個(gè)Slave的Java_HOME 的不同修改其hadoop-env.sh 。
    4) 為了方便,使用hadoop命令或者start-all.sh等命令,修改Master上/etc/profile 新增以下內(nèi)容:
    export HADOOP_HOME=/home/hadoop/hadoop-0.20.203
    exportPATH=$PATH:$HADOOP_HOME/bin
    修改完畢后,執(zhí)行source /etc/profile 來(lái)使其生效。

    6)配置conf/hadoop-env.sh文件

    配置conf/hadoop-env.sh文件
    #添加 export JAVA_HOME=/usr/lib/jvm/java-6-sun/
    這里修改為你的jdk的安裝位置。
    測(cè)試hadoop安裝:
    Bin/hadoop jar hadoop-0.20.2-examples.jarwordcount conf/ /tmp/out
    3. 集群配置(所有節(jié)點(diǎn)相同)3.1配置文件:conf/core-site.xml




    fs.default.name
    hdfs://node1:49000


    hadoop.tmp.dir
    /home/hadoop/hadoop_home/var



    1)fs.default.name是NameNode的URI。hdfs://主機(jī)名:端口/
    2)hadoop.tmp.dir :Hadoop的默認(rèn)臨時(shí)路徑,這個(gè)最好配置,如果在新增節(jié)點(diǎn)或者其他情況下莫名其妙的DataNode啟動(dòng)不了,就刪除此文件中的tmp目錄即可。不過(guò)如果刪除了NameNode機(jī)器的此目錄,那么就需要重新執(zhí)行NameNode格式化的命令。
    3.2配置文件:conf/mapred-site.xml




    mapred.job.tracker
    node1:49001


    mapred.local.dir
    /home/hadoop/hadoop_home/var


    1)mapred.job.tracker是JobTracker的主機(jī)(或者IP)和端口。主機(jī):端口。
    3.3配置文件:conf/hdfs-site.xml




    dfs.name.dir
    /home/hadoop/name1, /home/hadoop/name2 #hadoop的name目錄路徑



    dfs.data.dir
    /home/hadoop/data1, /home/hadoop/data2



    dfs.replication

    2



    1) dfs.name.dir是NameNode持久存儲(chǔ)名字空間及事務(wù)日志的本地文件系統(tǒng)路徑。 當(dāng)這個(gè)值是一個(gè)逗號(hào)分割的目錄列表時(shí),nametable數(shù)據(jù)將會(huì)被復(fù)制到所有目錄中做冗余備份。
    2) dfs.data.dir是DataNode存放塊數(shù)據(jù)的本地文件系統(tǒng)路徑,逗號(hào)分割的列表。 當(dāng)這個(gè)值是逗號(hào)分割的目錄列表時(shí),數(shù)據(jù)將被存儲(chǔ)在所有目錄下,通常分布在不同設(shè)備上。
    3)dfs.replication是數(shù)據(jù)需要備份的數(shù)量,默認(rèn)是3,如果此數(shù)大于集群的機(jī)器數(shù)會(huì)出錯(cuò)。
    注意:此處的name1、name2、data1、data2目錄不能預(yù)先創(chuàng)建,hadoop格式化時(shí)會(huì)自動(dòng)創(chuàng)建,如果預(yù)先創(chuàng)建反而會(huì)有問(wèn)題。
    3.4配置masters和slaves主從結(jié)點(diǎn)配置conf/masters和conf/slaves來(lái)設(shè)置主從結(jié)點(diǎn),注意最好使用主機(jī)名,并且保證機(jī)器之間通過(guò)主機(jī)名可以互相訪問(wèn),每個(gè)主機(jī)名一行。
    vi masters:
    輸入:
    node1
    vi slaves:
    輸入:
    node2
    node3
    配置結(jié)束,把配置好的hadoop文件夾拷貝到其他集群的機(jī)器中,并且保證上面的配置對(duì)于其他機(jī)器而言正確,例如:如果其他機(jī)器的Java安裝路徑不一樣,要修改conf/hadoop-env.sh
    $ scp -r /home/hadoop/hadoop-0.20.203 root@node2: /home/hadoop/

    4 hadoop啟動(dòng)4.1 格式化一個(gè)新的分布式文件系統(tǒng)先格式化一個(gè)新的分布式文件系統(tǒng)
    $ cd hadoop-0.20.203
    $ bin/hadoop namenode -format
    成功情況下系統(tǒng)輸出:

    12/02/06 00:46:50 INFO namenode.NameNode:STARTUP_MSG:
    /************************************************************
    STARTUP_MSG: Starting NameNode
    STARTUP_MSG: host = ubuntu/127.0.1.1
    STARTUP_MSG: args = [-format]
    STARTUP_MSG: version = 0.20.203.0
    STARTUP_MSG: build =http://svn.apache.org/repos/asf/hadoop/common/branches/branch-0.20-security-203-r 1099333; compiled by 'oom' on Wed May 4 07:57:50 PDT 2011
    ************************************************************/

    12/02/0600:46:50 INFO namenode.FSNamesystem: fsOwner=root,root
    12/02/06 00:46:50 INFO namenode.FSNamesystem:supergroup=supergroup
    12/02/06 00:46:50 INFO namenode.FSNamesystem:isPermissionEnabled=true
    12/02/06 00:46:50 INFO common.Storage: Imagefile of size 94 saved in 0 seconds.
    12/02/06 00:46:50 INFO common.Storage: Storagedirectory /opt/hadoop/hadoopfs/name1 has been successfully formatted.
    12/02/06 00:46:50 INFO common.Storage: Imagefile of size 94 saved in 0 seconds.
    12/02/06 00:46:50 INFO common.Storage: Storagedirectory /opt/hadoop/hadoopfs/name2 has been successfully formatted.
    12/02/06 00:46:50 INFO namenode.NameNode:SHUTDOWN_MSG:
    /************************************************************
    SHUTDOWN_MSG: Shutting down NameNode atv-jiwan-ubuntu-0/127.0.0.1
    ************************************************************/


    查看輸出保證分布式文件系統(tǒng)格式化成功
    執(zhí)行完后可以到master機(jī)器上看到/home/hadoop//name1和/home/hadoop//name2兩個(gè)目錄。在主節(jié)點(diǎn)master上面啟動(dòng)hadoop,主節(jié)點(diǎn)會(huì)啟動(dòng)所有從節(jié)點(diǎn)的hadoop。
    4.2 啟動(dòng)所有節(jié)點(diǎn)啟動(dòng)方式1:
    $ bin/start-all.sh (同時(shí)啟動(dòng)HDFS和Map/Reduce)
    系統(tǒng)輸出:

    starting namenode, logging to /usr/local/hadoop/logs/hadoop-hadoop-namenode-ubuntu.out
    node2: starting datanode, loggingto /usr/local/hadoop/logs/hadoop-hadoop-datanode-ubuntu.out
    node3: starting datanode, loggingto /usr/local/hadoop/logs/hadoop-hadoop-datanode-ubuntu.out
    node1: starting secondarynamenode,logging to /usr/local/hadoop/logs/hadoop-hadoop-secondarynamenode-ubuntu.out
    starting jobtracker, logging to/usr/local/hadoop/logs/hadoop-hadoop-jobtracker-ubuntu.out
    node2: starting tasktracker,logging to /usr/local/hadoop/logs/hadoop-hadoop-tasktracker-ubuntu.out
    node3: starting tasktracker,logging to /usr/local/hadoop/logs/hadoop-hadoop-tasktracker-ubuntu.out
    As you can see in slave's output above, it will automatically format it's storage directory(specified by dfs.data.dir) if it is not formattedalready. It will also create the directory if it does not exist yet.
    執(zhí)行完后可以到master(node1)和slave(node1,node2)機(jī)器上看到/home/hadoop/hadoopfs/data1和/home/hadoop/data2兩個(gè)目錄。
    啟動(dòng)方式2:
    啟動(dòng)Hadoop集群需要啟動(dòng)HDFS集群和Map/Reduce集群。
    在分配的NameNode上,運(yùn)行下面的命令啟動(dòng)HDFS:
    $ bin/start-dfs.sh(單獨(dú)啟動(dòng)HDFS集群)
    bin/start-dfs.sh腳本會(huì)參照NameNode上${HADOOP_CONF_DIR}/slaves文件的內(nèi)容,在所有列出的slave上啟動(dòng)DataNode守護(hù)進(jìn)程。
    在分配的JobTracker上,運(yùn)行下面的命令啟動(dòng)Map/Reduce:
    $bin/start-mapred.sh (單獨(dú)啟動(dòng)Map/Reduce)
    bin/start-mapred.sh腳本會(huì)參照J(rèn)obTracker上${HADOOP_CONF_DIR}/slaves文件的內(nèi)容,在所有列出的slave上啟動(dòng)TaskTracker守護(hù)進(jìn)程。

    4.3 關(guān)閉所有節(jié)點(diǎn)從主節(jié)點(diǎn)master關(guān)閉hadoop,主節(jié)點(diǎn)會(huì)關(guān)閉所有從節(jié)點(diǎn)的hadoop。
    $ bin/stop-all.sh
    Hadoop守護(hù)進(jìn)程的日志寫(xiě)入到 ${HADOOP_LOG_DIR} 目錄 (默認(rèn)是 ${HADOOP_HOME}/logs).
    ${HADOOP_HOME}就是安裝路徑.
    5 .測(cè)試1)瀏覽NameNode和JobTracker的網(wǎng)絡(luò)接口,它們的地址默認(rèn)為:
    NameNode - http://node1:50070/
    JobTracker - http://node2:50030/
    3) 使用netstat –nat查看端口49000和49001是否正在使用。
    4) 使用jps查看進(jìn)程
    要想檢查守護(hù)進(jìn)程是否正在運(yùn)行,可以使用 jps 命令(這是用于 JVM 進(jìn)程的ps 實(shí)用程序)。這個(gè)命令列出 5 個(gè)守護(hù)進(jìn)程及其進(jìn)程標(biāo)識(shí)符。
    5)將輸入文件拷貝到分布式文件系統(tǒng):
    $ bin/hadoop fs -mkdir input
    $ bin/hadoop fs -put conf/core-site.xml input
    運(yùn)行發(fā)行版提供的示例程序:
    $ bin/hadoop jar hadoop-0.20.2-examples.jar grep input output 'dfs[a-z.]+'
    6.補(bǔ)充
    Q: bin/hadoop jar hadoop-0.20.2-examples.jar grep input output 'dfs[a-z.]+' 什么意思啊?
    A: bin/hadoop jar(使用hadoop運(yùn)行jar包) hadoop-0.20.2_examples.jar(jar包的名字) grep (要使用的類(lèi),后邊的是參數(shù))input output 'dfs[a-z.]+'
    整個(gè)就是運(yùn)行hadoop示例程序中的grep,對(duì)應(yīng)的hdfs上的輸入目錄為input、輸出目錄為output。
    Q: 什么是grep?
    A: A map/reduce program that counts the matches of a regex in the input.
    查看輸出文件:
    將輸出文件從分布式文件系統(tǒng)拷貝到本地文件系統(tǒng)查看:
    $ bin/hadoop fs -get output output
    $ cat output/*
    或者
    在分布式文件系統(tǒng)上查看輸出文件:
    $ bin/hadoop fs -cat output/*
    統(tǒng)計(jì)結(jié)果:
    root@v-jiwan-ubuntu-0:~/hadoop/hadoop-0.20.2-bak/hadoop-0.20.2#bin/hadoop fs -cat output/part-00000
    3 dfs.class
    2 dfs.period
    1 dfs.file
    1 dfs.replication
    1 dfs.servers
    1 dfsadmin
    7. HDFS常用操作
    hadoopdfs -ls 列出HDFS下的文件
    hadoop dfs -ls in 列出HDFS下某個(gè)文檔中的文件
    hadoop dfs -put test1.txt test 上傳文件到指定目錄并且重新命名,只有所有的DataNode都接收完數(shù)據(jù)才算成功
    hadoop dfs -get in getin 從HDFS獲取文件并且重新命名為getin,同put一樣可操作文件也可操作目錄
    hadoop dfs -rmr out 刪除指定文件從HDFS上
    hadoop dfs -cat in/* 查看HDFS上in目錄的內(nèi)容
    hadoop dfsadmin -report 查看HDFS的基本統(tǒng)計(jì)信息,結(jié)果如下
    hadoop dfsadmin -safemode leave 退出安全模式
    hadoop dfsadmin -safemode enter 進(jìn)入安全模式
    8.添加節(jié)點(diǎn)可擴(kuò)展性是HDFS的一個(gè)重要特性,首先在新加的節(jié)點(diǎn)上安裝hadoop,然后修改$HADOOP_HOME/conf/master文件,加入 NameNode主機(jī)名,然后在NameNode節(jié)點(diǎn)上修改$HADOOP_HOME/conf/slaves文件,加入新加節(jié)點(diǎn)主機(jī)名,再建立到新加節(jié)點(diǎn)無(wú)密碼的SSH連接
    運(yùn)行啟動(dòng)命令:
    start-all.sh
    然后可以通過(guò)http://(Masternode的主機(jī)名):50070查看新添加的DataNode
    9負(fù)載均衡start-balancer.sh,可以使DataNode節(jié)點(diǎn)上選擇策略重新平衡DataNode上的數(shù)據(jù)塊的分布


    結(jié)束語(yǔ):遇到問(wèn)題時(shí),先查看logs,很有幫助。

    posted @ 2012-02-13 23:19 paulwong 閱讀(5546) | 評(píng)論 (0)編輯 收藏

    工作心得之二 業(yè)務(wù)

    說(shuō)到業(yè)務(wù)是個(gè)讓人又愛(ài)又恨的東西,客戶(hù)、領(lǐng)導(dǎo)把它看的很重,不少“技術(shù)控”卻瞧不起它,認(rèn)為它是“低智商”的代名詞。當(dāng)然了,這些看法都很偏激。技術(shù)僅僅是一個(gè)工具,因“業(yè)務(wù)”的需求而誕生至使用,小說(shuō)里常常寫(xiě)到,當(dāng)一個(gè)人學(xué)會(huì)了屠龍之術(shù),卻發(fā)現(xiàn)天地之間沒(méi)有龍給他“屠”,這個(gè)是最悲慘的事情了,這里的“龍”就是業(yè)務(wù),“屠龍之術(shù)”就是技術(shù),離開(kāi)了業(yè)務(wù)的技術(shù)是沒(méi)有意義的。
    業(yè)務(wù)本身是個(gè)抽象的集合,真正把它搞懂了其實(shí)也能鍛煉人的抽象能力。
    說(shuō)來(lái)說(shuō)去“業(yè)務(wù)”是個(gè)什么東西,似乎沒(méi)有明確的定義,我覺(jué)得“業(yè)務(wù)”就是個(gè)“標(biāo)準(zhǔn)”,程序員完成的系統(tǒng)必須滿(mǎn)足這個(gè)“標(biāo)準(zhǔn)”,不同行業(yè),不同硬件環(huán)境都會(huì)有自己的合適的標(biāo)準(zhǔn),某項(xiàng)技術(shù)都有其對(duì)應(yīng)的“標(biāo)準(zhǔn)”。
    比如一直討論很久的問(wèn)題,C++和Java到底誰(shuí)快,為此也有衍生出了很多討論,技術(shù)控也是樂(lè)此不疲,但是或多或少都脫離具體環(huán)境。
    計(jì)算機(jī)語(yǔ)言發(fā)展了這么多年,都會(huì)相互學(xué)習(xí)優(yōu)點(diǎn),不過(guò)總有些本質(zhì)的區(qū)別,比如C++的優(yōu)勢(shì)是和硬件結(jié)合緊密,Java的優(yōu)勢(shì)是屏蔽了硬件限制,兩者在誕生的時(shí)候發(fā)展的方向就有不同,比如通信系統(tǒng)的交換機(jī)等各類(lèi)硬件的程序非C/C++莫屬,Java在這里難有使用的地方,但是在異構(gòu)硬件集群中,現(xiàn)在很火的“云”系統(tǒng),Java的優(yōu)勢(shì)就很明顯,現(xiàn)在常用的服務(wù)器系統(tǒng)大多都是Java。當(dāng)然也有人說(shuō)Java免費(fèi),所以比C++更容易推廣,的確沒(méi)錯(cuò),但是這也屬于“業(yè)務(wù)”的范疇。
    說(shuō)完了業(yè)務(wù)的大范圍,下面說(shuō)說(shuō)具體行業(yè)的業(yè)務(wù)。我最熟悉的是電信的業(yè)務(wù)。相比金融、電商系統(tǒng),從網(wǎng)上的信息來(lái)看似乎電信的系統(tǒng)是最沒(méi)技術(shù)含量的,其實(shí)電信的數(shù)據(jù)量遠(yuǎn)大于金融、電商,只是大量的數(shù)據(jù)是后臺(tái)處理,可以異步展現(xiàn),所以給的要求并不高,總體來(lái)說(shuō)電信系統(tǒng)是入門(mén)的技術(shù)低,做好了很不容易。

    我和不少電信的程序員人聊過(guò),他們紛紛吐槽是,工作就是配置各種業(yè)務(wù)參數(shù),體力活。但是說(shuō)到具體的業(yè)務(wù)模型時(shí),卻說(shuō)不清楚。

    我總結(jié)的電信系統(tǒng)分2兩大部分,業(yè)務(wù)模型(CRM)和工作流(IOM)。CRM和IOM是比較老的名詞了,新的我也不太清楚。
    模型如下:

    主產(chǎn)品+子產(chǎn)品+產(chǎn)品規(guī)則+動(dòng)作

    解釋如下:
    主產(chǎn)品,和硬件掛鉤。現(xiàn)在的電信產(chǎn)品有手機(jī)(移動(dòng),聯(lián)通,電信分屬不同網(wǎng)段)、固話(huà)、ADSL、光纖、2B+D、30B+D等。
    子產(chǎn)品,依賴(lài)于主產(chǎn)品。比如移動(dòng)電話(huà)的各種優(yōu)惠包,寬帶的互聯(lián)星空等。
    產(chǎn)品規(guī)則,這里是最讓人抓狂的。產(chǎn)品規(guī)則分3類(lèi)、
    1、主產(chǎn)品規(guī)則,主產(chǎn)品之間是沒(méi)有任何關(guān)系的,比如一家人可以裝兩條寬帶,用多個(gè)手機(jī)。
    2、子產(chǎn)品規(guī)則,基于不同主產(chǎn)品的子產(chǎn)品之間沒(méi)有任何關(guān)系,基于同一主產(chǎn)品的子產(chǎn)品之間有各種規(guī)則,比如手機(jī)的資費(fèi)包開(kāi)通了一個(gè)就不能開(kāi)通另一個(gè),這類(lèi)為互斥。不同的優(yōu)惠可以共同作用,這類(lèi)為疊加。由于各種子產(chǎn)品的數(shù)量繁多,所以這些規(guī)則的校驗(yàn)和實(shí)現(xiàn)是個(gè)很龐大的數(shù)字。
    3、運(yùn)營(yíng)商制定的規(guī)則,比如,從硬件角度來(lái)說(shuō),裝寬帶、裝電話(huà)、開(kāi)通手機(jī)是互不相干的,但是運(yùn)營(yíng)商制定了各種套餐,“強(qiáng)迫”統(tǒng)一辦理。這個(gè)無(wú)論是對(duì)程序員還是消費(fèi)者都是是很討厭的……
    動(dòng)作,裝、拆,(改=裝+拆)

    分析完了以后可以發(fā)現(xiàn)真正麻煩的地方是業(yè)務(wù)規(guī)則這塊,一個(gè)電信客戶(hù)系統(tǒng)的質(zhì)量高低很大程度上就由這個(gè)“業(yè)務(wù)規(guī)則引擎”決定,如果只是悶頭往這個(gè)引擎里加參數(shù)的確無(wú)聊,但是這正了解這個(gè)引擎的工作步驟還是很有趣的,個(gè)人認(rèn)為理解一個(gè)系統(tǒng)的運(yùn)行是很容易提高能力的。

    下面說(shuō)說(shuō)“工作流”,消費(fèi)者的任何一個(gè)請(qǐng)求在電信系統(tǒng)中都會(huì)轉(zhuǎn)變一個(gè)流程,某些特殊的業(yè)務(wù)流程會(huì)很長(zhǎng),比如裝高清寬帶,需要人上門(mén)施工,并測(cè)試寬帶質(zhì)量等,這些都成功了才會(huì)觸發(fā)其它的步驟。消費(fèi)者的業(yè)務(wù)請(qǐng)求在后端實(shí)現(xiàn)往往是“事務(wù)”型的,比如原來(lái)是套餐A,改成套餐B的會(huì)有3個(gè)步驟,不熟悉電信業(yè)務(wù)的人可以想下“神州行”改“全球通”。當(dāng)步驟1和2施工成功后,步驟3發(fā)現(xiàn)現(xiàn)有條件不滿(mǎn)足時(shí)(這里的判斷不在當(dāng)前系統(tǒng)中,或者說(shuō)當(dāng)前系統(tǒng)無(wú)法判斷,必須將數(shù)據(jù)發(fā)送到另一個(gè)平臺(tái)之后由那個(gè)平臺(tái)來(lái)判斷,這種情況在電信系統(tǒng)里很常見(jiàn),比如當(dāng)前系統(tǒng)沒(méi)有客戶(hù)資料,所以無(wú)法判斷),也就意味著不能辦理套餐B,這樣得回復(fù)成套餐A,這樣需要對(duì)步驟1和2得進(jìn)行反向施工,也就是“事務(wù)回滾”。先后這就是“工作流”的任務(wù)。
    工作流在電信系統(tǒng)中是很重要的角色,相比于是電商和金融系統(tǒng),電信系統(tǒng)的工作流最強(qiáng)大。
    簡(jiǎn)單解釋下工作流,工作流有兩個(gè)最基本單元(節(jié)點(diǎn)),邏輯節(jié)點(diǎn)和工作節(jié)點(diǎn)(不同的系統(tǒng)中叫法也不同,但是作用都一樣)。
    邏輯節(jié)點(diǎn),就是if判斷。
    工作節(jié)點(diǎn),就是一個(gè)具體的施工環(huán)節(jié),一般關(guān)聯(lián)一個(gè)平臺(tái)。
    一般工作流的具體配置都由這兩種節(jié)點(diǎn)組成。

    工作流定義的關(guān)系有,串行和并行(電信里的叫法是同進(jìn)同退,一般直接定義成事務(wù))。
    于一個(gè)系統(tǒng)來(lái)說(shuō),業(yè)務(wù)層的調(diào)優(yōu)效果優(yōu)于代碼層的調(diào)優(yōu)效果(代碼錯(cuò)誤引起的宕機(jī)問(wèn)題不屬于調(diào)優(yōu)范圍)。比如,一個(gè)業(yè)務(wù)的判斷規(guī)則精簡(jiǎn)了,比你優(yōu)化幾個(gè)計(jì)算語(yǔ)句強(qiáng)的多。比如之前說(shuō)的例子,在步驟1、2、3中,因?yàn)?出了問(wèn)題,導(dǎo)致1、2得反向施工,所以實(shí)際有5步操作,1、2、3、2反向、1反向。所以如果3最容易出問(wèn)題,那么應(yīng)該調(diào)整順序應(yīng)該是3、1、2,把最容易出問(wèn)題的放在最開(kāi)始,這樣可以避免不必要的步驟。其實(shí)在系統(tǒng)上線(xiàn)后運(yùn)行一段時(shí)間,就可以統(tǒng)計(jì)出那些平臺(tái)的出錯(cuò)率高,調(diào)整順序幾乎是0修改,但是帶來(lái)的效率提升是明顯的,但是沒(méi)有幾個(gè)地方有這么做的。

    說(shuō)了這么多,我覺(jué)得把整個(gè)系統(tǒng)的框架搞明白還是很能提高個(gè)人能力,抽象邏輯對(duì)于程序員來(lái)說(shuō)必不可少。所以現(xiàn)在每次抱怨工作無(wú)聊時(shí),我都會(huì)想想,真的就不能挖出點(diǎn)東西么?

    posted @ 2012-02-13 23:15 paulwong 閱讀(240) | 評(píng)論 (0)編輯 收藏

    工作心得之一 團(tuán)隊(duì)

    轉(zhuǎn)眼又是一年,也是我工作的第五個(gè)年頭。一直想抽時(shí)間寫(xiě)點(diǎn)這幾年的工作心得,但一直沒(méi)時(shí)間,今天難得空閑,可以寫(xiě)點(diǎn)。這幾年下來(lái),我擔(dān)任過(guò)很過(guò)角色,碼農(nóng),組長(zhǎng),設(shè)計(jì)/架構(gòu)等都有涉及,所以總結(jié)也分3部分:團(tuán)隊(duì)、業(yè)務(wù)、技術(shù)。今天先說(shuō)說(shuō)團(tuán)隊(duì),估計(jì)有很多人也有想法,歡迎大家討論。

    俗話(huà)說(shuō),雙全難敵四手,一個(gè)人再牛也比不了一個(gè)團(tuán)隊(duì)。

    我在3家公司呆過(guò),有國(guó)企也有外企,也和很多朋友聊天談到不同的企業(yè)團(tuán)隊(duì),發(fā)現(xiàn)不同企業(yè)的團(tuán)隊(duì)質(zhì)量上的差距是很明顯的。首先聲明,這里僅僅是我對(duì)我所知的環(huán)境做個(gè)比較,并不針對(duì)哪些公司,更沒(méi)有貶低誰(shuí)的意思。

    對(duì)于一個(gè)人來(lái)說(shuō),有一個(gè)好的團(tuán)隊(duì)就好象在社會(huì)里有個(gè)“家”,如果是一個(gè)壞的團(tuán)隊(duì),那么就是一個(gè)“坑”。
    為了提高開(kāi)發(fā)效率,現(xiàn)在有越來(lái)越多的開(kāi)發(fā)模式被提出來(lái)了,但是經(jīng)常有人抱怨說(shuō)采用敏捷開(kāi)發(fā)模式,效率沒(méi)一點(diǎn)上升,反而因?yàn)橹贫ǜ鞣N規(guī)則導(dǎo)致效率下降很多,提出這種模式的人只會(huì)扯淡。我想有這種抱怨的“管理者”應(yīng)該很多吧,當(dāng)然更多人都知道開(kāi)發(fā)模式其實(shí)是很有效的手段,只是不知道怎么或者什么時(shí)候用它。其實(shí)老外在這方面覺(jué)得挺好,他們的工作流程是這樣的,接到某個(gè)任務(wù)后,會(huì)分配到若干人員頭上,那么這些人員就成了一個(gè)“臨時(shí)”的團(tuán)隊(duì),如果在大型公司里,這樣是很常見(jiàn)的,網(wǎng)上有個(gè)詞叫“內(nèi)部外包”制,他們按照“敏捷”的模型/步驟完成任務(wù)。這樣的團(tuán)隊(duì)有個(gè)特點(diǎn)是,團(tuán)隊(duì)中的人相互不熟悉,但是齊心,采用某些開(kāi)發(fā)模式或者流程可以彌補(bǔ)因?yàn)槟吧鷰?lái)的問(wèn)題,合理的安排每個(gè)人都任務(wù),所以起到很好的效果。說(shuō)到這里我覺(jué)得就夠了,抱怨“開(kāi)發(fā)模式”無(wú)用的團(tuán)隊(duì)的特點(diǎn)是,成員之間很熟悉,但是心不齊,這種情況什么模式都沒(méi)用。不知道多少人有同感。
    但是團(tuán)隊(duì)怎樣才能真正的團(tuán)結(jié)是個(gè)問(wèn)題。這里就把一個(gè)團(tuán)隊(duì)可以分成底層的員工和上層的領(lǐng)導(dǎo)。
    員工是每個(gè)人都起點(diǎn),所以先從員工說(shuō)起(當(dāng)然有名爹的除外)。
    作為員工,需要什么?
    員工所需要的很簡(jiǎn)單,待遇 、發(fā)展平臺(tái) 和 環(huán)境。前兩者很好理解。
    待遇,很多人明確就是有錢(qián)就干,沒(méi)錢(qián)就滾蛋,的確錢(qián)很重要,但這個(gè)真不是全部,后面細(xì)說(shuō)。
    平臺(tái),關(guān)系到市場(chǎng)等等因素,比較明顯,也沒(méi)什么好說(shuō)的。
    至于環(huán)境這個(gè)就很抽象了,環(huán)境這里也分很多因素,最關(guān)鍵的一個(gè)是來(lái)自于領(lǐng)導(dǎo),舉個(gè)例子來(lái)說(shuō)明,某個(gè)項(xiàng)目出了個(gè)問(wèn)題,客戶(hù)大發(fā)雷霆,公司領(lǐng)導(dǎo)屁顛屁顛跑來(lái)賠罪,然后很瀟灑的在大酒店請(qǐng)客戶(hù)吃了頓,擺平客戶(hù)后回頭很瀟灑的把當(dāng)事人罵一頓,當(dāng)事人第二天瀟灑的離職,然后就能看見(jiàn)很多人罵街……,估計(jì)很多人都有過(guò)這樣或者看見(jiàn)過(guò)這樣的場(chǎng)景。這是我覺(jué)得中國(guó)很多團(tuán)隊(duì)的最大問(wèn)題,領(lǐng)導(dǎo)眼里一切都是“客戶(hù)”至上,或許有些道理,但是如果把員工放輕了就很是問(wèn)題。如果把客戶(hù)看成“金礦”,那么員工就是“礦工”,誠(chéng)然,客戶(hù)是給錢(qián)的,但是這個(gè)過(guò)程得通過(guò)員工來(lái)完成,客戶(hù)和員工對(duì)于“領(lǐng)導(dǎo)”來(lái)說(shuō)應(yīng)該是同等重要的,公司給客戶(hù)的形象完全來(lái)自員工,絕不是領(lǐng)導(dǎo)請(qǐng)的那幾頓飯。再說(shuō)明白點(diǎn),就是領(lǐng)導(dǎo)要給予員工起碼的尊重,而不是使喚完了就結(jié)束,這樣才能換來(lái)員工的忠誠(chéng)。

    下面說(shuō)說(shuō)“錢(qián)”的問(wèn)題,我想說(shuō)的是,錢(qián)不代表一切,錢(qián)只能解決一時(shí)的問(wèn)題,但不可能長(zhǎng)久,光是提高待遇的結(jié)果就是,員工越來(lái)越“貪”。
    還是舉個(gè)例子,美國(guó)做過(guò)實(shí)驗(yàn),讓一個(gè)人在獨(dú)立的房間里,和外界無(wú)法聯(lián)系,實(shí)驗(yàn)者在里面每呆一天就能獲得很多報(bào)酬,我想這個(gè)實(shí)驗(yàn)大家都知道,結(jié)果是,沒(méi)人撐得了1星期。把這個(gè)實(shí)驗(yàn)抽象一下,把你放在一個(gè)團(tuán)隊(duì)里,團(tuán)隊(duì)里的每個(gè)人都看不起你,鄙視你,無(wú)論給你多少錢(qián),你也呆不久,當(dāng)然毅力驚人的財(cái)迷除外……
    對(duì)于一個(gè)團(tuán)隊(duì)來(lái)說(shuō),需要給員工一種感覺(jué),“歸屬感”。說(shuō)起來(lái)很抽象,那么還是舉例子,想下我們大學(xué)畢業(yè)吃散伙飯那會(huì),多少人哭的昏天黑地?那種感覺(jué)算是歸屬感。一起翹課,一起掛科,一起出丑等等等等,才讓我們有了歸屬感。那么回到社會(huì)里來(lái),怎么讓一個(gè)團(tuán)隊(duì)有個(gè)歸屬感呢?這里得看“公司”和“領(lǐng)導(dǎo)”的本事了。

    先從公司說(shuō)起吧,這里得說(shuō)個(gè)看似不相干的事。
    中國(guó)古代有很多團(tuán)隊(duì),比如戲班子,建筑隊(duì)等,新加入的菜鳥(niǎo)都會(huì)有個(gè)專(zhuān)門(mén)的“師傅”帶,這時(shí),師傅不僅僅是傳授技藝,還會(huì)在思想和情感上教育徒弟,所以古時(shí)有“一日為師,終身為父”的說(shuō)法,這不僅僅是出于師長(zhǎng)的尊重,很多時(shí)候“師傅”完全承擔(dān)了“父親”的角色。現(xiàn)在時(shí)代不同了,職場(chǎng)中很難找到推心置腹的人,逐漸演變成了干一份活拿一份錢(qián)。沒(méi)錯(cuò),看起來(lái)很公平,也是從資本主義那里學(xué)來(lái)的(但是只學(xué)了皮毛而已),造成結(jié)果就是讓員工覺(jué)得自己僅僅是個(gè)機(jī)器,需要的時(shí)候租一下,不需要的時(shí)候隨時(shí)給T掉。
    其實(shí)在任何大企業(yè)里,員工在入職時(shí)都有員工培訓(xùn),定期舉行teambuilding,workshop,outing(我只在外企里享受過(guò)這些活動(dòng),具體解釋也說(shuō)不大清楚,簡(jiǎn)單來(lái)說(shuō)就是游玩組織活動(dòng)之類(lèi)的)等,不少企業(yè)為了省錢(qián),都免了,其實(shí)這些真的很重要。先說(shuō)說(shuō)國(guó)外的吧(是國(guó)外,不是外企在中國(guó)的分公司),最常見(jiàn)的方式有, 老板和大家一起喝啤酒,打桌球/高爾夫等。這樣就可以創(chuàng)造一個(gè)員工相互交流的平臺(tái)和時(shí)間,老板有更多時(shí)間來(lái)和員工交流,
    現(xiàn)在在回想下我們的團(tuán)隊(duì),一年都見(jiàn)不著老板幾次面,也沒(méi)幾次聚會(huì),動(dòng)不動(dòng)還扣點(diǎn)錢(qián),這樣的公司下面肯定是沒(méi)好團(tuán)隊(duì)的,人員流動(dòng)肯定大。部分大企業(yè)有各種活動(dòng),但是有的做的不好,比如年會(huì)就是包個(gè)大場(chǎng)地,大飯店,來(lái)幾個(gè)表演,抽獎(jiǎng),大多數(shù)都是這樣了吧,我也和同事聊過(guò),感覺(jué)就是領(lǐng)導(dǎo)來(lái)自?shī)首詷?lè)一把,完全沒(méi)員工的事,吃飽走人就行(抽獎(jiǎng)?恩抽到最好,我是比較背的那種)。有多少領(lǐng)導(dǎo)真的是放下身價(jià)真的和員工進(jìn)行互動(dòng)?
    估計(jì)“員工僅僅是個(gè)工具,和服務(wù)器這類(lèi)機(jī)械沒(méi)本質(zhì)區(qū)別。”是那些老板的真實(shí)想法。

    如果公司在大環(huán)境下創(chuàng)造不好,下面的團(tuán)隊(duì)很難發(fā)展好。

    說(shuō)完公司大環(huán)境就說(shuō)說(shuō)關(guān)系到自己的的團(tuán)隊(duì)。
    任何一個(gè)團(tuán)隊(duì)都有個(gè)“老大”,我是一直這么稱(chēng)呼的,有點(diǎn)黑社會(huì)的味道,為什么呢?因?yàn)橐龊靡粋€(gè)領(lǐng)導(dǎo),還真得和“古惑仔”電影中的“老大”學(xué)習(xí)。
    1、尊重下屬。真正的“尊重”才能換來(lái)他們的忠誠(chéng),當(dāng)然他們會(huì)有不同理由離開(kāi)團(tuán)隊(duì),但是離開(kāi)后還能是好朋友(有多少離職后是老死不通音信的?)。在中國(guó)(國(guó)外不清楚),大多數(shù)人(不是全部)都有“土皇帝”的情節(jié),總覺(jué)得下屬就是自己的“奴隸”,做什么都是應(yīng)該的。到最后肯定是光桿司令。當(dāng)然,員工之間也應(yīng)該相互尊重,但員工間的矛盾對(duì)于團(tuán)隊(duì)來(lái)說(shuō)是小問(wèn)題。

    2、公平。對(duì)于員工來(lái)說(shuō),公平分兩層,一個(gè)是在員工之間,有些人和領(lǐng)導(dǎo)熟,承擔(dān)的任務(wù)輕,反之則重,這個(gè)就不多說(shuō)了,都清楚。另一層的公平是在員工和客戶(hù)之間,有的時(shí)候明顯是客戶(hù)的錯(cuò)誤,但是為了“效益”硬說(shuō)成是員工的,或許這樣的行為可以換來(lái)一時(shí)的利益,但是換個(gè)位置想想,一個(gè)人在你面前只會(huì)諂媚,臟水都往自己身上潑,你會(huì)瞧的起他么?時(shí)間長(zhǎng)了客戶(hù)不把你當(dāng)人,員工也不把你當(dāng)人,不知道你自己把自己當(dāng)什么……

    3、合理地護(hù)短,直接說(shuō)清楚比較難,還得舉個(gè)例子。當(dāng)客戶(hù)無(wú)論提出什么要求,如果領(lǐng)導(dǎo)都一字不落的轉(zhuǎn)發(fā),對(duì)于員工來(lái)說(shuō),有沒(méi)有這個(gè)領(lǐng)導(dǎo)是沒(méi)區(qū)別的,自然不理你。換個(gè)角度,當(dāng)客戶(hù)的任務(wù)過(guò)重時(shí),如果領(lǐng)導(dǎo)能和客戶(hù)交涉,為員工爭(zhēng)取些權(quán)益,員工就會(huì)有一種“保護(hù)傘”的感覺(jué),自然也就會(huì)依靠你。當(dāng)然凡事得適當(dāng)。

    到這里是不是很像黑社會(huì)的老大?以上三點(diǎn)對(duì)于任何行業(yè)的團(tuán)隊(duì)都適用。

    4、合理的薪資,這個(gè)又是焦點(diǎn)話(huà)題,老外定義的合理的薪資是基本工資夠員工在當(dāng)前城市生活,但是一定要有合理的獎(jiǎng)勵(lì)體系,有出色表現(xiàn)的時(shí)候要按時(shí)獎(jiǎng)勵(lì),這個(gè)薪資體系是和銷(xiāo)售的薪資構(gòu)成很像(但細(xì)節(jié)和落實(shí)程度就有很大差別)。獎(jiǎng)勵(lì)體系是國(guó)外工資里很重要的一部分,國(guó)內(nèi)雖然有各種績(jī)效考核,結(jié)果到頭來(lái)總是有什么預(yù)算不夠,人員太多等等廢話(huà)成了一紙空文。甚至演變成“拼爹”,反正在壟斷行業(yè)里,出來(lái)問(wèn)題,就T來(lái)T去,沒(méi)爹的孩子就成了臨時(shí)工。

    在老外眼里獎(jiǎng)勵(lì)措施是很重要的,比懲罰措施更重要(中國(guó)做法只有責(zé)任落實(shí)到個(gè)人,出了問(wèn)題一定得找個(gè)零時(shí)工出來(lái)……),為什么說(shuō)獎(jiǎng)勵(lì)措施很重要呢?再舉例子,在眾多抱怨中,最多的是“我干了XXX事,他們不管,一時(shí)犯困就被罰”或者類(lèi)似的。不可否認(rèn)有對(duì)丑事選擇性遺忘的的因素,但是領(lǐng)導(dǎo)對(duì)下屬出色表現(xiàn)視而不見(jiàn),但對(duì)錯(cuò)誤嚴(yán)厲懲罰的做法是團(tuán)隊(duì)最大的“傷害”,這樣給員工的感覺(jué)就是“干得好和干得一般”沒(méi)區(qū)別,但是“犯錯(cuò)了就肯定會(huì)追究”,這樣是最消磨員工的積極性和創(chuàng)造性的,所以很多人是做一天和尚撞一天鐘。我和兩個(gè)老外聊過(guò),他們那里如果這個(gè)月干得好了,最高獎(jiǎng)金是工資的4倍(最高,不是平均,他們所在的公司也是很不錯(cuò)的公司,那里也不是所有企業(yè)有這么好的獎(jiǎng)勵(lì)),所以人人會(huì)主動(dòng)找事干,每周一次的聚會(huì)都會(huì)找老板展露自己的“成果”。國(guó)內(nèi)企業(yè)也有獎(jiǎng)勵(lì)制度,但首先那種獎(jiǎng)勵(lì)程度實(shí)在不值一提,其次,員工有方便的通道來(lái)告訴領(lǐng)導(dǎo)么,領(lǐng)導(dǎo)知道了會(huì)重視么?

    提高產(chǎn)品的效率、質(zhì)量必須從團(tuán)隊(duì)開(kāi)始。我見(jiàn)過(guò)的最好團(tuán)隊(duì),6個(gè)人合作了4年,5個(gè)員工+1老大。每次任務(wù)下來(lái)后,“老大”不需要多廢話(huà)話(huà),每個(gè)人就知道自己負(fù)責(zé)哪塊,老大只需要和客戶(hù)扯皮,也基本不需要擔(dān)心哪個(gè)人跳槽,員工郁悶了就喊老大去喝啤酒。這個(gè)團(tuán)隊(duì)也沒(méi)什么開(kāi)發(fā)模式,更沒(méi)什么規(guī)章制度。

    最后,希望大家在新年里都能找到自己的團(tuán)隊(duì)。

    posted @ 2012-02-13 23:08 paulwong 閱讀(245) | 評(píng)論 (0)編輯 收藏

    管理隨筆

    項(xiàng)目管理說(shuō)到底就是人的管理,這是我在項(xiàng)目管理中意識(shí)到的幾個(gè)關(guān)注點(diǎn)。

    1. 規(guī)則制定。 沒(méi)有規(guī)矩,不成方圓,軍隊(duì)沒(méi)有紀(jì)律就是一盤(pán)散沙,做項(xiàng)目亦如此。各個(gè)公司甚至項(xiàng)目都有自己不同的規(guī)則,規(guī)則的存在是為了約束成員的行為,鼓勵(lì)對(duì)團(tuán)隊(duì)發(fā)展有利的行為,減少對(duì)團(tuán)隊(duì)發(fā)展有害的行為。同時(shí)規(guī)則的制定需要人性化。這里舉個(gè)例子,我公司并不要求員工按時(shí)上班,也無(wú)上班打卡。于是項(xiàng)目經(jīng)理在上班時(shí)間在辦公室看不到幾個(gè)人,有些事情想當(dāng)面跟某成員說(shuō)都要先跟成員預(yù)約時(shí)間。項(xiàng)目進(jìn)度不緊,任務(wù)也不重,做的按部就班,并無(wú)大的出錯(cuò)。因?yàn)楹芏嗳瞬粊?lái),經(jīng)常來(lái)的幾個(gè)人也開(kāi)始來(lái)的少了,這樣的規(guī)則有無(wú)問(wèn)題?

    這樣的規(guī)則就造成了一個(gè)現(xiàn)象:辦公室里一個(gè)人都沒(méi)了。同時(shí)由于溝通的時(shí)間越來(lái)越少,項(xiàng)目本來(lái)可以做得更好的但是現(xiàn)在只是沒(méi)有出大的差錯(cuò)而已。懶人更懶,積極上進(jìn)的人積極性也大受打擊,熱情降低。本來(lái)可以集中辦公的,現(xiàn)在變成虛擬團(tuán)隊(duì)了。

    規(guī)則的制定既需要限制成員的自由,又要給成員最大的自由,所有的規(guī)則制定的出發(fā)點(diǎn)只有一個(gè):團(tuán)隊(duì)發(fā)展。第一條,對(duì)團(tuán)隊(duì)發(fā)展有壞的影響的規(guī)則都不是好規(guī)則。然后才是第二條,規(guī)則需要人性化。第三,規(guī)則的合理有效性。

    上面的例子,如果改為: 上班不打卡,但是員工需要每天到公司上班,如果某天因?yàn)橛惺聛?lái)不了在不影響項(xiàng)目的前提下需要提前一天通知項(xiàng)目經(jīng)理,一個(gè)月不來(lái)的次數(shù)不能超過(guò)5次。早上上班時(shí)間可以定為10:00,10點(diǎn)還遲到的次數(shù)一個(gè)月不能超過(guò)10次。不過(guò)這需要增加有一個(gè)人來(lái)記錄。



    2. 賞罰分明。不論是好規(guī)則還是壞規(guī)則,有規(guī)則就要執(zhí)行,就會(huì)有人經(jīng)常違反,有人經(jīng)常遵守,就會(huì)有賞有罰。賞罰分明的好處,就是要讓大家知道,干得好和干得壞的待遇不一樣。比如上面的新的上班規(guī)則,如果有人違反了,怎么辦?如果是你的得力下屬違反了,怎么辦?甚至于如果是你自己違反了,怎么辦?如果因?yàn)槟愀硞€(gè)成員私交很好,就酌情處理,那你的后門(mén)以后會(huì)被踏平,大家都會(huì)來(lái)努力跟你搞好關(guān)系,項(xiàng)目沒(méi)人做了。如果拉不下面子,不妨自己故意違反一次,然后按規(guī)定處罰自己。

    當(dāng)然,罰只能是一種手段,罰不能常用,應(yīng)該常用的是賞。項(xiàng)目經(jīng)理一定要有能力拿到經(jīng)費(fèi),哪怕很少。賞不能自己掏腰包對(duì)吧? 總之,做好做壞一定要不一樣,而且最好馬上就能不一樣,而不是體現(xiàn)到年終的績(jī)效考核上,那太遠(yuǎn)了。


    那上面的規(guī)則就可以進(jìn)一步變成: 一個(gè)月遲到10次口頭警告,團(tuán)隊(duì)里面通報(bào)。天天天遲到(20次)則通告上級(jí)經(jīng)理,扣季度獎(jiǎng)金xxx。一個(gè)月不來(lái)次數(shù)超過(guò)5次,口頭警告,團(tuán)隊(duì)里面通報(bào)。一個(gè)月不來(lái)次數(shù)超過(guò)10次,則通告上級(jí)經(jīng)理,勸退xxx。一個(gè)月無(wú)遲到,無(wú)缺勤則拿全勤獎(jiǎng),xxxx。

    如果有人下午四點(diǎn)鐘來(lái),五點(diǎn)鐘走,怎么辦?呵呵,這樣的人很少吧?有也是奇葩,那你就再修訂規(guī)則吧。

    3. 溝通和社交風(fēng)格,迎合能力。
    溝通是個(gè)大話(huà)題,項(xiàng)目中項(xiàng)目經(jīng)理75%以上的時(shí)間用于溝通。。。

    posted @ 2012-02-13 22:25 paulwong 閱讀(242) | 評(píng)論 (0)編輯 收藏

    JBOSS集群安裝

    軟件及環(huán)境:
    jboss-5.1.0.GA
    nginx-0.8.15
    centos5.5
    nginx:192.168.1.251
    tomat1:192.168.1.251
    tomat2:192.168.1.252
    jboss安裝目錄為:/usr/local/jboss
    nginx安裝目錄為:/usr/local/nginx

    JDK、JBOSS、nginx安裝略過(guò)!

    Jboss1配置:

    /opt/jboss4.3/jboss-as/server/node2/deploy/jboss-web.deployer/server.xml

    <!--由于在LINUX環(huán)境下,會(huì)有多個(gè)IP,address不能改成${0.0.0.0},這樣會(huì)對(duì)127.0.0.1也會(huì)進(jìn)行監(jiān)聽(tīng),導(dǎo)致啟動(dòng)出錯(cuò)-->
    <Connector protocol="HTTP/1.1" port="8080" address="${ jboss.bind.address}">

    <!--將<Engine name="jboss.web" defaultHost="localhost">修改為-->
    <Engine name="jboss.web" defaultHost="localhost" jvmRoute="jboss1">

    /opt/jboss4.3/jboss-as/server/node2/deploy/jboss-messaging.sar/messaging-service.xml
    <!--將20行的<attribute name="ServerPeerID">${jboss.messaging.ServerPeerID:0}</attribute>修改-->
    <attribute name="ServerPeerID">${jboss.messaging.ServerPeerID:1}</attribute>

    Jboss2配置:

    /opt/jboss4.3/jboss-as/server/node2/deploy/jboss-web.deployer/server.xml

    <!--由于在LINUX環(huán)境下,會(huì)有多個(gè)IP,address不能改成${0.0.0.0},這樣會(huì)對(duì)127.0.0.1也會(huì)進(jìn)行監(jiān)聽(tīng),導(dǎo)致啟動(dòng)出錯(cuò)-->
    <Connector protocol="HTTP/1.1" port="8080" address="${ jboss.bind.address}">

    <!--將<Engine name="jboss.web" defaultHost="localhost">修改為-->
    <Engine name="jboss.web" defaultHost="localhost" jvmRoute="jboss2">

    /opt/jboss4.3/jboss-as/server/node2/deploy/jboss-messaging.sar/messaging-service.xml
    <!--將20行的<attribute name="ServerPeerID">${jboss.messaging.ServerPeerID:0}</attribute>修改-->
    <attribute name="ServerPeerID">${jboss.messaging.ServerPeerID:2}</attribute>

    如果想要session同步的話(huà),要在站點(diǎn)的web.xml里面加入<distributable/>

    測(cè)試文件index.jsp內(nèi)容如下:
    <%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding
    ="UTF-8"%>
     
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
     
    <%@page import="java.util.*"%>
     
    <%@page import="java.net.InetAddress;"%>
     
    <html>
     
    <head>
     
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
     
    <title>Cluster App Test</title>
     
    </head>
     
    <body>
     
    <%
     InetAddress ip 
    = InetAddress.getLocalHost();
     
    //out.println(ip.getHostAddress());
     
    %>
     This is responsed by 
    <font color="red"> <%=ip.getHostAddress() %></font><br>
     Host Name : 
    <font color="red"><%=ip.getHostName() %></font><br>
     Time : 
    <font color="red"><%=new Date() %></font><br>
     
    <%
     ip 
    = null;
     
    %>
    <br/> <br/> <br/> <br/>
    Server Info:
    <%
    out.println(request.getLocalAddr() 
    + " : " + request.getLocalPort()+"<br>");%>
    <%
      out.println(
    "<br>Session ID " + session.getId()+"<br>");
     
    // 如果有新的 Session 屬性設(shè)置
     
    String dataName = request.getParameter("dataName");
     
    if (dataName != null && dataName.length() > 0) {
        
    String dataValue = request.getParameter("dataValue");
         session.setAttribute(dataName, dataValue);
      }
      out.print(
    "<br/> <b>Session 列表</b>");
      Enumeration e 
    = session.getAttributeNames();
     
    while (e.hasMoreElements()) {
        
    String name = (String)e.nextElement();
        
    String value = session.getAttribute(name).toString();
         out.println( name 
    + " = " + value+"<br>");
             System.out.println( name 
    + " = " + value);
       }
    %>
     
    <form action="index.jsp" method="POST">
        名稱(chēng):
    <input type=text size=20 name="dataName">
        
    <br>
       
    &nbsp;&nbsp;值:<input type=text size=20 name="dataValue">
        
    <br>
       
    <input type=submit>
      
    </form>
     
    </body>
     
    </html>

    Jboss動(dòng)好像沒(méi)什么要求,,可以?xún)蓚€(gè)同時(shí)啟動(dòng),等啟動(dòng)完之后再啟動(dòng)NGINX就OK了!

    Jboss的啟動(dòng)命令為(必須加參數(shù)-b ,很多配置文件都依賴(lài)于${ jboss.bind.address}這個(gè)值,也就是命令行輸入的IP地址):
    /usr/local/jboss/bin/run.sh -c all -b 192.168.1.251


    等都啟動(dòng)完成,就可以防問(wèn)http://192.168.1.251/cluster-test/

    寫(xiě)一個(gè)session,刷新,如果session在不同的機(jī)器上保持不變,那就集成功了!如下圖:

    posted @ 2012-02-13 16:18 paulwong 閱讀(2005) | 評(píng)論 (0)編輯 收藏

    jboss中控制臺(tái)jmx-console 登錄的用戶(hù)名和密碼設(shè)置

    默認(rèn)情況訪問(wèn) http://localhost:8080/jmx-console 就可以瀏覽jboss的部署管理的一些信息,不需要輸入用戶(hù)名和密碼,使用起來(lái)有點(diǎn)安全隱患。下面我們針對(duì)此問(wèn)題對(duì)jboss進(jìn)行配置,使得訪問(wèn)jmx- console也必須要知道用戶(hù)名和密碼才可進(jìn)去訪問(wèn)。步驟如下:

    i) 找到JBoss安裝目錄/server/default/deploy/jmx-console.war/WEB-INF/jboss-web.xml文 件,去掉<security-domain>java:/jaas/jmx-console</security- domain>的注釋。修改后的該文件內(nèi)容為:

    <jboss-web>
       
    <!-- Uncomment the security-domain to enable security. You will
          need to edit the htmladaptor login configuration to setup the
          login modules used to authentication users.
    -->
          
    <security-domain>java:/jaas/jmx-console</security-domain>
    </jboss-web>


    ii)修改與i)中的jboss-web.xml同級(jí)目錄下的web.xml文件,查找到<security-constraint/>節(jié)點(diǎn),去掉它的注釋?zhuān)薷暮笤摬糠謨?nèi)容為:

    <!-- A security constraint that restricts access to the HTML JMX console
       to users with the role JBossAdmin. Edit the roles to what you want and
       uncomment the WEB-INF/jboss-web.xml/security-domain element to enable
       secured access to the HTML JMX console.
    -->
       
    <security-constraint>
         
    <web-resource-collection>
           
    <web-resource-name>HtmlAdaptor</web-resource-name>
           
    <description>An example security config that only allows users with the
             role JBossAdmin to access the HTML JMX console web application
           
    </description>
           
    <url-pattern>/*</url-pattern>
           
    <http-method>GET</http-method>
           
    <http-method>POST</http-method>
         
    </web-resource-collection>
         
    <auth-constraint>
           
    <role-name>JBossAdmin</role-name>
         
    </auth-constraint>
       
    </security-constraint>

       在此處可以看出,為登錄配置了角色JBossAdmin。

    iii) 在第一步中的jmx-console安全域和第二步中的運(yùn)行角色JBossAdmin都是在login-config.xml中配置,我們?cè)贘Boss安 裝目錄/server/default/conf下找到它。查找名字為:jmx-console的application-policy:

    <application-policy name = "jmx-console">
           
    <authentication>
              
    <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule"
                 flag 
    = "required">
               
    <module-option name="usersProperties">props/jmx-console-users.properties</module-option>
               
    <module-option name="rolesProperties">props/jmx-console-roles.properties</module-option>
              
    </login-module>
           
    </authentication>
        
    </application-policy>


    在此處可以看出,登錄的角色、用戶(hù)等的信息分別在props目錄下的jmx-console-roles.properties和jmx-console-users.properties文件中設(shè)置,分別打開(kāi)這兩個(gè)文件。
    其中jmx-console-users.properties文件的內(nèi)容如下:

    # A sample users.properties file for use with the UsersRolesLoginModule
    admin
    =admin

    該文件定義的格式為:用戶(hù)名=密碼,在該文件中,默認(rèn)定義了一個(gè)用戶(hù)名為admin,密碼也為admin的用戶(hù),讀者可將其改成所需的用戶(hù)名和密碼。
    jmx-console-roles.properties的內(nèi)容如下:

    # A sample roles.properties file for use with the UsersRolesLoginModule
    admin
    =JBossAdmin, HttpInvoker

    該文件定義的格式為:用戶(hù)名=角色,多個(gè)角色以“,”隔開(kāi),該文件默認(rèn)為admin用戶(hù)定義了JBossAdmin和HttpInvoker這兩個(gè)角色。
    配置完成后讀者可以通過(guò)訪問(wèn): http://localhost:8088/jmx-console/ ,輸入jmx-console-roles.properties文件中定義的用戶(hù)名和密碼,訪問(wèn)jmx-console的頁(yè)面。

    posted @ 2012-02-13 11:04 paulwong 閱讀(9557) | 評(píng)論 (0)編輯 收藏

    一個(gè)完整的JENKINS下的ANT BUILD.XML文件

         摘要: Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--><?xml version="1.0" encoding="UTF-8"?><project name="genwar" default="all...  閱讀全文

    posted @ 2012-02-08 18:40 paulwong 閱讀(5747) | 評(píng)論 (1)編輯 收藏

    僅列出標(biāo)題
    共115頁(yè): First 上一頁(yè) 88 89 90 91 92 93 94 95 96 下一頁(yè) Last 
    主站蜘蛛池模板: 免费看无码特级毛片| 久久亚洲国产精品一区二区| 亚洲精品乱码久久久久蜜桃 | 亚洲成人在线电影| 中文字幕久精品免费视频| 亚洲精品夜夜夜妓女网| 三级黄色免费观看| 精品无码无人网站免费视频| 亚洲精品国产自在久久| 九九久久精品国产免费看小说| 亚洲国产成人久久综合野外| 一区在线免费观看| 亚洲乱码日产一区三区| 日本免费人成网ww555在线 | 最近免费中文字幕mv电影| 亚洲精品成人久久| 色播精品免费小视频| 中文字幕亚洲综合小综合在线| 成年人免费观看视频网站| 亚洲暴爽av人人爽日日碰| 免费永久国产在线视频| 一级毛片无遮挡免费全部| 亚洲午夜久久久影院| 香蕉成人免费看片视频app下载| 久久亚洲春色中文字幕久久久 | 最近免费中文字幕中文高清 | 成年女人18级毛片毛片免费观看| 亚洲日本在线电影| 一本久到久久亚洲综合| 国产精品免费αv视频| 久久亚洲伊人中字综合精品| 91av视频免费在线观看| 亚洲午夜一区二区三区| 免费看国产一级特黄aa大片| 久久国产一片免费观看| 亚洲一二成人精品区| 猫咪社区免费资源在线观看| 理论亚洲区美一区二区三区| 国产午夜亚洲不卡| 久久99热精品免费观看牛牛| 亚洲第一成人在线|