Java 2 EE 计数体系包含如 Serverlet , JSP , JMX 等等。
以OpenJDK为例,当前比较常用的有1.6.0、1.7.0、1.8.0等版本,当一台主机上有多个OpenJDK时,可使用 “alternatives” 命令设定默认使用的版本。
Java代码的运行:.java(source code) –> javac –> .class(bytecode)
JSP :Java Server Page
JSP Container : JSP + Servlet Container
基于jasper将静态输出的数据转为java代码进行输出,结果为servlet规范的代码
.jsp –>jasper–> .java –> javac –> .class –> jvmtomcat 是JSP Container的开源实现,tomcat是 Java 2 EE 技术体系的不完整实现,tomcat在使用前需要部署Java环境。
JSP Container 技术的商业实现包括:WebSphere, WebLogic, Oc4j, Glassfish, Geronimo, JOnAS, JBoss等等
JSP Container 技术的开源实现包括:Tomcat, Jetty, Resin
yum install -y java-1.8.0-openjdk tomcat tomcat-webapps tomcat-admin-webapps tomcat-docs-webapp
vim /etc/profile.d/java.sh
export JAVA_HOME=/usr
source /etc/profile.d/java.sh
echo $JAVA_HOME
server.xml:主配置文件
web.xml:每个webapp只有“部署”后才能被访问,它的部署方式通常由web.xml进行定义,其存放位置为WEB-INF/目录中;此文件为所有的webapps提供默认配置
context.xml:每个web都可以专用的配置文件,它通常由专用的配置文件context.xml来定义,其存放位置为WEB-INF/目录中;此文件为所有的webapps提供默认配置
tomcat-users.xml:用户认证的账号和密码文件
tomcat主配置文件的默认配置实例:
<Server port="8005" shutdown="SHUTDOWN">
<Service name="Catalina">
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
<Engine name="Catalina" defaultHost="localhost">
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log." suffix=".txt" pattern="%h %l %u %t "%r" %s %b" />
Host>
Engine>
Service>
Server>
组件详解:每个组件都由一个Java“类”实现,这些组件大体可分为以下几个类型:
一个Server可包含多个Service
代表tomcat instance,即表现出的一个java进程;监听在8005端口,只接收“SHUTDOWN”。各server监听的端口不能相同,因此,在同一物理主机启动多个实例时,需要修改其监听端口为不同的端口;
一个Service中仅能有一个Engine
一个Engine可对应多个Connector,但一个Connector仅能对应一个Engine
用于实现将一个或多个connector组件关联至一个engine组件
负责接收请求,常见的有三类http/https/ajp;
进入tomcat的请求可分为两类:
由其它的web server反代:来自前端的反代服务器;
Connector属性
port=”8080”
protocol=”HTTP/1.1”
connectionTimeout=”20000”
address:监听的IP地址;默认为本机所有可用地址
maxThreads:最大并发连接数,默认为200
enableLookups:是否启用DNS查询功能
acceptCount:等待队列的最大长度
一个Engine中可包含多个Host,一个Host中可包含多个Context
Engine组件:Servlet实例,即servlet引擎,其内部可以一个或多个host组件来定义站点,通常需要通过defaultHost来定义默认的虚拟主机
name=” “
defaultHost=”localhost”
jvmRoute=” “
Host组件:位于engine内部用于接收请求并进行相应处理的主机或虚拟主机
Host属性
#提供webapp和测试页面
mkdir -pv /appdata/webapps/ROOT/{lib,classes,WEB-INF,META-INF}
vim /appdata/webapps/ROOT/index.jsp
#增加以下内容
<%@ page language="java" %>
<html>
<head><title>TomcatAtitle>head>
<body>
<h1><font color="red">TomcatA.achudk.comfont>h1>
<table align="centre" border="1">
<tr>
<td>Session IDtd>
<% session.setAttribute("achudk.com","achudk.com"); %>
<td><%= session.getId() %>td>
tr>
<tr>
<td>Created ontd>
<td><%= session.getCreationTime() %>td>
tr>
table>
body>
html>
#修改主配置文件
<Server port="-1" shutdown="SHUTDOWN">
<Service name="Catalina">
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
<Engine name="Catalina" defaultHost="localhost">
<Host name="tomcat.achudk.com" appBase="/appdata/webapps" unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="node1_access" suffix=".log" pattern="%h %l %u %t "%r" %s %b" />
<Context path="/tc1" docBase="/" reloadable="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="node1_test_access_" suffix=".log" pattern="%h %l %u %t "%r" %s %b" />
Context>
Host>
Engine>
Service>
Server>
tomcat安装完成后可通过本机的8080端口访问tomcat默认页面。
vim /etc/tomcat/tomcat-user.xml
#增加下面三条
"admin-gui"/>
"manager-gui"/>
"tomcat" password="tomcat" roles="admin-gui,manager-gui"/>
#重启tomcat服务
systemctl restart tomcat
重启tomcat服务后,测试使用默认页,可以试用tomcat的两个管理工具:”Manager Apps” 和 “Host-Manager”
/: webapps的根目录
index.jsp:主页
WEB-INF/:当前webapp的私有资源路径;通常用于存储当前webapp的web.xml和context.xml配置文件
META-INF/:类似于WEB-INF/
classes/:类文件,当前webapp所提供的类
lib/:类文件,当前webapp所提供的类,被打包为jar格式
热部署:在实际生产环境中如果采用非灰度发布的形式,无论是部署新的webapps或者发布更新原有的webapps,在上述过程中tomcat服务不能中断,所以可能需要专业的部署工具来实现持续发布的效果
冷部署:在灰度发布的生产环境或在实验环境中,tomcat服务重启后,各webapps加载因需重新加载JRE,整个过程会非常慢,此时也需要部署工具来加速发布过程
mkdir /var/lib/tomcat/webapps/test/{WEB-INF,META-INF,lib,classes}
vim /test/index.jsp
#增加如下内容
<%@ page language="java" %>
<%@ page import="java.util.*" %>
<html>
<head>
<title>Test Pagetitle>
head>
<body>
<% out.println("Test : Hello world"); %>
body>
html>
重启tomcat服务后,测试访问 URL/test 页面是否显示 Test : Hello world
布置新的webapps相关文件,此处为了方便演示,将test复制重命名为test2后演示热部署过程
cd /var/lib/tomcat/webapps
cp -a test/ test2/
#修改下index.jsp文件,使其与test的index.jsp文件内容不同,以示区别
vim /var/lib/tomcat/webapps/test2/index.jsp
<%@ page language="java" %>
<%@ page import="java.util.*" %>
<html>
<head>
<title>Test Pagetitle>
head>
<body>
<% out.println("Test2 : Hello world");
%>
body>
html>
在Tomcat默认页面上,使用”Manager Apps”工具,可在Deploy一段的 “Context Path (required):” 中填写 test2 ,点击deploy即完成部署。
角色及IP分配:
负载均衡器:nginx :172.16.50.2/16(公网) 192.168.50.12/24(内网)
动态资源服务器1 :tomcat1 :192.168.50.13/24
动态资源服务器2 :tomcat2 :192.168.50.14/24
#准备webapps
cd /var/lib/tomcat/webapps/
mkdir test/{WEB-INF,META-INF,lib,classes}
vim test/index.jsp
<html>
<head><title>TomcatAtitle>head>
<body>
<h1><font color="red">TomcatA.achudk.comfont>h1>
<table align="centre" border="1">
<tr>
<td>Session IDtd>
<% session.setAttribute("achudk.com","achudk.com"); %>
<td><%= session.getId() %>td>
tr>
<tr>
<td>Created ontd>
<td><%= session.getCreationTime() %>td>
tr>
table>
body>
html>
#修改tomcat主配置文件
vim /etc/tomcat/server.xml
#将8005的连接器的端口改为-1,关闭内置的管理端口8005,能加快tomcat服务启动或停止的速度
<Server port="-1" shutdown="SHUTDOWN">
Server>
cd /etc/nginx
vim nginx.conf
#在http {}中增加以下指令
upstream tcsrvs {};
server 192.168.50.13:8080;
server 192.168.50.14:8080;
#在server {} 配置段中,增加以下内容
proxy_pass http://tcsrvs;
访问172.16.50.2,两个服务器交替响应。
vim /etc/httpd/conf.d/tomcat.conf
BalancerMember http://192.168.50.13:8080
BalancerMember http://192.168.50.14:8080
ProxySet lbmethod=byrequests
ServerName tc1.achudk.com
ProxyRequests off
ProxyVia on
ProxyPreserveHost on
Require all granted
Proxypass / balancer://tcsrvs/
ProxyPassReverse / balancer://tcsrvs/
Require all granted
访问172.16.50.2,两个服务器交替响应。
session sticky
原理:通过标记等方式来识别请求报文,将请求相同资源的请求调度至同一台动态资源服务器
特性:每台后端服务器保存的会话各不相同,使每个服务器在保存会话方面成为单点
session replication cluster
原理:每台服务器保存会话后,向同一组播域中的其他主机同步保存的会话信息
特性:每台后端服务器保存的会话信息相同,单个组播域内仅能存在少数几台主机,否则会话信息同步效率会很低
session server
原理:在动态资源服务器后端设置一台会话存储服务器,专用于保存会话信息,多个动态资源服务器可同时向该存储中写入数据
特性:每台后端动态资源服务器不保存会话信息,共享会话存储服务器的内容,会话存储服务器为避免成为单点,要设置多个,多个session server之间为主从关系
vim /etc/httpd/conf.d/tomcat.conf
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
BalancerMember http://192.168.50.13:8080 route=TomcatA loadfactor=1
BalancerMember http://192.168.50.14:8080 route=TomcatB loadfactor=2
ProxySet lbmethod=byrequests
ProxySet stickysession=ROUTEID
ServerName tc1.achudk.com
ProxyRequests off
ProxyVia on
ProxyPreserveHost on
Require all granted
Proxypass / balancer://tcsrvs/
ProxyPassReverse / balancer://tcsrvs/
Require all granted
vim /etc/nginx/nginx.conf
#增加以下内容
upstream tcsrvs {
hash $request_uri consistent; //根据uri来调度
# hash $cookie_name consistent; //根据cookie来调度
server 192.168.50.13:8080;
server 192.168.50.14:8080;
}
vim /etc/httpd/conf.d/tomcat.conf
#增加一个Location
SetHandler balancer-manager
ProxyPass !
Require all granted
配置启用集群,修改各台服务器tomcat服务的配置文件,将下列配置放置于或中;
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8">
<Manager className="org.apache.catalina.ha.session.DeltaManager" expireSessionsOnShutdown="false" notifyListenersOnReplication="true"/>
<Channel className="org.apache.catalina.tribes.group.GroupChannel">
<Membership className="org.apache.catalina.tribes.membership.McastService"
address="228.10.10.10"
port="45564"
frequency="500"
dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="192.168.50.13"
port="4000"
autoBind="100"
selectorTimeout="5000"
maxThreads="6"/>
<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
<Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
Sender>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
Channel>
<Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/>
<Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
<Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
tempDir="/tmp/war-temp/"
deployDir="/tmp/war-deploy/"
watchDir="/tmp/war-listen/"
watchEnabled="false"/>
<ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
Cluster>
配置webapps
编辑WEB-INF/web.xml,添加元素
注意:CentOS 7上的tomcat自带的文档中的配置示例有语法错误
<ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
解决办法1:将auto修改为指定的IP地址
解决办法2:修改/etc/hosts文件,将localhost修改为指定IP