茫茫網海中的冷日
         
茫茫網海中的冷日
發生過的事,不可能遺忘,只是想不起來而已!
 恭喜您是本站第 1671792 位訪客!  登入  | 註冊
主選單

Google 自訂搜尋

Goole 廣告

隨機相片
IMG_00001.jpg

授權條款

使用者登入
使用者名稱:

密碼:


忘了密碼?

現在就註冊!

爪哇咖啡屋 : [分享]Servlet + JSP + mysql jdbc + chinese

發表者 討論內容
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[分享]Servlet + JSP + mysql jdbc + chinese
作者 Yuan-Chen Cheng <ycheng@sinica.edu.tw>, 看板 BSD
標題 Servlet + JSP + mysql jdbc + chinese
時間 Computing Center, Academia Sinica (Thu Sep 21 00:26:49 2000)
路徑 bbs.yzu!news.yzu!news.ncu!news.csie.ncu!netnews.csie.nctu!news.civil.nc
來源 140.109.7.52

JSP / Servlet 怎樣才能處理中文.
順便談 mysql jdbc + 中文

鄭原真 (ycheng@sinica.edu.tw)

Copyright 2000.
本文版權 : GPL or BSD style, 請保留作者姓名。

本文假設你已經會使用 JSP 或是 Servlet 撰寫英文的 Web-Page.
如果你還不會,或是根本不知道 JSP 或是 Servlet 是幹什麼的,
那這篇文章不是寫給你看的。

在 Java Servlet Spec v2.0 中,對於多國語言的支援,並不足。
你必須找到 Java Servlet Spec v2.2 的實作才行,筆者試過的
是 Apache Jakarta Tomcat 3.1 軟體(註一)。

本文測試平台是 Debian Woody, Sun jdk1.2.2, Tomcat 3.1,
mm.mysql-2.0.2


Java Server 如何處理中文.

前言

首先, 如何正確的了解你一個 Big5 中文在 Java 中是正確的
中文 Unicode 呢 ?

輸出一個 String("今").length() 吧 ! 由於 "今" 在 Big5 是由兩個
byte 組成, 但對 java 來說,java 的字元是 unicode, 也就是說,
無論是一個英文字或是一個中文字,其 length() 都是 1. 也就是說,
(new String("今")).length() ==> 1。才是正確的。


Servlet 輸出中文的一個例子.

下面是一個典型的 Java Servlet.
HelloWorldExample.java =>
----------- cut here -----------------
import java.io.*;
import java.text.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class HelloWorldExample extends HttpServlet {

    public void doGet(HttpServletRequest request,
                      HttpServletResponse response)
        throws IOException, ServletException
    {
        response.setLocale(new Locale(new String("zh"), new String("TW")));
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();

        out.println("<html>");
        out.println("<head>");

        String title = new String("hello 大家好");

        out.println("<title>" + title + "</title>");
        out.println("</head>");
        out.println("<body bgcolor=\"white\">");
        out.println("<body>");

        out.println("<p>");

        out.println("<h1>" + title + "</h1>");
        out.println("</body>");
        out.println("</html>");
    }
}
----------- cut here -----------------

可以正常輸出中文的關鍵是:
        response.setLocale(new Locale(new String("zh"), new String("TW")));

注意這一行應該要放在
        PrintWriter out = response.getWriter();

之前執行。另外編譯時注意
        javac -encoding Big5 HelloWorldExample.java

或是 (linux 上的 jdk1.2.2)
        export LANG=zh_TW.Big5
        export LC_CTYPE=zh_TW.Big5
        javac HelloWorldExample.java

注意, 這個例子在 jserv v1.1.2 並不能 work, 因為該版本實做的
JavaSoft Java Servlet APIs 2.0, 而 setLocale 是到
Servlet APIs 2.2 才有。


Java Server Page 如何處理中文

在此簡略說明,先看下面的例子:
test.jsp
----------------------
<%@ page contentType="text/html; charset=big5" %>
<html>
<body bgcolor="white">
中文TEST.<p>
<%= (new String("今天")).length() %>
</body>
</html>
----------------------

關鍵在第一行。有了這一行就行了。

For Hacker:

理論上這一行可以放在文件的任何地方,但由於 Java 時做上
開檔案後通探N必須指定 encoding,當 java jsp engine 發現 charset
跟 default 不同時,通常必須重新開檔案。所以實做上這一行放在越前面越好。
不過話是這樣說,由於通?jsp 會在 run time 被 compile 成 java bytecode,
也就是說只有在 .jsp 更新時才需要 recompile。overhead 實在有限。


Java 連結到 MySql 如何使用中文

Java 以 jdbc 連結到 databases server,MySql 有 Free 的
jdbc driver. 以下不擬說明如何使用 jdbc, 僅說明如何修改
你的 code 使可以用中文。

mysql 儲存中文資料有兩種方法, 第一種是使用 big5 內碼儲存,
其優點是葫棫w碟/記憶體空間, 相較於使用 UTF8 之下, 若輸出
為 Big5,更省去一次的 Unicode (UTF8) 與 Big5 需要經過
Table lookup 的轉換。但使用 Big5 就會有 Big5 先天上的問題。
典型的問題是 Big5 字串在處理字的邊界的問題。Big5 先天上的
問題是這樣的,就以 "問題" 這個字串為例,問字的第二個 byte
跟題字的第一個 byte 所形成的字是 "暋" 字。所以當我們在作
文字搜尋找包含 "暋" 的字串,我們會連包含 "問題" 的字串也
一起找到。但 UTF8 內碼在設計上就避開了這個問題, 犧牲的是
必須用較多的 byte (octets) 表示。

我只有試過 MySql 內的 Data 用 UTF8, Big5 沒試過。要注意的
是,在 UTF8 中,中文的長度是 3 個 bytes, 由於 MySQL 固定
字串欄位送進過長的資料時,會發生過長處被截斷。但 MySql 不懂
UTF8, 所以可能發生一個 UTF8 字元第二 or 三個 byte 被截掉
問題,在 ASCII 中問題不大,頂多出現一個 "I Love Yo", "u" 不
見了。但在 java 把資料讀進來,把 UTF8 轉成 java 內部的表示
法時,就會發生有些 Byte 無法轉成功的問題,應該會造成
Exception. (註二)

好, 回來,在 jdbc 中,並沒有規範在 Database 中的字元的內碼,
而把這個問題留給各個 jdbc driver 處理。mysql jdbc driver
要在 database 中設為 utf8 的設定方式如下:
        Properties pr;
        Connection db;

        pr = new Properties();
        pr.put("characterEncoding", "UTF8");
        pr.put("useUnicode", "TRUE");
        Class.forName("org.gjt.mm.mysql.Driver").newInstance();
        db = DriverManager.getConnection("jdbc:mysql:///test", pr);

其餘請自行參考一般 jdbc 程式寫作的資料。當然, compile 此 Servlet 時需
要在呼叫 javac 時加上 "-encoding Big5"。

若要使用 Big5 的話, 上面 "UTF8" 改成 "Big5" 即可。但這樣作會出現另一個
問題, 就是中文第二個 byte 有 '\' 的問題。這個問題我不知道有沒有方便的解
法,不知道 compile mysql 時將 encoding 設為 big5 可否解決這個問題。(註二)

註一:請到 http://jakarta.apache.org/ 下去 Download.
註二:這個我沒有測試過,誰要測了跟大家說結果的?
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[分享]Apache + Tomcat with mod_jk.so
Apache + Tomcat with mod_jk.so

安裝 Tomcat

wget http://archive.apache.org/dist/jakarta/tomcat-5/v5.5.11/bin/jakarta-tomcat-5.5.11.tar.gz
tar zxf jakarta-tomcat-5.5.11.tar.gz -C /usr/local
mv /usr/local/jakarta-tomcat-5.5.11 /usr/local/tomcat


下載 JDK 5.0 http://java.sun.com/j2se/1.5.0/download.jsp
chmod +x jdk-1_5_0_04-linux-i586.bin
./jdk-1_5_0_04-linux-i586.bin
mv jdk1.5.0_04 /usr/local/java

解開後放到 /usr/local/java
編輯一個 script for tomcat (/usr/local/bin/tomcat.sh)
#!/bin/sh
export JAVA_HOME=/usr/local/java

export CATALINA_HOME=/usr/local/tomcat
case $1 in
      start)
            /usr/local/tomcat/bin/startup.sh
            ;;
      stop)
            /usr/local/tomcat/bin/shutdown.sh

            ;;
esac

啟動 tomcat 用 tomcat.sh start, 關閉用 tomcat.sh stop
註: 在啟動 tomcat 前, JAVA_HOME, CATALINA_HOME 變數是必要的



編譯 mod_jk.so

wget http://archive.apache.org/dist/jakarta/tomcat-5/v5.5.11/src/jakarta-tomcat-5.5.11-src.tar.gz
tar zxf jakarta-tomcat-5.5.11-src.tar.gz

cd jakarta-tomcat-5.5.11-src/jakarta-tomcat-connectors/jk/native
./buildconf.sh
./configure --with-apxs=/usr/local/apache/bin/apxs
make
cp apache-1.3/mod_jk.so /usr/local/apache/libexec

註: 加 mod_jk.so 的用意就是可以用 JkMount 把 webapps 下的目錄 mount 到 DocumentRoot, 使可以不用打 :8080



設定 Apache
在 httpd.conf 加入

LoadModule jk_module          libexec/mod_jk.so
AddModule mod_jk.c
JkWorkersFile conf/mod_jk.properties
JkLogFile logs/mod_jk.log
JkLogLevel info

# 指定那些檔案、目錄要用 Tomcat 去跑
JkMount /*.jsp ajp13
JKMount /jsp-examples/* ajp13

註: apache 在編譯時, configure 需加入 --enable-module=so 參數

在 apache conf 目錄下建編立 mod_jk.properties, 內容如下
workers.tomcat_home=/usr/local/tomcat
workers.java_home=/usr/local/java
worker.list=ajp13
worker.ajp13.port=8009
worker.ajp13.host=localhost
worker.ajp13.type=ajp13

註: ajp13 指 Apache JServ Protocol version 1.3



啟動 tomcat, 重新啟動 apache, 連連看

http://[your host]/index.jsp
http://[your host]/jsp-examples/

若有看到網頁, jsp 範例程式也正常, 大功告成!

冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[分享]Java Server Side 中文解決方案
Java Server Side 中文解決方案

在網站上看了很多文章關於在Java裡面使用中文的方法,只有嘆氣搖頭。
為什麼要用getBytes然後再轉BIG5呢?這種解決方法從一開始根本就錯了。

最好的解決方法是從資料進來的時候就要正確的抓到資料。

我這一兩個月利用下班時間寫了一個用Java Servlet以及XML/XSL來作的留言板,同時支援簡體、繁體,甚至日文的輸入與顯示,這是怎麼做到的呢?很簡單,利用Unicode。

我的servlet處理中文只要兩個指令:
response.setContentType("text/html;charset=UTF-8");
request.setCharacterEncoding("UTF-8"); (此功能j2ee 1.3就有了) 


之後不管你要getParameter或是printWriter.write都可以把所有的String直接拿來用,不用再做什麼轉換。存到database裡面的資料也是直接儲存unicode。
我用的資料庫是PostgreSQL因為它是唯一支援Unicode的開放軟體資料庫(唯一要注意的是PostgreSQL在initdb要用SQL-ASCII或是UNICODE,不能用mule-internal,如果你用過PostgreSQL應該知道我在講什麼)。你如果用的是Oracle或SQLserver, DB2他們的新版應該都是支援Unicode的。mySQL雖然很快,但是它的功能實在不足(也沒有支援unicode),尤其JDBC的driver還沒有官方版,不用也罷。
我本來想移植到mySQL上,但是它竟然連resultSet.isBeforeFirst()都沒有實作,那我怎麼判斷結果有沒有資料啊?

你會說,但是user輸入的是BIG5啊?別擔心,browser早就幫你解決這個問題了。
只要你用response.setContentType("text/html;charset=UTF-8");接下來雖然你輸入的是big5,但是當browser送出來的時候,它就會根據charset來作編碼轉換。
這樣我們再設request.setCharacterEncoding("UTF-8");然後你用getParameter時它就會把UTF-8轉成真正的unicode。

這個就是系統的美妙之處了,當你在簡體的系統上看同樣的page時,因為文件的內容Java已經幫你從unicode轉成UTF-8了,所以你還是可以看到繁體字,而你在reply這篇文章時雖然用的是GB,但是當從browser送出來的時候,它又轉成UTF-8了,然後我們的程式一樣處理,當你回到繁體系統來看,又可以看到剛剛發的簡體的reply。

如果你在英文的系統下,想要copy一篇中文文章進來,絕對不能用BIG5直接貼,因為這時系統的default encoding不對,轉碼會錯。這時你要先用browser先把文章讀出來,把"中文字"(不是BIG5碼)copy,貼進來。因為當你在browser裡面看到中文字時,這個中文字已經是用unicode在顯示了。

所以這個解決方案才能真正做到: "所見即所得"。也就是說,只要你看得到你輸入的東西,你就可以看到你想要的輸出結果。這也就是你在英文環境下,貼BIG5的"亂碼",這個程式也會回big5的"亂碼"給你的原因。

Unicode是Java一個對國際化╱本土化很好的支援,我們要好好利用這個優點,做出以前想都沒辦法想的軟體。LinuxFab雖然可以顯示繁體與簡體,但我若是大陸的使用者,沒看到"簡繁"那小小的兩個字,而在繁體的網頁輸入了簡體呢?會有問題。
除了用unicode,其他解決的方法都會很複雜,現在Java對server side的國際化支援算是完整了(1.3之前沒有request.setCharaterEncoding(),總是礙手礙腳),希望大家不要在把unicode當成是不如php, perl的缺點,東拼西湊的湊到可以顯示中文;把精力放在程式本身,而不是轉碼上。

台灣用Java的人還是不多,尤其是企業;理由不外是performance, 穩定性。
但是你如果知道美國的嘉信理財(我工作的公司),擁有全世界最強大的商用超級電腦,我們的程式已經有大約20-30%轉換成Java,轉換的工作還在繼續中,那你會怎麼想?Server side的Java有絕大多數CGI無法比擬的優點:Thread執行序,在只比較一個request的時候,CGI會佔優勢,但是當成百上千個request來的時候,Thread的優勢就會出來。我們公司也是在比較過兩者的表現之後,才決定進行CGI到Java的轉換的。

我的工作是把這些Java的功能加以中文化來提供給住在美國的華裔,對於Java中文化的問題已經研究了快兩年了,期間碰過不少問題,幸而跟我們合作的IBM對於我們提出的問題都能迅速改進,所以我還能保住我的工作。其實這些問題,在apache, tomcat等等的開放原始碼都已經解決了,我真的不得不佩服這些熱心的人。所以每次我的問題提出來之後,都還會附加:Tomcat不會有這個問題。我想這多少也刺激他們迅速的改進。
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[分享]如何讓Tomcat支持中文文件名
如何讓Tomcat支持中文文件名,包括顯示和下載中文文件名檔案
1>在jsp文件最開頭加入下面這行(這裡是解決中文不能顯示的問題):
<%@ page language="java" contentType="text/html; charset=UTF-8" %>

2>然後改tomcat的server.xml文件(這裡是解決含有中文的文件、圖片的不能下載、顯示的問題):
<Connector 
port="8080"  maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
debug="0" connectionTimeout="20000" 
disableUploadTimeout="true" URIEncoding="UTF-8"/>

URIEncoding="UTF-8" 加上這句就可以識別中文文件了,也就是不光可以在jsp中顯示中文,還可以下載顯示。
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[分享]Apache 及 Tomcat 的結合

Apache 及 Tomcat 的結合

網頁應用伺服器上,Apache 為眾多伺服器的首選,對於 JSP 的服務來說當然是以 Tomcat 為主要的選擇,在目前的主流上若要使用 JSP 開發 Web 網頁程式的話, Apache 和 Tomcat 當然是最佳選擇,在這裡就由小弟介紹如何使用 Apache 配合 connector 來連結 Tomcat。

首先在一個重要的 Web 服務平台上,若打算要把 Apache 和 JSP 分開以分化流量並保護 JSP 程式的話,一般都會把 JSP 放在另一台跑 Tomcat 的主機上,而靜態的 html 則是放在 Apache 上。JSP 程式主機若以安全原則來說是不應該放在別人看得到的公開網路上,最好是放在一個 Web Cluster 的內部環境裡面,以下是這次範列的 Web Server 加構圖。

我們的環境下,使用者連上我們的 http-fountain,而 java-garden是放在內部的網路裡,Web 程式雖然是放在 java-garden 裡,但使用卻感覺不出來。



+-------+
| User |
+-------+
| (Port 80)
+-------+
| http | (http-fountain, eth0: 11.22.33.44, eth1: 192.168.1.86)
+-------+
| (Port 8009)
+-------+
| JSP | (java-garden, 192.168.1.87)
+-------+

這樣的設計有幾點好處:程式和網頁分開減少檔案損壞的風險、JSP 應用伺服器較不會被外界攻擊、可單一維護程式或網頁、若日後流量大的話 Tomcat 可以做負載平衡。

以下我們就來看看如何建立這一個完整的環境。

設定 DNS:

DNS 應該不用說了吧,一定要先對完整才可以使用得當,請使用 host 工具來看看是否設定正確。在這個 Web Cluster 上內部應該要查得到 http-fountain 和 java-garden。

root # host http-fountain.l-penguin.idv.tw
http-fountain.l-penguin.idv.tw has address 192.168.1.86
root # host java-garden.l-penguin.idv.tw
java-garden.l-penguin.idv.tw has address 192.168.1.87

而外部的使用者應該 只能 查到 http-fountain 的公開 IP

root # host http-fountain.l-penguin.idv.tw
http-fountain.l-penguin.idv.tw has address 11.22.33.44

因為有內外部,所以你有可能需要使用到 Bind 9 的 View 功能,至於詳細的使用方法請參考 bind - DNS 設定 (New window)

建立一個美好泡咖啡的花園 java-garden.l-penguin.idv.tw:

設定 Java 環境


首先你的機器應該有有 Java 環境這樣 Tomcat 才可以順利執行。你可以到 Sun 的下載區去下載最近版本的 Java JDK ( http://java.sun.com/javase/downloads/index.jsp ) 並且安裝它。在這裡我是下載可自解的二進制可執行檔 (Linux self-extracting file)。

最後你可以發現下載後會是一個 .bin 檔案,你可以附與它一個 x 可執行權限然後開始執行。

root # chmod +x jdk-1_5_0_07-linux-i586.bin
root # ./jdk-1_5_0_07-linux-i586.bin

解開之後會多出一個目錄,我習慣把應用程式搬到 /usr/local 之下,而這個 Java 也不例外。

root # mv jdk1.5.0_07/ /usr/local/java

當然為了 Tomcat 的安裝與執行,你並需設定 JAVA_HOME 這個環境變數,你可以設定在 /etc/profile 上。

root # echo 'JAVA_HOME=/usr/local/java' >> /etc/profile

如果你要馬上生效的話,執行 export 把這個變數轉成環境變數。


root # export JAVA_HOME=/usr/local/java
root # env | grep JAVA_HOME
JAVA_HOME=/usr/local/java
root #

設定 Tomcat 環境:

現在是重頭戲 Tomcat 的表演時刻了,你可以到 http://tomcat.apache.org/ 下載最新版本的 Tomcat 來安裝,當然我是下載 Tomcat 5.5 版本的 Tomcat 二進制可執行檔。解開之後移到 /usr/local/tomcat5 目錄。

root # wget http://apache.cdpa.nsysu.edu.tw/tomcat/tomcat-5/v5.5.17/bin/apache-tomcat-5.5.17.tar.gz
root # tar -zxvf apache-tomcat-5.5.17.tar.gz
root # mv apache-tomcat-5.5.17 /usr/local/tomcat5

嚐試啟動 Tomcat 並看看它的樣子!

現在你已經把 Tomcat 裝好,並且擁有 JAVA 環境了,你可以試著啟動 Tomcat 來看看。

root # /usr/local/tomcat5/bin/startup.sh
Using CATALINA_BASE: /usr/local/tomcat5
Using CATALINA_HOME: /usr/local/tomcat5
Using CATALINA_TMPDIR: /usr/local/tomcat5/temp
Using JRE_HOME: /usr/local/java
root #

好的,你可以看看 Tomcat 是使用那些 Port。

root # netstat -ntulp | grep java

tcp 0 0 ::ffff:127.0.0.1:8005 :::* LISTEN 2157/java
tcp 0 0 :::8009 :::* LISTEN 2157/java
tcp 0 0 :::8080 :::* LISTEN 2157/java
root #

由 netstat 可得知它是使用了 8080 和 8009,這個 8009 等一下是要由 mod_jk2 來使用的,而 8080 是 Tomcat 的 Web Service 服務,你可以在 Web Browser 輸入 http://java-garden.l-penguin.idv.tw:8080/ 看看。

Tomcat Web Service

當然這個 java-garden 只有在內部才可看到,使用者是看不到的,若使用者看得到的話就失去了我故意安排 java-garden 在內部網的安全心意了。

以上就完成了 Tomcat 的設置,下面再來看看如何設定 Apache 並使用 mod_jk2 這個 connector 來連結 Apache 和 Tomcat。

建設 http 噴水池 http-fountain.l-penguin.idv.tw:

建立基本的 Apache

首先你要設定安裝基本的 Apache,安裝 Apache 你可以參考 LAMP (New window) 文章有詳細的安裝過程,並不需要有額外的安裝選項。

編譯 mod_jk2 模組


在編譯 mod_jk2 之前,我先來說明一下為什麼要在眾多的 connector 之中選擇 mod_jk2。目前的連結器中主要有下面的幾種:

  • mod_jserv
  • mod_jk
  • mod_jk2
  • mod_webapp

而我使用下表來表示它們各自差異。

連結器
通訊協定
支援平衡負載
mod_jserv ajp 1.2 第一個 AJP 連結器,不支援負載平衡。
mod_jk ajp 1.3 支援負載平衡,但已不用。
mod_jk2 ajp 1.3 支援負載平衡。
mod_webapp warp 1.0 不支援負載平衡

現在來看看下面的編譯過程。

當你安裝完成 Apache 之後,還需要編繹 mod_jk2 這個連結器才可以該 Apache 和 Tomcat 相互溝通,以下我示範使用 mod_jk2 原始檔來編譯,你可以到 http://tomcat.apache.org/download-connectors.cgi 下載得到。

root # wget http://apache.cdpa.nsysu.edu.tw/tomcat/tomcat-connectors/jk2/jakarta-tomcat-connectors-jk2-src-current.tar.gz
root #
tar -zxvf jakarta-tomcat-connectors-jk2-src-current.tar.gz

解開之後你會在同目錄之下得到一個 jakarta-tomcat-connectors-jk2-2.0.4-src 的目錄,接下來請依如下的順序來編譯。

root # cd jakarta-tomcat-connectors-jk2-2.0.4-src/
root # cd jk/native2/
root # ./configure --with-apxs2=/usr/local/httpd/bin/apxs --with-apache2=/usr/local/httpd/
root # make
root # cd ../build/jk2/apache2/

經過以上煩雜的動作之後,會得到一個叫做 mod_jk2.so 的 module,請把它複製到 apache 的 module 目錄裡。

root # cp mod_jk2.so /usr/local/httpd/modules/

設定 httpd.conf 及 mod_jk2 需要的設定檔 (workers2.properties),同時建立 java-garden 的 JSP 連結

現在請編輯 httpd.conf 檔案以便在 apache 啟動時載入 mod_jk2 模組。

root # vi /usr/local/httpd/conf/httpd.conf
--------------------------------------------------------------

LoadModule jk2_module modules/mod_jk2.so
--------------------------------------------------------------

編輯 workers2.properties

root # vi /usr/local/httpd/conf/workers2.properties
--------------------------------------------------------------

[logger]
level=DEBUG

[config:]
file=/usr/local/httpd/conf/workers2.properties
debug=0
debugEnv=0

[shm:]
info=Scoreboard. Required for reconfiguration and status with multiprocess servers
file=/usr/local/httpd/logs/jk2.shm
size=1000000
debug=0
disabled=0

[workerEnv:]
info=Global server options
timing=1
debug=0

[channel.socket: java-garden.l-penguin.idv.tw :8009]
info=Ajp13 forwarding over socket
debug=0
tomcatId= java-garden.l-penguin.idv.tw :8009

[channel.jni:jni]
info=The jni channel, used if tomcat is started inprocess

[status:]

info=Status worker, displays runtime informations

[uri:/jkstatus/*]
info=Display status information and checks the config file for changes.
group=status:

[uri:/java-garden/*.jsp]
info=java-garden.
context=/java-garden
worker=ajp13: java-garden.l-penguin.idv.tw :8009
debug=0
--------------------------------------------------------------

以上在 workers2.properties 檔裡粗體字表示需要注意的地方,是要輸入 Tomcat 主機的名稱或是 IP。編輯好了以上的設定之後還不能完全啟動,必需再為 Tomcat 設立 java-garden 的虛擬目錄才行。

上面 [uri:/java-garden/*.jsp] 表示只有 .jsp 檔案才會經由 mod_jk2 向 Tomcat 請求需要,一般的 html 或圖片影像檔就由本機的 http 主機負責傳輸就可以了。

在 Tomcat 上為 java-garden 建立虛擬目錄

要編輯 Tomcat 的虛擬目錄你需要看得懂 XML 語法,其實也跟 httpd.conf 差不多一樣,而它的編輯檔是在 ${TOMCAT_HOME}/conf/server.xml 之下,而目錄是建在 <host> 和 </host> 之間。

現在請到你的 Tomcat 主機裡執行編輯動作。

root # vi /usr/local/tomcat5/conf/server.xml

--------------------------------------------------------------
<Host>
~略~
<Context path=" /java-garden "
docBase=" /data/web/java-garden "
debug="0"
reloadable="true"
crossContext="true">
</Context>
</Host>
--------------------------------------------------------------

在 server.xml 文件文打粗體的表示要注意的地方,path 表示為 http 網址後的連結,docBase 表示真正所在的目錄位置。

最終一回-實際驗收

終於到了可以實際驗收的階段了,請記得只要你收改過設定檔,就要重新啟動 httpd 和 Tomcat 服務以重新讀取設定檔。

Tomcat 主機

root # /usr/local/tomcat5/bin/shutdown.sh
Using CATALINA_BASE: /usr/local/tomcat5
Using CATALINA_HOME: /usr/local/tomcat5
Using CATALINA_TMPDIR: /usr/local/tomcat5/temp
Using JRE_HOME: /usr/local/java
root # /usr/local/tomcat5/bin/startup.sh
Using CATALINA_BASE: /usr/local/tomcat5

Using CATALINA_HOME: /usr/local/tomcat5
Using CATALINA_TMPDIR: /usr/local/tomcat5/temp
Using JRE_HOME: /usr/local/java
root #

Http 主機

root # /usr/local/httpd/bin/apachectl stop
root # /usr/local/httpd/bin/apachectl start

我在 Tomcat 主機上的 /data/web/java-garden 放了幾隻 jsp 文件,包含一個 index.html 檔;而在 HTTP 主機上放了幾個 html 文件,也包含了一個 index.html 檔,現在來看看是否可以正常的執行。

若你要測試的話請在 Web Browser 輸入 http://http-fountain.l-penguin.idv.tw/java-garden/index.jsp 看看有什麼反應。

The example of java-garden, show the index.jsp.

再來看看 index.html 檔。

The example of http-fountain, show the index.htm

好了,經過以上的實驗,你可以發現其實 Apache 只有在要求 jsp 時才會向 Tomcat 主機要求回應,否則的話都是由 Web 主機本身回應。

參考文件

冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[分享]jsp中使用multipart/form-data類型的form提交亂碼問題
jsp中使用multipart/form-data類型的form提交亂碼問題

項目時發現以前是application/x-www-form-urlencoded的FORM提交數據時正常, 現在為表單添加個上傳功能就有亂碼了, 在網上看了篇文章
引言:

This problem had been bugging me for 3 days!

Background:
Use JSP and Servlet to implement file upload。The uploaded file is stored in file system, the related info like description and Mime type, size and path name is stored in MySQL。JSP and DB table both use UTF-8 CHARSET. If successfully,Servelet forwards to success page with related file info returned.

Promblem(all happened with Chinese characters):
1. On Jetty,except the filename was encoded by UTF-8(unreadable), everything is good.
2. But on Tomcat, all that characters were inserted into DB and returned to client were corrupted.

Solution:
1.No matter how you set a form's charset,Tomcat always treats it by iso 8859-1.So what we read from the input strem are 8859-1 encoded.
If we need to search a substring in the content, we have to use getBytes("ISO-8859-1") on the substring. Also, use String(subBytes, "UTF-8") to return some substrings.
2.In the success jsp, we should add <%@ page contentType="text/html;charset=UTF-8"%>.
(And the is useless.)
3.In the post() method of Servlet, we must add request.setCharacterEncoding("UTF-8"); And it must sit before any sentences that read input stream.

After the previous steps, everything is good on Tomcat.

But on Jetty, the filename was still encoded by UTF-8. I tried to convert UTF-8 to system default encoding by new String(fileName.getBytes("UTF-8"), system.getProperty("file.encoding")), but no use.


看起來在Jetty上跑沒事, 好像是Tomcat的編碼問題, 解決方法也簡單, page charset 用utf8就好了, 如果你用spring就加個filter:
 <filter>
  <filter-name>encodingFilter</filter-name>
  <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  <init-param>
   <param-name>encoding</param-name>
   <param-value>UTF-8</param-value>
  </init-param>
 </filter>



原文出處:
jsp中使用multipart/form-data类型的form提交乱码问题 - Wonderful Dream™ - JavaEye技术网站

冷日補充:
沒想到冷日也碰上類似的問題了,確認了資料庫、前端網頁、Form的編碼以後,已經很確認冷日都是使用『UTF-8』了!(謎:冷日本來就愛用UTF-8.....
也就把目標轉到Form的encoding上(可以參閱這篇:[轉貼]javascript構造可以上傳文件的form表單)!
也曾經在網路上看到:「enctype="multipart/form-data"是不能传递表单数据的」,經實驗,這句話是唬爛低!
結論是,Tomcat碰到『multipart/form-data』時,是使用「ISO-8859-1」這個編碼!
只要我們收資料時,做一個轉碼,哪有啥multipart/form-data不能傳遞表單數據低道理?給大家一個範例:
dataSource2Insert = new String(value.getBytes("ISO-8859-1"), "UTF-8") ;

這樣就可以收到正常編碼的資料啦,祝大家順利!
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[分享]Apache Tomcat Connector 實務

Apache Tomcat Connector實務

Introduction

Apache Tomcat Connector的目的是讓User可以透過80或443的port訪問Tomcat Server。也許你會想: 我直接把Tomcat Server的port從8080改成80不就好了嗎?也許這是一種方式,假如你的server主機上不只有tomcat,必須還有apache時,該怎麼辦?又或者你想提供一個單一入口管道可以去訪問不同機器上的Tomcat Server,可能也會需要用到它。而我所遇到的問題是因為facebook的FB.ui API在2012年3月之後,如果主機不是使用80或443的port會造成Dialong Hang住。此外,我的server上還有裝這個筆記本,才會讓我想使用這個解決方法。

網路上其實可以找到許多關於設定Apache Tomcat Connector的文章,我也想著: 大部分已經寫的很齊全了,我應該不需要再著墨。然而在我實際操作時,也遇到不少問題。雖然我是邊看電影邊研究怎做(不可能的任務2、3與交響情人夢),也花了一個工作天才完成。我所使用的作業系統是CentOS5.6,Apache2.2.3。其中要做的事情,只是要把mod_jk.so安裝到apache上,接著做些設定就好了,但為什麼我要花一個工作天研究呢? 原因很簡單,首先是mod_jk最新版是2012年發佈的,大部分教學都已經是過時的玩意了;還有我希望能夠支援http與https,而教學大都對http做說明。 廢話少說,我們直接開始進行安裝與設定工作。

下載與編譯

首先至Apache Tomcat Connector 下載頁面,取得source code並編譯。這裡必須注意的是: apxs必須安裝https-devel才會出現,不妨先使用find / | grep apxs找看看系統中是否存在與位置在哪。


/tomcat-connectors-1.2.35-src.tar.gz
tar zxvf tomcat-connectors-1.2.35-src.tar.gz
/native
./httpd

在編譯完成後,會產生mod_jk.so到apache-2.0資料夾中。將它複製到httpd/modules中並修改httpd.conf,加入“LoadModule jk_module modules/mod_jk.so”。

Tomcat的設定

設定相當簡單,只需要在%TOMCAT_HOME%/confg/server.xml中,加入ajp1.3的connector即可。目的是為了提供Apache連進來的管道。如下圖,Apache連至Tomcat所使用的port為8009,而Tomcat會將它導向至8443。(8443一般為https的port,如果沒使用就改為8080 port)

Apache的設定

Apache設定重點為網址過濾導向清單與Tomcat對應設定。在我的主機上有以下項目:

  • httpd.conf: http server設定
  • ssl.conf: https設定
  • mod_jk.conf: apache tomcat connector設定
  • workers.properties: 與tomcat的對應設定

httpd.conf要將其它config給加進去。其中關係是httpd.conf包含ssl.conf與mod_jk.conf,mod_jk.conf包含workers.properties。這裡最需要注意的是: 順序。ssl.conf要在mod_jk.conf之後給include進來,否則你在ssl.conf中怎設定都會無法作用(我在這裡被荼毒很久)。

接著設定mod_jk.conf。最需要注意的是JkWorkersFileJkMount,JkWorkersFile是workers.properties的路徑,而JkMount是負責設定URL的對應。以我的例子而言,在Tomcat Server上我有LearningEnglish與LogoutArmyCD兩個應用程式,因此我針對LearningEnglish與LogoutArmyCD兩個名稱做filter,當然你也可以針對附檔名去處理。這兩個AP分別對應到lelacd,這標記是記錄在workers.properties中。


/workers.properties
JkLogFile /jk.log
JkShmFile /jk-runtime-status
JkLogLevel info
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories
JkRequestLogFormat "%w %V %T"
 
JkMount /LearningEnglish le
JkMount /* le
 
JkMount /LogoutArmyCD lacd
JkMount /* lacd


ssl.conf的部分只需要加入Filter對應即可。當User透過https訪問到LearningEnglish或LogoutArmyCD時,會自動導向至le與lacd所設定的Tomcat Server上。


>
...
JkMount /LearningEnglish le
JkMount /* le
 
JkMount /LogoutArmyCD lacd
JkMount /* lacd
>

workers.properties的樣本可以從/tomcat-connectors-1.2.35-src/conf中找到。下面的設定是LearningEnglish這個AP的設定。需注意的是,如果你要改成自己的標記,只要將le部分替代掉即可,而worker.le.host與worker.le.port分別代表Tomcat Server的ip位置與所使用的ajp13的port。


worker.balancer.balance_workers=le
worker.list=le
worker.le.reference=worker.template
worker.le.host=localhost
worker.le.port=8009
worker.le.type=ajp13
worker.le.activation=A


最後將Tomcat與Apache Server重新啟動就可以使用了!

Summary

mod_jk與workers.properties還有許多有的沒的設定我並沒有深入去研究,如果有興趣的人可以參考官網文件嘗試修改看看。另外在我使用這個方法之後,對應用程式並非沒有任何影響。舉例來說,原先透過HttpServletResponse寫出做頁面導向的javascript(window.top.location)無法正常執行。因此在使用這個方式之後,作者建議你要將應用程是仔細測過一次!

OS: “當年”就是使用這個來破只允許80 port通過的防火牆,好讓機器可以上msn。


原文出處: Apache Tomcat Connector實務 [阿兩的筆記本 Ryoutsu's Notebook]
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[分享]Linux - Apache + Tomcat 整合配置
Linux - Apache + Tomcat 整合配置
============================
Apache Redhat 內建
Tomcat tomcat-6.0.35
tomcat-connectors tomcat-connectors-1.2.35-src.tar.gz(apache與tomcat整合用mod)

1.設定java環境,在rc.local中加入
    JAVA_HOME=/opt/jdk16031
    CLASSPATH=$JAVA_HOME/lib:$JAVA_HOME/jre/lib
    CATALINA_BASE=/opt/myzone-tomcat
    CATALINA_HOME=/opt/myzone-tomcat
    export JAVA_HOME
    export CLASSPATH
    export CATALINA_BASE
    export CATALINA_HOME
    PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH:$HOME/bin

2.安裝tomcat-connectors
解壓縮tomcat-connectors-1.2.35-src.tar.gz
之後進入native目錄,執行
    ./configure --with-apxs=/usr/sbin/apxs
    make

完成之後mod_jk.so會存放在native/apache-2.0目錄中,
複製到/etc/httpd/modules/

3.安裝tomcat
解壓縮apache-tomcat-6.0.35.zip,之後將整個目錄移到/opt下即可
3.1.設定tomcat參數
打開bin/catalina.sh
加入
    JAVA_HOME=/opt/jdk16031
    CATALINA_BASE=/opt/myzone-tomcat
    CATALINA_HOME=/opt/myzone-tomcat
    CATALINA_PID=/opt/myzone-tomcat/logs/tomcat.pid
    JAVA_OPTS=" -Xmx512M -Xms256M -XX:MaxNewSize=128m -XX:MaxPermSize=128m -server -Djava.awt.headless=true  &nb sp;-Dcom.sun.management.jmxremote $JAVA_OPTS "

3.2.修改conf/server.xml(要確認同一目錄下有web.xml)
修改port(原8005)
    <Server port="7005" shutdown="SHUTDOWN">

  註解掉這一部分
    <!--
    <Connector port="8080" protocol="HTTP/1.1"
        connectionTimeout="20000"
        redirectPort="8443" />
    -->

  修改port(原8009)
    <Connector port="7009" protocol="AJP/1.3" redirectPort="443" />

  設定虛擬目錄
    <Host name="192.168.1.241"  appBase="/opt/webroot"
        unpackWARs="true" autoDeploy="true"
        xmlValidation="false" xmlNamespaceAware="false">
    <Context path="" docBase="myzone"  reloadable="true" crossContext="true" debug="0"/>

3.3.修改content.xml
改為

4.設定Apache
4.1.修改/etc/httpd/conf/httpd.conf
變更/加入以下項目
    DocumentRoot "/opt/webroot"
    DirectoryIndex index.shtml index.php index.jsp index.html index.htm index.html.var

    Alias /webapps/ "/opt/webroot/webapps/"

    <Directory "/opt/webroot/myzone">
        Options +Includes
        AllowOverride None
        Order allow,deny
        Allow from all
    </Directory>
    <Directory "/opt/webroot/webapps">
        Options +Includes
        AllowOverride None
        Order deny,allow
        allow from all
    </Directory>
    <VirtualHost *:80>
        ServerAdmin    root@testweb.myzone.com
        DirectoryIndex index.php index.shtml index.htm index.html index.jsp
        DocumentRoot   /opt/webroot/myzone
        ServerName      testweb.myzone.com
    ##指定那些檔案交給tomcat處理
        JkMount /*.jsp       controller
        JkMount /servlet/*   controller
        JkMount /*.action    controller
        JkMount /*.do        controller
   ##虛擬目錄也交給tomcat處理
        JkMount /go/*        controller
        JkMount /DynaImage   controller
        JkMount /PhotoView   controller
        #JkMount /*       controller
        ErrorLog           logs/error_log
        CustomLog       logs/access_log common
    </VirtualHost>

4.2.修改/etc/httpd/conf.d/ssl.conf
  設定自動輸入SSL憑證檔密碼
    SSLPassPhraseDialog  builtin
    修改為
    SSLPassPhraseDialog  exec:/opt/webroot/csr_ myzone /server.pass

  VirtualHost設定內加入

    DirectoryIndex index.php index.shtml index.htm index.html index.jsp
    DocumentRoot   /opt/webroot/myzone
    ServerName      testweb.apezgo.com
    ##指定那些檔案交給tomcat處理
        JkMount /*.jsp       controller
        JkMount /servlet/*   controller
        JkMount /*.action    controller
        JkMount /*.do        controller
   ##虛擬目錄也交給tomcat處理
        JkMount /go/*        controller
        JkMount /DynaImage   controller
        JkMount /PhotoView   controller
        #JkMount /*       controller

server.pass內容
    #!/bin/bash
    SSLPhrasePassword='123456'
    echo  $SSLPhrasePassword

4.3.增加tomcat-connectors設定
在/etc/httpd/conf.d/中增加 mod_jk.conf
    #載入mod_jk Module
    LoadModule      jk_module modules/mod_jk.so
    ### 配置 mod_jk
    JkWorkersFile /etc/httpd/conf/workers.properties
    #JkMountFile   /etc/httpd/conf/uriworkermap.properties
    # Where to put jk logs
    JkLogFile /etc/httpd/logs/mod_jk.log
    # Set the jk log level [debug/error/info]
    JkLogLevel info
    # Select the log format
    JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"
    # JkOptions indicate to send SSL KEY SIZE,
    JkOptions  +ForwardKeySize +ForwardURICompat -ForwardDirectories
    # JkRequestLogFormat set the request format
    JkRequestLogFormat "%w %V %T"

在/etc/httpd/conf/中增加檔案 workers.properties
    #workers.tomcat_home=/opt/myzone-tomcat
    #workers.java_home=/opt/jdk16031
    worker.list=controller,server01(,server02)
    ##server01配置(要使用server02達到負載平衡,複製一份相同設定並做適當修改即可)
    worker.server01.port=7009
    worker.server01.host=192.168.1.241
    worker.server01.type=ajp13
    worker.server01.lbfactor=1
    ##controller配置(ap負載平衡用)
    worker.controller.type=lb
    worker.retries=3
    worker.controller.balance_workers=server01(,server02)
    worker.controller.sticky_session=1

在/etc/httpd/conf/中增加檔案 uriworkermap.properties
    #所有請求都由controller這個server處理
    /*=controller
    #所有包含jkstatus請求的都由status這個server處理
    #/jkstatus=status
    #所有以.gif結尾的請求都不由controller這個server處理,以下幾個都是一樣的意思
    !/*.gif=controller
    !/*.jpg=controller
    !/*.png=controller
    !/*.css=controller
    !/*.js=controller
    !/*.htm=controller
    !/*.html=controller
    !/*.shtml=controller
    !/*.php=controller

5.測試
5.1.在/opt/webroot/myzone/下新增index.html,內容如下
  test

5.2.在/opt/webroot/webapps/下新增hello.jsp,內容如下
  <%@ page contentType="text/html;charset=big5" %>
  <%
  String str1="Hello World!";
  out.println(str1);
  %>

5.3.打開瀏覽器,輸入
http://192.168.1.241
http://192.168.1.241/webapps/hello.jsp

原文出處:Linux - Apache + Tomcat 整合配置 @ 人本自然 :: 隨意窩 Xuite日誌
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[分享]架設 Apache run 80、Tomcat run 8080 用 mod_jk 架設的步驟
架設Apache run 80、Tomcat run 8080 用 mod_jk 架設的步驟

清除指令make distclean
一、安裝apr
./configure –prefix=/usr/local/apr

make && make install
[code]
二、安裝apr-util
[code]
./configure –with-apr=/usr/local/apr  –prefix=/usr/local/apr

make && make install

三、安裝apr-iconv-1.2.1
./configure –with-apr=/usr/local/apr –prefix=/usr/local/apr

make && make install

四、安裝pcre-8.32
./configure –prefix=/usr/local/pcre –docdir=/usr/share/doc/pcre-8.34 –enable-unicode-properties
–enable-pcre16 –enable-pcre32 –enable-pcregrep-libz –enable-pcregrep-libbz2
–enable-pcretest-libreadline –disable-static

make && make install

安裝openssl
./config shared

make && make install

other:安裝php
./configure –prefix=/usr/local/php –with-config-file-path=/usr/local/php/etc –with-mysql=/usr/local/mysql
–with-mysqli=/usr/local/mysql/bin/mysql_config –with-iconv-dir=/usr/local –with-freetype-dir
–with-jpeg-dir –with-png-dir –with-zlib –with-libxml-dir=/usr –with-ldap –with-ldap-sasl
–with-xmlrpc –with-curl –with-curlwrappers –with-mcrypt –with-gd –with-openssl –with-mhash
–enable-xml –enable-rpath –enable-discard-path –enable-safe-mode –enable-bcmath –enable-shmop
–enable-sysvsem –enable-inline-optimization –enable-mbregex –enable-fastcgi –enable-fpm
–enable-force-cgi-redirect –enable-mbstring –enable-gd-native-ttf –enable-pcntl –enable-sockets
–enable-zip –enable-soap –enable-so –with-openssl=/usr/local/openssl –with-openssl=shared
–with-apxs2=/usr/local/httpd/bin/apxs –with-ldap=/usr/lib64

make && make install

五、安裝Apache Web Server
./configure –prefix=/usr/local/httpd –with-apr=/usr/local/apr –with-apr-util=/usr/local/apr
–with-pcre=/usr/local/pcre –with-ssl=/usr/local/openssl –enable-ssl –enable-so

make && make install

六、安裝mod_jk.so 編譯tomcat-connectors-1.2.37-src
configure需要進入native folder
./configure –with-apxs=/usr/local/apache2/bin/apxs

make && make install

七、設定conf/httpd.conf
新增:
LoadModule jk_module modules/mod_jk.so
Include conf/extra/mod_jk.conf

修改:將Virtual hosts的config檔案include進httpd.conf
將前面的『#』拿掉
# Virtual hosts
Include conf/extra/httpd-vhosts.conf

八、從tomcat-connectors-1.2.37-src
(一)、複製httpd-jk.conf到/usr/local/apache2/conf/extra/
將httpd-jk.conf重新命名為mod_jk.conf
(二)、複製 workers.properties到/usr/local/apache2/conf/extra/

九、修改conf/extra/mod_jk.conf
(一)、把第22行變成註解,在該行最前面加上『#』
#LoadModule jk_module modules/mod_jk.so

因為so檔已經在httpd.conf裡面載入了,不需重覆載入。
(二)、在 前面加上下面的敘述
JkLogStampFormat “[%a %b %d %H:%M:%S %Y] "
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories
JkRequestLogFormat “%w %V %T"

JkMount /folder1/ mobile
JkMount /folder1/* mobile

JkMount /folder2/ pcweb
JkMount /folder2/* pcweb

(三)、修改第28行workers.properties的位置
JkWorkersFile conf/extra/workers.properties

十、修改conf/extra/workers.properties
在檔案最後加上
worker.balancer.balance_workers=pcweb
worker.list=pcweb
worker.pcweb.reference=worker.template
worker.pcweb.host=192.168.10.153
worker.pcweb.port=8009
worker.pcweb.type=ajp13
worker.pcweb.activation=A

worker.balancer.balance_workers=mobile
worker.list=mobile
worker.mobile.reference=worker.template
worker.mobile.host=192.168.10.154
worker.mobile.port=8009
worker.mobile.type=ajp13
worker.mobile.activation=A

十一、修改conf/extra/httpd-vhosts.conf
將舊的設定全部加上『#』變成註解,並在下面的資料加在最後面
<VirtualHost *:80>
JkMount /folder1 mobile
JkMount /folder1/* mobile

JkMount /folder2 pcweb
JkMount /folder2/* pcweb
</VirtualHost>

十二、修改tomcat server 的conf/server.xml
<Connector port="8009″ protocol="AJP/1.3″ redirectPort="8443″ /> <!–這是導向https 443–>
改成
<Connector port="8009″ protocol="AJP/1.3″ redirectPort="8080″ /> <!–這是導向8080 ports–>

十三、先啟動Tomcat Server再啟動Apache Server

原文出處:架設Apache run 80、Tomcat run 8080 用 mod_jk 架設的步驟 | Fly&Fly
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[分享]Apache HTTP Server 與 Tomcat 的三種連接方式介紹

Apache HTTP Server 與 Tomcat 的三種連接方式介紹

整合 Apache Http Server 和 Tomcat 可以提升對靜態文件的處理性能、利用 Web 服務器來做負載均衡以及容錯、無縫的升級應用程序。本文介紹了三種整合 Apache 和 Tomcat 的方式。

劉 冬( javayou@gmail.com), 開發工程師,  

2007 年 1 月 15 日

首先我們先介紹一下為什麼要讓 Apache 與 Tomcat 之間進行連接。事實上 Tomcat 本身已經提供了 HTTP 服務,該服務默認的端口是 8080,裝好 tomcat 後通過 8080 端口可以直接使用 Tomcat 所運行的應用程序,你也可以將該端口改為 80。

既然 Tomcat 本身已經可以提供這樣的服務,我們為什麼還要引入 Apache 或者其他的一些專門的 HTTP 服務器呢?原因有下面幾個:

1. 提升對靜態文件的處理性能

2. 利用 Web 服務器來做負載均衡以及容錯

3. 無縫的升級應用程序

這三點對一個 web 網站來說是非常之重要的,我們希望我們的網站不僅是速度快,而且要穩定,不能因為某個 Tomcat 宕機或者是升級程序導致用戶訪問不了,而能完成這幾個功能的、最好的 HTTP 服務器也就只有 apache 的 http server 了,它跟 tomcat 的結合是最緊密和可靠的。

接下來我們介紹三種方法將 apache 和 tomcat 整合在一起。

JK


這是最常見的方式,你可以在網上找到很多關於配置JK的網頁,當然最全的還是其官方所提供的文檔。JK 本身有兩個版本分別是 1 和 2,目前 1 最新的版本是 1.2.19,而版本 2 早已經廢棄了,以後不再有新版本的推出了,所以建議你採用版本 1。

JK 是通過 AJP 協議與 Tomcat 服務器進行通訊的,Tomcat 默認的 AJP Connector 的端口是 8009。JK 本身提供了一個監控以及管理的頁面 jkstatus,通過 jkstatus 可以監控 JK 目前的工作狀態以及對到 tomcat 的連接進行設置,如下圖所示:

圖 1:監控以及管理的頁面 jkstatus

在這個圖中我們可以看到當前JK配了兩個連接分別到 8109 和 8209 端口上,目前 s2 這個連接是停止狀態,而 s1 這個連接自上次重啟後已經處理了 47 萬多個請求,流量達到 6.2 個 G,最大的並發數有 13 等等。我們也可以利用 jkstatus 的管理功能來切換 JK 到不同的 Tomcat 上,例如將 s2 啟用,並停用 s1,這個在更新應用程序的時候非常有用,而且整個切換過程對用戶來說是透明的,也就達到了無縫升級的目的。關於 JK 的配置文章網上已經非常多了,這裡我們不再詳細的介紹整個配置過程,但我要講一下配置的思路,只要明白了配置的思路,JK 就是一個非常靈活的組件。

JK 的配置最關鍵的有三個文件,分別是

httpd.conf
Apache 服務器的配置文件,用來加載 JK 模塊以及指定 JK 配置文件信息

workers.properties
到 Tomcat 服務器的連接定義文件


uriworkermap.properties
URI 映射文件,用來指定哪些 URL 由 Tomcat 處理,你也可以直接在 httpd.conf 中配置這些 URI,但是獨立這些配置的好處是 JK 模塊會定期更新該文件的內容,使得我們修改配置的時候無需重新啟動 Apache 服務器。

其中第二、三個配置文件名都可以自定義。下面是一個典型的 httpd.conf 對 JK 的配置


# (httpd.conf)
# 加載 mod_jk 模塊
LoadModule jk_module modules/mod_jk.so
#
# Configure mod_jk
#
JkWorkersFile conf/workers.properties
JkMountFile conf/uriworkermap.properties
JkLogFile logs/mod_jk.log
JkLogLevel warn

接下來我們在 Apache 的 conf 目錄下新建兩個文件分別是 workers.properties、uriworkermap.properties。這兩個文件的內容大概如下


#
# workers.properties
#
# list the workers by name
worker.list=DLOG4J, status
# localhost server 1
# ------------------------
worker.s1.port=8109
worker.s1.host=localhost
worker.s1.type=ajp13
# localhost server 2
# ------------------------
worker.s2.port=8209
worker.s2.host=localhost
worker.s2.type=ajp13
worker.s2.stopped=1
worker.DLOG4J.type=lb
worker.retries=3
worker.DLOG4J.balanced_workers=s1, s2
worker.DLOG4J.sticky_session=1
worker.status.type=status

以上的 workers.properties 配置就是我們前面那個屏幕抓圖的頁面所用的配置。首先我們配置了兩個類型為 ajp13 的 worker 分別是 s1 和 s2,它們指向同一台服務器上運行在兩個不同端口 8109 和 8209 的 Tomcat 上。接下來我們配置了一個類型為 lb(也就是負載均衡的意思)的 worker,它的名字是 DLOG4J,這是一個邏輯的 worker,它用來管理前面配置的兩個物理連接 s1 和 s2。最後還配置了一個類型為 status 的 worker,這是用來監控 JK 本身的模塊。有了這三個 worker 還不夠,我們還需要告訴 JK,哪些 worker 是可用的,所以就有 worker.list = DLOG4J, status 這行配置。

接下來便是 URI 的映射配置了,我們需要指定哪些鏈接是由 Tomcat 處理的,哪些是由 Apache 直接處理的,看看下面這個文件你就能明白其中配置的意義


/*=DLOG4J
/jkstatus=status
!/*.gif=DLOG4J
!/*.jpg=DLOG4J
!/*.png=DLOG4J
!/*.css=DLOG4J
!/*.js=DLOG4J
!/*.htm=DLOG4J
!/*.html=DLOG4J

相信你已經明白了一大半了:所有的請求都由 DLOG4J 這個 worker 進行處理,但是有幾個例外,/jkstatus 請求由 status 這個 worker 處理。另外這個配置中每一行數據前面的感歎號是什麼意思呢?感歎號表示接下來的 URI 不要由 JK 進行處理,也就是 Apache 直接處理所有的圖片、css 文件、js 文件以及靜態 html 文本文件。

通過對 workers.properties 和 uriworkermap.properties 的配置,可以有各種各樣的組合來滿足我們前面提出對一個 web 網站的要求。您不妨動手試試!


http_proxy

這是利用 Apache 自帶的 mod_proxy 模塊使用代理技術來連接 Tomcat。在配置之前請確保是否使用的是 2.2.x 版本的 Apache 服務器。因為 2.2.x 版本對這個模塊進行了重寫,大大的增強了其功能和穩定性。

http_proxy 模式是基於 HTTP 協議的代理,因此它要求 Tomcat 必須提供 HTTP 服務,也就是說必須啟用 Tomcat 的 HTTP Connector。一個最簡單的配置如下


ProxyPass /images !
ProxyPass /css !
ProxyPass /js !
ProxyPass / http://localhost:8080/

在這個配置中,我們把所有 http://localhost 的請求代理到 http://localhost:8080/ ,這也就是 Tomcat 的訪問地址,除了 images、css、js 幾個目錄除外。我們同樣可以利用 mod_proxy 來做負載均衡,再看看下面這個配置


ProxyPass /images !
ProxyPass /css !
ProxyPass /js !
ProxyPass / balancer://example/
<Proxy balancer://example/>
BalancerMember http://server1:8080/
BalancerMember http://server2:8080/
BalancerMember http://server3:8080/
</Proxy>

配置比 JK 簡單多了,而且它也可以通過一個頁面來監控集群運行的狀態,並做一些簡單的維護設置。

圖 2:監控集群運行狀態

ajp_proxy

ajp_proxy 連接方式其實跟 http_proxy 方式一樣,都是由 mod_proxy 所提供的功能。配置也是一樣,只需要把 http:// 換成 ajp:// ,同時連接的是 Tomcat 的 AJP Connector 所在的端口。上面例子的配置可以改為:


ProxyPass /images !
ProxyPass /css !
ProxyPass /js !
ProxyPass / balancer://example/
<Proxy balancer://example/>
BalancerMember ajp://server1:8080/
BalancerMember ajp://server2:8080/
BalancerMember ajp://server3:8080/
</Proxy>

採用 proxy 的連接方式,需要在 Apache 上加載所需的模塊,mod_proxy 相關的模塊有 mod_proxy.so、mod_proxy_connect.so、mod_proxy_http.so、mod_proxy_ftp.so、mod_proxy_ajp.so, 其中 mod_proxy_ajp.so 只在 Apache 2.2.x 中才有。如果是採用 http_proxy 方式則需要加載 mod_proxy.so 和 mod_proxy_http.so;如果是 ajp_proxy 則需要加載 mod_proxy.so 和 mod_proxy_ajp.so這兩個模塊。


三者比較

相對於 JK 的連接方式,後兩種在配置上是比較簡單的,靈活性方面也一點都不遜色。但就穩定性而言就不像 JK 這樣久經考驗,畢竟 Apache 2.2.3 推出的時間並不長,採用這種連接方式的網站還不多,因此,如果是應用於關鍵的互聯網網站,還是建議採用 JK 的連接方式。

參考資料


原文出處:Apache HTTP Server 与 Tomcat 的三种连接方式介绍*/
前一個主題 | 下一個主題 | 頁首 | | |



Powered by XOOPS 2.0 © 2001-2008 The XOOPS Project|