diggbag

          BlogJava 聯系 聚合 管理
            0 Posts :: 13 Stories :: 6 Comments :: 0 Trackbacks

          2012年8月1日 #

          以下方法在centOS下執行通過:
          1.先定位占用cpu高的進程

          top

          2.使用以下命令

          ps p 14766 -L -o pcpu,pid,tid,time,tname,stat,psr | sort -n -k1 -r

          其中14766是剛才1中cpu占用率高的進程pid

          3.2.4 32525 32537 01:58:41 ?        Sl     6
          0.8 32525  1771 00:43:12 ?        Sl     0
          0.8 32525  1769 00:39:46 ?        Sl     0
          0.7 32525 12324 00:33:36 ?        Sl     0
          0.5 32525  1772 00:27:50 ?        Sl     0
          0.5 32525  1768 00:25:45 ?        Sl     0
          0.4 32525 30760 00:19:13 ?        Sl     0
          0.4 32525  1773 00:22:36 ?        Sl     0
          0.4 32525  1770 00:20:25 ?        Sl     0
          0.3 32525 32385 00:00:10 ?        Sl     0
          0.1 32525 31668 00:00:03 ?        Sl     0
          0.1 32525 31667 00:00:03 ?        Sl     0
          0.1 32525  1790 00:07:10 ?        Sl     1

           

          其中第3個結果就是此進程中有問題的線程nid

          4.通過jstack命令dump出堆棧

          "AppController_ThreadPool_L2_Pool Thread" daemon prio=10 tid=0x0000000051c2b000 nid=0x7bb3 in Object.wait() [0x000000005e3c5000]
             java.lang.Thread.State: TIMED_WAITING (on object monitor)
                  at java.lang.Object.wait(Native Method)
                  at org.company.threadpool.ThreadPoolImpl$PoolThread.run(ThreadPoolImpl.java:142)
                  - locked <0x00002aaca30341a8> (a org.company.threadpool.ThreadPoolImpl$PoolThread)

          其中的nid就是線程的編碼,只不過是經過了16進制的轉換。

          即十進制的31776對應的十六進制)0x7bb3,定位到線程后一切好辦。 

          posted @ 2012-08-01 17:22 哲同 閱讀(3713) | 評論 (0)編輯 收藏

          2012年7月12日 #

          1.在使用jaxbMarshaller生成xml的過程中,有java bean如下使用到了泛型:

          @XmlRootElement(name = "ReturnInfo")
          @XmlType()
          public class ReturnInfo<T> {

          private List<T> resultList;

           public List<T> getResultList() {

            return resultList;
           }

           public void setResultList(List<T> resultList) {

            this.resultList = resultList;
           }

          }

          2.在最初測試的時候jaxbMarshaller報異常,無法找到處理泛型的辦法。

          3.在使用jaxb時需要在java bean打上@XmlSeeAlso(MultiQueryInfo.class)注釋,作用就是是在jaxb綁定一個class時候可以使用

          其他的class,在jaxb使用多態的時候都需要用到此標簽;其中括號中可以添加多個class,如@XmlSeeAlso(A.class,B.class)

          4.在客戶端的bean中也需要用到此注釋,否則同樣報轉換錯誤:

          Exception in thread "main" java.lang.ClassCastException: com.sun.org.apache.xerces.internal.dom.ElementNSImpl cannot be cast to com.jd.fms.adsettlement.client.domain.MultiQueryInfo

          posted @ 2012-07-12 19:04 哲同 閱讀(7972) | 評論 (0)編輯 收藏

          2012年4月18日 #

          1.pom.xml文件報Plugin execution not covered by lifecycle configuration: org.apache.maven.plugins:maven-resources-plugin:2.2:resources (execution: default-resources, phase: process-resources) pom.xml /testMaven-common line 3 Maven Project Build Lifecycle Mapping Problem

          2.導致此錯誤是m2eclipse插件0.12及之前的版本在Eclipse 內執行了一系列的生命周期引起沖突導致的,如果你的maven報此類錯誤,而又用到了maven-resources-plugin這個插件,那么請按你的項目pom.xml中加上

          <plugin>
                <groupId>org.eclipse.m2e</groupId>
                <artifactId>lifecycle-mapping</artifactId>
                <version>1.0.0</version>
                <configuration>
                  <lifecycleMappingMetadata>
                    <pluginExecutions>
                      <pluginExecution>
                        <pluginExecutionFilter>
                          <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-resources-plugin</artifactId>
                          <versionRange>[1.2,)</versionRange>
                          <goals>
                          <goal>resources</goal>
                           <goal>testResources</goal>
                          </goals>
                        </pluginExecutionFilter>
                        <action>
                          <ignore />
                        </action>
                      </pluginExecution>
                    </pluginExecutions>
                  </lifecycleMappingMetadata>
                </configuration>
              </plugin>

          解決沖突,具體原因參看http://wiki.eclipse.org/M2E_plugin_execution_not_covered


           

          posted @ 2012-04-18 18:19 哲同 閱讀(14858) | 評論 (1)編輯 收藏

          2012年4月10日 #

          1.使用背景:項目中想使用規則引擎,調研后發現流行的開源規則引擎都比較重量級,考慮到項目只需要通過配置文件設定規則集,故使用java動態使用groovy即可達到目的;

          2.通過以下方式配置spring使用groovy,和采用java編程沒有太大區別,groovy提供較平順的從java過來的學習曲線,下面的例子中的groovy類活生生就是一個java類,只不過是寫在xml文件中的java類罷了;

          3.spring通過org.springframework.scripting.groovy.GroovyScriptFactory類反射生成groovy類,由于使用到jdk的動態代理,所以所有用groovy定義的類必須實現java定義的接口,這是可以運行的關鍵;

          4.配置spring.xml

          <beans xmlns="http://www.springframework.org/schema/beans"
            xmlns:lang="http://www.springframework.org/schema/lang"
           xsi:schemaLocation="
                  http://www.springframework.org/schema/beans
                  http://www.springframework.org/schema/beans/spring-beans.xsd
                  http://www.springframework.org/schema/lang
                  http://www.springframework.org/schema/lang/spring-lang-2.5.xsd
            "
           default-autowire="byName">

          此文件頭必不可少,否則無法識別lang標簽;

          <lang:groovy id="groovyHello" >
            <lang:inline-script>
                  <![CDATA[
                  package com.jd.fms;
                      import com.jd.fms.netty.GroovyHelloWorld;
                      public class TestGroovyHelloWorld implements GroovyHelloWorld{
              public void doit(){
              System.out.println("hello world");
              }
             }
                  ]]>
              </lang:inline-script>
           </lang:groovy>

          采用lang:groovy定義groovy片段,當然也可以采用

          <lang:groovy id=" script-source="....">的方式引入文件。
          不要忘記的是在工程中定義GroovyHelloWorld的接口,該接口需要實現一個doit方法。
          5.項目中直接通過
          @Autowired
           GroovyHelloWorld groovyHelloWorld;
          調用即可;
          6.groovy為java提供了很好的動態語言能力,如果項目沒有必要使用太重量級的規則引擎,
          那么使用動態語言讓業務人員直接配置也不失為一個好方法。

           

          posted @ 2012-04-10 17:55 哲同 閱讀(1990) | 評論 (0)編輯 收藏

          2012年2月16日 #

          近日在公司項目中,使用到spring+mybatis的架構,特對mybatis的batch模式做了相關研究,得出以下結論:

               1.Mybatis內置的ExecutorType有3種,默認的是simple,該模式下它為每個語句的執行創建一個新的預處理語句,單條提交sql;而batch模式重復使用已經預處理的語句,
          并且批量執行所有更新語句,顯然batch性能將更優;
           
          2.但batch模式也有自己的問題,比如在Insert操作時,在事務沒有提交之前,是沒有辦法獲取到自增的id,這在某型情形下是不符合業務要求的;
           
          3. 在測試中使用simple模式提交10000條數據,時間為18248 毫秒,batch模式為5023 ,性能提高70%;
           
          4.通過走碼和研讀spring相關文件發現,在同一事務中batch模式和simple模式之間無法轉換,由于本項目一開始選擇了simple模式,所以碰到需要批量更新時,只能在單獨的事務中進行;
           
          5.在代碼中使用batch模式可以使用以下方式:
           
          //從spring注入原有的sqlSessionTemplate
          @Autowired
          private SqlSessionTemplate sqlSessionTemplate;
           
          public void testInsertBatchByTrue() {
           
          //新獲取一個模式為BATCH,自動提交為false的session
          //如果自動提交設置為true,將無法控制提交的條數,改為最后統一提交,可能導致內存溢出
          SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(
          ExecutorType.BATCH, false);
          //通過新的session獲取mapper
              fooMapper = session.getMapper(FooMapper.class);
              int size = 10000;
              try {
                  for (int i = 0; i < size; i++) {
                          Foo foo = new Foo();
                          foo.setName(String.valueOf(System.currentTimeMillis()));
                          fooMapper.insert(foo);
                              if (i % 1000 == 0 || i == size - 1) {
                              //手動每1000個一提交,提交后無法回滾
          session.commit();
                              //清理緩存,防止溢出
                                      session.clearCache();
                  }
                  }
              } catch (Exception e) {
          //沒有提交的數據可以回滾
                                  session.rollback();
                      } finally {
          session.close();
                  }
              }
           
          6.上述代碼沒有使用spring的事務,改動手動控制,如果和原spring事務一起使用,將無法回滾,必須注意,最好單獨使用;

          posted @ 2012-02-16 17:40 哲同 閱讀(21979) | 評論 (1)編輯 收藏

          2012年2月2日 #

          項目框架是struts2+spring,在未使用AOP機制前,在action層注入的service是沒有問題的,但是當嘗試在action層使用AOP機制攔截相關異常時,會出現注入失敗的問題,出現空指針異常。

          問題分析:原因是一般struts2+spring應用中,spring的插件只負責為action的ioc部分,但并沒有進行功能加強,即采用代理的機制,所有的action還是使用struts2進行管理,
          在使用AOP后,這些action需要由spring進行管理,如果沒有由spring進行代理,將出現注入失敗。

          解決辦法:在每個action前加上@Component("loginAction") @Scope("prototype"),在struts的配置中使用loginAction的名字進行配置,@Scope用于聲明action使用多實例,這樣AOP可以進行正常注入

          posted @ 2012-02-02 12:14 哲同 閱讀(2680) | 評論 (2)編輯 收藏

          2011年10月24日 #

               摘要: 1 RESTful簡要介紹 RESTful風格的WebService之所以當下如此流行,是由于其相對于SOAP風格的WebService更簡潔、更輕量級,REST風格的WebService傳輸的是JSON或極其簡潔的XML,因而其效率和性能都比較理想。 RESTful風格的WebService主張重用HTTP協議,面向資源編程(ROA)。扼要的說,RESTful風格WebServic...  閱讀全文
          posted @ 2011-10-24 17:27 哲同 閱讀(7982) | 評論 (0)編輯 收藏

          2011年10月21日 #

          接口抽象

          RESTful Web 服務使用標準的 HTTP 方法 (GET/PUT/POST/DELETE) 來抽象所有 Web 系統的服務能力,而不同的是,SOAP 應用都通過定義自己個性化的接口方法來抽象 Web 服務,這更像我們經常談到的 RPC。例如本例中的 getUserList 與 getUserByName 方法。

          RESTful Web 服務使用標準的 HTTP 方法優勢,從大的方面來講:標準化的 HTTP 操作方法,結合其他的標準化技術,如 URI,HTML,XML 等,將會極大提高系統與系統之間整合的互操作能力。尤其在 Web 應用領域,RESTful Web 服務所表達的這種抽象能力更加貼近 Web 本身的工作方式,也更加自然。

          同時,使用標準 HTTP 方法實現的 RRESTful Web 服務也帶來了 HTTP 方法本身的一些優勢:

          • 無狀態性(Stateless)

          HTTP 協議從本質上說是一種無狀態的協議,客戶端發出的 HTTP 請求之間可以相互隔離,不存在相互的狀態依賴。基于 HTTP 的 ROA,以非常自然的方式來實現無狀態服務請求處理邏輯。對于分布式的應用而言,任意給定的兩個服務請求 Request 1 與 Request 2, 由于它們之間并沒有相互之間的狀態依賴,就不需要對它們進行相互協作處理,其結果是:Request 1 與 Request 2 可以在任何的服務器上執行,這樣的應用很容易在服務器端支持負載平衡 (load-balance)。

          • 安全操作與冪指相等特性(Safety /Idempotence)

          HTTP 的 GET、HEAD 請求本質上應該是安全的調用,即:GET、HEAD 調用不會有任何的副作用,不會造成服務器端狀態的改變。對于服務器來說,客戶端對某一 URI 做 n 次的 GET、HAED 調用,其狀態與沒有做調用是一樣的,不會發生任何的改變。

          HTTP 的 PUT、DELTE 調用,具有冪指相等特性 , 即:客戶端對某一 URI 做 n 次的 PUT、DELTE 調用,其效果與做一次的調用是一樣的。HTTP 的 GET、HEAD 方法也具有冪指相等特性。

          HTTP 這些標準方法在原則上保證你的分布式系統具有這些特性,以幫助構建更加健壯的分布式系統。

          安全控制

          為了說明問題,基于上面的在線用戶管理系統,我們給定以下場景:

          參考一開始我們給出的用例圖,對于客戶端 Client2,我們只希望它能以只讀的方式訪問 User 和 User List 資源,而 Client1 具有訪問所有資源的所有權限。

          如何做這樣的安全控制?

          通行的做法是:所有從客戶端 Client2 發出的 HTTP 請求都經過代理服務器 (Proxy Server)。代理服務器制定安全策略:所有經過該代理的訪問 User 和 User List 資源的請求只具有讀取權限,即:允許 GET/HEAD 操作,而像具有寫權限的 PUT/DELTE 是不被允許的。

          如果對于 REST,我們看看這樣的安全策略是如何部署的。如下圖所示:


          圖 4. REST 與代理服務器 (Proxy Servers)
          REST

          一般代理服務器的實現根據 (URI, HTTP Method) 兩元組來決定 HTTP 請求的安全合法性。

          當發現類似于(http://localhost:8182/v1/users/{username},DELETE)這樣的請求時,予以拒絕。

          對于 SOAP,如果我們想借助于既有的代理服務器進行安全控制,會比較尷尬,如下圖:


          圖 5. SOAP 與代理服務器 (Proxy Servers)
          REST

          所有的 SOAP 消息經過代理服務器,只能看到(http://localhost:8182/v1/soap/servlet/messagerouter, HTTP POST)這樣的信息,如果代理服務器想知道當前的 HTTP 請求具體做的是什么,必須對 SOAP 的消息體解碼,這樣的話,意味著要求第三方的代理服務器需要理解當前的 SOAP 消息語義,而這種 SOAP 應用與代理服務器之間的緊耦合關系是不合理的。

          關于緩存

          眾所周知,對于基于網絡的分布式應用,網絡傳輸是一個影響應用性能的重要因素。如何使用緩存來節省網絡傳輸帶來的開銷,這是每一個構建分布式網絡應用的開發人員必須考慮的問題。

          HTTP 協議帶條件的 HTTP GET 請求 (Conditional GET) 被設計用來節省客戶端與服務器之間網絡傳輸帶來的開銷,這也給客戶端實現 Cache 機制 ( 包括在客戶端與服務器之間的任何代理 ) 提供了可能。HTTP 協議通過 HTTP HEADER 域:If-Modified-Since/Last- Modified,If-None-Match/ETag 實現帶條件的 GET 請求。

          REST 的應用可以充分地挖掘 HTTP 協議對緩存支持的能力。當客戶端第一次發送 HTTP GET 請求給服務器獲得內容后,該內容可能被緩存服務器 (Cache Server) 緩存。當下一次客戶端請求同樣的資源時,緩存可以直接給出響應,而不需要請求遠程的服務器獲得。而這一切對客戶端來說都是透明的。


          圖 6. REST 與緩存服務器 (Cache Server)
          REST

          而對于 SOAP,情況又是怎樣的呢?

          使用 HTTP 協議的 SOAP,由于其設計原則上并不像 REST 那樣強調與 Web 的工作方式相一致,所以,基于 SOAP 應用很難充分發揮 HTTP 本身的緩存能力。


          圖 7. SOAP 與緩存服務器 (Cache Server)
          REST

          兩個因素決定了基于 SOAP 應用的緩存機制要遠比 REST 復雜:

          其一、所有經過緩存服務器的 SOAP 消息總是 HTTP POST,緩存服務器如果不解碼 SOAP 消息體,沒法知道該 HTTP 請求是否是想從服務器獲得數據。

          其二、SOAP 消息所使用的 URI 總是指向 SOAP 的服務器,如本文例子中的 http://localhost:8182/v1/soap/servlet/messagerouter,這并沒有表達真實的資源 URI,其結果是緩存服務器根本不知道那個資源正在被請求,更不用談進行緩存處理。

          關于連接性

          在一個純的 SOAP 應用中,URI 本質上除了用來指示 SOAP 服務器外,本身沒有任何意義。與 REST 的不同的是,無法通過 URI 驅動 SOAP 方法調用。例如在我們的例子中,當我們通過

          getUserList SOAP 消息獲得所有的用戶列表后,仍然無法通過既有的信息得到某個具體的用戶信息。唯一的方法只有通過 WSDL 的指示,通過調用 getUserByName 獲得,getUserList 與 getUserByName 是彼此孤立的。

          而對于 REST,情況是完全不同的:通過 http://localhost:8182/v1/users URI 獲得用戶列表,然后再通過用戶列表中所提供的 LINK 屬性,例如 <link>http://localhost:8182/v1/users/tester</link>獲得 tester 用戶的用戶信息。這樣的工作方式,非常類似于你在瀏覽器的某個頁面上點擊某個 hyperlink, 瀏覽器幫你自動定向到你想訪問的頁面,并不依賴任何第三方的信息。



          總結

          典型的基于 SOAP 的 Web 服務以操作為中心,每個操作接受 XML 文檔作為輸入,提供 XML 文檔作為輸出。在本質上講,它們是 RPC 風格的。而在遵循 REST 原則的 ROA 應用中,服務是以資源為中心的,對每個資源的操作都是標準化的 HTTP 方法。

          本文主要集中在以上的幾個方面,對 SOAP 與 REST 進行了對比,可以看到,基于 REST 構建的系統其系統的擴展能力要強于 SOAP,這可以體現在它的統一接口抽象、代理服務器支持、緩存服務器支持等諸多方面。并且,伴隨著 Web Site as Web Services 演進的趨勢,基于 REST 設計和實現的簡單性和強擴展性,有理由相信,REST 將會成為 Web 服務的一個重要架構實踐領域。

          posted @ 2011-10-21 11:05 哲同 閱讀(14010) | 評論 (1)編輯 收藏

          2011年10月17日 #

          HA是High Availability 的首字母組合,翻譯過來,可以叫做高可用,或高可用性,高可用(環境)。我覺得應該說HA是一個觀念而不是一項或一系列具體技術,就象網格一樣。作過系統方案就知道了,評價系統的性能當中就有一項高可用。廣義的高可用涉及到系統的各個方面,簡單來說,讓系統不會中斷 運行,就是高可用。包括軟件的高可用,硬件的高可用,網絡的高可用等等。具體實現的方案包括操作系統的集群,數據庫的集群,硬件的冗余,網絡的冗余等等。做HA方面的軟件,有IBM的HACMP(很多常用AIX的人,常說的HA就指HACMP,亂啊)、SUN的Sun Cluster、HP的MC/SG等。

          在2000年以前,大家談HA,大部分時候說的是操作系統一級的雙機熱備,主流產品當時有IBM HACMP4.1,HP的MC/SG啥版本忘了,sun的系統很多人不用VCS,用的是一個叫dataware的東西。現在很多人眼中的HA也還是這樣。時至今日,HA包括的東西可就多了,先不說其他方面,單就數據庫,單就Oracle,與HA相關的產品先后有:高級復制(AdvanceRepication)、OPS/RAC(Real Application Cluster)、數據衛士(Data Guard)、oracle流(Oracle Streams)、分區(Oracle Partition)這樣數款產品。照這么說,RAC只是HA這個概念下的一個具體產品而已!目前為止,只有RAC和分區是Oracle要收取 licence的,其他的,只要給經驗豐富的第三方實施方付一定的規劃/設計及部署費用就可以了;當然,也可以自己照著文檔依葫蘆畫瓢,但是這樣弄出的環境是否能達到高可用就難說了。事實上,大部分人所說的HA,還是狹義上的HA,也就是OS一級的雙機熱備。

          RAC是real application cluster的簡稱,它是在多個主機上運行一個數據庫的技術,即是一個db多個instance。它的好處是 可以由多個性能較差的機器構建出一個整體性能很好的集群,并且實現了負載均衡,那么當一個節點出現故障時,其上的服務會自動轉到另外的節點去執行,用戶甚 至感覺不到什么。

          雙機熱備(HA)和RAC有啥區別呢?


          1、對于硬件來說,基本上一樣,共享存儲、光纖線(也有還用SCSI線的)、多臺小型機(可以做多節點的相互熱備,也可以做多節點的RAC)、光纖交換機(如果是用光纖卡的話);但做RAC,在主機之間,最好使用高帶寬網絡交換機(雖然不用也可以做成);因此硬件成本相差不大。
          2、軟件呢,差別可不小。如果是雙機熱備,必須買操作系統級的雙機管理軟件;如果是RAC,目前還是建議購買雙機管理軟件(盡管10g的crs+asm可以擺脫雙機軟件了,但ASM目前實在太難伺候了),當然還得買RAC license。
          3、日常維護。RAC要求的技術含量更高,也應該更勤快。最關鍵的是得買oracle服務,否則遇到有些問題(bug),你就比單機還不高可用了。
          4、優缺點。這個,看看RAC的官方論述吧。如果能用好,確實是很有好處的。目前我們的40多個客戶的使用情況來看,RAC確實大大降低了他們的downtime,另一方面可以說就是提高了生產力咯。

          Dataguard一般是出于容災的目的。是主數據庫的備用庫(standby 庫)通過自動傳送和接受archivelog,并且在dataguard庫自動apply 這些log,從而達到和主數據庫同步的目的,可能dataguard 庫是建立的異地的,當主庫所在的區域出現了致命性的災難時(火災、地震等),主庫沒法修復時,這時可以切換dataguard 為主庫的模式,對外提供服務,而它的數據基本是當前最新的。目前可能大家對于 dataguard 庫的使用已經拓展出了其他更多的用途,比如備份,跑報表等等。
          posted @ 2011-10-17 10:08 哲同 閱讀(357) | 評論 (0)編輯 收藏

          2011年10月9日 #

          1.出現的問題
           
          日志文件沒有新的輸出。

          2.
          問題分析
            dump
          出堆棧,如下:
            "main" prio=10 tid=0x000000005de12000 nid=0x27e8 runnable [0x0000000040240000]
             java.lang.Thread.State: RUNNABLE
              at java.net.SocketInputStream.socketRead0(Native Method)
              at java.net.SocketInputStream.read(SocketInputStream.java:129)
              at java.io.DataInputStream.readFully(DataInputStream.java:178)
              at java.io.DataInputStream.readFully(DataInputStream.java:152)
              at net.sourceforge.jtds.jdbc.SharedSocket.readPacket(SharedSocket.java:842)
             
          at net.sourceforge.jtds.jdbc.SharedSocket.getNetPacket(SharedSocket.java:723)
             
          - locked <0x0000000759fd9f90> (a java.util.ArrayList)
              at net.sourceforge.jtds.jdbc.ResponseStream.getPacket(ResponseStream.java:466)
              at net.sourceforge.jtds.jdbc.ResponseStream.read(ResponseStream.java:135)
              at net.sourceforge.jtds.jdbc.ResponseStream.readString(ResponseStream.java:290)
              at net.sourceforge.jtds.jdbc.ResponseStream.readNonUnicodeString(ResponseStream.java:274)
              at net.sourceforge.jtds.jdbc.TdsData.readData(TdsData.java:936)
              at net.sourceforge.jtds.jdbc.TdsCore.tdsRowToken(TdsCore.java:3007)
              at net.sourceforge.jtds.jdbc.TdsCore.nextToken(TdsCore.java:2270)
              at net.sourceforge.jtds.jdbc.TdsCore.getNextRow(TdsCore.java:765)
             
          at net.sourceforge.jtds.jdbc.JtdsResultSet.next(JtdsResultSet.java:596)
              at org.apache.commons.dbcp.DelegatingResultSet.next(DelegatingResultSet.java:207)
              at org.apache.commons.dbcp.DelegatingResultSet.next(DelegatingResultSet.java:207)
              at com.jd.cis.worker.OppProductWorker.importData(OppProductWorker.java:310)
              at com.jd.cis.worker.BaseWorker.importDataSource(BaseWorker.java:416)
              at com.jd.cis.worker.OppProductWorker.doRun(OppProductWorker.java:276)
              at com.jd.cis.worker.BaseWorker.run(BaseWorker.java:448)
              at com.jd.cis.worker.OppProductWorker.main(OppProductWorker.java:564)

             
          上面有鎖,對應的代碼為
              statement.setFetchSize(1000);
              .....
              resultSet = statement.executeQuery();
             
          while (resultSet.next()) {
                 ......
              }
             
          查詢相關文檔,了解到JTDS默認的socketTimeout0,即讀取數據沒有超時時間。
             
          當數據鏈接意外終止的時候,JDTS可能檢測不到,就會一直等待數據,阻塞進程。

             
          在本地重現該問題,在循環體里面設置斷點,進入斷點后,斷掉所有網絡鏈接,取消斷點,繼續運行,發現程序被一致阻塞了。
             
          當設置socketTimeout60秒,重試,程序阻塞60秒后拋出異常。

             
          該問題在查詢SQLServer數據庫,大數據量查詢,分批獲取的時候,容易出現
             
          3.
          解決方案
           
          jdtsurl鏈接中加上socketTimeout(單位秒)的設置,或在dbcp中如下設置
            <property name="connectionProperties" value="characterEncoding=UTF-8;
          socketTimeout=60"/>
           
          這個參數和mybatisdefaultStatementTimeout 參數是不一樣的

           
          同時Worker中加入異常捕獲重試機制
          posted @ 2011-10-09 13:22 哲同 閱讀(3876) | 評論 (0)編輯 收藏

          僅列出標題  
          主站蜘蛛池模板: 涡阳县| 江油市| 碌曲县| 巴楚县| 左贡县| 合川市| 江孜县| 通山县| 于田县| 花莲市| 牙克石市| 浠水县| 赤水市| 房产| 芷江| 杭州市| 河源市| 易门县| 洪湖市| 济宁市| 社旗县| 东辽县| 定襄县| 平武县| 安溪县| 中西区| 广州市| 营口市| 申扎县| 玉环县| 甘孜县| 潞城市| 湘阴县| 阳泉市| 临沭县| 高台县| 永年县| 磐石市| 庆安县| 顺平县| 泊头市|