Tomcat优化
Tomcat是java开发的应用程序,作用:作为web服务器处理html页面,但能力一般,更多的用于jsp、servlet容器处理java开发的jsp动态页面。
组织架构:连接器 、 容器
连接器:暴露端口,接受请求
容器:分为四个子容器
Tomcat使用最多的是8核16G,8核16G这个偏向与中大型web服务器/应用类部署。Tomcat适合中低配2核4G或者4核8G。因为Tomcat是单进程多线程的模式,是个轻量级且并发求请求数最多只能跑到1000左右。所以单台高配置的Tomcat的服务器并不能跑满服务器性能,会造成很大资源浪费。如果想跑满,常规做法是一台服务器上部署多个Tomcat。
CPU与内存资源配比1:4
Tomcat配置 JVM 参数:
环境规格以 2C4G为例
配置添加在Tomcat的bin目录下的 catalina.sh中,位置在 cygwin=false前(119行前)。
JAVA_OPTS="$JAVA_OPTS -server -Xms2048m -Xmx2048m -Xmn768m -Xx:ParallelGCThreads=2 -XX:PermSize=1024m -XX:MaxPermSize=1024m -Djava.awt.headless=true -XX:+DisableExplicitGC"
参数说明:
-server:一定要作为第一个参数,只要 Tomcat 是运行在生产环境中,这个参数必须给加上,不然后面的参数不会生效 。多个CPU性能佳。
-Xms:表示 Java 初始化堆的大小,-Xms 与-Xmx 设成一样的值,避免 JVM 反复重新申请内存,导致性能大起大落,默认值为物理内存的 1/64
-Xmx:表示最大 Java 堆大小,当应用程序需要的内存超出堆的最大值时虚拟机就会提示内存溢出,并且导致应用服务崩溃,因此一般建议堆的最大值设置为物理内存的最大值的 50%。
默认(MinHeapFreeRatio参数可以调整)空余堆内存小于 40%时,JVM 就会增大堆直到 -Xmx 的最大限制。。因此建议-Xms与-Xmx设成一样的值,均设为物理内存的一半。其目的是为了避免在java每次GC(垃圾回收机制清理堆区)后需要重新调整堆的大小而浪费资源。
-Xmn:新生代的内存空间大小,注意:此处的大小是(eden+ 2 survivor space)。与 jmap-heap 中显示的 New gen 是不同的。整个堆大小 = 新生代大小 + 老生代大小 + 永久代大小。在保证堆大小不变的情况下,增大新生代后,将会减小老生代大小。此值对系统性能影响较大,Sun 官方推荐配置为整个堆的 3/8。
堆区进一步细化分为:新生代、中生代、老生代
java中每new一个对象所占用的内存空间就是新生代的空间,当java垃圾回收机制对堆区进行资源回收后,那些新生代中没有被回收的资源将被转移到中生代,中生代被转移到老生代。
整个JVM堆大小=新+老+永久
-XX:ParallelGCThreads 参数的值来计算出默认的并行 CMS 线程数。
-XX:ParallelGCThreads:配置并行收集器的线程数,即:同时有多少个线程一起进行垃圾回收,此值建议配置与 CPU 数目相等。
-Djava.awt.headless=true:免避在Linux/Unix环境下Web网页不能正常显示图片
-XX:+DisableExplicitGC:禁止调用System.gc( ),防止误调用gc方法导致系统的JVM大起大落而使系统响应时间变慢。
tomcat程序优化:线程 、 UI字符集编码 、关闭反向解析、控制最大线程数、等待队列数、进程缓存、连接超时、最大请求数量
JVM优化:-server -xms -xmx -XX:PermSize -XX:MaxPermSize -ParallelGCThreads
Nginx+Tomcat负载均衡、动静分离群集
bin:存放启动和关闭Tomcat脚本
conf:存放Tomcat不同的配置文件
webapps:Tomcat的主要Web发布目录
Nginx:优秀的HTTP服务器软件,有强大的静态资源处理能力,运行稳定,内存、CPU等系统资源消耗非常低。理论上支持高达50000个并发连接数的响应。
Nginx配置反向代理的主要参数:
- upstream 服务池名{ }
配置后端服务器池,以提供响应数据。
- proxy_pass http://服务池名
配置将访问请求转发给后端服务器池的服务器处理
动静分离原理:
服务端接收来自客户端的请求,既有静态资源也有动态资源,静态资源由Nginx提供服务,动态资源由Nginx转发至后端。
Nginx静态处理优势
Nginx处理静态页面的效率远高于Tomcat的处理能力
若Tomcat的请求量为1000次,则Nginx的请求量为6000次。
Tomcat每秒的吞吐量为0.6M,则Nginx的每秒吞吐量为3.6M
Nginx处理静态资源的能力是Tomcat的六倍
nginx.conf配置:
#gzip on;
upstream tomcat_servers {
server 192.168.179.21:8080 weight=1;
server 192.168.179.21:8081 weight=1;
server 192.168.179.22:8080 weight=1;
}
weight权重,默认为1
对于动态页面请求的location:
location ~* *\.jsp$ {
proxy_pass http://tomcat_servers;
#用于后端服务器获取真实的客户端IP地址
proxy_set_header HOST $host;
proxy_set_header X-Real-IP $remote_addr
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Nginx负载均衡模式:
▲rr 负载均衡模式(轮询模式):
每个请求安时间顺序逐一分配到不同的后端服务器,如果超过了最大失败次数后(max_fails,默认1),在时效时间内(fail_timeout,默认10秒),该节点失效权重变为0,超过失效时间后,则恢复正常,或者全部节点都为down后,那么将所有节点都恢复为有效继续探测,一般来说rr可以根据权重来进行均匀分配。
▲least_conn最少连接:
优先将客户端请求调度到当前连接最少的服务器
ip_hash 负载均衡模式:
每个请求按访问IP的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题,但是ip_hash会造成负载不均,有的服务请求接受多,有的服务请求接受少,所以不建议采用ip_hash模式,session 共享问题可用后端服务的session共享代替nginx的ip_hash(使用后端服务器自身通过相关机制保持session同步)
▲fair(第三方)负载均衡模式:
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
url_hash(第三方)负载均衡模式:
基于用户请求的uri做hash。和ip_hash算法类似,是对每个请求按url的hash结果分配,使每个URL定向到同一个后端服务器,但是也会造成分配不均的问题,这种模式后端服务器为缓存时比较好。
sticky_cookie_insert:
使用sticky_cookie_insert启用会话亲缘关系,这会导致来自同一客户端的请求被传递到一组服务器在同一台服务器。与ip_hash不同之处在于,它不是基于IP来判断客户端的,而是基于cookie来判断。因此可以避免上述ip_hash中来自同一局域网的客户端和前段代理导致负载失衡的情况。
语法格式:
upstream tomcat_servers {
server tomcat_servers1.example.com;
server tomcat_servers2.example.com;
sticky_cookie_insert srv_id expires=1h domain=xny.com path=/;
}
- expires:设置浏览器中保持cookie的时间
- domain:定义cookie的域
- path:为cookie定义路径
总结;
nginx 动静分离 通过 反向代理实现的
反向代理模式分为两种:
七层反向代理:
http {
upstream 服务器组名称 {
server IP1:PORT [weight=1 ...];
server IP2:PROT;
.......
调度算法(rr轮询/加权轮询、least_conn最小链接、ip_hash、url_hash、fair);
}
server {
location ~ ... {
proxy_pass http://服务器组名称;
proxy_set_header HOST $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_fowarded_for;
}
}
}
四层反向代理:
配置 --with-stream 模块
http模块上面添加同一级别的stream模块(nginx tomcat都关闭长连接)
stream {
upstream appserver {
server 192.168.179.21:8080;
server 192.168.179.21:8081;
server 192.168.179.24:8080;
}
server {
listen 8080;
proxy_pass appserver;
}
}
基于7层的http/https/mail等应用协议的代理
基于4层的IP+tcp或udp端口的代理
实验:四层与七层结合部署达到负载均衡动静分离效果
根据图示,先部署环境,三台nginx三台tomcat,其中两台tomcat我在同一台虚拟机上部署
先部署四层反向代理nginx服务器:
需要重新编译,添加 --with-stream
cd /usr/local/nginx/conf/
vim nginx.conf
events {
worker_connections 1024;
}
stream{
upstream web_server {
server 192.168.179.20:80;
server 192.168.179.22:80;
}
server {
listen 80;
proxy_pass web_server;
}
}
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"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 81;
server_name localhost;
#charset koi8-r;
如果使用80端口,需要将下面localhost端口改为80之外的端口,这里设为81.
下面部署两台七层反向代理:
cd /etc/nginx/conf.d/
vim default.conf
upstream tomcat_server {
server 192.168.179.21:8080;
server 192.168.179.21:8081;
server 192.168.179.23:8080;
}
server {
listen 80;
server_name localhost;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location ~* .*\.jsp$ {
proxy_pass http://tomcat_server;
proxy_set_header HosT $host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
#error_page 404 /404.html;
创建静态网页、动态网页;
在tomcat中创建动态网页 :
cd /usr/local/tomcat/webapps/
vim index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head>
<title>JSP test1 page</title>
</head>
<body>
<% out.println("动态页面 1,http://www.test1.com");%>
</body>
</html>
在nginx中创建静态网页:
cd /usr/share/nginx/html
vim index.html
<html>
<body>
<h1>this is nginx1 test web!</h1>
</body>
</html>
进行测试:
静态:
因为keepalive_timeout 65;所以这里要等待65s才会更新;
修改timeout: vim /etc/nginx/nginx.conf 或 vim /usr/local/nginx/conf/nginx.conf 中的 keepalive_timeout 0;
动态:
complete!
tomcat配置部署:
systemctl stop firewalld
setenforce 0
tar zxvf jdk-8u91-linux-x64.tar.gz -C /usr/local/
vim /etc/profile
export JAVA_HOME=/usr/local/jdk1.8.0_91
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:${JRE_HOME}/bin:$PATH
source /etc/profile
tar zxvf apache-tomcat-8.5.16.tar.gz
mv /opt/apache-tomcat-8.5.16/ /usr/local/tomcat
/usr/local/tomcat/bin/shutdown.sh
/usr/local/tomcat/bin/startup.sh
netstat -ntap | grep 8080
3.动静分离配置
(1)Tomcat1 server 配置
mkdir /usr/local/tomcat/webapps/test
vim /usr/local/tomcat/webapps/test/index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head>
<title>JSP test1 page</title> #指定为 test1 页面
</head>
<body>
<% out.println("动态页面 1,http://www.test1.com");%>
</body>
</html>
vim /usr/local/tomcat/conf/server.xml
#由于主机名 name 配置都为 localhost,需要删除前面的 HOST 配置
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
<Context docBase="/usr/local/tomcat/webapps/test" path="" reloadable="true">
</Context>
</Host>
/usr/local/tomcat/bin/shutdown.sh
/usr/local/tomcat/bin/startup.sh
netstat -lntp | grep java #检查是否开启
------主要目录说明----------------------------------------------------------------------------------------------
●bin:存放启动和关闭 Tomcat 的脚本文件,如 catalina.sh、startup.sh、shutdown.sh
●conf:存放 Tomcat 服务器的各种配置文件,如主配置文件 server.xml 和 应用默认的部署描述文件 web.xml
●lib:存放 Tomcat 运行需要的库文件的 jar 包,一般不作任何改动
●logs:存放 Tomcat 执行时的日志
●temp:存放 Tomcat 运行时产生的文件
●webapps:存放 Tomcat 默认的 Web 应用项目资源的目录
●work:Tomcat 的工作目录,存放 Web 应用代码生成和编译文件
----------------------------------------------------------------------------------------------------------