文章目录
Tomcat简介
- Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。对于一个初学者来说,可以这样认为,当在一台机器上配置好Apache 服务器,可利用它响应HTML(标准通用标记语言下的一个应用)页面的访问请求。实际上Tomcat是Apache 服务器的扩展,但运行时它是独立运行的,所以当你运行tomcat 时,它实际上作为一个与Apache 独立的进程单独运行的。
- 诀窍是,当配置正确时,Apache 为HTML页面服务,而Tomcat 实际上运行JSP 页面和Servlet。另外,Tomcat和IIS等Web服务器一样,具有处理HTML页面的功能,另外它还是一个Servlet和JSP容器,独立的Servlet容器是Tomcat的默认模式,Tomcat一般处理动态页面而处理静态HTML的能力不如Apache服务器。
一、jdk的安装与配置
- 首先从官网下载jdk包,解压到指定目录/usr/local/
[root@LNMPserver1 ~]# tar zxf jdk-7u79-linux-x64.tar.gz -C /usr/local/
[root@LNMPserver1 ~]# cd /usr/local/
[root@LNMPserver1 local]# ls
bin etc games include jdk1.7.0_79 lib lib64 libexec lnmp openresty sbin share src
[root@LNMPserver1 local]# ln -s jdk1.7.0_79/ java
# 做软连接,升级的时候只升级软连接,较为方便
- 配置java的环境变量
vim /etc/profile
写入:
source /etc/profile # 是环境变量生效
- 检测jdk环境是否正确
[root@server1 ~]# vim test.java
public class test{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}
[root@server1 ~]# javac test.java #javac编译.java脚本
[root@server1 ~]# java test #运行脚本
Hello World!
二、Tomcat的安装与配置
- 下载安装包,并解压到指定目录/usr/local,打开tomcat并查看其端口
[root@LNMPserver1 ~]# tar zxf apache-tomcat-7.0.37.tar.gz -C /usr/local/
[root@LNMPserver1 ~]# cd /usr/local/
[root@LNMPserver1 local]# ls
apache-tomcat-7.0.37 etc include jdk1.7.0_79 lib64 lnmp sbin src
bin games java lib libexec openresty share
[root@LNMPserver1 local]# ln -s apache-tomcat-7.0.37/ tomcat
[root@LNMPserver1 local]# tomcat/bin/startup.sh
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr/local/java
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
2. 编辑OpenResty的nginx配置文件
vim /usr/local/openresty/nginx/conf/nginx.conf
写入:
61 location ~ \.jsp$ {
62 proxy_pass http://127.0.0.1:8080;
63 }
/usr/local/openresty/nginx/sbin/nginx -t # 测试
/usr/local/openresty/nginx/sbin/nginx -s reload # 重启服务
- 测试: 浏览器输入:http://172.25.66.1/index.jsp 显示页面,但没有jsp的效果。
但是,浏览器输入http://172.25.66.1:8080/ 显示tomcat猫图形界面
- 将LNMPserver1上配置的好的tomcat,发送到LNMPserver2上
scp -r tomcat/ root@172.25.66.2:/usr/local/
scp -r java/ root@172.25.66.2:/usr/local/
- 在LNMPserver2上同样配置java环境变量,并且启动tomcat
vim /etc/profile
写入:
source /etc/profile # 是环境变量生效
[root@LNMPserver2 local]# tomcat/bin/startup.sh
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr/local/java
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
[root@LNMPserver2 local]# netstat -tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 866/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 942/master
tcp 0 0 :::8080 :::* LISTEN 1048/java
tcp 0 0 :::22 :::* LISTEN 866/sshd
tcp 0 0 ::1:25 :::* LISTEN 942/master
tcp 0 0 ::ffff:127.0.0.1:8005 :::* LISTEN 1048/java
tcp 0 0 :::8009 :::* LISTEN 1048/java
- 实现LNMPserver1和LNMPserver2的tomcat负载均衡
- 修改nginx的配置文件
http {
#upstream memcache { ##所有的请求,通过转发给memcache缓存服务
# server localhost:11211; ##memcache服务在本机的11211端口
# keepalive 512;
# }
upstream tomcat {
server 172.25.66.1:8080;
server 172.25.66.2:8080;
}
#location /memc { ##设置memcache的访问及其存储
# internal; ##只允许内部
# memc_connect_timeout 100ms; #定义连接发送及其超时时间
# memc_send_timeout 100ms;
# memc_read_timeout 100ms;
# set $memc_key $query_string; #memcache以键值对的形式存储
# set $memc_exptime 300;
# memc_pass memcache;
# }
location ~ \.jsp$ {
proxy_pass http://tomcat;
}
检测并重启服务:
[root@LNMPserver1 local]# openresty/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/openresty/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/openresty/nginx/conf/nginx.conf test is successful
[root@LNMPserver1 local]# openresty/nginx/sbin/nginx -s reload
- 分别在两台tomcat后端编写测试页内容
[root@LNMPserver1 ROOT]# vim /usr/local/tomcat/webapps/ROOT/test.jsp
[root@LNMPserver1 ROOT]# cat /usr/local/tomcat/webapps/ROOT/test.jsp
server1 the time is:<%=new java.util.Date() %>
[root@LNMPserver2 local]# vim /usr/local/tomcat/webapps/ROOT/test.jsp
[root@LNMPserver2 local]# cat /usr/local/tomcat/webapps/ROOT/test.jsp
server2 the time is:<%=new java.util.Date() %>
以80端口(nginx默认端口)访问该页面,发现已经轮询,说明实现利用nginx实现负载均衡。
三、在tomcat中实现session共享
什么是session?
在计算机中,尤其是在网络应用中,session称为“会话控制”。
Session对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的 Web 页时,如果该用户还没有会话,则 Web服务器将自动创建一个 Session 对象。
当会话过期或被放弃后,服务器将终止该会话。
Session对象最常见的一个用法就是存储用户的首选项。例如,如果用户指明不喜欢查看图形,就可以将该信息存储在 Session 对象中。
在计算机专业术语里:session是指一个终端用户与交互系统进行通信的时间间隔,通常指从注册入系统到注销系统之间所经过的时间以及如果需要的话,可能还有一定操作空间。
session技术则是服务端的解决方案,它是通过服务器来保持状态的。由于Session这个词汇包含的语义很多,因此需要在这里明确一下 Session的含义。首先,我们通常都会把Session翻译成会话,因此我们可以把客户端浏览器与服务器之间一系列交互的动作称为一个 Session。从这个语义出发,我们会提到Session持续的时间,会提到在Session过程中进行了什么操作等等;其次,Session指的是服务器端为客户端所开辟的存储空间,在其中保存的信息就是用于保持状态。从这个语义出发,我们则会提到往Session中存放什么内容,如何根据键值从 Session中获取匹配的内容等。要使用Session,第一步当然是创建Session了。那么Session在何时创建呢?当然还是在服务器端程序运行的过程中创建的,不同语言实现的应用程序有不同创建Session的方法,而在Java中是通过调用HttpServletRequest的getSession方法(使用true作为参数)创建的。在创建了Session的同时,服务器会为该Session生成唯一的Session id,而这个Session id在随后的请求中会被用来重新获得已经创建的Session;在Session被创建之后,就可以调用Session相关的方法往Session中增加内容了,而这些内容只会保存在服务器中,发到客户端的只有Session id;当客户端再次发送请求的时候,会将这个Session id带上,服务器接受到请求之后就会依据Session id找到相应的Session,从而再次使用之。正式这样一个过程,用户的状态也就得以保持了。
为什么要使用session?
为了对数据的保存更加牢靠,我们选择交叉存放session的方法,即将访问tomcat1上的数据存放在memcache2中,将访问tomcat2上的数据存放在memcache1中,这样存放,当某个tomcat服务断了之后,访问它的客户session并不会消失,而是存放在了对立的memcache,如果存放session的memcache坏了,那么它的数据会立即切换到另一个memcached中。
配置session
LNMPserver1和LNMPserver2上相同的操作,都重新编写测试页内容(一个用户信息提交页面),内容如下:
vim /usr/local/tomcat/webapps/ROOT/test.jsp
写入:
<%@ page contentType="text/html; charset=GBK" %>
<%@ page import="java.util.*" %>
<html><head><title>Cluster App Test</title></head>
<body>
Server Info:
<%
out.println(request.getLocalAddr() + " : " + request.getLocalPort()+"<br>");%>
<%
out.println("<br> ID " + session.getId()+"<br>");
String dataName = request.getParameter("dataName");
if (dataName != null && dataName.length() > 0) {
String dataValue = request.getParameter("dataValue");
session.setAttribute(dataName, dataValue);
}
out.print("<b>Session list</b>");
Enumeration e = session.getAttributeNames();
while (e.hasMoreElements()) {
String name = (String)e.nextElement();
String value = session.getAttribute(name).toString();
out.println( name + " = " + value+"<br>");
System.out.println( name + " = " + value);
}
%>
<form action="test.jsp" method="POST">
name:<input type=text size=20 name="dataName">
<br>
key:<input type=text size=20 name="dataValue">
<br>
<input type=submit>
</form>
</body>
</html>
浏览器输入http://172.25.66.1/test.jsp 显示新的测试页面,开始测试:
我们发现,虽然之前实现了负载均衡,但是,我们的session并没有保存住,每次提交或者刷新后,session就丢失了,这样显然不合理。
使用nginx的sticky模块,实现session粘滞
这里需要使用nginx1.10.1版本,有这个sticky模块。之后的需要付费使用。
步骤:解压nginx-1.10.1 版本的压缩包,nginx的sticky安装包,去掉nginx的版本号以及关闭debug日志,编译,添加sticky模块,然后安装,关掉openresty下的nginx,重新编辑nginx的配置文件,把以前的openresty下的nginx文件复制过来即可,查看并添加一个sticky模块,检查语法是否有错误,并开启nginx。
[root@LNMPserver1 ~]# tar zxf nginx-1.10.1.tar.gz
[root@LNMPserver1 ~]# tar zxf nginx-sticky-module-ng.tar.gz
[root@LNMPserver1 ~]# cd nginx-1.10.1
[root@LNMPserver1 nginx-1.10.1]# vim auto/cc/gcc
[root@LNMPserver1 nginx-1.10.1]# ./configure --prefix=/usr/local/lnmp/nginx --with-http_ssl_module --with-http_stub_status_module --with-threads --with-file-aio --add-module=/root/nginx-sticky-module-ng
[root@LNMPserver1 nginx-1.10.1]# make && make install
[root@LNMPserver1 nginx-1.10.1]# /usr/local/openresty/nginx/sbin/nginx -s stop
[root@LNMPserver1 nginx-1.10.1]# cp /usr/local/openresty/nginx/conf/nginx.conf /usr/local/lnmp/nginx/conf/nginx.conf
cp: overwrite `/usr/local/lnmp/nginx/conf/nginx.conf'? y
[root@LNMPserver1 nginx-1.10.1]# vim /usr/local/lnmp/nginx/conf/nginx.conf
修改:
upstream tomcat {
sticky; # 添加sticky模块
server 172.25.66.1:8080;
server 172.25.66.2:8080;
}
注释掉这三个参数:
location ~ \.php$ {
# set $key $uri$args;
# srcache_fetch GET /memc $key;
# srcache_store PUT /memc $key;
检测并启动nginx
[root@LNMPserver1 nginx-1.10.1]# /usr/local/lnmp/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/lnmp/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/lnmp/nginx/conf/nginx.conf test is successful
[root@LNMPserver1 nginx-1.10.1]# /usr/local/lnmp/nginx/sbin/nginx
这里我们实现了session数据不覆盖前面的而是追加到后面,但是发现数据绑定的主机都是server1,就实现了会话保持。但是我们希望的是负载均衡+session共享。
实现session交叉存储
- LNMPserver2上安装memcache,并打开服务
yum install -y memcached
/etc/init.d/memcached start
- 将这些安装包放在server1和server2的/usr/local/tomcat/lib目录下
- 然后编辑tomcat的配置文件
vim /usr/local/tomcat/conf/context.xml
在第35行到40行添加如下内容:
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:172.25.66.1:11211,n2:172.25.66.2:11211"
failoverNodes="n1"
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
/>
- 将配置文件同样发送给server2
[root@server1 ~]# scp /usr/local/tomcat/conf/context.xml root@172.25.66.2:/usr/local/tomcat/conf/
## 拷贝到server2之后将37行的n1改为n2
## 这里需要重启tomcat
[root@server1 ~]# /usr/local/tomcat/bin/shutdown.sh
[root@server1 ~]# /usr/local/tomcat/bin/startup.sh
[root@server2 ~]# /usr/local/tomcat/bin/shutdown.sh
[root@server2 ~]# /usr/local/tomcat/bin/startup.sh
- 浏览器测试,查看日志。发现成功实现session交叉存储。