基於JMX通知架構的AJAX深度開發__架構

來源:互聯網
上載者:User
文章提示 AJAX和JMX分別位於系統管理棧的兩個對立端。然而,如今AJAX模型已普遍存在於豐富的瀏覽器用戶端。這使得該模型在構架領域為在問題解析管道中提高支援模式所具有的優點變得模糊起來。

  本文將詳細描述一種AJAX架構的優點-它可以把管理狀態"廣播"到一個能夠使用瀏覽器的使用者基上而不必等待頁面更新。

  這種架構是一個通用模型的擴充-可用於把JMX事件和屬性記載到一個伺服器端記錄檔中;而且,這種變化進一步把管理資訊記錄或"廣播"到(支援AJAX的)使用者基。

  在本文中,我們將特別分析AJAX請求/響應模型和把管理資料繪製到頁面的過程,還有漂亮的JMX通知架構-所有這些都通過一個裝配的servlet清晰地整合到一起。

  接下來我們還會粗略地看一下通常在標準AJAX討論中所不及的內容-安全和容量模型。

  本文中,我們使用BEA WebLogic 8.1用作這些軟體的發布平台,儘管這裡的架構和方法也適用於其它J2EE應用程式伺服器。

  一、關鍵需求

  針對於企業Java和J2EE應用程式的系統管理棧形成了問題解析管道的一部分-在此,Java/J2EE應用程式與一個管理層進行互動以監視潛在的問題,例如應用程式伺服器線程饑餓,堆溢出或到一個資料庫的陳舊串連等。

  管理層通常包括JMX Mbeans-要裝配並使用哪個應用程式,以及其它一些產品例如讀取這些JMX屬性的Wily Introscope和HP OpenView-如果超過一個事先配置的門檻值,那麼它能夠從Wily中得到警告。

  這個模型存在一個問題-如果系統在後台出現問題的話,針對JMX管理的伺服器端模式將無法協助瀏覽器端客戶,因為這種模型全部是以伺服器為中心的。例如,如果一新的J2EE Web應用程式要被發布或該應用程式在幾分鐘內將要關閉-因為Wily檢測到一個問題,那麼在瀏覽器上的使用者並不知道發生了這麼緊迫的管理事件。

  通過全面地允許使用者進入問題解析管道,系統管理員可以管理終端使用者體驗-通過把管理資訊廣播到使用者基並在一定程度上控制使用者的行為來實現。

  為了通過HTTP協議實現把管理資訊傳遞給客戶,存在這樣一個問題:如果用戶端使用者不是公開地使用GET或POST更新頁面而是偷偷地更新一隱形架構,那麼管理方面如何把管理資訊發送到一個HTTP客戶。

  二、方案描述

  本文要實現一簡單的AJAX指令碼,它將從MBean伺服器取得以XML訊息形式的管理資訊並經由一個servlet解決這個問題。這些管理資訊必須被加以管理並且被反饋到所有的參與其中的能夠接收AJAX請求的應用程式伺服器。

  在伺服器端:

  ·一個J2EE應用程式伺服器簇用於服務於來自基於瀏覽器的使用者和線上交易處理(OLTP)使用者基(例如有兩個或四個伺服器)的請求。通過使用一個第三方Web伺服器,使用者請求被跨越該簇(OLTP簇)平衡裝載。

  ·一個標準MBean(UserWeb)用於儲存管理資訊,如加上中繼資料屬性的管理訊息。該Mbean宿主在J2EE"管理"伺服器和在OLTP簇上的J2EE伺服器上。

  ·在管理伺服器上,由系統管理員使用針對JMX的HTMLAdaptor來設定警告狀態,稍候再試(在相鄰XMLHttp-Requests之間的間隔)以及警告訊息-例如"System Down in 10 Minutes."。然後,管理員把該狀態廣播到管理伺服器上的Mbeans-由該管理伺服器來把它們的狀態重設到master管理狀態。

  在用戶端:

  ·支援AJAX的用戶端使用一個XMLHttpRequest(它調用一個servlet以返回XML訊息形式的相關的MBean值)來檢索狀態、稍候再試和訊息。

  ·然後由用戶端JavaScript分析這個XML訊息,重設稍候再試並且用管理訊息重畫螢幕的一部分。

  ·在retry-interval秒之後,該客戶進行另外一個XMLHttpRequest並且客戶周期再次開始。 三、 基本架構

  圖1顯示出全面的方案架構,其中表1描述了相應的基本架構元素。


圖1 方案架構

元素 描述
標準MBean(UserWeb) 用於警告狀態和訊息的屬性,還有getter/setters和一個方法來廣播(通知)MBean狀態
MBean助理(UserWebMBeanHelper) 封裝裝配的代碼以便於使用UserWeb MBean
MBean伺服器 J2EE容器內的MBean伺服器
Servlet(Admin.java) 裝配的Servlet,基於UserWebMBean的內容格式化XML響應
事件聽者
(ManagementListener.java)
Singleton-它用管理伺服器上的UserWeb MBean把自己註冊為一個"alert.broadcast"類型事件的聽者
用戶端AJAX引擎(admin.js) 用於管理XMLHttpRequest-/-repaint周期的JavaScript
用戶端描述(main.jsp) 裝配的JSP。AJAX基於MBean屬性啟動該頁面
HTML適配器封裝器(StartHTMLAdaptor.java) 在聽連接埠+100啟動一個HTMLAdaptorServer以實現到MBeans的HTTP存取
     表1 架構元素

  (一) JMX通知模型

  這個模型包含兩個組件:

  ·MBean-為本地和遠程註冊的聽者啟用事件

  ·聽者-它用MBean註冊自己以聽取由該MBean所產生的事件

  第一個由UserWeb Mbean來實現,第二個由ManagementListener來實現。

  (二) 系統管理使用者資訊的JMX MBean

  UserWeb標準的MBean是一個簡單類-它包含關鍵的屬性和方法(表2)。

元素 描述
AlertEnabled 如果AlertStatus>-1,則為真
AlertMessage 使用者將在螢幕上看到的資訊
AlertReady 如果AlertStatus>0,則為真
CallBack 在每兩個XMLHttpRequest之間的毫秒數
BroadcastState 方法-它用一個事件(alert.broadcast)(它把Mbean狀態作為事件數目據傳遞)來通知在本地/遠程JVM上的所有登入的聽者

    表2 UserWeb Mbeam屬性和方法

  (三) 事件聽者

  Singleton ManagementListener類實現了Weblogic.management.RemoteNotificationListener-它擴充了javax.management.NotificationListener和java.rmi.Remote以允許在一個遠程WebLogic JVM上的事件通過使用RMI技術被通知到遠程聽者。
在應用程式伺服器啟動時,在每個JVM上的一個聽者用管理伺服器上的UserWeb MBean註冊自己。

  (四) MBean助理

  使用一個助理類來對Mbeans加以封裝是個不錯的注意。這樣,我們可以從裝配的代碼中調用這個助理從而調用MBean方法。
UserWebMBeanHelper類被用作UserWeb Mbean的封裝。所有助理的祖先是ApplicationMBeanHelper,它負責:

  ·尋找本地和遠程MBean伺服器

  ·調用這些伺服器以取得/設定MBean屬性並且調用MBean方法

  為了確保相匹配,MBean和MBean助理都實現介面UserWebMBean。

  (五) 裝配Servlet

  一個應用程式可以被裝配以使用JMX。用AOP術語來說就是,把管理方面織入到應用程式代碼中。本文中第一個JMX裝配點是一個 HTTPServlet。這個servlet是AJAX請求的目標,並且它實現一個控制器模式-它可以被精心製作以使用簡單的請求參數來處理其它AJAX 請求。
從一個MVC的角度來看,該模型是UserWeb Mbean,視圖是支援AJAX的(JSP)頁面,而控制器是被裝配的servlet。

  (六) 用戶端AJAX引擎

  這是一組JavaScript函數,它們:

  ·管理XMLHttpRequest並且響應處理重複性操作

  ·分析由XMLHttpRequest返回的XML訊息

  ·用XML訊息內容重畫螢幕

  客戶描述

  這是main.jsp頁面-它包含用戶端AJAX引擎和可重畫的部分。

  (七) 序列

  實質上,伺服器端序列參與管理管理屬性的設定並且把這些屬性廣播到所有的感興趣(聽)的JVM上。而,用戶端序列參與檢索這些屬性並且以管理指定的間隔時間用重要的管理資訊來重畫該HTML頁面。

  (八) JMX通知(伺服器序列)

  ·UserWeb MBeans和MBean事件聽者在應用程式伺服器啟動時被使用相應的啟動類建立並且註冊

  ·管理員設定"master"UserWeb MBean屬性(警告訊息和稍候再試),然後向宿主在遠端管理伺服器上的聽者廣播或通知這一狀態

  ·遠程聽者處理通知-通過把master(通知)資料複製到本地UserWeb MBean實現

  (九) XMLHttpRequest查詢(客戶序列)

  ·支援AJAX的用戶端間隔地調用一個servlet以查詢管理狀態

  ·該servlet讀取本地UserWeb MBean屬性,然後把它們插入到一個XML訊息中並且返回該XML訊息作為一個到瀏覽器客戶的XML響應(以後討論可供選擇的訊息格式)

  ·然後,AJAX客戶分析XML文檔,提取警告和稍候再試等訊息,重畫螢幕,然後使用這一稍候再試來設定下一個XMLHttpRequest的延遲時間。

  下面詳細描述其中的每一步。 

四、註冊MBeans和MBean聽者

  在每一個J2EE伺服器執行個體上,在伺服器啟動時運行兩個啟動類:

  ·ManagementStartup-它把UserWeb MBean註冊到本地MBean伺服器。Startup類參數包括警告狀態的預設設定,還有MBean名稱和MBean類。例如:

<StartupClass
Arguments="ServerName=admin,
MBeanName=ExampleApp:Name=UserWeb,
MBeanClass=com.grahamh.management.userWeb.UserWeb"
ClassName="com.grahamh.management.startup.ManagementStartup"
FailureIsFatal="true" Name="UserWEB" Notes=""
Targets="admin,OLTPCluster"/>

  ·MbeanRegistrations-它用管理伺服器上的UserWeb MBean來註冊一個Singleton POJO-ManagementListener。

  一個javax.management.NotificationFilterSupport對象被用於列舉UserWeb MBean將產生和聽者將接收的通知的類型:

//MbeanRegistrations.java
MBeanHelperFactory.getWebHelper().registerListener();
//UserWebMbeanListener.java
public void registerListener() throws UserWebException{
try {
 //得到聽者和過濾
 ManagementListener listener = MBeanHelperFactory.getListener();
 NotificationFilterSupport filter = listener.getSupportedEvents();
 //得到admin mbean伺服器;
 //用UserWeb MBean註冊該聽者和過濾
 RemoteMBeanServer rmbs = getAdminMbeanServer();
 rmbs.addNotificationListener("ExampleApp:Name=UserWeb", listener, filter, null);
}
catch (Exception e) {
 throw new UserWebException("Unable to registerListener: "+ e.getMessage(), e);
}
}

  該listener.getSupportedEvents()方法返回下面的過濾器(filter):

NotificationFilterSupport filter = new NotificationFilterSupport();
filter.enableType("alert.broadcast");

  當ManagementListener在伺服器啟動時,在(遠端)管理伺服器上建立一個到MBean伺服器的串連,而且(本地的) ManagementListener被註冊為一個聽者-聽取在UserWeb MBean上產生的事件,並且有一個過濾器被設定為"alert.broadcast"事件類型。

  因為該 ManagementListener實現Weblogic.management.RemoteNotificationListener,所以它可以得到在本地JVM或一遠程JVM上產生的JMX通知;在本文中,是指在遠端管理伺服器JVM上產生的JMX通知。

五、廣播Admin MBean屬性

  管理和託管UserWeb Mbeans可以進行獨立地設定-這給任何一個J2EE伺服器一個本地化的AJAX響應。然而,一個普通操作,管理和支援(OA&M)支援模式將設定admin MBean的屬性,然後使用通知模型把這些屬性廣播到遠程應用程式伺服器上的MBeans,以備隨後的AJAX檢索之用。

  因為該UserWeb MBean是基於ApplicationMBean-它擴充了 javax.management.NotificationBroadcasterSupport,所以該基礎結構正適合於由UserWeb MBean來通知所有的聽者。因此,管理員設定相關的MBean屬性(使用HTMLAdaptor)並且點擊BroadcastState(見圖2)。


圖2 使用HTMLAdaptor看到的MBean視圖

  因而,UserWeb.broadcastState()方法被執行-它同步地通知所有的聽者有關admin MBean的狀態:

public void broadcastState() throws Exception {
 try {
  Notification n = new Notification("alert.broadcast", "ExampleApp:Name=UserWeb", 0);
  n.setUserData(new UserWeb(this));
  this.sendNotification(n);
 }
 catch (Exception e) {
  throw e;
 }
}

  因為資料在網路上是序列化傳輸的,所以這種並非暫時的對象圖必須是可序列化的。

  六、使用聽者接收來自MBean Props的通知

  所謂的事件聽者就是ManagementListener Singleton。在管理伺服器上的JMX通知架構遠程調用ManagementListener中的handleNotification()方法- 該方法存在於每個OLTP簇JVMs(它們是在伺服器啟動時註冊的)上的每一個聽者之中:

public void handleNotification(Notification notification, Object handback) {
System.out.println("Received alert: " + notification.getType());
//取得來自通知的事件userdata
Object userData = notification.getUserData();
if (userData instanceof UserWeb) {
 //來自於destin8 Web
 UserWeb WebVo = (UserWeb)userData;
 UserWebMBeanHelper helper = MBeanHelperFactory.getWebHelper();
 //使用MbeanHelper從值對象擷取資料並放入本地MBean中
 helper.setAlertMessage(WebVo.getAlertMessage());
 helper.setAlertStatus(WebVo.getAlertStatus());
 helper.setCallBack(WebVo.getCallBack());
 helper.setRefreshAlertStatus(WebVo.getRefreshAlertStatus());
}
}

  "master" UserWeb資料被置入本機使用者Web MBean中-經由它的MBean助理來實現。因而,每個管理伺服器被用master UserWeb狀態所更新。這就是JMX元素所具有的功能。

七、 管理狀態的AJAX請求

  要使瀏覽器用戶端支援AJAX,需要具備如下:

  ·main.jsp-被裝配的JSP頁面,它能夠檢查(JMX)警告狀態並向伺服器查詢警告。這個.jsp檔案包括admin.js

  ·admin.js-這是一個JavaScript公用程式,它使用XMLHttpRequest來向伺服器查詢管理狀態,分析XML響應,並且重畫螢幕的"status"地區

  被包含在main.jsp中的JavaScript描述如下:

<script type="text/javascript" src="./js/admin.js" ></script>

   不是連續地查詢,而是只有啟動瀏覽器警告功能時我們才進行查詢。我們使用UserWebMBeanHelper來檢查這個功能。如果該功能被啟動,那麼當頁面載入時,JavaScript函數initAdmin()將被調用:

<%
if (MBeanHelperFactory.getWebHelper().isAlertEnabled()) {
%>
<body bgcolor="#F4FFE4" onload="initAdmin();">
<%
} else {
%>
<body bgcolor="#F4FFE4">
<%
}
%>

  重畫的'status'螢幕地區定義如下:

<span id="adminBanner" class="style1"></span>

  "adminBanner"將被使用來標記可重畫的地區-當分析XML響應並提取訊息時。

  這個initAdmin()方法調度一個JavaScript方法trapAlert()-這個方法在callbackTimeout毫秒後執行:

function setCallback() {
 callBack = setTimeout('trapAlert()',callbackTimeout);
}
function initAdmin() {
 setCallback();
}

  注意,是由trapAlert()方法來實現啟動XMLHttpRequest:

function trapAlert() {
 if (window.XMLHttpRequest) {
  req = new XMLHttpRequest();
 } else if (window.ActiveXObject) {
  req = new ActiveXObject("Microsoft.XMLHTTP");
 }
 req.onreadystatechange = processRequest;
 req.open("GET", './admin?reqid=0', true);
 req.send(null);
}

  在此,HTTP GET用來讀資料(只使用了一個小的請求參數),並且目標是admin servlet。這個請求是非同步,並且當請求狀態變化時,processRequest JavaScript函數被調用:

req.onreadystatechange = processRequest;

  在繼續處理前等待一個響應,這看上去似乎非常合理;然而,如果一個網路或伺服器問題導致一個事務無法完成,那麼你要冒著使你的指令碼掛起來的危險。相比之下,一個相應於onreadystatechange事件的非同步呼叫更為靈活些。

  在請求完成時,processRequest事件處理器被調用:

function processRequest() {
 if (req.readyState == 4) {
  if (req.status == 200) {
   parseMessages();
  }
  ....
  setCallback();//只有完成時才這樣做
 }
}

  列表1(見下載源碼)顯示了所有可用的狀態代碼。當請求完成並且返回HTTP狀態碼200(OK)時,parseMessages()方法被調用以從 XML訊息中提取資料。然後,再次調度trapAlert()方法。如果XML響應有一個不同的稍候再試,那麼這個值會由parseMessages() 函數設定。

八、分析XML響應並重畫螢幕

  parseMessages()函數首先提取XML響應

response = req.responseXML;

  然後,它提取有關警告狀態,警告文本和稍候再試等的元素:

itemStatus = response.getElementsByTagName('status')[0].firstChild.nodeValue;
itemText = response.getElementsByTagName('textBody')[0].firstChild.nodeValue;
callbackTimeout = parseInt(response.getElementsByTagName('callBack')[0].firstChild.nodeValue);

  然後,警告文本被重畫到adminBanner文件項目(見上):

document.getElementById("adminBanner").innerHTML= itemText;

  該警告訊息顯示在如圖3所示的螢幕上。

圖3 重畫的螢幕

  九、Servlet格式化XML響應

  為了使瀏覽器把管理警告顯示給使用者,需要使用XMLHttpRequest來要求管理狀態。

  當瀏覽器發送請求時,該servlet使用MBean助理來檢查警告狀態並且,如果一警告可用,即構建一個XML文檔作為響應。

  如果沒有返回狀態,那麼響應狀態被設定如下:

response.setStatus(HttpServletResponse.SC_NO_CONTENT);

  否則,該文本/XML響應類型被設定為:

response.setContentType("text/xml");

  列表2顯示了完整的servlet方法。

  當該servlet被調用並且返回XML內容時,控制台應該列印出:

Received alert: alert.broadcast
<message>
<status>1</status>
<textBody>
<![CDATA[System Down in 10 Minutes]]>
</textBody>
<callBack>10000</callBack>
</message>

  十、容量建模和安全性

  因為AJAX以有趣的方式開通了架構,所以存在兩個關鍵方面要求加以考慮:

  ·容量建模

  ·安全性

  當然,緩衝和響應訊息類型(XML或文本)也都是比較重要的。

十一、容量建模

  支援AJAX的豐富的用戶端不必再如以前那樣頻繁地提交請求。但是隨著XMLHttpRequest非同步地執行在瀏覽器端,向伺服器發出的HTTP請求的數目也會相應於稍候再試而有所增加。

  ·再試間隔(考慮時間)=20秒

  ·串連的使用者數=5000

  ·事務每秒(TPS)=5000/20=250

  我們期望一個由HTTP使用者基所產生的額外的每秒能夠實現250次的請求(事務)。

  當然,這依賴於在伺服器上的這些請求所完成的任務來提高回應時間上的潛力。在我們的執行個體中,每個請求必須尋找MBean屬性並且格式化一個XML響應,但是該響應很小而且MBean處理是在本地記憶體中。由於每個Web伺服器線程每秒能夠處理大約200個GET請求,以及使用者橫跨一個大約運行著200個線程的J2EE伺服器來請求平衡載入,所以增加的載入並不太重要。

  還應注意,當建模AJAX架構時,增加的載入數可能隨著頻寬的減少而有所位移。

  十二、安全性

  假定你只要求WebUser組中的使用者能夠存取該admin servlet,情況會怎樣呢。

  如果僅是被認證的使用者才能存取admin servlet,那麼XMLHttpRequest將以該使用者身份運行-如果該使用者已經認證。

  例如,一旦使用者Joe登入進這個應用程式,並且Joe是一個WebUser組的成員,那麼XMLHttpRequest將能啟用admin servlet。

  把下列代碼添加到admin servlet將會確認被認證的主題,並分別返回true和Joe:

request.isUserInRole("WebUser");
request.getRemoteUser();

  十三、緩衝

  一些使用者已經發現IE會緩衝來自AJAX請求的響應;這可能是由於瀏覽器/版面設定,但是一個強制性的解決辦法是為該URL加上時間印戳:

var urlstr = "./admin?reqId=0&ts=" + new Date().getTimeStamp();

  十四、用不用XML。

  一些AJAX設計者欣然棄用XML而發送以普通文本形式的響應:

response.setContentType("text/plain");

  這明顯要依賴於你的用戶端需求和客戶與所需求的資料之間的耦合程度。一個簡單的文本響應對於一個文本警告就足夠了;然而,本文中XML模型的優點在於,響應資料可以被進一步詳細描述從而提煉狀態和狀態相關的資料。本文向你展示了怎樣分析一更複雜的響應-客戶可能必須編碼以進行接收之。

  十五、 結論

  AJAX代表了一些新型的架構機會,然而它們不應該被豐富的用戶端功能所遮蔽。本文在衡量了AJAX所提供的優點的同時,也強調了其對於容量和安全方面的技術要求-這是使用這種新型技術所必須要求的。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.