1.Tomcat是Java语言开发的,Tomcat服务器是一个免费的开放源代码的Web应用服务器,是Apache软件基金会的Jakarta项目中的一个核心项目,由Apache、Sun和其他一些公司及个人共同开发而成
2.Tomcat属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP程序的首选
3.一般来说,Tomcat虽然和Apache或者Nginx这些Web服务器一样,具有处理HTML页面的功能,然而由于其处理静态HTML的能力远不及Apache或者Nginx,所以Tomcat通常是作为一个Servlet和JSP容器,单独运行在后端
Tomcat 由一系列的组件构成,其中核心的组件有三个
名称 功能
Web 容器 完成 Web 服务器的功能
Servlet 容器 名字为 catalina,用于处理 Servlet 代码
JSP 容器 用于将 JSP 动态网页翻译成 Servlet 代码
JavaServlet
JavaServlet是运行在Web服务器或应用服务器上的程序,它是作为来自web浏览器或其他HTTP客户端的请求和HTTP服务器上的数据库或应用程序之间的中间层。使用Servlet,可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。与CGI (公共网关接口)功能相类似。
JSP容器
JSP全称:Java Server Pages。是一种动态网页开发技术。它使用JSP标签在HTML网页中插入Java代码。标签通常以<%开头 以%>结束。JSP是一种Java servlet,主要用于实现Java web应用程序的用户界面部分。
JSP 通过网页表单获取用户输入数据、访问数据库及其他数据源,然后动态地创建网页。
Tomcat顶层架构
1.Tomcat中最顶层的容器是Server,代表着整个服务器,一个Server可以包含至少一个Service,用于具体提供服务
2.Service主要包含两个部分:Connector和Container。Tomcat的心脏就是这两个组件,这两个组件的作用:Connector用于处理连接相关的事情,并提供Socket与Request和Response相关的转化; Container用于封装和管理Servlet,以及具体处理Request请求,在Container内部包含了4个子容器
Tomcat 功能组件结构:
tomcat的核心功能有两个,分别是负责接受和反馈外部请求的连接器connector,和负责处理请求的容器container。其中连接器和容器相辅相成,一起构成了基本的web服务service。每个tomcat服务器可以管理多个service。
connector:负责对外接受和响应请求。它是tomcat与外界的交通枢纽,监听端口接受外界请求,并将请求处理后传递给容器做业务处理,最后将容器处理后的结果相应给外界。
container:负责对内处理业务逻辑。其内部由engine,host,context和wrapper四个容器组成,用于管理和调用servlet相关逻辑。
service:对外提供的web服务,主要包含connector和container两个核心组件,以及其他功能组件。tomcat可以管理多个service,且各service之间相互独立。
Tomcat请求过程
1.用户在浏览器中输入该网址,请求被发送到本机端口8080,被在那里监听的Coyote HTTP/1.1 Connector获得
2.Connector把该请求交给它所在的Service的Engine (Container) 来处理,并等待Engine的回应
3.Engine获得请求localhost/test/index.jsp,匹配所有的虚拟主机Host
4.Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机),名为localhostHost获得请求/test/index.jsp,匹配它所拥有的所有Context。Host匹配到路径为/test的Context(如果匹配不到就把该请求交给路径名为“”的Context去处理)
5.path="/test"的Context获得请求/ index. jsp,在它的mapping table中寻找出对应的Servlet。Context 匹配到URLPattern为* .jsp的Servlet,对应于JspServlet类
6.构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet()或doPost(),执行业务逻辑、数据存储等
Context把执行完之后的HttpServletResponse对象返回给Host .
7.Host把HttpServletResponse对象返回给Engine
8.Engine把HttpServletResponse对象返回Connector
9.Connector把HttpServletResponse对象返回给客户Browse
1.关闭防火墙,将安装 Tomcat 所需软件包传到/opt目录下
jdk-8u201-linux-x64.rpm
apache-tomcat-9.0.16.tar.gz
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
2.安装JDK
cd /opt
rpm -ivh jdk-8u201-linux-x64.rpm
java -version
3.设置 JDK 环境变量
vim /etc/profile.d/java.sh
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
source /etc/profile.d/java.sh
java -version
CLASSPATH:编译、运行Java程序时,JRE会去该变量指定的路径中搜索所需的类(.class)文件。
dt.jar:是关于运行环境的类库,主要是可视化的 swing 的包。
tools.jar:主要是一些jdk工具的类库,包括javac、java、javap(jdk自带的一个反编译工具)、javadoc等
JDK :java development kit (java开发工具)
JRE :java runtime environment (java运行时环境)
JVM :java virtuak machine (java虚拟机),使java程序可以在多种平台上运行class文件
首先使用文本工具编写java源代码,比如 Hello.java ;
在命令行中,输入命令:javac Hello.java,对源代码进行编译,生成 class 字节码文件;
编译完成后,如果没有报错信息,输入命令:java Hello,运行 class 字节码文件,由 JVM 对字节码进行解释和运行,
打印 “Hello World”。
vim Hello.javapublic class Hello {
public static void main(String[] args){
System.out.println("Hello world!");
}
}javac Hello.java
java Hello
4.安装启动 Tomcat
cd /opt
tar zxvf apache-tomcat-9.0.16.tar.gz
mv apache-tomcat-9.0.16 /usr/local/tomcat
##启动tomcat##
/usr/local/tomcat/bin/startup.sh
netstat -natp | grep 8080
#使用浏览器访问Tomcat的主页
http://192.168.50.56:8080
5.优化 Tomcat 启动速度
vim /usr/java/jdk1.8.0_201-amd64/jre/lib/security/java.security
#修改117行;##/dev/random和/dev/urandom都是伪终端,但是/dev/urandom提供的数据流更快
securerandom.source=file:/dev/urandom
#创建一个软连接,将tomcat的命令放入/usr/local/bin
ln -s /usr/local/tomcat/bin/* /usr/local/bin/
#重启Tomcat
shutdown.sh
startup.sh
查看manager文件:
cd /usr/local/tomcat/webapps/manager/META-INF
vim context.xml
#允许所有主机访问。
在conf,tomcat-users.xml中,添加账户密码
1.创建 kgc 和 benet 项目目录和文件
mkdir /usr/local/tomcat/webapps/kgc
mkdir /usr/local/tomcat/webapps/benet
echo "This is kgc page\!" > /usr/local/tomcat/webapps/kgc/index.jsp
echo "This is benet page\!" > /usr/local/tomcat/webapps/benet/index.jsp
2.修改 Tomcat 主配置文件 server.xml
vim /usr/local/tomcat/conf/server.xml
--165行前--插入
/usr/local/tomcat/bin/shutdown.sh
/usr/local/tomcat/bin/startup.sh
3.客户端浏览器访问验证
echo "192.168.233.71 www.kgc.com www.benet.com" >> /etc/hosts
浏览器访问 http://www.kgc.com:8080/ 页面显示This is kgc page\!
浏览器访问 http://www.benet.com:8080/ 页面显示This is benet page\!
2.修改 Tomcat 主配置文件
1.vim /usr/local/tomcat/conf/server.xml #165行前插入
2.#重启服务;命令路径优化后可以直接使用shutdown.sh和startup.sh
/usr/local/tomcat/bin/shutdown.sh
/usr/local/tomcat/bin/startup.sh
Tomcat默认安装下的缺省配置并不适合生产环境,它可能会频繁出现假死现象需要重启,
只有通过不断压测优化才能让它最高效率稳定的运行。
优化主要包括三方面,分别为操作系统优化(内核参数优化),Tomcat配置文件参数优化,Java虚拟机(JVM)调优。
##Tomcat 配置文件参数优化##
常用的优化相关参数如下:
【redirectPort】如果某连接器支持的协议是HTTP,当接收客户端发来的HTTPS请求时,则转发至此属性定义的端口。
【maxThreads】Tomcat使用线程来处理接收的每个请求,这个值表示Tomcat可创建的最大的线程数,即支持的最大并发连接数,默认值是 200。
【minSpareThreads】最小空闲线程数,Tomcat 启动时的初始化的线程数,表示即使没有人使用也开这么多空线程等待,默认值是 10。
【maxSpareThreads】最大备用线程数,一旦创建的线程超过这个值,Tomcat就会关闭不再需要的socket线程。默认值是-1(无限制)。一般不需要指定。
【URIEncoding】指定 Tomcat 容器的 URL 编码格式,语言编码格式这块倒不如其它 Web服务器软件配置方便,需要分别指定。
【connnectionTimeout】网络连接超时,单位:毫秒,设置为 0 表示永不超时,这样设置有隐患的。通常默认 20000 毫秒就可以。
【enableLookups】是否反查域名,以返回远程主机的主机名,取值为:true 或 false,如果设置为 false,则直接返回 IP 地址,为了提高处理能力,应设置为 false。
【disableUploadTimeout】上传时是否使用超时机制。应设置为 true。
【connectionUploadTimeout】上传超时时间,毕竟文件上传可能需要消耗更多的时间,这个根据你自己的业务需要自己调,以使Servlet有较长的时间来完成它的执行,需要与上一个参数一起配合使用才会生效。
【acceptCount】指定当所有可以使用的处理请求的线程数都被使用时,可传入连接请求的最大队列长度,超过这个数的请求将不予处理,默认为 100 个。
【compression】是否对响应的数据进行GZIP压缩,off:表示禁止压缩;on:表示允许压缩(文本将被压缩)、force:表示所有情况下都进行压缩,默认值为 off,压缩数据后可以有效的减少页面的大小,一般可以减小 1/3 左右,节省带宽。
【compressionMinSize】表示压缩响应的最小值,只有当响应报文大小大于这个值的时候才会对报文进行压缩,如果开启了压缩功能,默认值就是 2048。
【compressableMimeType】压缩类型,指定对哪些类型的文件进行数据压缩。
【noCompressionUserAgents="gozilla, traviata"】对于以下的浏览器,不启用压缩
以上是一些常用的配置参数,还有好多其它的参数设置,还可以继续深入的优化,HTTP Connector 与 AJP Connector 的参数属性值,
可以参考官方文档的详细说明进行学习。
vim /usr/local/tomcat/conf/server.xml
......
redirectPort="8443"
--71行--插入
minSpareThreads="50"
enableLookups="false"
disableUploadTimeout="true"
acceptCount="300"
maxThreads="500"
processorCache="500"
URIEncoding="UTF-8"
compression="on"
compressionMinSize="2048"
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain,image/gif,image /jpg,image/png"/>
Tomcat的Connector的配置信息:
minSpareThreads: 空闲线程的最小数量,用于处理请求。
enableLookups: 是否启用DNS反向解析。当设置为false时,请求将不会被解析为主机名。
disableUploadTimeout: 是否禁用上传超时,即设置连接不会在上传期间超时。
acceptCount: 当所有线程都在忙碌时,可以排队等待处理的请求数量。
maxThreads: Tomcat可以创建的最大线程数。
processorCache: 连接器可以缓存的最大处理器数。
URIEncoding: URI的字符编码。
compression: 是否启用响应内容压缩。
compressionMinSize: 响应内容压缩的最小大小。
compressableMimeType: 可以被压缩的MIME类型列表。
MIME(Multipurpose Internet Mail Extensions)的意思是“多用途互联网邮件扩展”。
它是一种用于指示在互联网上发送或存储在计算机上的文件或文档的性质和格式的标准。
MIME类型用于指定浏览器和其他互联网应用程序应如何处理文件。
常见的MIME类型
文本: text/plain、text/html、text/css、text/javascript
图像: image/jpeg、image/png、image/gif
音频: audio/mpeg、audio/ogg、audio/wav
视频: video/mp4、video/webm、video/quicktime
应用程序: application/pdf、application/json、application/xml
MIME类型在确保互联网上的不同类型文件被软件和应用程序正确解释和处理方面发挥着关键作用!
内核优化
Linux内核优化中主要针对两个配置文件 /etc/security/limits.conf 和/etc/sysctl.conf
通常是利用调用内核参数的程序sysctl -a 查询出最优内核参数,然后写入 /etc/sysctl.conf 文件内的。
[root@www opt]# sysctl -a |grep fs.file-max
fs.file-max = 197221 #查询出的文件句柄数量上限。
sysctl: reading key "net.ipv6.conf.all.stable_secret"
sysctl: reading key "net.ipv6.conf.default.stable_secret"
sysctl: reading key "net.ipv6.conf.ens33.stable_secret"
sysctl: reading key "net.ipv6.conf.lo.stable_secret"
sysctl: reading key "net.ipv6.conf.virbr0.stable_secret"
sysctl: reading key "net.ipv6.conf.virbr0-nic.stable_secret"
文件句柄(File Handle)是操作系统用于跟踪和管理打开的文件或资源的数据结构。
在操作系统中,每个打开的文件、网络连接、设备等都会被分配一个唯一的句柄,
操作系统通过这个句柄来标识和访问这些资源。
句柄数是指操作系统能够同时管理的句柄的数量。在一个计算机系统中,
许多应用程序和进程需要打开和使用文件、网络连接等资源。每个资源都需要一个句柄来进行操作。
如果系统的句柄数限制太低,就可能导致应用程序无法打开足够的文件、网络连接或其他资源,
从而影响系统的性能和可用性。
因此,调整句柄数的设置是确保系统能够处理并发连接和资源请求的重要一环。
在高负载的服务器环境中,适当地增加句柄数的限制可以提高系统的并发能力和性能。
但是过于激进地增加句柄数可能会消耗过多的系统资源,因此需要根据实际需求和硬件配置进行调整。
永久配置:
注意:设置保存后,需要重新ssh连接才会看到配置更改的变化
vim /etc/security/limits.conf
# 65535 为Linux系统最大打开文件数
* soft nproc 65535
* hard nproc 65535
* soft nofile 65535
* hard nofile 65535
* soft nproc 65535: 最大进程数软限制为 65535,即可以使用 ulimit -u 命令查看和修改的值。
* hard nproc 65535: 最大进程数硬限制为 65535,即最大可分配的进程数。
* soft nofile 65535:最大打开文件数软限制为 65535,即可以使用 ulimit -n 命令查看和修改的值。
* hard nofile 65535:最大打开文件数硬限制为 65535,即最大可分配的文件数。
这里使用的通配符 * 表示对所有用户生效。
其他调试内核参数的查看: sysctl -a
kernel.sysrq = 0: 禁用了内核的SysRq功能,SysRq允许在系统崩溃或出现问题时执行一些调试操作。
kernel.core_uses_pid = 1: 设置核心转储文件名中包含进程ID,有助于标识是哪个进程导致了核心转储。
kernel.msgmnb 和 kernel.msgmax: 增加IPC消息队列的默认和最大大小,用于进程间通信。
kernel.shmmax 和 kernel.shmall: 调整共享内存的最大大小和分配页面数。
net.ipv4.ip_forward = 0: 禁用IP数据包的转发功能,通常用于不充当路由器的系统。
net.ipv4.conf.default.rp_filter 和 net.ipv4.conf.all.rp_filter: 控制反向路径过滤,提高网络安全性。
net.ipv4.icmp_echo_ignore_all: 允许或禁止系统响应ping请求。
net.ipv4.icmp_echo_ignore_broadcasts: 禁止系统对广播和多播地址的ICMP回显和时间戳请求作出响应。
net.ipv4.conf.default.accept_source_route: 不接受源路由,增加网络安全性。
net.ipv4.tcp_syncookies = 1: 启用SYN Cookies,保护系统免受TCP SYN 攻击。
net.ipv4.tcp_max_tw_buckets = 6000: 设置允许的TIME_WAIT套接字最大数量,避免服务器性能下降。
net.ipv4.tcp_sack = 1: 启用有选择的应答(SACK)来提高TCP性能。
net.ipv4.tcp_window_scaling = 1: 启用TCP窗口缩放功能,允许大窗口的TCP传输。
net.ipv4.tcp_rmem, net.ipv4.tcp_wmem: 调整TCP套接字读取和写入缓冲区大小。
net.ipv4.tcp_mem: 设置TCP缓冲区的最小、默认和最大值。
net.core.wmem_default, net.core.rmem_default, net.core.rmem_max, net.core.wmem_max: 调整网络核心
缓冲区的大小。
net.core.netdev_max_backlog: 控制网络接口接收数据包的排队队列大小。
net.ipv4.tcp_max_orphans: 设置系统允许的孤立TCP连接最大数量。
net.ipv4.tcp_max_syn_backlog: 控制系统允许的三次握手队列长度。
net.ipv4.tcp_synack_retries 和 net.ipv4.tcp_syn_retries: 设置SYN-ACK和SYN请求的重试次数。
net.ipv4.tcp_tw_recycle 和 net.ipv4.tcp_tw_reuse: 启用TIME_WAIT套接字快速回收和重用。
net.ipv4.tcp_fin_timeout: 设置TCP连接FIN(关闭连接)的超时时间。
net.ipv4.tcp_keepalive_time: 设置TCP keepalive探测包发送频率,以检测连接状态。
net.ipv4.ip_local_port_range: 设置本地端口范围,用于分配本地应用程序端口。
net.ipv6.conf.all.disable_ipv6 和 net.ipv6.conf.default.disable_ipv6: 禁用IPv6。
net.netfilter.nf_conntrack_max 和其他 net.netfilter.nf_conntrack_*: 控制连接跟踪和防火墙相关设置。
net.nf_conntrack_max: 设置最大连接跟踪项数。
vm.overcommit_memory = 0: 控制内存超额分配策略,避免OOM killer杀掉进程。
vm.swappiness = 0: 设置内存交换行为,降低内存交换。
fs.file-max = 999999: 设置进程可以同时打开的最大文件句柄数。
net.ipv4.tcp_max_tw_buckets = 6000: 设置操作系统允许的TIME_WAIT套接字最大数量。
net.ipv4.ip_local_port_range = 1024 65000: 设置系统允许的本地端口范围。
net.ipv4.tcp_tw_recycle = 1: 启用TIME_WAIT套接字快速回收。
net.ipv4.tcp_tw_reuse = 1: 允许TIME-WAIT套接字重用。
net.ipv4.tcp_syncookies = 1: 启用SYN Cookies,防止TCP SYN 攻击。
net.core.somaxconn = 40960: 设置最大监听队列长度,用于控制最大并发连接数。
net.core.netdev_max_backlog = 262144: 设置每个网络接口接收数据包队列的最大大小。
net.ipv4.tcp_max_syn_backlog = 262144: 设置接受SYN请求队列的最大长度。
net.ipv4.tcp_rmem, net.ipv4.tcp_wmem: 设置TCP套接字读取和写入缓冲区的最小、默认和最大大小。
net.core.rmem_default, net.core.wmem_default, net.core.rmem_max, net.core.wmem_max: 设置内核套接字接收和
发送缓冲区大小。
net.ipv4.tcp_syncookies = 1: 设置启用SYN Cookies,用于解决TCP SYN 攻击。
查看指定的进程方法:
ps -T -p
查看线程的方法:
ps -aT
-------------------------------------------------------------------------------------------------------------------------
Tomcat配置JVM参数:
-Xms: 设置JVM的初始堆大小,即Java堆的最小大小。例如:-Xms512m表示设置初始堆大小为512MB。
-Xmx: 设置JVM的最大堆大小,即Java堆的最大大小。例如:-Xmx1024m表示设置最大堆大小为1GB。
-XX:NewSize: 设置新生代的初始大小。例如:-XX:NewSize=128m表示设置新生代的初始大小为128MB。
-XX:MaxNewSize: 设置新生代的最大大小。例如:-XX:MaxNewSize=256m表示设置新生代的最大大小为256MB。
-Xmnsize: 设置新生代的大小。与-XX:NewSize和-XX:MaxNewSize不同,-Xmnsize直接设置新生代的大小,
而不是设置初始大小和最大大小。
-XX:NewRatio: 设置新生代与老年代的比例。例如:-XX:NewRatio=2表示新生代的大小是老年代大小的1/2。
-XX:SurvivorRatio: 设置Eden区与Survivor区的比例。
例如:-XX:SurvivorRatio=8表示Eden区的大小是Survivor区大小的1/8。
-Xss: 设置线程栈的大小。例如:-Xss256k表示设置线程栈的大小为256KB。
新生代(Young Generation):新生代是Java堆内存的一部分,用于存放刚刚被创建的对象。在Java程序中,
有很多对象是很快被创建和销毁的,这些短时间存活的对象会被分配到新生代中。
新生代又可以细分为三个部分:Eden区(Eden Space)和两个Survivor区(Survivor Space,通常是S0和S1)。
新对象首先被分配到Eden区,当Eden区满了之后,会触发Minor GC(年轻代垃圾回收),
将存活的对象复制到其中一个Survivor区,同时清理不再使用的对象。经过多次Minor GC后,
仍然存活的对象会被移到老年代。
老年代(Old Generation):老年代是Java堆内存的另一部分,用于存放长时间存活的对象。在Java程序中,
有一些对象会被频繁使用,并且存活时间很长,这些长时间存活的对象会被移到老年代中。
老年代的内存空间通常比较大,因为其中存放的对象有较长的生命周期。当老年代的内存空间不足时,
会触发Major GC(老年代垃圾回收),对老年代进行整理和清理,以释放不再使用的对象。
合理设置新生代和老年代的大小以及选择合适的垃圾回收器,可以提高Java应用程序的性能和垃圾回收效率。