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

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

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

    鷹翔宇空

    學習和生活

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      110 Posts :: 141 Stories :: 315 Comments :: 1 Trackbacks
    原文引自:http://www.bea.com.cn/support_pattern/JDBC_Causes_Server_Hang_Pattern.html


    問題描述
    在通過由應用程序或 WebLogic Server 本身使用的 JDBC 連接進行調用時,此連接會在整個調用期間內阻塞一個 WebLogic Server 執行線程。盡管在 SQL 查詢上阻塞的線程需要等待,但 JVM 將通過其線程調度機制確保 CPU 獲得可運行線程。但是,由 JDBC 調用占用的線程將保留給應用程序使用,直至該調用從 SQL 查詢返回。

    即使事務超時也不會終止由在此事務中登記的資源完成的任何操作,或者使其超時。這些操作將正常地運行,而不會出現中斷。事務超時只是在事務上設置一個標記,將其標記為回滾,這樣提交此事務的任何后續請求都將失敗,系統拋出 TimedOutExceptionRollbackException。但是,如前所述,長時間運行的 JDBC 調用會導致 WebLogic Server 執行線程阻塞,如果所有線程均被阻塞,沒有能夠處理傳入請求執行線程,則最終可導致實例掛起。

    最新版本的 WebLogic Server 具有健全性檢查功能,能夠定期檢查線程不響應的時間是否達到特定時長(缺省值為 600 秒)。如果是這樣,系統會向日志文件輸出一條如下的錯誤消息:

    ####<Nov 6, 2004 1:42:30 PM EST> <Warning> <WebLogicServer> <mydomain> <myserver> <CoreHealthMonitor> <kernel identity> <>
    <000337> <ExecuteThread: '64' for queue: 'default' has been busy for "740" seconds working on the request "Scheduled Trigger",
    which is more than the configured time (StuckThreadMaxTime) of "600" seconds.>


    這并不會中斷線程,而只是提供給管理員的一項通知。阻塞線程恢復為正常狀態的唯一途徑是等待它正處理的請求完成。這種情況下,WebLogic Server 日志文件中將出現一條如下的消息:

    ####<Nov 7, 2004 4:17:34 PM EST> <Info> <WebLogicServer><mydomain> <myserver> <ExecuteThread: '66' for queue: 'default'>
    <kernel identity> <> <000339> <ExecuteThread: '66' for queue: 'default' has become "unstuck".>


    健康檢查功能的時間間隔是可以配置的。請檢查 config.xml 文件 <Server> 標記中的 StuckThreadMaxTime 屬性:http://e-docs.bea.com/wls/docs81/config_xml/Server.html#StuckThreadMaxTime (English) 或 WebLogic Server 管理控制臺幫助中的“Detecting stuck threads”一節:http://e-docs.bea.com/wls/docs81/perform/WLSTuning.html#stuckthread (English)。

    返回頁首

    故障排除
    不同的編程技術或 JDBC 連接池配置可以造成死鎖或長時間運行的 JDBC 調用,進而使 WebLogic Server 實例掛起。常規服務器掛起模式中提供了有關如何排除和分析掛起 WebLogic Server 實例的一般信息。

    本模式討論導致服務器掛起的 JDBC 調用,并從 JDBC 角度討論導致 WebLogic Server 實例掛起的常見問題的原因。本模式中引用的其它支持模式位于 WebLogic Server Support Patterns Site (English)。

    快速鏈接

    為什么發生此問題?
    以下是在 JDBC 調用時導致 WebLogic Server 實例掛起的各種可能原因:
    返回頁首

    同步的 DriverManager.getConnection()
    舊版本的 JDBC 應用程序代碼有時使用 DriverManager.getConnection() 調用來通過特定驅動程序取得數據庫連接。不建議使用此項技術,因為它可能會導致死鎖,或者至少相對降低連接請求的性能。究其原因,是因為所有 DriverManager 調用都采用類同步模式,也就是說一個線程中的一個 DriverManager 調用將阻塞一個 WebLogic Server 實例內任何其它線程中的所有其它 DriverManager 調用。

    此外,SQLException 的構造器會構造一個 DriverManager 調用,而且大多數驅動程序使用 DriverManager.println() 調用進行日志記錄,這其中的任何一項都會阻塞發出 DriverManager 調用的所有其它線程。

    DriverManager.getConnection() 在返回為數據庫建立的物理連接之前可能會需要相對較長的時間。即使不發生死鎖,所有其它調用也需要等到這個線程獲得連接。在像 WebLogic Server 這樣的多線程系統中,這不是最佳的方式。

    此處的信息來自 http://forums.bea.com/bea//thread.jspa?forumID=2022&threadID=200063365&message
    ID=202311284&start=-1#202311284
    (English)。
    此外,我們的文檔也明確指出不應使用 DriverManager.getConnection()http://e-docs.bea.com/wls/docs81/faq/jdbc.html#501044 (English)。

    如果愿意在 JDBC 代碼中使用 JDBC 連接,應使用 WebLogic Server JDBC 連接池,為其定義一個數據源,并從此數據源獲得連接。這樣您將享有池的所有優點(資源共享、連接重用、數據庫關閉后的連接刷新等等)。它還將幫助您避免 DriverManager 調用可能發生的死鎖。有關如何使用 JDBC 連接池、數據源及 WebLogic Server 中的其它 JDBC 對象的詳細信息,請參閱:http://e-docs.bea.com/wls/docs81/jdbc/intro.html#1036718 (English) 和 http://e-docs.bea.com/wls/docs81/jdbc/programming.html#1054307 (English)。

    DriverManager.getConnection() 調用中阻塞的典型線程如下:
    "ExecuteThread-39" daemon prio=5 tid=0x401660 nid=0x33 waiting for monitor entry [0xd247f000..0xd247fc68]
    ? at java.sql.DriverManager.getConnection(DriverManager.java:188)
    ? at com.bla.updateDataInDatabase(MyClass.java:296)
    ? at javax.servlet.http.HttpServlet.service(HttpServlet.java:865)
    ? at weblogic.servlet.internal.ServletStubImpl.invokeServlet
    (ServletStubImpl.java:120)
    ? at weblogic.servlet.internal.ServletContextImpl.invokeServlet
    (ServletContextImpl.java:945)
    ? at weblogic.servlet.internal.ServletContextImpl.invokeServlet
    (ServletContextImpl.java:909)
    ? at weblogic.servlet.internal.ServletContextManager.invokeServlet
    (ServletContextManager.java:269)
    ? at weblogic.socket.MuxableSocketHTTP.invokeServlet
    (MuxableSocketHTTP.java:392)
    ? at weblogic.socket.MuxableSocketHTTP.execute(MuxableSocketHTTP.java:274)
    ? at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:130)




    返回頁首

    長時間運行的 SQL 查詢
    長時間運行的 SQL 查詢在其執行期間將阻塞執行線程,直至它們將結果返回給發出調用的應用程序。這就意味著,需要修改 WebLogic Server 實例的配置來處理應用程序負載要求的足夠多的調用。這種情況的限制因素是執行線程數和 JDBC 連接池中的連接數。一般的經驗方法是將池中的連接數設置為等于執行線程數,以便能夠實現最優的資源利用。如果使用 JTS,則池中的可用連接應更多一些,因為某些連接可能會保留給實際處于非活動狀態的事務。

    對于在長時間運行的 SQL 調用期間掛起的線程,其在 Thread Dump 中的堆棧與掛起的數據庫的堆棧十分相似。有關詳細信息,請對比下一小節的內容。

    掛起的數據庫
    對于依賴于數據庫的應用程序來說,良好的數據庫性能是其性能的關鍵。因此,掛起的數據庫可能會阻塞 WebLogic Server 實例中許多或所有可用的執行線程并最終導致服務器掛起。要診斷這一問題,應從掛起的 WebLogic Server 實例獲得 5 到 10 個 Thread Dump,并檢查您的執行線程(在缺省隊列或您的應用程序線程隊列中)當前是否在 SQL 調用之中并在等待來自數據庫的結果。當前發出 SQL 查詢的線程的典型堆棧跟蹤如下例所示:

    "ExecuteThread: '4' for queue: 'weblogic.kernel.Default'" daemon prio=5
    tid=0x8e93c8 nid=0x19 runnable [e137f000..e13819bc]
    ? at java.net.SocketInputStream.socketRead0(Native Method)
    ? at java.net.SocketInputStream.read(SocketInputStream.java:129)
    ? at oracle.net.ns.Packet.receive(Unknown Source)
    ? at oracle.net.ns.DataPacket.receive(Unknown Source)
    ? at oracle.net.ns.NetInputStream.getNextPacket(Unknown Source)
    ? at oracle.net.ns.NetInputStream.read(Unknown Source)
    ? at oracle.net.ns.NetInputStream.read(Unknown Source)
    ? at oracle.net.ns.NetInputStream.read(Unknown Source)
    ? at oracle.jdbc.ttc7.MAREngine.unmarshalUB1(MAREngine.java:931)
    ? at oracle.jdbc.ttc7.MAREngine.unmarshalSB1(MAREngine.java:893)
    ? at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:375)
    ? at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1983)
    ? at oracle.jdbc.ttc7.TTC7Protocol.fetch(TTC7Protocol.java:1250)
    ? - locked <e8c68f00> (a oracle.jdbc.ttc7.TTC7Protocol)
    ? at oracle.jdbc.driver.OracleStatement.doExecuteQuery(OracleStatement.java:2529)
    ? at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2857)
    ? at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate
    (OraclePreparedStatement.java:608)
    ? - locked <e5cc44d0> (a oracle.jdbc.driver.OraclePreparedStatement)
    ? - locked <e8c544c8> (a oracle.jdbc.driver.OracleConnection)
    ? at oracle.jdbc.driver.OraclePreparedStatement.executeQuery
    (OraclePreparedStatement.java:536)
    ? - locked <e5cc44d0> (a oracle.jdbc.driver.OraclePreparedStatement)
    ? - locked <e8c544c8> (a oracle.jdbc.driver.OracleConnection)
    ? at weblogic.jdbc.wrapper.PreparedStatement.executeQuery(PreparedStatement.java:80)
    ? at myPackage.query.getAnalysis(MyClass.java:94)
    ? at jsp_servlet._jsp._jspService(__jspService.java:242)
    ? at weblogic.servlet.jsp.JspBase.service(JspBase.java:33)
    ? at weblogic.servlet.internal.ServletStubImpl$ServletInvocationAction.run
    (ServletStubImpl.java:971)
    ? at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:402)
    ? at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:305)
    ? at weblogic.servlet.internal.RequestDispatcherImpl.includ
    e(RequestDispatcherImpl.java:607)
    ? at weblogic.servlet.internal.RequestDispatcherImpl.include
    (RequestDispatcherImpl.java:400)
    ? at weblogic.servlet.jsp.PageContextImpl.include(PageContextImpl.java:154)
    ? at jsp_servlet._jsp.__mf1924jq._jspService(__mf1924jq.java:563)
    ? at weblogic.servlet.jsp.JspBase.service(JspBase.java:33)
    ? at weblogic.servlet.internal.ServletStubImpl$ServletInvocationAction.run
    (ServletStubImpl.java:971)
    ? at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:402)
    ? at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:305)
    ? at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run
    (WebAppServletContext.java:6350)
    ? at weblogic.security.acl.internal.AuthenticatedSubject.doAs
    (AuthenticatedSubject.java:317)
    ? at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:118)
    ? at weblogic.servlet.internal.WebAppServletContext.invokeServlet
    (WebAppServletContext.java:3635)
    ? at weblogic.servlet.internal.ServletRequestImpl.execute(ServletRequestImpl.java:2585)
    ? at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:197)
    ? at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:170)


    線程將處于運行狀態。您應比較不同 Thread Dump 中的線程,查看它們是否及時接收 SQL 調用的返回結果或者它們是否在此同一調用中長時間掛起。如果 Thread Dump 似乎指示 SQL 調用的響應時間較長,則應檢查相應的數據庫日志,查看是不是數據庫中的問題導致這種執行速度緩慢或掛起的狀況。

    返回頁首

    低速網絡
    WebLogic Server 與數據庫之間的通信依賴于性能良好且可靠的網絡,來及時地處理請求。因此,網絡性能低下可導致正在等待 SQL 查詢結果的執行線程被掛起或阻塞。相關的堆棧跟蹤將與上面掛起的數據庫小節中的示例相似。僅僅通過分析 WebLogic Server Thread Dump 不可能找到掛起或 SQL 查詢速度低下的根本原因。它們給出 SQL 調用的性能存在問題的第一個提示。下一步是檢查是否存在導致 SQL 調用性能不佳的數據庫網絡或網絡問題。

    死鎖
    應用程序級的死鎖與數據庫級的死鎖都可導致線程掛起。您應檢查 Thread Dump,查看是否存在應用程序級的死鎖。有關如何執行這一操作的信息在服務器掛起 - 應用程序死鎖模式中提供。數據庫死鎖可以在數據庫日志中檢測,或者通過可在 WebLogic Server 日志文件中找到的“SQL 異常”檢測。下面是相關“SQL 異常”的一個示例:

    java.sql.SQLException: ORA-00060: deadlock detected while waiting for resource
    ? at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:170)
    ? at oracle.jdbc.oci8.OCIDBAccess.check_error(OCIDBAccess.java:1614)
    ? at oracle.jdbc.oci8.OCIDBAccess.executeFetch(OCIDBAccess.java:1225)
    ? at oracle.jdbc.oci8.OCIDBAccess.parseExecuteFetch(OCIDBAccess.java:1338)
    ? at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:1722)
    ? at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:1647)
    ? at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout
    (OracleStatement.java:2167)
    ? at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate
    (OraclePreparedStatement.java:404)


    數據庫檢測死鎖并通過回滾引發死鎖的一個或多個事務來解決死鎖這一過程通常需要一些時間,因此在回滾結束之前,會有一個或多個執行線程被阻塞。

    RefreshMinutes 或 TestFrequencySeconds
    如果發現數據庫性能低下、SQL 調用速度緩慢或連接高峰的時期反復出現,其原因可能在于 JDBC 連接池中 RefreshMinutesTestFrequencySeconds配置屬性的設置。有關內容在探查 JDBC 故障模式中詳細介紹。除非 WebLogic Server 實例與數據庫之間沒有防火墻,否則您應禁用此功能。

    池收縮
    數據庫的物理連接是應當打開一次并盡可能長時間保持打開的資源,因為新的連接請求對于數據庫、操作系統內核及 WebLogic Server 而言是一個相當大的資源開銷。因此,應在生產系統中禁用池收縮,使這一開銷保持最小程度。如果啟用池收縮,一旦對該池發出的連接請求不能得到滿足,空閑的池連接就將被關閉,然后重新打開。

    這些活動可能會需要一些時間,因此相關應用程序請求需要的時間可能會異常的長,使用戶以為系統掛起。有關如何優化 JDBC 連接池配置的信息在探查 JDBC 故障模式中提供。

    返回頁首

    分析掛起的 WebLogic Server 實例
    有關如何分析掛起的 WebLogic Server 實例的一般信息在常規服務器掛起模式中提供。

    大多數情況下,首先從掛起的系統獲得 Thread Dump 對于了解進展情況(例如不同的線程在做些什么以及它們為什么掛起)是非常有益的。通常,可以在生產系統上獲得 Thread Dump,但是對于很早以前的 JVM 版本 (<1.3.1_09) 則應小心,因為它們可能會在 Thread Dump 期間崩潰。此外,如果 WebLogic Server 實例有大量線程,則意味著完成 Thread Dump 需要一段時間,而其余線程將被阻塞。

    請進行多個 Thread Dump(5 到 10 個),這些 Thread Dump 彼此之間有若干秒鐘的延遲。這使得您可以檢查不同進程的進度情況。而且,它還將指示系統是否確實掛起(根本沒有進度)或者吞吐速度是否極低,看起來像是系統已掛起。

    有關如何進行 Thread Dump 的信息在“常規服務器掛起”支持模式或我們的文檔中提供:http://e-docs.bea.com/wls/docs81/cluster/trouble.html (English)。

    此外,還請檢查是整個 WebLogic Server 實例掛起還是應用程序掛起。“常規服務器掛起”支持模式也包括此信息。

    分析 Thread Dump 可以指示出實例的掛起是否確實是由于前一小節為什么發生此問題?中提到的某一種原因。例如,如果所有線程都在一個 DriverManager 方法(如 getConnection())中,則您已經確定出掛起的根本原因,并需要更改應用程序,以使用數據源或 Driver.connect() 來代替 DriverManager.getConnection()

    Samurai 是一個非常有用的工具,可用于分析 Thread Dump 并監視不同 Thread Dump 之間線程的進度。可從 dev2dev 下載此工具,網址:http://dev2dev.bea.com/resourcelibrary/utilitiestools/adminmgmt.jsp (English)。

    dev2dev 上有關分析 Thread Dump 的白皮書:http://dev2dev.bea.com/products/wlplatform81/articles/thread_dumps.jsp (English) 也有助于深入探究 Thread Dump,以了解有關服務器掛起的更多內容。

    返回頁首

    優化 JDBC 代碼和 JDBC 連接池配置的技巧
    對于開發 JDBC 代碼和配置 JDBC 連接池,有一些最佳的慣例,可以幫助避免常見問題并優化資源利用,避免服務器實例掛起。

    JDBC 編程
    為了優化 WebLogic Server 中資源的利用,節約數據庫資源,應使用 JDBC 連接池進行應用程序的 JDBC 調用。在應用程序代碼中建立和破壞的連接會造成不必要的開銷,應當避免。要獲得 JDBC 編程的一般文檔,請參閱:http://e-docs.bea.com/wls/docs81/jdbc/rmidriver.html#1028977 (English)。此外,有關 JDBC 性能調整的詳細信息位于:http://e-docs.bea.com/wls/docs81/jdbc/performance.html#1027791 (English)。

    可以在 dev2dev Java Database Connectivity (English) 頁上查看有關 JDBC 的綜合性信息,它有助于優化 JDBC 代碼和 JDBC 資源的利用,網址為:http://dev2dev.bea.com/technologies/jdbc/index.jsp (English)。

    JDBC 連接池配置
    關于如何針對生產環境配置連接池的建議,請參閱探查 JDBC 故障模式。為避免出現掛起或者性能不佳的情況,應考慮這些配置技巧。


    返回頁首

    已知問題
    您可以定期查看所用 WLS 版本的“Release Notes”,了解 Service Pack 中的“Known Issues”或“Resolved Issues”的詳細信息及瀏覽與 JDBC 服務器掛起有關的問題。方便起見,下面提供了這些發行說明的鏈接:
    請注意,WLS 8.1 SP3 中已經進行一些更改來解決 CR134921,其中對于特定的 JDBC 連接,用于回滾事務的調用沒有立即處理,因為驅動程序必須等待任何當前正執行的語句返回。

    使用搜索功能也可以搜索到“Release Notes”,還可以搜索到其它支持解決辦法及與 CR 有關的信息,如需要更多幫助?中所提到的內容。如果客戶簽訂了技術支持合同,則可以登錄
    http://support.bea.com/,登錄后會看到為 Solutions 和 Bug Central 提供的 Browse portlet,可在其中按產品版本瀏覽最新提供的 CR。

    需要更多幫助?
    如果您已經理解這個模式,但仍需要更多幫助,您可以:
    1. http://support.bea.com/上查詢 AskBEA(例如,使用“jdbc server hang”),以查找其它已發布的解決辦法。技術支持合同客戶:確保已經登錄,可以訪問提供的與 CR 有關的信息。
    2. http://newsgroups.bea.com/ 上,向 BEA 的某個新聞組提出更詳細具體的問題。
    如果這還不能解決您的問題,并且您擁有有效的技術支持合同,您可以通過登錄以下網站來打開支持案例:http://support.bea.com/
    posted on 2006-07-31 10:19 TrampEagle 閱讀(3857) 評論(0)  編輯  收藏 所屬分類: java
    主站蜘蛛池模板: 亚洲短视频在线观看| 成人免费夜片在线观看| 国产AV无码专区亚洲AWWW| 色窝窝免费一区二区三区| 免费无码一区二区三区蜜桃| 亚洲成av人无码亚洲成av人| 亚洲神级电影国语版| 亚洲2022国产成人精品无码区| 亚洲国产a级视频| 国产大片线上免费看| 免费电视剧在线观看| 亚洲免费二区三区| 久操视频在线免费观看| 免费萌白酱国产一区二区三区| 黄网站在线播放视频免费观看| 亚洲国产精品无码久久九九大片| 亚洲综合久久成人69| 亚洲成在人天堂一区二区| 亚洲乱码无码永久不卡在线| 亚洲区小说区图片区| 四虎永久成人免费| 国产免费爽爽视频免费可以看| 成人毛片18岁女人毛片免费看| 1024免费福利永久观看网站| 久久99热精品免费观看动漫| 青青草原1769久久免费播放 | 九九九精品成人免费视频| 亚洲免费视频在线观看| 中国人免费观看高清在线观看二区| 一级美国片免费看| 久久av免费天堂小草播放| 国产精品黄页免费高清在线观看| 免费国产高清毛不卡片基地| 美女视频免费看一区二区| 日本高清免费中文在线看| 成人精品视频99在线观看免费| 久久久精品视频免费观看| a级成人免费毛片完整版| 成全在线观看免费观看大全| 日韩精品免费在线视频| 色欲色香天天天综合网站免费 |