很多公司在招聘進階系統維護人員的時候,希望應聘者有一些開發經驗或者要會寫程式,至少也要讀得懂用某些語言寫的程式并能作簡單修改。這并非是無事找事,故意擡高門檻。實際上,有的時候,為了能夠更好地監控我們的系統,或者驗證我們安裝的系統滿足應用的要求,我們必須要使用一些代碼。比如,我們的應用伺服器 運作正常嗎?我們的資料庫連接配接正常嗎?我們的伺服器把 HTTP request 正确地傳給了我們的應用伺服器嗎?我們的MySQL + Resin 能正常處理漢字嗎? 這些在實踐中都是常常遇到的問題,下面我們來仔細說說。
一. 應用伺服器運作正常嗎?
相對于其它應用來說,WEB 應用比較特殊,因為它需要放到應用伺服器或者說 WEB 容器裡面來運作。由于既有 WEB 應用,又有 WEB 應用伺服器,兩者交織在了一起,當出現問題的時候,可能就會出現不能快速準确定位到底是 WEB 應用的問題還是 WEB 應用伺服器的問題。所有,我們應該有相應的措施來區分問題到底出現在哪個身上。筆者在實踐中采取的措施是,用了一個簡單的 JSP 頁面來實時驗證 WEB 應用伺服器的狀況,當監控系統(比如what'sup)保障的時候,監控人員隻需要通過檢視 WEB 應用伺服器監控頁面,就知道到底是哪個的問題了,然後采取相應的措施。筆者所用的代碼可以說是再簡單不過了:
# cat $RESIN_HOME/webapps/ROOT/test_resin.jsp
<%= 1 + 1 %>
然後,在 What'sup 裡面進行配置,讓它去 GET 該頁面,如果能夠取到值2, 就顯示正常,否則,報警。
二. 資料庫連接配接正常嗎?
有一段時間,資料庫老出問題,監控人員分不清到底是系統問題還是資料庫問題,就老是“騷擾”我,比較痛苦。為此,筆者“湊”了下面的代碼,來監控資料庫:
# cat $RESIN_HOME/webapps/ROOT/test_oracle.jsp
<%@ page contentType="text/html;charset=gb2312" import="java.sql.*" %>
<%
// define variables
String CLASS="oracle.jdbc.driver.OracleDriver";
String NODE1_AND_DB="jdbc:oracle:thin:@(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = 172.17.1.3)(PORT = 1521))(CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME =RACDB.GLOBAL)))";
String NODE2_AND_DB="jdbc:oracle:thin:@(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = 172.17.1.4)(PORT = 1521))(CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME =RACDB.GLOBAL)))";
String USER="<username>";
String PASSWORD="<password>";
String SQL="select count(*) from tab";
// init
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
// check NODE1
try
{
Class.forName(CLASS);
conn = DriverManager.getConnection(NODE1_AND_DB,USER,PASSWORD);
stmt = conn.createStatement();
rs=stmt.executeQuery(SQL);
out.println("<br>");
out.println("172.17.1.3 is OK");
}
catch(SQLException e)
out.println("172.17.1.3 is not OK");
}
finally
try
{
if(rs != null) rs.close();
if(stmt != null) stmt.close();
if(conn != null) conn.close();
}
catch(SQLException e)
out.println("DB close error " + getClass());
// check NODE2
conn = DriverManager.getConnection(NODE2_AND_DB,USER,PASSWORD);
out.println("172.17.1.4 is OK");
out.println("172.17.1.4 is not OK");
%>
由于我們的資料庫都是 RAC 來的,是以需要監控兩個結點,從上面的代碼可以看出,該頁面能夠監控RAC的兩個結點。然後,在 What'sup 裡面配置,讓它去 GET 該頁面,如果傳回"is OK",則顯示正常,否則,報警。
注意,盡管該代碼是監控 ORACLE RAC 的,但是隻要經過簡單修改,就可以用來監控其它資料庫了。相信讀者有修改這點簡單代碼的功力,是以筆者就不具體闡述了。
三. 伺服器把 HTTP request 正确地傳給了我們的應用伺服器嗎?
曾經遇到過一個怪事情,筆者維護的一台伺服器的 RESIN 不能正常處理 HTTP GET 請求,但是 telnet 8080 端口又沒有問題。開發人員懷疑,是不是筆者的伺服器有沒有把 HTTP GET 請求正确地發給 RESIN,或者是 RESIN 不能正确處理 HTTP GET 請求。于是,筆者搞了下面的代碼,來表明自己的“清白”,呵呵呵呵。
# cat $RESIN_HOME/webapps/ROOT/disp_http_request_header.jsp
<%@ page contentType="text/html; charset=gb2312" language="java" import="java.sql.*,java.util.*"%>
out.print("1.Local Address: " + request.getLocalAddr() + "<br>");
out.print("2.Local Name: " + request.getLocalName() + "<br>");
out.print("3.Server Name: " + request.getServerName() + "<br>");
out.print("4.Server Port: " + request.getServerPort() + "<br>");
out.print("5.Remote Host: " + request.getRemoteHost() + "<br>");
out.print("6.User Agent: " + request.getHeader("user-agent") + "<br>");
out.print("7.User Agent: " + request.getHeader("referer") + "<br>");
out.print("8.Protocol: " + request.getProtocol() + "<br>");
out.print("9.Method: " + request.getMethod() + "<br>");
out.print("10.Request URI: " + request.getRequestURI() + "<br>");
out.print("11.Servlet Path: " + request.getServletPath()+ "<br>");
out.print("12.Path Info: " + request.getPathInfo() + "<br>");
out.print("13.Real Path: " + request.getRealPath("/")+ "<br>");
然後,再從浏覽器裡面請求該頁面,一切正常。看來,不是筆者伺服器或者 RESIN 的問題。後來,經過開發的反複折騰,重要找到了問題,都是 filter 惹的禍 !!!
四. MySQL + Resin 能正常處理漢字嗎?
擺弄過 MySQL 5.0.x + Resin 3.0.x 的讀者可能遇到過,這種比較優秀的搭配,有時候在處理漢字的時候會“鬧鬼”,不能正常處理漢字。是以,我們在安裝了這個配置之後,最好是用代碼來驗證一下,自己的安裝配置有沒有問題。當然,首先你得保證,你的 LINUX 系統的字元集沒有問題,這樣配置 i18n 檔案可以保證你的 LINUX 系統字元集沒問題。
# cat /etc/sysconfig/i18n
LANG="zh_CN.GB18030"
LANGUAGE="zh_CN.GB18030:zh_CN.GB2312:zh_CN"
SUPPORTED="zh_CN.UTF-8:zh_CN:zh:en_US.UTF-8:en_US:en"
SYSFONT="lat0-sun16"
接下來,在安裝MySQL 5.0.x 的時候,選擇預設字元集為 gb2312。然後,就可以用下面的代碼來驗證了,
# cat $RESIN_HOME/webapps/ROOT/test_resin_mysql_cn.jsp
String CLASS="com.mysql.jdbc.Driver";
// note: default character set of mysql is gb2312
// version of connectorJ is greater 5.0
String dbString = "jdbc:mysql://localhost/test?user=admin&password=password&useUnicode=true&characterEncoding=gb2312";
String SQL_create_table = "create table test.cn(col1 varchar(10))";
String SQL_insert_cn = "insert into test.cn values('中文')";
String SQL_select_cn = "select * from test.cn";
// check
conn = DriverManager.getConnection(dbString);
stmt.execute(SQL_create_table);
stmt.execute(SQL_insert_cn);
rs = stmt.executeQuery(SQL_select_cn);
while(rs.next())
out.println(rs.getString("col1"));
out.println("<br>");
out.println("DB operation error " + getClass());
然後,用浏覽器去請求該頁面,如果你看到了“中文”這兩個字,恭喜你,你的安裝配置沒問題。
總之,上面的這些代碼并不複雜。但是,在實踐中,它們确實有用,所有,學學還是有好處的。
注意,盡管筆者是在 RESIN 裡面使用這些代碼,但是,毫無疑問,隻要稍做改變(甚至不需做任何改變),這些代碼也可以用在其它 WEB 應用伺服器裡面。
<a href="http://down.51cto.com/data/2349223" target="_blank">附件:http://down.51cto.com/data/2349223</a>
本文轉自zkjian517 51CTO部落格,原文連結:http://blog.51cto.com/zoukejian/58640