DAY53 tomcat服务配置优化

264 阅读9分钟

什么是Tomcat

Tomcat是Java 语言开发的,Tomcat 服务器是一个免费的开放源代码的Web应用服务器,是Apache 软件基金会的 Jakarta 项目中的一个核心项目,由Apache、Sun和其他一些公司及人共同开发而成。

Tomcat属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试 JSP 程序的首选。一般来说,Tomcat 虽然和Apache 或者Nginx这些Web服务器一样,具有处理HTML页面的功能,然而由于其处理静态HTML的能力远不及Apache 或者Nginx,所以Tomcat 通常是作为一个Servlet 和 JSP 容器,单独运行在后端。

  • 免费的、开放源代码的Web应用服务器
  • Apache软件基金会(Apache Software Foundation)Jakarta项目中的一个核心项目
  • 由Apache、Sun和一些公司及个人共同开发而成
  • 深受Java爱好者的喜爱,并得到部分软件开发商的认可
  • 目前比较流行的Web应用服务器

Tomcat核心组件

Tomcat核心组件有三个:

Tomcat由一系列的组件构成,其中核心的组件有三个:

(1)web容器: 完成Web服务器的功能。

(2)Servlet 容器: 名字为catalina,用于处理Servlet 代码。

(3)JSP容器: 用于将JSP动态网页翻译成Servlet 代码。

因此Tomcat 是Web 应用服务器,也是一个Servlet/JSP 容器。Tomcat 作为Servlet容器,负责处理客户请求,把请求传送给Servlet,并将Servlet的响应传送回给客户。

image.png

什么是servlet? (用来实现用Java语言开发的动态页面逻辑)

  • Servlet是 Java Servlet的简称,可以理解为是一一个服务连接器,是用Java编写的服务器端程序,具有独立于平台和协议的特性。
  • 简单的理解:servlet 就是一 个中间件,包含了接口和方法,将客户端和数据库连接,从而实现动态网页的创建。

什么是JSP?

  • JSP全称Java Server Pages, 是一种动态网页开发技术。|它使用JSP 标签在HTML网页中插入Java 代码。标签通常以<%开头,以%>结束。
  • JSP是一种Java servlet,主要用于实现Java web应用程序的用户界面部分。
  • JSP通过网页表单获取用户输入数据、访问数据库及其他数据源,然后动态地创建网页。

image.png

Tomcat 功能组件结构

Tomcat 的核心功能有两个,分别是负责接收和反馈外部请求的连接器Connector, 和负责处理请求的容器Container。

其中连接器和容器相辅相成,一起构成了基本的web服务Service。每个Tomcat服务器可以管理多个Service。

Tomcat 功能组件结构

  • Connector: 负责对外接收和响应请求。它是Tomcat与外界的交通枢细,监听端口接收外界请求,并将请求处理后传递给容器做业务处理,最后将容器处理后的结果响应给外界。

  • Container: 负责对内处理业务逻辑。其内部由Engine、 Host、Context和wrapper 四个容器组成,用于管理和调用Servlet 相关逻辑。

  • Service: 对外提供的Web服务。主要包含Connector 和Container 两个核心组件,以及其他功能组件。Tomcat 可以管理多个Service, 且各Service之间相互独立。

    (一个service就是一个外部应用,各个service之间是相互独立的,每个service可以监听不同的端口号)

Container结构分析:

每个Service 会包含一一个Container 容器。在Container 内部包含了4个子容器: 4个子容器的作用分别是:

(1) Engine: 引擎,用来管理多个虚拟主机,一个Service最多只能有一一个Engine;

(2) Host: 代表一个虚拟主机,也可以叫站点,通过配置Host就可以添加站点;

(3) Context: 代表一个Web应用,包含多个Servlet 封装器;

(4) wrapper: 封装器,容器的最底层。每一Wrapper 封装着一个servlet, 负责对象实例的创建、执行和销毁功能。

Engine、Host、Context 和Wrapper,这四个容器之间属于父子关系。

容器由一个引擎可以管理多个虚拟主机。每个虚拟主机可以管理多个web应用。每个Web

image.png

Tomcat请求过程

  1. 用户在浏览器中输入网址,请求被发送到本机端口8080, 被在那里监听的Connector 获得。
  2. Connector 把该请求交给它所在的Service 的Engine (Container) 来处理,并等待Engine 的回应。
  3. 请求会在Engine、 Host、 Context 和wrapper 这四个容器之间层层调用,最后在Servlet 中执行对应的业务逻辑、数据存储等。
  4. 执行完之后的请求响应在Context、 Host、 Engine 容器之间层层返回,最后返回给Connector,并通过Connector 返回给客户端。

image.png

Tomcat的端口和主要目录说明

Tomcat端口

客户端和tomcat进行连接时使用:

  • 8080端口:http的默认端口
  • 8443端口:https的默认端口

8005端口: shutdown用于关闭tomcat进程。tomcat监听的关闭端口,就是说这个端口负责监听关闭tomcat的请求。

8009端口: 用于转发,负责和其他http服务器建立连接。但一般不用,因为tomcat一般放在后端服务器,其他服务器转发给tomcat。

Tomcat主要目录

ls /usr/local/tomcat/

目录说明
bin存放启动和关闭Tomcat 的脚本文件,如catalina.sh、startup.sh、shutdown.sh
conf存放Tomcat 服务器的各种配置文件,如主配置文件server.xml 和应用默认的部署描述文件web.xml
lib存放Tomcat运行需要的库文件的jar 包,一般不作任何改动
logs存放Tomcat 执行时的日志
temp存放Tomcat 运行时产生的文件
webapps存放Tomcat默认的web应用项目资源的目录
workTomcat 的工作目录,存放web应用代码生成和编译文件

Tomcat 部署步骤

在部署 Tomcat 之前必须安装好 jdk,因为Tomcat是采用Java语言编写的,而jdk是java的开发工具,没有jdk,Tomcat是跑不起来的,所以 jdk 是 Tomcat 运行的必要环境。

官网下载JDK的安装包以及Tomcat的安装包

下载并安装 JDK

image.png

image.png

image.png

image.png

部署Tomcat服务

在部署Tomcat之前必须安装好jdk,因为jdk是Tomcat运行的必要环境。

image.png

image.png

image.png

image.png

优化tomcat启动速度

第一次启动tomcat可能会发现Tomcat启动很慢,如果/dev/random中的随机数不足,默认情况下可能会需要几十秒,可以修改jdk参数进行改。

/dev/urandom,它可以作为生成较低强度密码的伪随机数生成器,不建议用于生成高强度长期密码

vim /usr/java/jdk1.8.0_201-amd64/jre/lib/security/java.security
 --117行--修改这一行
 securerandom.source= file:/dev/urandom

image.png

Tomcat虚拟主机配置

可能有时候公司会有多个项目需要运行,那么肯定不可能是一台服务器上运行多个Tomcat 服务,这样会消耗太多的系统资源。此时,就需要使用到 Tomcat 虚拟主机。

创建zjl和zjl2项目目录和文件

image.png

修改Tomcat主配置文件server.xml\

vim /usr/local/tomcat/conf/server.xml

image.png

image.png

将映射关系写入/etc/hosts 文件中

image.png

 访问测试

image.png

image.png

HTTP 请求过程:

(1)Connector 连接器监听的端口是 8080。由于请求的端口和监听的端口一致,连接器接受了该请求。

(2)因为引擎的默认虚拟主机是 www.yuji.com ,并且虚拟主机的目录是webapps。所以请求找到了 tomcat/webapps 目录。

(3)访问的路径为根路径,URI 为空,即空是 Web 程序的应用名,也就是 context。此时请求找到 /usr/local/tomcat/webapps/yuji 目录,解析 index.jsp 并返回。

Tomcat优化

Tomeat默认安下的缺省配置并不适合生产环境,可能会频繁出现假死现象需要重启,只有通过不断压测优化才能让它最高效率稳定的运行。

优化主要包括三方面,分别为操作系统优化(内核参数优化)  ,Tomcat配置文件参数优化Java虚拟机(JVM))调优

操作系统优化(内核参数优化)

通过内核对TCP的连接实现优化:TCP连接数优化,time_wait的优化

Tomcat配置文件参数优化

Apache和Nginx是通过进程处理接收的每个请求,Tomcat是通过线程来处理接收的每个请求。

可使用 ps -aT | grep java 查看tomcat线程。

vim /usr/local/tomcat/conf/server.xml
 ......
 <Connector port="8080" protocol="HTTP/11.1" 
 connectionTimeout="20000" 
 redirectPort="8443" 
 --71行--插入以下参数
 minSpareThreads="50" 
 enableLookups="false" 
 disableUploadTimeout="true" 
 acceptCount="300" 
 maxThreads="500" 
 processorCache="500"
 URIEncoding="UTF-8"              #字符集
 maxKeepAliveRequests="100"       #最大长连接数
 compression="on" 
 compressionMinSize="2048" 
 compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain,image/gif,image /jpg,image/png"/>

Java虚拟机(JVM)调优

.bat 是在windows系统中运行的脚本

.sh 是在Linux系统中运行的脚步。

Tomcat 配置 JVM 参数:

环境规格以 2C4G 为例。

配置添加在 Tomcat 的 bin 目录下 catalina.sh 里,位置在 cygwin=false 前。

vim /usr/local/tomcat/bin/catalina.sh
 ​
 JAVA_OPTS="$JAVA_OPTS -server -Xms2048m -Xmx2048m -Xmn768m -XX:ParallelGCThreads=2 -XX:PermSize=1024m -XX:MaxPermSize=1024m -Djava.awt.headless=true -XX:+DisableExplicitGC" 
 cygwin=false

Nginx+Tomcat负载均衡、动静分离

image.png

image.png

image.png

standalone模式,Tomcat单独运行,直接接受用户的请求,不推荐。

反向代理,单机运行,提供了一个Nginx作为反向代理,可以做到静态由nginx提供响应,动态jsp

代理给Tomcat

LNMT:Linux + Nginx + MySQL + Tomcat

LAMT:Linux + Apache(Httpd)+ MySQL + Tomcat

前置一台Nginx,给多台Tomcat实例做反向代理和负载均衡调度,Tomcat上部署的纯动态页面更

适合

LNMT:Linux + Nginx + MySQL + Tomcat

多级代理

LNNMT:Linux + Nginx + Nginx + MyS

动态服务器的问题,往往就是并发能力太弱,往往需要多台动态服务器一起提供服务。如何把并发的压力分摊,这就需要调度,采用一定的调度策略,将请求分发给不同的服务器,这就是Load Balance负载均衡。

当单机Tomcat,演化出多机多级部署的时候,一个问题便凸显出来,这就是Session。而这个问题的由来,都是由于HTTP协议在设计之初没有想到未来的发展。

部署Nginx 负载均衡器

环境简介:

ngnix:192.168.184.103

tomcat1:192.168.184.102:8080|192.168.184.102:8081

tomcat2: 192.168.59.104

部署Nginx 负载均衡器

1. #关闭防火墙
systemctl stop firewalld
setenforce 0
​
2. #安装依赖关系包
yum -y install pcre-devel zlib-devel gcc gcc-c++ make
​
3. #新建用户和组便于管理
useradd -M -s /sbin/nologin nginx
​
4. #切换至opt目录,将下载好的压缩包传进来解压
cd /opt
tar -zxf nginx-1.12.0.tar.gz 
​
4. #切换至解压后的目录下编译
cd nginx-1.12.0
​
./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_stub_status_module
​
5. #安装
make && make install -j4
​
6. #做软连接,让系统识别nginx的操作命令
ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/
​
7. #将nginx命令加入服务
cd /lib/systemd/system
vim nginx.service
#!/bin.bash
[Unit]
Description=nginx
After=network.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/bin/kill -s HUP $MAINPID
ExecStop=/usr/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
​
8. #重新加载单元.启动服务
systemctl daemon-reload 
systemctl start nginx
​
9. #查看是否成功启动
ss -ntap|grep nginx
http://192.168.184.103/

部署第一台Tomcat

1. #关闭防火墙
systemctl stop firewalld
setenforce 0
​
2. #切换至/opt,将安装 Tomcat 所需软件包传到/opt目录下
apache-tomcat-9.0.16.tar.gz 
jdk-8u201-linux-x64.rpm
​
3. #安装JDK
rpm -ivh jdk-8u201-linux-x64.rpm 
​
4. #修改环境变量配置文件
vim /etc/profile
export JAVA_HOME=/usr/java/jdk1.8.0_201-amd64
export CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar
export PATH=$JAVA_HOME/bin:$PATH
​
5. #刷新配置文件
source /etc/profile
​
6. #切换至/opt下,解压tomcat包
cd /opt
tar -zxf apache-tomcat-9.0.16.tar.gz 
​
7. #将解压后的包拷贝至/usr/local/下并重命名
cp -r apache-tomcat-9.0.16 /usr/local/tomcat
​
8. #添加用户设置属主属组
useradd -s /sbin/nologin tomcat
chown tomcat:tomcat /usr/local/tomcat -R
​
​
9. #新建服务文件
vim /etc/systemd/system/tomcat.service
[Unit]
Description=Tomcat
#After=syslog.target network.target remote-fs.target nss-lookup.target
After=syslog.target network.target
​
[Service]
Type=forking
ExecStart=/usr/local/tomcat/bin/startup.sh
ExecStop=/usr/local/tomcat/bin/shutdown.sh
RestartSec=3
PrivateTmp=true
User=tomcat
Group=tomcat
​
[Install]
WantedBy=multi-user.target
​
10. #重新加载服务,并开启,查看是否成功启动
​
systemctl daemon-reload
systemctl start tomcat
ss -ntap |grep 8080
​
​
​
#############新建动态页面站点###########3
​
11. #切换至webapp下,新建test目录
cd /usr/local/tomcat/webapps/
mkdir test
​
12. #建立动态页面文件
vim test/index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
  <head>
     <title>JSP test2 page </title>
  </head>
  <body>
     <% out.println("动态页面2,http://www.test2.com");%>
  </body>
</html>
​
13. #修改主配置文件
vim /usr/local/tomcat/conf/server.xml
删除原来的站点模块
添加
<Host name="localhost" appBase="webapps"
            unpackWARs="true" autoDeploy="true" xmlValidation="false"
            xmlNamespaceAware="false">
                <Context docBase="/usr/local/tomcat/webapps/test"
                path="" reloadable="true" />
      </Host>
​
​
14. #重启服务,并在网页测试
systemctl restart tomcat.service 
http://192.168.184.104:8080/

image.png

部署第二台Tomcat

1. #关闭防火墙
systemctl stop firewalld
setenforce 0
​
2. #切换至/opt,将安装 Tomcat 所需软件包传到/opt目录下
apache-tomcat-9.0.16.tar.gz 
jdk-8u201-linux-x64.rpm
​
3. #安装JDK
rpm -ivh jdk-8u201-linux-x64.rpm 
​
4. #修改换将变量配置文件
vim /etc/profile
export JAVA_HOME=/usr/java/jdk1.8.0_201-amd64
export CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar
export PATH=$JAVA_HOME/bin:$PATH
​
5. #刷新配置文件
source /etc/profile
​
6. #切换至/opt下,解压tomcat包
cd /opt
tar -zxf apache-tomcat-9.0.16.tar.gz 
​
7. #将解压后的包拷贝至/usr/local/下并重命名
cp -r apache-tomcat-9.0.16 /usr/local/tomcat
​
8. #添加用户设置属主属组
useradd -s /sbin/nologin tomcat
chown tomcat:tomcat /usr/local/tomcat -R
​
​
9. #新建服务文件
vim /etc/systemd/system/tomcat.service
[Unit]
Description=Tomcat
#After=syslog.target network.target remote-fs.target nss-lookup.target
After=syslog.target network.target
​
[Service]
Type=forking
ExecStart=/usr/local/tomcat/bin/startup.sh
ExecStop=/usr/local/tomcat/bin/shutdown.sh
RestartSec=3
PrivateTmp=true
User=tomcat
Group=tomcat
​
[Install]
WantedBy=multi-user.target
​
10. #重新加载服务,并开启,查看是否成功启动
​
systemctl daemon-reload
systemctl start tomcat
ss -ntap |grep 8080
​
​
​
#############新建动态页面站点###########3
​
11. #切换至webapp下,新建test目录
cd /usr/local/tomcat/webapps/
mkdir test
​
12. #建立动态页面文件
vim test/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>
​
13. #修改主配置文件
vim /usr/local/tomcat/conf/server.xml
删除原来的站点模块
添加
<Host name="localhost" appBase="webapps"
            unpackWARs="true" autoDeploy="true" xmlValidation="false"
            xmlNamespaceAware="false">
                <Context docBase="/usr/local/tomcat/webapps/test"
                path="" reloadable="true" />
      </Host>
​
​##我们可以给这一台Tomcat做一个多实例,只需要动态页面多创建一个tomcat2,这里不再演示


14. #重启服务,并在网页测试
systemctl restart tomcat.service 
http://192.168.184.102:8080/

我们测试一下

image.png

image.png

nginx 配置

1. #切换至/usr/local/nginx/html/目录下
cd /usr/local/nginx/html/
​
2. #创建test文件夹,并在里面创建静态网页
mkdir test
cd test
vim test.html
this is static test web !!
​
3. #拖一张图片至test下改名为1.jpg
mv 1.jfif 1.jpg
​
4. #配置主配置文件
vim /usr/local/nginx/conf/nginx.conf
​
#配置负载均衡服务器列表,weight参数表示权重,权重越高,被分配到的概率越大  
#gzip  on;  
    upstream tomcat_server {
                    server 192.168.59.105:8080 weight=1;
                    server 192.168.59.118:8080 weight=1;
                 
                    }
                    
                    
#动静分离
 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;
     }
​
#静态图片正则
         location ~* .*\.(jpg|html|png|gif)$ {
         root /usr/local/nginx/html/test;
     }
​
​
         location / {
            root   html;
            index  index.html index.htm;
     }
​
​
​
5.  #重启nginx并测试
http://192.168.184.103/1.jpg
http://192.168.184.103/test.html

image.png

image.png

image.png

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定向到同一个后端服务器,但是也会造成分配不均的问题,这种模式后端服务器为缓存时比较好。