跳轉到內容

WebObjects/Web 應用程式/部署/常見問題及故障排除

來自華夏公益教科書,開放書籍,為開放世界

斷開管道

[編輯 | 編輯原始碼]

我正在開發的應用程式在呼叫 editingContext.saveChanges 時會凍結大約一分鐘,系統輸出中添加了以下訊息

 <WorkerThread3> <WOWorkerThread id=3 socket=Socket[addr=/xxx.xxx.xxx.xxx,port=51634,localport=51563]>
Exception while sending response: java.net.SocketException: Broken pipe

奇怪的是,實際上沒有丟擲異常,並且更改已儲存到資料庫中。關於此訊息的含義,有什麼線索嗎?

Chuck Hill

[編輯 | 編輯原始碼]

此訊息意味著 woadaptor 在分配的時間內未收到應用程式的響應。此時,woapdator 會結束通話應用程式,假設它已宕機或過於繁忙。如果運行了多個例項,woadaptor 會將請求轉發到另一個例項。對於元件操作,這會產生會話過期或無法恢復頁面的錯誤訊息。

當應用程式最終完成請求處理後,它會嘗試將結果返回給 woadaptor,但會發現它已經結束通話了(即關閉了套接字,斷開了管道)。此時,上述異常會輸出到日誌中。

有幾種方法可以避免這種情況

  • 最佳化應用程式,以便更快地處理請求。
  • 使用 WOLongReponsePage 處理長時間執行的請求。
  • 增加 JavaMonitor 中的連線超時和接收超時值,以便 woadaptor 能夠等待足夠長的時間以供應用程式提供響應。

注意:如果此訊息出現在其他上下文中(即不是在請求處理時間過長時),它可能只是意味著使用者在瀏覽器中點選了停止或點選了另一個連結。

我的 stderr 去哪了!?

[編輯 | 編輯原始碼]

Wotaskd 使用一個名為 SpawnOfWotaskd.sh 的指令碼啟動新的 WOA 例項,該指令碼位於 OS X 上的 /System/Library/WebObjects/JavaApplications/wotaskd.woa/Contents/Resources/SpawnOfWotaskd.sh。由於某種原因,此指令碼被編寫為丟棄 stderr。這意味著如果您想獲得執行緒堆疊轉儲,您將無法做到。幸運的是,這是一個簡單的修復。如果您編輯 SpawnOfWotaskd.sh,庫存版本看起來像

 #!/bin/sh
 $@ 1>/dev/null 2>&1 & 

注意流 1 會轉到 /dev/null,流 2 會寫入流 1。不好。將其更改為

 #!/bin/sh
 $@ 1>>/var/log/webobjects.err 2>&1 & 

現在唯一的問題是,WebObjects 應用程式通常以 appserver 使用者身份執行,這意味著它們將無法寫入此檔案。要解決此問題,您可以以 root 身份“touch /var/log/webobjects.err”,然後將空白檔案的所有者更改為 WebObjects 應用程式執行的任何使用者。

無法連線到視窗伺服器 - 許可權不足

[編輯 | 編輯原始碼]

啊,是的,AWT 的樂趣。如果您接觸任何 AWT 類(即使是不合理的類,如 Dimension 或 Rectangle),都會建立一個 AWT Toolkit(在靜態塊中),並且 AWT 會嘗試連線到視窗伺服器。當然,當您在開發模式下執行時,您擁有對視窗伺服器的訪問許可權,一切都很順利。一旦您嘗試以 appserver 使用者身份部署,一切都崩潰了。您有兩個選擇來解決此問題

  • 不要使用它們。這是避免此問題最萬無一失的方法。如果您不需要,請不要使用 AWT 類。顯然,這通常說起來容易做起來難。
  • 將 -Djava.awt.headless=true 新增到您的 VM 啟動引數中。這會告訴 AWT 使用無頭模式。如果您使用的是較舊版本的 Apple JVM,這仍然會導致問題(奇怪的除錯語句會要求您在控制檯中按一個鍵)。
  • PJA Toolkit。這實際上是一個很酷的庫。它是 AWT 工具包的純 Java 實現。在普通系統上,您的 AWT 實現是 JNI(與您的本機視窗系統對話)。PJA 為正常 AWT 工具包嘗試執行的所有功能提供純 Java 實現。顯然,它實際上並不使用視窗伺服器,而是類似於帶有虛擬幀緩衝區的 VNC 伺服器。
  • 以 root 身份執行。這通常不建議,但您可以修改 /System/Library/StartupItems/WebObjects/WebObjects 指令碼,使其以 root 身份執行 WO,而不是以 appserver 使用者身份執行。您將在該指令碼中找到有關如何執行此操作的說明。

Java Monitor 問題

[編輯 | 編輯原始碼]

對於在 Mac OS X 上遇到監視器問題的人,請檢查以下引數

  • 檢查機器在 DNS 中是否正確識別,包括反向查詢。
  • 驗證您在監視器中新增機器時是否包含完全限定名稱,例如“machine.domain.com”,而不僅僅是“machine”。使用較短的版本可能看起來有效,但實際上無效(這已由 Apple 記錄)。
  • 檢查介面卡配置 (/System/Library/WebObjects/Adaptors/Apache/apache.conf),特別是例項發現方法:這需要與 wotaskd 的命令列啟動一致(請參閱 /System/Library/StartupItems/ 中的指令碼)。您可能需要手動修改指令碼。
  • 當一切都設定好後,重新啟動。它應該可以工作。

WOtaskd 未啟動

[編輯 | 編輯原始碼]

在較舊版本的 OS X 伺服器中,WOtaskd 和 JavaMonitor 是使用 StartupItems 系統啟動的。在較新的版本的 OS X 伺服器和 WebObjects 中,Apple 則使用其新的 launchd 框架。如果您使用開發者工具安裝 WebObjects,您通常只會獲得 Startupitem 指令碼,因此您應該按照這些說明操作。

WOtaskd/WOMonitor LaunchDaemon

[編輯 | 編輯原始碼]

要詳細瞭解 launchd,您可以閱讀 Apple 的文件

WebObjects launch daemon 專案預設情況下處於停用狀態,因此您需要做的第一件事是啟用它們

  1. cd /System/Library/LaunchDaemons
  2. 編輯“com.apple.womonitor.plist”和“com.apple.wotaskd.plist”
  3. 將 Disabled 鍵從“true”更改為“false”
  4. 儲存並退出

接下來,您需要手動載入 launch daemon 專案

  1. 以 root 身份執行“launchctl”
  2. “list”並查詢 com.webobjects.womonitor 和 com.webobjects.wotaskd
  3. 如果它們存在,您需要手動載入它們
    1. “load /System/Library/LaunchDaemons/com.apple.wotaskd.plist”
    2. “load /System/Library/LaunchDaemons/com.apple.womonitor.plist”
  4. 再次“list”並驗證它們都出現
  5. “start com.webobjects.wotaskd”
  6. “start com.webobjects.womonitor”
  7. 退出 launchctl(使用 ctrl-c)

wotaskd 和 womonitor 現在都應該在執行。您可以透過訪問 https://:56789 來測試監視器。

如果這不起作用,請檢查 /Library/WebObjects/Configuration 上的檔案系統許可權,它應該是 appserver:appserverusr,或者至少它們應該對此目錄具有寫入許可權。

在終端視窗中執行以下命令將告訴您 wotaskd 無法啟動的確切原因...

sudo -u appserver /System/Library/WebObjects/JavaApplications/wotaskd.woa/Contents/Resources/javawoservice.sh -appPath /System/ Library/WebObjects/JavaApplications/wotaskd.woa/wotaskd

WOtaskd/WOMonitor StartupItems

[編輯 | 編輯原始碼]

在開發者安裝和較舊的 Mac OS X 伺服器安裝中,WebObjects 是使用舊的 StartupItems 系統啟動的。預設情況下,wotaskd 和 womonitor 處於停用狀態。幸運的是,啟用它們很容易

  1. cd /System/Library/StartupItems/WebObjects
  2. 編輯“WebObjects”
  3. 搜尋“-appPath”,您將在指令碼的此區域找到四個註釋掉的程式碼行。
    • 要以 root 身份執行 WebObjects,請取消註釋前兩條命令(您應該看到 WOTASKD 和 WOMONITOR 行)
    • 要以其他使用者身份執行 WebObjects(預設情況下為 appserver 使用者),請取消註釋第二組程式碼行
  4. 儲存並退出
  5. 使用兩種方法之一啟動 WebObjects 服務
    • sudo systemstarter start "WebObjects 服務"
    • ./WebObjects start

完成這些更改後,wotaskd 和 womonitor 將在重啟後自動啟動。

注意:不要在安裝了 WO 5.3.* 的 MacOS X 10.4.* Server 機器上執行這些步驟。在該系統中,程序是作為 LaunchDeamon 啟動的(如上所述)。如果你啟用了啟動項,系統會嘗試啟動兩次 wotaskd,這會導致任何操作都無法正常進行。

處理死鎖/應用程式掛起

[編輯 | 編輯原始碼]

有幾種處理死鎖和應用程式掛起的方法。

如果你正在使用 效能分析器 或偵錯程式,你通常可以暫停執行並檢視你的應用程式在哪個地方停止執行。

如果你使用的是 JDK 1.4,你可以向你的應用程式傳送 QUIT 訊號,它會轉儲所有活動執行緒。在 OS X 上,找到你的應用程式的 pid,然後執行 "kill -QUIT yourAppPID"。執行緒堆疊跟蹤將轉儲到日誌檔案。如果你的日誌中沒有輸出,請參閱上面的“我的 stderr 在哪裡?!”以瞭解可能的因素。

如果你使用的是 JDK 1.5,除了可以嚮應用程式傳送 QUIT 訊號外,你還可以(以 root 或啟動使用者的身份)連線到它,並使用 "jstack" 應用程式透過呼叫 "jstack yourAppPID" 來獲取執行緒堆疊轉儲。

如果看到 WOWorkerThreads 掛起等待恢復會話,通常意味著先前的請求從未正確檢查回其會話的位置丟擲了異常。WebObjects 中的會話訪問是單執行緒的。導致此問題常見的案例包括從你的 awake 方法以及從 DirectAction 方法中丟擲異常。

在 JDK 1.4 中,你將能夠看到每個堆疊跟蹤持有的物件鎖列表。你可以透過查詢包含兩個或多個重疊鎖的多個執行緒來查詢死鎖。在 JDK 1.5 中,VM 會檢測死鎖情況,並在執行緒堆疊轉儲中識別它們。

華夏公益教科書