最新消息:XAMPP默认安装之后是很不安全的,我们只需要点击左方菜单的 "安全"选项,按照向导操作即可完成安全设置。

Linux下nginx与Tomcat的配置和优化

XAMPP下载 中文小张 83浏览 0评论

nginx的安装

编译安装,我们可以在http://nginx.org/download/nginx-1.8.0.tar.gz下载源码包。

如果需要自动安装可以下载预编译的版本http://nginx.org/en/linux_packages.html#stable。

本文中采用编译安装。步骤如下:

# 检查和安装依赖项(gcc、正则表达式工具、传送内容压缩的zlib库、openssl开启https支持),-y表示静默安装
yum -y install gcc pcre pcre-devel zlib zlib-devel openssl openssl-devel
# 下载源码包
wget http://nginx.org/download/nginx-1.8.0.tar.gz
# 解压源码包
tar zxvf nginx-1.8.0.tar.gz
# 进入解压的目录配置相关参数(可以使用–help查看可选项)
cd nginx-1.8.0/
./configure –help
./configure –prefix=/opt/nginx # 安装目录
# 安装
make && make install
# 启动和关闭nginx
cd /opt/nginx/sbin/
./nginx
ps -aux|grep nginx # 查看进程(正常工作的时候有守护进程和工作进程)
./nginx -h # 查看帮助

如果需要系统启动的时候运行nginx需要配置Linux的启动脚本文件,以CentOS为例:

vim  /etc/rc.d/rc.local # 在该文件追加nginx启动命令
/opt/nginx/sbin/nginx

nginx的配置

nginx的主配置文件位于安装目录下的conf/nginx.conf.

# 顶层配置信息管理服务器级别行为
worker_processes  1;
# event指令与事件模型有关,配置处理连接有关信息
events {
worker_connections  1024;
}
# http指令处理http请求
http {
# mime type映射
include       mime.types;
default_type  application/octet-stream;
sendfile        on;
#tcp_nopush     on;
#keepalive_timeout  0;
keepalive_timeout  65;
#gzip  on;
# server 表示一个虚拟主机,一台服务器可配置多个虚拟主机
server {
# 监听端口
listen       80;
# 识别的域名
server_name  localhost;
# 一个关键设置,与url参数乱码问题有关
charset utf-8;
#access_log  logs/host.access.log  main;
#location表达式:
#syntax: location [=|~|~*|^~|@] /uri/ { … }
#分为两种匹配模式,普通字符串匹配,正则匹配
#无开头引导字符或以=开头表示普通字符串匹配
#以~或~* 开头表示正则匹配,~*表示不区分大小写
#多个location时匹配规则
#总体是先普通后正则原则,只识别URI部分,例如请求为/test/1/abc.do?arg=xxx
#1. 先查找是否有=开头的精确匹配,即location = /test/1/abc.do {…}
#2. 再查找普通匹配,以 最大前缀 为规则,如有以下两个location
#   location /test/ {…}
#   location /test/1/ {…}
#   则匹配后一项
#3. 匹配到一个普通格式后,搜索并未结束,而是暂存当前结果,并继续再搜索正则模式
#4. 在所有正则模式location中找到第一个匹配项后,以此匹配项为最终结果
#   所以正则匹配项匹配规则受定义前后顺序影响,但普通匹配不会
#5. 如果未找到正则匹配项,则以3中缓存的结果为最终结果
#6. 如果一个匹配都没有,返回404
#location =/ {…} 与 location / {…} 的差别
#前一个是精确匹配,只响应/请求,所有/xxx类请求不会以前缀匹配形式匹配到它
#而后一个正相反,所有请求必然都是以/开头,所以没有其它匹配结果时一定会执行到它
#location ^~ / {…} ^~意思是非正则,表示匹配到此模式后不再继续正则搜索
#所有如果这样配置,相当于关闭了正则匹配功能
#因为一个请求在普通匹配规则下没得到其它普通匹配结果时,最终匹配到这里
#而这个^~指令又相当于不允许正则,相当于匹配到此为止
location / {
root   html; # 网站根目录,默认是安装目录下的html目录(可以指定绝对路径)
index  index.html index.htm;
# deny all; 拒绝请求,返回403
# allow all; 允许请求
}
location /test/ {
deny all;
}
location ~ /test/.+\.jsp$ {
# proxy_pass表示代理
proxy_pass  http://192.168.132.144:8080;
}
location ~ \.jsp$ {
proxy_pass  http://192.168.132.144:8080;
}
# 定义各类错误页
error_page  404              /404.html;
# redirect server error pages to the static page /50x.html
#
error_page   500 502 503 504  /50x.html;
location = /50x.html {
root   html;
}
# @类似于变量定义
# error_page 403 http://www.jikexueyuan.com这种定义不允许,所以利用@实现
error_page 403 @page403;
location @page403 {
proxy_pass http://http://www.jikexueyuan.com;
}
}
# another virtual host using mix of IP-, name-, and port-based configuration
server {
listen       80;
#listen 9090
server_name  www.test.com test.com other.cc;
location / {
# root d:\\test; 注意,win下d:\test因转义符问题不允许
root d:/test
index  index.html index.htm;
}
}
}

nginx的优化

# nginx不同于apache服务器,当进行了大量优化设置后会魔术般的明显性能提升效果
# nginx在安装完成后,大部分参数就已经是最优化了,我们需要管理的东西并不多
#user  nobody;
# 阻塞和非阻塞网络模型:
# 同步阻塞模型,一请求一进(线)程,当进(线)程增加到一定程度后
# 更多CPU时间浪费到切换一,性能急剧下降,所以负载率不高
# Nginx基于事件的非阻塞多路复用(epoll或kquene)模型
# 一个进程在短时间内可以响应大量的请求
# 建议值 <= cpu核心数量,一般高于cpu数量不会带好处,也许还有进程切换开销的负面影响
worker_processes 4;
# 将work process绑定到特定cpu上(核心数量与数字位数对应,进程数量与数字的组数对应),避免进程在cpu间切换的开销
worker_cpu_affinity 0001 0010 0100 1000
# 8内核4进程时的设置方法 worker_cpu_affinity 00000001 00000010 00000100 10000000
# 每进程最大可打开文件描述符数量(linux上文件描述符比较广义,网络端口、设备、磁盘文件都是)
# 文件描述符用完了,新的连接会被拒绝,产生502类错误
# linux最大可打开文件数可通过ulimit -n FILECNT或 /etc/security/limits.conf配置
# 理论值 系统最大数量 / 进程数。但进程间工作量并不是平均分配的,所以可以设置的大一些
worker_rlimit_nofile 655350
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
#pid        logs/nginx.pid;
events {
# 并发响应能力的关键配置值
# 每个进程允许的最大同时连接数,work_connectins * worker_processes = maxConnection;
# 要注意maxConnections不等同于可响应的用户数量,
# 因为一般一个浏览器会同时开两条连接,如果反向代理,nginx到后端服务器的连接也要占用连接数
# 所以,做静态服务器时,一般 maxClient = work_connectins * worker_processes / 2
# 做反向代理服务器时 maxClient = work_connectins * worker_processes / 4
# 这个值理论上越大越好,但最多可承受多少请求与配件和网络相关,也可最大可打开文件,最大可用sockets数量(约64K)有关
worker_connections  500;
# 指明使用epoll 或 kquene (*BSD)
use epoll
# 备注:要达到超高负载下最好的网络响应能力,还有必要优化与网络相关的linux内核参数
}
http {
include       mime.types;
default_type  application/octet-stream;
#log_format  main  ‘$remote_addr – $remote_user [$time_local] “$request” ‘
#                  ‘$status $body_bytes_sent “$http_referer” ‘
#                  ‘”$http_user_agent” “$http_x_forwarded_for”‘;
# 关闭此项可减少IO开销,但也无法记录访问信息,不利用业务分析,一般运维情况不建议使用
access_log off
# 只记录更为严重的错误日志,可减少IO压力
error_log logs/error.log crit;
#access_log  logs/access.log  main;
# 启用内核复制模式,应该保持开启达到最快IO效率
sendfile        on;
# 简单说,启动如下两项配置,会在数据包达到一定大小后再发送数据
# 这样会减少网络通信次数,降低阻塞概率,但也会影响响应及时性
# 比较适合于文件下载这类的大数据包通信场景
#tcp_nopush     on; 在
#tcp_nodelay on|off on禁用Nagle算法
#keepalive_timeout  0;
# HTTP1.1支持持久连接alive
# 降低每个连接的alive时间可在一定程度上提高可响应连接数量,所以一般可适当降低此值
keepalive_timeout  30s;
# 启动内容压缩,有效降低网络流量
gzip on;
# 过短的内容压缩效果不佳,压缩过程还会浪费系统资源
gzip_min_length 1000;
# 可选值1~9,压缩级别越高压缩率越高,但对系统性能要求越高
gzip_comp_level 4;
# 压缩的内容类别
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
# 静态文件缓存
# 最大缓存数量,文件未使用存活期
open_file_cache max=655350 inactive=20s;
# 验证缓存有效期时间间隔
open_file_cache_valid 30s;
# 有效期内文件最少使用次数
open_file_cache_min_uses 2;
server {
listen       80;
server_name  localhost;
#charset koi8-r;
#access_log  logs/host.access.log  main;
location / {
root   html;
index  index.html index.htm;
}
#error_page  404              /404.html;
# redirect server error pages to the static page /50x.html
#
error_page   500 502 503 504  /50x.html;
location = /50x.html {
root   html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
#    proxy_pass   http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
#    root           html;
#    fastcgi_pass   127.0.0.1:9000;
#    fastcgi_index  index.php;
#    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
#    include        fastcgi_params;
#}
# deny access to .htaccess files, if Apache’s document root
# concurs with nginx’s one
#
#location ~ /\.ht {
#    deny  all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
#    listen       8000;
#    listen       somename:8080;
#    server_name  somename  alias  another.alias;
#    location / {
#        root   html;
#        index  index.html index.htm;
#    }
#}
# HTTPS server
#
#server {
#    listen       443 ssl;
#    server_name  localhost;
#    ssl_certificate      cert.pem;
#    ssl_certificate_key  cert.key;
#    ssl_session_cache    shared:SSL:1m;
#    ssl_session_timeout  5m;
#    ssl_ciphers  HIGH:!aNULL:!MD5;
#    ssl_prefer_server_ciphers  on;
#    location / {
#        root   html;
#        index  index.html index.htm;
#    }
#}
}

tomcat的安装

tomcat的运行需要java环境的支持,Oracle提供了2种Linux平台下的jdk,分别是.rpm包和.tar.gz包,前者是一个自动安装程序,后者我们可以自定义配置,推荐使用后者。
linux下jdk的安装

# 解压jdk到指定目录
tar zxvf jdk-8u31-linux-x64.tar.gz -C /opt/
# 配置环境变量(在CentOS中/etc/profile.d/目录中的shell脚本会在系统启动时扫描加载)
vim /etc/profile.d/java.sh
# java.sh的内容如下
JAVA_HOME=/opt/jdk1.8.0_31
PATH=$JAVA_HOME/bin:$PATH
export JAVA_HOME PATH
# 重新加载profile,让环境变量生效
source /etc/profile
# 进入任意目录执行java命令检查配置是否生效
java -version

linux下tomcat的安装

# 下载解压tomcat
wget http://mirrors.hust.edu.cn/apache/tomcat/tomcat-8/v8.0.26/bin/apache-tomcat-8.0.26.tar.gz
tar zvxf apache-tomcat-8.0.26.tar.gz -C /opt/
# 运行tomcat
cd /opt/apache-tomcat-8.0.26/bin/
./startup.sh

注意:和windows版本的tomcat不同的是tomcat启动之后是在后台运行的不会在控制台打印输出,我们可以查看tomcat安装目录下的log/catalina.out文件来获取控制台输出;我们也可以使用tail命令来监控此文件来实时获取服务器的状态:

tail -f /opt/apache-tomcat-8.0.26/logs/catalina.out

配置tomcat开机自启动

编辑/etc/rc.d/rc.local追加:

export JAVA_HOME=/opt/jdk1.8.0_31
export CATALINA_HOME=/opt/apache-tomcat-8.0.26
$CATALINA_HOME/bin/startup.sh

tomcat的优化

tomcat的优化实际上就是合理配置$CATALINA_HOME/bin/catalina.sh和$CATALINA_HOME/conf/server.xml。
catalina.sh配置

# windows下设置方法
#set JAVA_OPTS=%JAVA_OPTS% -server -Xms512m -Xmx512m -XX:PermSize=512M -XX:MaxPermSize=512m
# 通过内存设置充分利用服务器内存
# -server模式启动应用慢,但可以极大程度提高运行性能
# java8开始,PermSize被MetaspaceSize代替,MetaspaceSize共享heap,不会再有java.lang.OutOfMemoryError: PermGen space,可以不设置
# headless=true适用于linux系统,与图形操作有关,如生成验证码,含义是当前使用的是无显示器的服务器,应用中如果获取系统显示有关参数会抛异常
# 可通过jmap -heap proccess_id查看设置是否成功
JAVA_OPTS=” -server -Xms2048m -Xmx2048m -XX:PermSize=256m -XX:MaxPermSize=512m -Djava.awt.headless=true”

server.xml配置

<!– protocol 启用 nio模式,(tomcat8默认使用的是nio)(apr模式利用系统级异步io) –>
<!– minProcessors最小空闲连接线程数–>
<!– maxProcessors最大连接线程数–>
<!– acceptCount允许的最大连接数,应大于等于maxProcessors–>
<!– enableLookups 如果为true,requst.getRemoteHost会执行DNS查找,反向解析ip对应域名或主机名–>
<Connector port=”8080″ protocol=”org.apache.coyote.http11.Http11NioProtocol”
connectionTimeout=”20000″
redirectPort=”8443″
maxThreads=”500″
minSpareThreads=”100″
maxSpareThreads=”200″
acceptCount=”200″
enableLookups=”false”
/>

源码地址
nginx和tomcat的负载均衡

源码地址
nginx是一个反向代理服务器,它的负载均衡也是基于反向代理来实现的,反向代理的原理图如下:

从浏览器角度来看,它并不知道tomcat的存在。

配置nginx将所有请求转交给tomcat
编辑nginx.conf,修改location如下:

location / {
# root   html;
index  index.html index.htm;
proxy_pass http://127.0.0.1:8080;
}

重新加载nginx:./nginx -s reload。如果我们的服务器IP地址是http://192.168.132.144/,我们提交的http://192.168.132.144/test.jsp请求将被替换为http://192.168.132.144:8080/test.jsp.

所谓的负载均衡就是后台有多个应用服务器tomcat(集群),nginx根据一定的策略(默认是平均策略)将请求转发给多个tomcat分担了来自前端的请求——最终多个后台服务器均衡分担了前端的负载。

在http节点中添加tomcat集群:

# tomcat集群
upstream tomcats{
server 127.0.0.1:8080;
server 192.168.132.145:8080;
server 192.168.132.146:8080;
}

配置location为tomcat集群

location / {
# root   html;
index  index.html index.htm;
# 将请求转交给tomcat集群
proxy_pass http://tomcats;
}

nginx的集群配置详解:

# upstream 配置一组后端服务器,
# 请求转发到upstream后,nginx按策略将请求指派出某一服务器
# 即配置用于负载均衡的服务器群信息
upstream backends {
#均衡策略
#none 轮询(权重由weight决定)
#ip_hash
#fair
#url_hash
server 192.168.1.62:8080;
server 192.168.1.63;
# weight:权重,值越高负载越大;
# server 192.168.1.64 weight=5;
# backup:备份机,只有非备份机都挂掉了才启用;
server 192.168.1.64 backup;
# down: 停机标志,不会被访问,主要用于停机维护
server 192.168.1.65 down;
# max_fails:达到指定次数认为服务器挂掉;
# fail_timeout:挂掉之后过多久再去测试是否已恢复
server 192.168.1.66 max_fails=2 fail_timeout=60s;
}

均衡策略

none
nginx缺省的负载均衡策略是平均策略。实际使用中应该使用加权轮询(配置高的服务器得到的请求多),缺省情况下每个serrver的weight = 1.

例如有以下的配置:

server 192.168.61.22 weight = 6; # 60% 请求

server 192.168.61.23 weight = 4; # 40% 请求

ip_hash
根据客户端的IP进行hash运算,产生的效果是如果用户的IP不变每次访问的都是同一台后台服务器。
配置只需要在upstream中加入ip_hash;即可.

第三方策略

fair:自动管理(谁的响应能力强,自动分配更多负载)

url_hash:和IP哈希类似,只不过针对请求的url进行hash(基于缓存的server,页面静态化).

下面以fair模块为例,演示第三方策略的配置:

# 解压
unzip nginx-upstream-fair-master.zip
# 编译nginx的时候指定添加的第三方模块
./configure –prefix=/opt/nginx –add-module=/root/nginx-upstream-fair-master
# 如果是首次安装需要make && make install,已经安装nginx只需要make即可,编译结果在当前目录的objs目录下
make
# 使用objs/nginx 替换原来的nginx
/opt/nginx/sbin/nginx -s stop
cp nginx /opt/nginx/sbin/nginx

负载均衡时session的处理策略

session实际上是tomcat上的一个内存空间,所以在分布式集群的时候session存在一个问题。由于nginx的转发同一个用户的请求可能被转发到不同的Tomcat。

处理方式有以下3种:

粘性session。将用户锁定到特定的tomcat(例如采用ip_hash策略)。优点是简单,但是缺乏容错性,一旦服务器挂掉,用户的请求被转发到其他的tomcat,用户的session丢失。

session复制。当任意一个tomcat的session发生改变,向整个集群发送广播。容错性高,但是网络性能消耗大,性能不高。实现session复制功能需要以下2步:
1.在tomcat的server.xml中开启集群功能(在Engine标签中增加以下代码):

<Cluster className=”org.apache.catalina.ha.tcp.SimpleTcpCluster”/>
<!– 基于网络广播的策略,一个节点session变化,其它节点同步复制,节点多或数据量大时性能低下 –>
<Cluster className=”org.apache.catalina.ha.tcp.SimpleTcpCluster”>
<Channel className=”org.apache.catalina.tribes.group.GroupChannel”>
<!–
1.tomcat集群的端口冲突问题。例如同一台服务器运行多个tomcat。
2.服务器一般有多块网卡(内网和外网),tomcat都应该使用内网网卡
–>
<Receiver className=”org.apache.catalina.tribes.transport.nio.NioReceiver”
address=”auto”
port=”4000″  />
</Channel>
</Cluster>

2.修改应用的部署描述符web.xml告诉tomcat该应用支持分布式。在web-app标签下新增<distributable/>.

额外创建一个共享的空间用来存放session。我们需要借助一个分布式缓存,例如memcached、redis。

下面介绍使用memcached来管理分布式缓存。

memchched的安装依赖于libevent.

## 安装libevent
# 下载libevent
wget https://sourceforge.net/projects/levent/files/libevent/libevent-2.0/libevent-2.0.22-stable.tar.gz
# 解压
tar zxvf libevent-2.0.22-stable.tar.gz
cd libevent-2.0.22-stable/
# configure
./configure -prefix=/opt/libevent
# 编译和编译安装
make && make install
## 安装memcached
wget http://www.memcached.org/files/memcached-1.4.24.tar.gz
tar axvf memcached-1.4.24.tar.gz
cd memcached-1.4.24/
./configure –prefix=/opt/memcached –with-libevent=/opt/libevent
make && make install
## 启动分布式缓存(后台进程,以root用户,监听11211端口,使用内存128M,最大支持1024连接)
cd /opt/memcached/bin
./memcached -d -u root -p 11211 -m 128 -c 1024

所有的memcached服务器是同步的。
使用memcached管理session的工作原理(粘性session):

以tomcat为主存储,将session的变更存储到memcached中,一旦1tomcat down,就从memcached2中取出session推送到tomcat2.

使用memcached管理session的工作原理(非粘性session):
tomcat本身并不存储session,每次从共享的memcached中读写。

配置memcached:

复制jar包到tomcat/lib目录,jar分三类
1)spymemcached.jar memcached java客户端
2)msm相关的包
memcached-session-manager-{version}.jar 核心包
memcached-session-manager-tc{tomcat-version}-{version}.jar Tomcat版本相关的包
3)序列化工具包,有多种可选方案,不设置时使用jdk自带序列化,其它可选kryo,javolution,xstream,flexjson等
msm-{tools}-serializer-{version}.jar
其它序列化工具相关包 一般第三方序列化工具不需要实现serializable接口

配置Context,加入处理session的Manager MemcachedBackupSessionManager Context配置查找顺序:1)conf/context.xml 全局配置,作用于所有应用
2) conf/[enginename]/[hostname]/context.xml.default 全局配置,作用于指定host下全部应用
3) conf/[enginename]/[hostname]/[contextpath].xml 只作用于contextpath指定的应用
4) 应用META-INF/context.xml 只作用于本应用
5) conf/server.xml 下 作用于Context docBase指定的应用 所以,只希望session管理作用于特定应用,最好用3,4方式设置,希望作用全体,可用1,2,5设置。

Context.xml的配置如下:

<?xml version=”1.0″ encoding=”UTF-8″?>
<Context>
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
<!– sticky session 最小配置–>
<!– className 管理器类名 –>
<!– memcachedNodes memcached服务器节点,以节点名:主机:端口形式表示,其中节点名随意命名,但不同tomcat间要一致 –>
<!– sticky隐含默认值为true,此时为sticky session模式 –>
<!– failoverNodes 仅适用于sticky模式, n1表示主要将session备份到n2,如果n2不可用,再用n1–>
<!– 另一台服务器配置正好相反,这样保证将session保存到其它机器,避免整个机器崩溃时tomcat与session一起崩溃–>
<Manager className=”de.javakaffee.web.msm.MemcachedBackupSessionManager”
memcachedNodes=”n1:192.168.1.62:11211,n2:192.168.1.63:11211″
failoverNodes=”n1″
/>
<!– 经常用到的生产环境sticky模式配置 –>
<Manager className=”de.javakaffee.web.msm.MemcachedBackupSessionManager”
memcachedNodes=”n1:192.168.1.62:11211,n2:192.168.1.63:11211″
failoverNodes=”n1″
requestUriIgnorePattern=”.*\.(jpg|png|css|js)$”
memcachedProtocol=”binary”
transcoderFactoryClass=”de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory”
/>
<!– 经常用到的生产环境non-sticky模式配置 –>
<Manager className=”de.javakaffee.web.msm.MemcachedBackupSessionManager”
memcachedNodes=”n1:192.168.1.62:11211,n2:192.168.1.63:11211″
sticky=”false”
sessionBackupAsync=”false”
lockingMode=”auto”
requestUriIgnorePattern=”.*\.(jpg|png|css|js)$”
memcachedProtocol=”binary”
transcoderFactoryClass=”de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory”
/>
<!–
<Manager className=”de.javakaffee.web.msm.MemcachedBackupSessionManager”
memcachedNodes=”n1:192.168.1.62:11211,n2:192.168.1.63:11211″
#sticky模式,默认true
sticky=”false”
#仅适用于sticky模式,n1表示主要将session备份到n2,如果n2不可用,再用n1
failoverNodes=”n1″
#忽略的请求类型,这些类型请求不处理session
requestUriIgnorePattern=”.*\.(jpg|png|css|js)$”
#例如context中设置sessionPath=/时,一个host下多个应用可能有相同session_id,
#此时向memcached写入时会造成混乱,可通过以下方式加前缀区分不同应用
storageKeyPrefix=”static:name|context|host|webappVersion|context.hash|host.hash|多项组合,以,间隔”
#设置mecached协议数据传输方式,默认text,设为binary有助力性能提升
memcachedProtocol=”binary”
#是否异步存储session变化,默认true,性能好,适用于sticky模式,
#non-sticky时建议设置为false,避免延迟造成信息不一致
sessionBackupAsync=”false”
#仅适用于non-sticky模式,为避免同步编辑冲突,在修改session时锁定
#同步编辑一种可能发生的情况是在ajax请求时,同一页多个请求同时发起,可能会访问不同后端
#auto 读模式不锁写模式锁
#uriPattern模式,将URI+”?”+queryString与模式Regex匹配,如果匹配则锁定
lockingMode=”none|all|auto|uriPattern:Regex”
#使用第三方序列化工具,提高序列化性能
#常用的第三方工具kryo, javolution, xstream等
#此时需要向tomcat/lib下添加相关jar包
transcoderFactoryClass=”de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory”
/>
–>
</Context>

集群环境中应用代码应该注意的问题

实体类必须是可序列化的(Serialable接口)

使用request.getRemoteAddr()方法获取的是nginx代理的地址,如果需要知道客户端的IP,需要在nginx中设置代理的头信息。

location / {
# root   html;
index  index.html index.htm;
# 将请求转交给tomcat集群
proxy_pass http://tomcats;
# 设置代理的头信息
proxy_set_header X-Real-IP $remote_addr;
}

在我们的应用中可以这样获取客户端的真实IP:

public class RealGetter{
/**
* 有X-Real-IP头,就获取X-Real-IP,否则request.getRemoteAddr()
*/
public String getIP(HttpServletRequest request){
String remoteIP = request.getRemoteAddr();
String headIP = request.getHeader(‘X-Real-IP’);
return headIP == null ? remoteIP : headIP;
}
}

常见问题以及解决方案

本机可以访问,而无法远程访问。
此种情况多数是由于防火墙设置不当或者启用了SELinux,我们可以执行以下的命令。

# 清除所有规则

iptables -F

# 重启iptables

service iptables restart

关闭SELinux

vim /etc/selinux/config

#SELINUX=enforcing #注释掉

#SELINUXTYPE=targeted #注释掉

SELINUX=disabled #增加

setenforce 0 #使配置立即生效

转载请注明:XAMPP中文组官网 » Linux下nginx与Tomcat的配置和优化