Tomcat9 运行模式更改为APR模式 附安装脚本

Tomcat支持三种接收请求的处理方式:BIO、NIO、APR

软件版本: Tomcat9.0.85

操作系统: Rockylinux8.9

BIO由于每个请求都要创建一个线程来处理,线程开销比较大,不能再高并发的场景,性能也是最低的。
NIO是一个基于缓冲区、并能提供非阻塞I/O操作的Java API,比传统的bio更好的并发性能。
APR(Apache Portable Run-time libraries)简单理解,就是从操作系统级别解决异步IO问题,大幅度的提高服务器的处理和响应性能, 也是Tomcat运行高并发应用的首选模式。

所需软件的下载地址

https://mirrors.cloud.tencent.com/apache/apr/

tomcat-native在tomcat的bin下
* apr
* apr-iconv
* apr-util
* tomcat-native

安装依赖

yum install -y apr-devel openssl-devel gcc make expat-devel libtool

安装软件

cd /usr/local/src
wget https://mirrors.cloud.tencent.com/apache/apr/apr-1.6.5.tar.gz
tar xf apr-1.6.5.tar.gz
cd apr-1.6.5/
./configure --prefix=/usr/local/apr
make && make install
cd /usr/local/src
wget https://mirrors.cloud.tencent.com/apache/apr/apr-iconv-1.2.2.tar.gz
tar xf apr-iconv-1.2.2.tar.gz
cd apr-iconv-1.2.2/
./configure --with-apr=/usr/local/apr --prefix=/usr/local/apr-iconv
make && make install
cd /usr/local/src
wget https://mirrors.cloud.tencent.com/apache/apr/apr-util-1.6.3.tar.gz
tar xf apr-util-1.6.3.tar.gz
cd apr-util-1.6.3/
./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr --with-apr-iconv=/usr/local/apr-iconv/bin/apriconv
make && make install
wget https://mirrors.cloud.tencent.com/apache/tomcat/tomcat-connectors/native/1.2.39/source/tomcat-native-1.2.39-src.tar.gz
tar xf tomcat-native-1.2.39-src.tar.gz
./configure --prefix=/usr/local/tomcat-native --with-apr=/usr/local/apr --with-ssl=yes
make && make install
echo -e 'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/apr/lib\nexport LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/tomcat-native/lib:$CATALINA_HOME/lib\nexport LD_RUN_PATH=$LD_RUN_PATH:/usr/local/apr/lib' >> /etc/profile
source /etc/profile

 

启用 Tomcat Native Library(上面已配置,这一步可不做)

在 $CATALINA_HOME/bin 目录下新建 setenv.sh:

LD_LIBRARY_PATH=/usr/local/tomcat-native/lib:$CATALINA_HOME/lib
export LD_LIBRARY_PATH

tomcat的server.xml需要更换成以下配置

<Executor name="tomcatThreadPool"
namePrefix="catalina-exec-"
maxThreads="300"
minSpareThreads="30"/>
<Connector executor="tomcatThreadPool"
port="8080"
protocol="org.apache.coyote.http11.Http11AprProtocol"
connectionTimeout="20000"
redirectPort="8443"
acceptCount="900"
disableUploadTimeout="true"
URIEncoding="UTF-8"
enableLookups="false"
compression="on"
compressionMinSize="1024"
/>

 

 

/usr/local/tomcat/bin/startup.sh

 

查看端口情况

[root@slave bin]# netstat  -tulnp | grep 8080
tcp6       0      0 :::8080                 :::*                    LISTEN      84309/java

 

附脚本

#!/bin/bash
###
# @Descripttion:
# @Author: zhouzl
# @version: tomcat9apr环境配置 在rocky8.10上测试通过
# @Date: 2024-02-27 16:22:57
# @LastEditors: zhouzl
# @LastEditTime: 2024-12-17 14:23:57
# 基于openjdk-1.8.0.432,如果是其它版需要替换tomcat.service中的相关参数
# 脚本为的source环境执行完毕之后可能会不生效.需要重新执行一遍 source /etc/profile 解决方法是使用 source 脚本名 的方式来执行脚本
# ps: 脚本里面无法成功启动tomcat,需要手工启动
###
tomcatversion='9.0.98'
aprversion='1.7.5'
apriconvversion='1.2.2'
aprutilvreion='1.6.3'
tomcatnativeversion='1.3.1'
#tomcat-native 位于tomcat安装包的bin下面
#判断程序是否存在
program_exists() {
local ret='0'
command -v "$1" >/dev/null 2>&1 || { local ret='1'; }
# fail on non-zero return value
if [ "$ret" -ne 0 ]; then
return 1
fi
return 0
}
#获取输入
function get_char()
{
SAVEDSTTY=$(stty -g)
stty -echo
stty cbreak
dd if=/dev/tty bs=1 count=1 2> /dev/null
stty -raw
stty echo
stty "$SAVEDSTTY"
}
enable_pause=1
#暂停
function pause()
{
if [ "x$1" != "x" ]; then
echo "$1"
fi
if [ $enable_pause -eq 1 ]; then
echo "Press any key to continue!"
char=$(get_char)
fi
}
program_exists java
yum install -y apr-devel wget openssl-devel gcc make expat-devel libtool net-tools wget java-1.8.0-openjdk*
source /root/.bash_profile
echo ".........tomcat安装............."
#判断tomcat是否存存,存在则跳过
if [ -h "/usr/local/tomcat" ];then
echo "tomcat已存在,跳过安装"
break
else
echo "................开始下载tomcat............."
wget https://mirrors.cloud.tencent.com/apache/tomcat/tomcat-9/v"${tomcatversion}"/bin/apache-tomcat-"${tomcatversion}".tar.gz
tar xvf apache-tomcat-"${tomcatversion}".tar.gz -C /usr/local/
ln -s /usr/local/apache-tomcat-"${tomcatversion}"/ /usr/local/tomcat
fi
cd /usr/local/src || exit
echo "开始安装APR"
wget https://mirrors.cloud.tencent.com/apache/apr/apr-"${aprversion}".tar.gz
tar xf apr-"${aprversion}".tar.gz
cd /usr/local/src/apr-"${aprversion}"/ || exit
./configure --prefix=/usr/local/apr
make && make install
echo "开始安装apr-iconv"
cd /usr/local/src || exit
wget https://mirrors.cloud.tencent.com/apache/apr/apr-iconv-"${apriconvversion}".tar.gz
tar xf apr-iconv-"${apriconvversion}".tar.gz
cd apr-iconv-"${apriconvversion}"/ || exit
./configure --with-apr=/usr/local/apr --prefix=/usr/local/apr-iconv
make && make install
echo "开始安装apr-util"
cd /usr/local/src || exit
wget https://mirrors.cloud.tencent.com/apache/apr/apr-util-"${aprutilvreion}".tar.gz
tar xf apr-util-"${aprutilvreion}".tar.gz
cd apr-util-"${aprutilvreion}"/ || exit
./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr --with-apr-iconv=/usr/local/apr-iconv/bin/apriconv
make && make install
JAVA_BIN=$(which java)
echo "${JAVA_BIN}"
JAVA_HOME=$(realpath "${JAVA_BIN}")
echo "${JAVA_HOME}"
BASE_NAME=$(basename "${JAVA_HOME}")
echo "${BASE_NAME}"
while [[ ${BASE_NAME} == "bin" || ${BASE_NAME} == "jre" || ${BASE_NAME} == "java" ]]
do
JAVA_HOME=$(dirname "${JAVA_HOME}")
echo "JAVA_HOME: " "${JAVA_HOME}"
BASE_NAME=$(basename "${JAVA_HOME}")
echo "BASE_NAME: " "${BASE_NAME}"
done
echo "JAVA_HOME: ${JAVA_HOME}"
echo "开始安装tomcat-native"
cd /usr/local/src || exit
wget https://mirrors.cloud.tencent.com/apache/tomcat/tomcat-connectors/native/"${tomcatnativeversion}"/source/tomcat-native-"${tomcatnativeversion}"-src.tar.gz
tar xf tomcat-native-"${tomcatnativeversion}"-src.tar.gz
cd /usr/local/src/tomcat-native-"${tomcatnativeversion}"-src/native || exit
./configure --prefix=/usr/local/tomcat-native --with-apr=/usr/local/apr --with-java-home="${JAVA_HOME}"
make && make install
echo -e "export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/apr/lib\nexport LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/tomcat-native/lib:$CATALINA_HOME/lib\nexport LD_RUN_PATH=$LD_RUN_PATH:/usr/local/apr/lib" >> /etc/profile
source /etc/profile
cat >/usr/local/tomcat/bin/setenv.sh <<EOF
LD_LIBRARY_PATH=/usr/local/tomcat-native/lib:$CATALINA_HOME/lib
export LD_LIBRARY_PATH
EOF
#tomcat配置文件
cat >/usr/local/tomcat/conf/server.xml <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- Note: A "Server" is not itself a "Container", so you may not
define subcomponents such as "Valves" at this level.
Documentation at /docs/config/server.html
-->
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<!-- Security listener. Documentation at /docs/config/listeners.html
<Listener className="org.apache.catalina.security.SecurityListener" />
-->
<!-- APR connector and OpenSSL support using Tomcat Native -->
<Listener className="org.apache.catalina.core.AprLifecycleListener" />
<!-- OpenSSL support using FFM API from Java 22 -->
<!-- <Listener className="org.apache.catalina.core.OpenSSLLifecycleListener" /> -->
<!-- Prevent memory leaks due to use of particular java/javax APIs-->
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<!-- Global JNDI resources
Documentation at /docs/jndi-resources-howto.html
-->
<GlobalNamingResources>
<!-- Editable user database that can also be used by
UserDatabaseRealm to authenticate users
-->
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
<!-- A "Service" is a collection of one or more "Connectors" that share
a single "Container" Note: A "Service" is not itself a "Container",
so you may not define subcomponents such as "Valves" at this level.
Documentation at /docs/config/service.html
-->
<Service name="Catalina">
<!--The connectors can use a shared executor, you can define one or more named thread pools-->
<!--
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="150" minSpareThreads="4"/>
-->
<!-- A "Connector" represents an endpoint by which requests are received
and responses are returned. Documentation at :
Java HTTP Connector: /docs/config/http.html
Java AJP Connector: /docs/config/ajp.html
APR (HTTP/AJP) Connector: /docs/apr.html
Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
-->
<!--Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
maxParameterCount="1000"
/-->
<Executor name="tomcatThreadPool"
namePrefix="catalina-exec-"
maxThreads="300"
minSpareThreads="30"/>
<Connector executor="tomcatThreadPool"
port="8080"
protocol="org.apache.coyote.http11.Http11AprProtocol"
connectionTimeout="20000"
redirectPort="8443"
acceptCount="900"
disableUploadTimeout="true"
URIEncoding="UTF-8"
enableLookups="false"
compression="on"
compressionMinSize="1024"
/>
<!-- A "Connector" using the shared thread pool-->
<!--
<Connector executor="tomcatThreadPool"
port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
maxParameterCount="1000"
/>
-->
<!-- Define an SSL/TLS HTTP/1.1 Connector on port 8443
This connector uses the NIO implementation. The default
SSLImplementation will depend on the presence of the APR/native
library and the useOpenSSL attribute of the AprLifecycleListener.
Either JSSE or OpenSSL style configuration may be used regardless of
the SSLImplementation selected. JSSE style configuration is used below.
-->
<!--
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true"
maxParameterCount="1000"
>
<SSLHostConfig>
<Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
certificateKeystorePassword="changeit" type="RSA" />
</SSLHostConfig>
</Connector>
-->
<!-- Define an SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2
This connector uses the APR/native implementation which always uses
OpenSSL for TLS.
Either JSSE or OpenSSL style configuration may be used. OpenSSL style
configuration is used below.
-->
<!--
<Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
maxThreads="150" SSLEnabled="true"
maxParameterCount="1000"
>
<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
<SSLHostConfig>
<Certificate certificateKeyFile="conf/localhost-rsa-key.pem"
certificateFile="conf/localhost-rsa-cert.pem"
certificateChainFile="conf/localhost-rsa-chain.pem"
type="RSA" />
</SSLHostConfig>
</Connector>
-->
<!-- Define an AJP 1.3 Connector on port 8009 -->
<!--
<Connector protocol="AJP/1.3"
address="::1"
port="8009"
redirectPort="8443"
maxParameterCount="1000"
/>
-->
<!-- An Engine represents the entry point (within Catalina) that processes
every request. The Engine implementation for Tomcat stand alone
analyzes the HTTP headers included with the request, and passes them
on to the appropriate Host (virtual host).
Documentation at /docs/config/engine.html -->
<!-- You should set jvmRoute to support load-balancing via AJP ie :
<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
-->
<Engine name="Catalina" defaultHost="localhost">
<!--For clustering, please take a look at documentation at:
/docs/cluster-howto.html (simple how to)
/docs/config/cluster.html (reference documentation) -->
<!--
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
-->
<!-- Use the LockOutRealm to prevent attempts to guess user passwords
via a brute-force attack -->
<Realm className="org.apache.catalina.realm.LockOutRealm">
<!-- This Realm uses the UserDatabase configured in the global JNDI
resources under the key "UserDatabase". Any edits
that are performed against this UserDatabase are immediately
available for use by the Realm. -->
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
<Host name="localhost" appBase="/data/wwwroot/default" unpackWARs="true" autoDeploy="true">
<Context path="" docBase="/data/wwwroot/default" reloadable="false" crossContext="true"/>
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t &quot;%r&quot; %s %b" />
<Valve className="org.apache.catalina.valves.RemoteIpValve" remoteIpHeader="X-Forwarded-For"
protocolHeader="X-Forwarded-Proto" protocolHeaderHttpsValue="https"/>
</Host>
</Engine>
</Service>
</Server>
EOF
mkdir -p /data/wwwroot/default
useradd www -s /sbin/nologin
chown -R www:www /usr/local/tomcat/
chmod -R 744 /usr/local/tomcat
chown -R www:www /data/wwwroot/
#生成tomcat启动服务
cat > /usr/lib/systemd/system/tomcat.service <<EOF
[Unit]
Description=Apache Tomcat Web Application Container
After=syslog.target network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
Environment="JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.432.b06-2.el8.x86_64/"
ExecStart=/usr/local/tomcat/bin/startup.sh
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/usr/local/tomcat/bin/shutdown.sh
PrivateTmp=true
User=www
Group=www
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable tomcat
systemctl restart tomcat

 

posted @   周智林  阅读(323)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示