Tomcat是由Apache软件基金会下属的Jakarta项目开发的一个Servlet容器,按照SunMicrosystems提供的技术规范,实现了对Servlet和JavaServerPage(JSP)的支持,并提供了作为Web服务器的一些特有功能,如Tomcat管理和控制平台、安全域管理和Tomcat阀等。由于Tomcat本身也内含了一个HTTP服务器,它也可以被视作一个单独的Web服务器。但是,不能将Tomcat 和 Apache Web 服务器混淆,Apache Web Server 是一个用 C 语言实现的 HTTP web server;这两个HTTP web server 不是捆绑在一起的。Apache Tomcat 包含了一个配置管理工具,也可以通过编辑 XML 格式的配置文件来进行配置。


java程序在JVM中运行的前提:加载器将程序自身使用的class和公共的java APIclass加载之后,通过执行引擎来运行;执行引擎需要跟主机上的系统调用进行交互;执行引擎可以调用JavaAPI,也可以调用系统的API,也称Native APIDSO,动态共享对象)


Java Runtime Data Areas

Tomcat 部署实例_第1张图片


method area;加载的公共class库中的class

heap;运行java线程的公共内存

Java stacks ;栈,每个java线程都有独有的栈,用于保存运行时的变量;

pc registerpc寄存器,或java 寄存器,线程所独有,用于保存当前线程执行的指令,指令计数器;

native method statck;本地方法栈,调用本地类库;

execution engine;所有的数据需要在执行引擎中运行;

native method interface;跟本地系统调用交互的接口;

native method libraries;本地方法库,系统调用;


Generations of Data in Garbage Collection


Tomcat 部署实例_第2张图片

Eden:新对象在Eden创建,过一段时间后,将不在使用的对象删除,正在使用的对象移动到Survivor;在幸存者区域里,继续使用的移动到老年代,不使用的移动到未使用空间;

Young:新生代

Tenured:老年代

Perm:持久代,方法区



Configuring the Heap and Garbage Collector

Tomcat 部署实例_第3张图片

-Xmx:新生代和老年代最大可以使用的内存空间;

-Xms:当前可以使用的最小内存空间,除去预留空间,包含新生代和老年代使用的内存;

reserved:以后可以申请使用的空间;

applet:小的可运行程序,本身是一种APIapplet在服务器端编译好,通过HTTP协议传送到客户端,客户端浏览器需要安装java插件(JRE)来运行这种applet


servlet:另一种class,程序员开发好的程序在服务器端第一次执行时被编译成java类,类在JVM中执行;但它不能把结果直接响应给客户端,前端需要有HTTP服务器来分析客户请求的报文。


JSPjspservlet的升级版,java开发的程序能够像php一样,利用代码嵌入的方式,放到网页文件里面,只需事先加入标签即可;有了jsp之后,前端是一个jsp分析器(jasper),当用户请求含有jsp代码的页面时,应用程序将jsp代码发送给jasperjasper将代码转换成servlet类,再由编译器进行编译,servlet被编译成java类,JVM调用公共类,然后在JVM中运行,将生成的结果发送给http服务器,由http服务器构建响应报文;包含jasperservlet等其他工具容器称为web容器,web容器通常可以使用内部的java类或公共类组件提供http服务,能够分析http请求,并构建响应报文。tomcat是一个完整意义上的web容器,但不是J2EE的实现;

JavaSE包含了Java二进制程序(如JVM和Java字节码编译器)和Java的核心代码库;

JaveEE标准包含了一组适用于创建企业级Web应用程序的API。Jave EE建立在Java SE的基础上,并依赖于JavaSE才能正常工作。当然,任何级别的应用程序均能从Java EE中获益,但Jave EE却更适合解决大型软件系统设计中的问题。

JAVAEE包含多个独立的API,Servlet和JSP就是其中的两个,而JAVA EE中著名的API中还包含如下的几个:

JAVA EEAPIs:
EJB(Enterprise JavaBeans):JAVA相关的诸多高级功能的实现,如RMI(Remote Method Invocation),对象/关系映射,跨越多个数据源的分布式事务等;

JMS(Java MessageService):高性能异步消息服务,实现JAVA EE应用程序与非JAVA程序的“透明”通信;

JMX(Java ManagementExtensions):在程序运行时对其进行交互式监控和管理的机制;

JTA(Java TransactionAPI):允许应用程序在自身的一个或多个组件中平滑地处理错误的机制;

JavaMail:通过工业标准的POP/SMTP/IMAP协议发送和接收邮件的机制;


Tomcat 部署实例_第4张图片



安装tomcat

首先安装JDK (开发工具):
jdk下载地址:
http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html
[root@node2 ~]# chmod +x jdk-6u31-linux-x64-rpm.bin
[root@node2 ~]#  ./jdk-6u31-linux-x64-rpm.bin
安装目录在/usr/java/latest
导出环境变量:
[root@node2 ~]# vi /etc/profile.d/jdk.sh
export JAVA_HOME=/usr/java/latest
export PATH=$JAVA_HOME/bin:$PATH
测试一下:
[root@node2 ~]# java -version
java version "1.6.0_31"
Java(TM) SE Runtime Environment (build 1.6.0_31-b04)
Java HotSpot(TM) 64-Bit Server VM (build 20.6-b01, mixed mode)
(mixed mode,编译和即时执行都支持)



安装tomcat程序:

下载地址:http://tomcat.apache.org/download-70.cgi

[root@node2 ~]# tar xf apache-tomcat-7.0.42.tar.gz -C /usr/local/
[root@node2 ~]# cd /usr/local/
[root@node2 src]# ln -sv apache-tomcat-7.0.42 tomcat
`tomcat' -> `apache-tomcat-7.0.42'
[root@node2 src]# cd tomcat/
[root@node2 tomcat]# ls
bin  conf  lib  LICENSE  logs  NOTICE  RELEASE-NOTES  RUNNING.txt  temp  webapps  work
# tomcat运行需要2个变量
[root@node2 tomcat]# vi /etc/profile.d/tomcat.sh
export CATALINA_HOME=/usr/local/tomcat
export PATH=$CATALINA_HOME/bin:$PATH
[root@node2 tomcat]# . /etc/profile.d/tomcat.sh
[root@node2 local]# catalina.sh -h
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr/java/latest
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Usage: catalina.sh ( commands ... )
commands:
  debug             Start Catalina in a debugger
  debug -security   Debug Catalina with a security manager
  jpda start        Start Catalina under JPDA debugger
  run               Start Catalina in the current window
  run -security     Start in the current window with security manager
  start             Start Catalina in a separate window
  start -security   Start in a separate window with security manager
  stop              Stop Catalina, waiting up to 5 seconds for the process to end
  stop n            Stop Catalina, waiting up to n seconds for the process to end
  stop -force       Stop Catalina, wait up to 5 seconds and then use kill -KILL if still running
  stop n -force     Stop Catalina, wait up to n seconds and then use kill -KILL if still running
  configtest        Run a basic syntax check on server.xml - check exit code for result
  version           What version of tomcat are you running?
Note: Waiting for the process to end and use of the -force option require that $CATALINA_PID is defined
启动tomcat:
[root@node2 local]# catalina.sh start
#默认监听8080端口;

安装成功后效果:

Tomcat 部署实例_第5张图片


tomcat启动脚本:
vi /etc/init.d/tomcat
#!/bin/sh
# Tomcat init script for Linux.
#
# chkconfig: 2345 96 14
# description: The Apache Tomcat servlet/JSP container.
JAVA_HOME=/usr/java/latest
CATALINA_HOME=/usr/local/tomcat
export JAVA_HOME CATALINA_HOME
exec $CATALINA_HOME/bin/catalina.sh $*
[root@node2 local]# chkconfig --add tomcat
[root@node2 local]# chkconfig tomcat on
[root@node2 local]# service tomcat stop
env: /etc/init.d/tomcat: Permission denied
[root@node2 local]# chmod +x /etc/init.d/tomcat
[root@node2 local]# service tomcat stop
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr/java/latest
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
[root@node2 local]# service tomcat start
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr/java/latest
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
# tomcat配置文件目录:
/usr/local/tomcat/conf
# web.xml:部署描述符定义文件
# tomcat-users.xml:用户授权信息
# server.xml:主配置文件
# jps命令用以显示正在运行的虚拟机;


一个tomcat实例可以有多个servlet容器,当外部请求从connector进来之后,送到与该connector关联的某个引擎上,connector需要通过service与引擎进行交互,引擎内部的host提供虚拟主机服务。

Java程序要运行需要class loader把程序使用的类以及公共类加载进JVM


部署(deployment):手动通知tomcat把程序用到的各种类加载完毕,通过部署描述符文件定义程序可以识别的MIME类型以及其他组件属性,每个jsp的源程序不能直接执行,需要在第一次被访问时进行编译或部署的时候被编译,当源文件修改后,还需要重新编译,tomcat可以配置为自动部署。在引擎内部的host组件中有context子组件,用以描述需要单独部署的访问路径;

server.xml中的Listener用来监听组件之间通信的通道;

global naming resources;全局命名资源,用以定义认证信息等


应用程序目录结构:

/WEB-INF 此目录为私有资源目录,其内部的所有文件和子目录均不能被公开访问;包含着此Web应用程序的配置文件web.xml(程序结构描述符文件)通常放置于此目录;
/WEB-INF/classes 当前Web应用程序的类文件的存在目录;
/WEB-INF/lib 可被打包为JAR格式的类文件通常放置于此目录;


# 修改访问tomcat的默认端口和状态页面:
[root@node2 conf]# cd /usr/local/tomcat/conf
[root@node2 conf]# vi server.xml
   
    
# 定义用户
[root@node2 conf]# cd /usr/local/tomcat/conf
[root@node2 conf]# vi tomcat-users.xml

    
    
    


定义一个虚拟主机:


[root@node2 conf]# cd /usr/local/tomcat/conf
[root@node2 conf]# vi server.xml
# 在
        
        
      
# 然后修改默认主机:
 
# 添加tomcat为系统服务:
[root@node2 tomcat]# vi /etc/init.d/tomcat
#!/bin/sh
# Tomcat init script for Linux.
#
# chkconfig: 2345 96 14
# description: The Apache Tomcat servlet/JSP container.
JAVA_HOME=/usr/java/latest
CATALINA_HOME=/usr/local/tomcat
export JAVA_HOME CATALINA_HOME
exec $CATALINA_HOME/bin/catalina.sh $*
[root@node2 tomcat]# chmod +x /etc/init.d/tomcat
[root@node2 tomcat]# chkconfig --add tomcat
[root@node2 tomcat]# chkconfig tomcat on
# 重启服务:
[root@node2 tomcat]# service tomcat stop
[root@node2 tomcat]# service tomcat start
#创建虚拟主机目录:
[root@node2 tomcat]# mkdir /tomcat/app1/WEB-INF/{classes,lib} -pv
[root@node2 tomcat]# vi /tomcat/app1/index.jsp
<%@ page language="java" %>
<%@ page import="java.util.*" %>

  
    JSP test page.
  
  
  

<% out.println("Hello,world!"); %>

[root@node2 Catalina]# cd /usr/local/tomcat/work/Catalina #运行成功后,将自动生成以主机名命名的目录 [root@node2 Catalina]# ls localhost www.magedu.com

#使用浏览器查看:

Tomcat 部署实例_第6张图片


可以装一个论坛试试:以JspRun为例


1、清空/tomcat/app1,然后将软件解压后生成的upload目录中的内容移动到/tomcat/app1

2、将tomcat服务重启启动

3、安装mysql数据库,为JspRun创建一个用户;

4http://172.16.1.2/install.jsp根据提示进行安装即可,最后如下图

Tomcat 部署实例_第7张图片


利用nginxtomcat实现前端代理


# 一、配置Nginx
[root@node1 conf.d]# cd  /etc/nginx/conf.d
[root@node1 conf.d]# vi  virtual.conf
# A virtual host using mix of IP-, name-, and port-based configuration
#
server {
    listen       80;
    server_name  www.magedu.com  alias  bbs.magedu.com;
    location / {
    index index.jsp ;
    proxy_pass http://172.16.1.2;
}
    location ~* \.(jsp|do)$ {
        proxy_pass http://172.16.1.2;
        }
    location ~* \.(html|gif|png|css|js|jpeg|jpg|htm)$ {
        proxy_pass http://172.16.1.3;
    }
}
#
#
# 将论坛程序安装完成后生成的文件全部复制到静态服务器上
[root@node2 ~]# scp -rp /tomcat/app1/* 172.16.1.3:/var/www/html
# 查看访问日志
# 1、在tomcat服务器上查看访问日志
172.16.1.1 - - [01/Oct/2013:10:21:52 +0800] "GET /test.jsp HTTP/1.0" 200 114
172.16.1.1 - - [01/Oct/2013:10:21:53 +0800] "GET /favicon.ico HTTP/1.0" 304 -
172.16.1.1 - - [01/Oct/2013:10:25:50 +0800] "GET / HTTP/1.0" 200 10955
# 2、在apache服务器上查看访问日志:
172.16.1.1 - - [26/Sep/2013:23:09:11 +0800] "GET /include/javascript/keyboard.js HTTP/1.0" 304 - "http://www.magedu.com/" "Mozilla/5.0 (X11; Linux x86_64; rv:10.0.12) Gecko/20130109 Firefox/10.0.12"
172.16.1.1 - - [26/Sep/2013:23:09:11 +0800] "GET /forumdata/cache/style_1.css HTTP/1.0" 304 - "http://www.magedu.com/" "Mozilla/5.0 (X11; Linux x86_64; rv:10.0.12) Gecko/20130109 Firefox/10.0.12"
172.16.1.1 - - [26/Sep/2013:23:09:11 +0800] "GET /forumdata/cache/style_1_append.css HTTP/1.0" 304 - "http://www.magedu.com/" "Mozilla/5.0 (X11; Linux x86_64; rv:10.0.12) Gecko/20130109 Firefox/10.0.12"
172.16.1.1 - - [26/Sep/2013:23:09:11 +0800] "GET /p_w_picpaths/default/logo.gif HTTP/1.0" 304 - "http://www.magedu.com/" "Mozilla/5.0 (X11; Linux x86_64; rv:10.0.12) Gecko/20130109 Firefox/10.0.12"
172.16.1.1 - - [26/Sep/2013:23:09:11 +0800] "GET /p_w_picpaths/default/header.gif HTTP/1.0" 304 - "http://www.magedu.com/forumdata/cache/style_1_append.css" "Mozilla/5.0 (X11; Linux x86_64; rv:10.0.12) Gecko/20130109 Firefox/10.0.12"



apache为tomcat提供代理:


# 安装apr-devel、apr-util-devel、tomcat-connectors
[root@node1 ~]# yum -y install apr-devel apr-util-devel
[root@node1 ~]# yum -y install httpd-devel
[root@node1 ~]# tar xf tomcat-connectors-1.2.37-src.tar.gz
[root@node1 ~]# cd tomcat-connectors-1.2.37-src/native
[root@node1 native]# ./configure --with-apxs
[root@node1 native]# make
[root@node1 native]# make install
[root@node1 native]# ls /etc/httpd/modules/
mod_jk.so
# 加载mod_jk模块:
[root@node1 ~]# cd /etc/httpd/conf.d/
[root@node1 conf.d]# vi mod_jk.conf
# Load the mod_jk
LoadModule  jk_module  modules/mod_jk.so
JkWorkersFile  /etc/httpd/conf.d/workers.properties
JkLogFile  logs/mod_jk.log
JkLogLevel  debug
JkMount  /*  TomcatA
JkMount  /status/  stat1
[root@node1 conf.d]# vi workers.properties
worker.list=tomcatA,stat1
worker.TomcatA.port=8009
worker.TomcatA.host=172.16.1.2
worker.TomcatA.type=ajp13
worker.TomcatA.lbfactor=1
worker.stat1.type = status
#查看模块是否加载
[root@node1 conf.d]# httpd -t -D DUMP_MODULES
 jk_module (shared)
#重启服务
[root@node1 conf.d]# service httpd restart
在tomcat服务器上定义jvmRoute
[root@node2 conf]# vi server.xml
 
#重启tomcat服务:
[root@node2 conf]# service tomcat stop
[root@node2 conf]# service tomcat start


最后测试:


Tomcat 部署实例_第8张图片


再添加一台tomcat服务器使apachetomcat进行负载均衡:

安装过程……


#修改tomcat服务器引擎参数jvmRoute
[root@node3 conf]# vi server.xml
 
#添加一个虚拟主机:
  
            
          
        
#创建目录:
[root@node3 ~]# mkdir -pv /tomcat/app1/WEB-INF/{classes,lib}
#创建测试页面:
[root@node3 ~]# vi /tomcat/app1/test.jsp
<%@ page language="java" %>

  TomcatB
  
    

TomcatB

<% session.setAttribute("abc","abc"); %>
Session ID<%= session.getId() %>
Created on <%= session.getCreationTime() %>
#重启服务: [root@node3 ~]# service tomcat stop [root@node3 ~]# service tomcat start

测试:

Tomcat 部署实例_第9张图片

# 在第一台tomcat也建立测试页:
[root@node2 ~]# vi /tomcat/app1/test.jsp
<%@ page language="java" %>

  TomcatA
  
    

TomcatA

<% session.setAttribute("abc","abc"); %>
Session ID<%= session.getId() %>
Created on <%= session.getCreationTime() %>

测试:

Tomcat 部署实例_第10张图片


#在apache服务器上:
[root@node1 ~]# cd /etc/httpd/conf.d/
[root@node1 conf.d]# vi mod_jk.conf
[root@node1 conf.d]# more mod_jk.conf
# Load the mod_jk
LoadModule  jk_module  modules/mod_jk.so
JkWorkersFile  /etc/httpd/conf.d/workers.properties
JkLogFile  logs/mod_jk.log
JkLogLevel  debug
JkMount  /*  lbcluster1
JkMount  /status/  stat1
[root@node1 conf.d]# vi workers.properties
worker.list = lbcluster1,stat1
worker.TomcatA.type = ajp13
worker.TomcatA.host = 172.16.1.2
worker.TomcatA.port = 8009
worker.TomcatA.lbfactor = 1
worker.TomcatB.type = ajp13
worker.TomcatB.host = 172.16.1.3
worker.TomcatB.port = 8009
worker.TomcatB.lbfactor = 1
worker.lbcluster1.type = lb
worker.lbcluster1.method = R
worker.lbcluster1.sticky_session = 0
worker.lbcluster1.balance_workers = TomcatA, TomcatB
worker.stat1.type = status


# 使用mod_proxy为tomcat进行反向代理:
[root@node1 conf.d]# vi /etc/httpd/conf.d/mod_proxy.conf
ProxyVia Off
ProxyRequests Off
ProxyPass / ajp://172.16.1.2:8009/
ProxyPa***everse / ajp://172.16.1.2:8009/

    Order allow,deny
    Allow from all


    Order allow,deny
    Allow from all


参数介绍:

ProxyPreserveHost{On|Off}:如果启用此功能,代理会将用户请求报文中的Host:行发送给后端的服务器,而不再使用ProxyPass指定的服务器地址。如果想在反向代理中支持虚拟主机,则需要开启此项,否则就无需打开此功能。


ProxyVia {On|Off|Full|Block}:用于控制在http首部是否使用Via:,主要用于在多级代理中控制代理请求的流向。默认为Off,即不启用此功能;On表示每个请求和响应报文均添加Via:;Full表示每个Via:行都会添加当前apache服务器的版本号信息;Block表示每个代理请求报文中的Via:都会被移除。

ProxyRequests{On|Off}:是否开启apache正向代理的功能;启用此项时为了代理http协议必须启用mod_proxy_http模块。同时,如果为apache设置了ProxyPass,则必须将ProxyRequests设置为Off。


ProxyPass [path] !|url [key=value key=value...]]:将后端服务器某URL与当前服务器的某虚拟路径关联起来作为提供服务的路径,path为当前服务器上的某虚拟路径,url为后端服务器上某URL路径。使用此指令时必须将ProxyRequests的值设置为Off。需要注意的是,如果path以“/”结尾,则对应的url也必须以“/”结尾,反之亦然。


ProxyPa***everse:用于让apache调整HTTP重定向响应报文中的Location、Content-Location及URI标签所对应的URL,在反向代理环境中必须使用此指令避免重定向报文绕过proxy服务器。

另外,mod_proxy模块在httpd2.1的版本之后支持与后端服务器的连接池功能,连接在按需创建在可以保存至连接池中以备进一步使用。连接池大小或其它设定可以通过在ProxyPass中使用key=value的方式定义。常用的key如下所示:
min:连接池的最小容量,此值与实际连接个数无关,仅表示连接池最小要初始化的空间大小。
max:连接池的最大容量,每个MPM都有自己独立的容量;都值与MPM本身有关,如Prefork的总是为1,而其它的则取决于ThreadsPerChild指令的值。
loadfactor:用于负载均衡集群配置中,定义对应后端服务器的权重,取值范围为1-100。
retry:当apache将请求发送至后端服务器得到错误响应时等待多长时间以后再重试。单位是秒钟。


如果Proxy指定是以balancer://开头,即用于负载均衡集群时,其还可以接受一些特殊的参数,如下所示:
lbmethod:apache实现负载均衡的调度方法,默认是byrequests,即基于权重将统计请求个数进行调度,bytraffic则执行基于权重的流量计数调度,bybusyness通过考量每个后端服务器的当前负载进行调度。
maxattempts:放弃请求之前实现故障转移的次数,默认为1,其最大值不应该大于总的节点数。
nofailover:取值为On或Off,设置为On时表示后端服务器故障时,用户的session将损坏;因此,在后端服务器不支持session复制时可将其设置为On。
stickysession:调度器的stickysession的名字,根据web程序语言的不同,其值为JSESSIONID或PHPSESSIONID。
上述指令除了能在banlancer://或ProxyPass中设定之外,也可使用ProxySet指令直接进行设置


在httpd.conf中的配置实例:

[root@node1 ~]# vi /etc/httpd/conf/httpd.conf
NameVirtualHost 172.16.1.1:80
ProxyRequests Off

BalancerMember ajp://172.16.1.2:8009 loadfactor=10 route=TomcatA
BalancerMember ajp://172.16.1.3:8009 loadfactor=10 route=TomcatB

#

    ServerAdmin [email protected]
    ServerName www.magedu.com
    ProxyPass / balancer://lbcluster1/ stickysession=jsessionid
    ProxyPa***everse / balancer://lbcluster1/
    ErrorLog logs/dummy-host.example.com-error_log
    CustomLog logs/dummy-host.example.com-access_log common


开启tomcat会话保持机制(基于内存复制的集群)


需要在server.xml中引擎和主机定义之间加入如下内容:


…………

 


            
            

              
            
            
            
          

          


          
        

……
……


定义在Engine容器中,则表示对所有主机均启动用集群功能。如果定义在某Host中,则表示仅对此主机启用集群功能。此外,需要注意的是,Receiver中的address="auto"一项的值最好改为当前主机集群服务所对应的网络接口的IP地址。


特别需要注意的地方:

在后端服务器上要定义默认路由,虽然后端服务器不需要网关就可以提供服务;但是如果需要做成会话共享的tomcat集群就需要添加默认网关;否则catalina.sh启动不了,并提示不能加入Multicast组中。