服务器之家:专注于服务器技术及软件下载分享
分类导航

云服务器|WEB服务器|FTP服务器|邮件服务器|虚拟主机|服务器安全|DNS服务器|服务器知识|Nginx|IIS|Tomcat|

服务器之家 - 服务器技术 - Tomcat - tomcat单机多实例的实现

tomcat单机多实例的实现

2021-09-15 17:06淡淡的id Tomcat

这篇文章主要介绍了tomcat单机多实例的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

1、前言

  首先要回答一个问题,为什么要用单机多实例
在不宕机的情况下,webapps里面存在多个项目,可能由于其中一个项目过度使用内存或者其他不确定的因素使得tomcat挂了,那么同一tomcat下的项目也会一同挂了;而使用不同的tomcat,同一台服务器下,每个tomcat的进程是不一样的额,一个项目出现问题tomcat挂了,那么由于是在不同进程,其他项目不会影响的。
  还有一个问题就是不同tomcat使用了不同端口,最后域名只有一个怎么分配?
其实这个使用nginx的反向代理,根据请求的前缀,代理到相应的tomcat项目服务端口对应的nginx server即可。

2、系统环境

系统:16.04.5 lts
jdk版本:openjdk 1.8
tomcat版本:apache-tomcat-9.0.13

3、环境搭建

3.1、下载tomcat

安装jdk:

?
1
apt-get install openjdk-8-jdk

访问官网:https://tomcat.apache.org/download-90.cgi

tomcat单机多实例的实现

找到core,点击tar.gz带弹出下载连接复制下载地址。
然后使用命令下载tomcat

?
1
wget http://mirrors.hust.edu.cn/apache/tomcat/tomcat-9/v9.0.13/bin/apache-tomcat-9.0.13.tar.gz

解压tomcat:

?
1
tar -xzvf apache-tomcat-9.0.13.tar.gz

建一个程序目录:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
##创建一个程序目录
mkdir /data
 
##移动解压文件到data目录下
mv ./apache-tomcat-9.0.13 /data/
 
cp /etc/profile /etc/profile.bak
echo "export catalina_home=/data/apache-tomcat-9.0.13" >> /etc/profile
echo "export path=\$path:\$catalina_home/bin">> /etc/profile && source /etc/profile
##创建sh文件
touch tomcat-start.sh tomcat-stop.sh
 
##更改权限
chmod 760 /data/tomcat-start.sh /data/tomcat-stop.sh

备份profile,并写入tomcat的catalina_home到环境变量,激活环境变量。

创建 tomcat-start.sh,内容如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/bin/bash
##这里的catalina_base,是当前脚本的的父目录,如果不在catalina_base的子目录的话,记得修改
export catalina_base=$(cd $(dirname $0); cd .. ; pwd)
 
echo $catalina_base
 
tomcat_id=`ps aux |grep "java"|grep "dcatalina.base=$catalina_base "|grep -v "grep"|awk '{ print $2}'`
 
if [ -n "$tomcat_id" ] ; then
echo "tomcat($tomcat_id) still running now , please shutdown it first";
 exit 2;
fi
 
tomcat_start_log=`$catalina_home/bin/startup.sh`
 
if [ "$?" = "0" ]; then
    echo "shell script: $0"
 echo "catalina_base: $catalina_base"
 echo "tomcat thread: $tomcat_id"
 echo "start succeed!!!"
else
 echo "$0 $catalina_base start failed"
 echo $tomcat_start_log
fi

创建 tomcat-stop.sh,内容如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/bin/bash
##这里的catalina_base,是当前脚本的的父目录,如果不在catalina_base的子目录的话,记得修改
export catalina_base=$(cd $(dirname $0); cd .. ; pwd)
 
echo $catalina_base
 
tomcat_id=`ps aux |grep "java"|grep "[d]catalina.base=$catalina_base "|awk '{ print $2}'`
 
if [ -n "$tomcat_id" ] ; then
tomcat_stop_log=`$catalina_home/bin/shutdown.sh`
else
 echo "tomcat instance not found : $catalina_base"
 exit
fi
 
if [ "$?" = "0" ]; then
 echo "shell script: $0"
 echo "catalina_base: $catalina_base"
 echo "stop succeed!!!"
else
 echo "$0 $catalina_base stop failed"
 echo $tomcat_stop_log
fi

复制两个tomcat:

?
1
2
3
4
5
6
7
8
##完成删除lib和bin文件夹内容,生成空的bin文件夹
cp -r apache-tomcat-9.0.13 /data/apache-tomcat-test1 && cd /data/apache-tomcat-test1 && rm -rf lib/ bin/ && mkdir bin && cd -
 
##复制启动和停止脚本到bin文件夹,带权限复制
cp -p tomcat-start.sh tomcat-stop.sh /data/apache-tomcat-test1/bin/
 
##一个同样的tomcat目录,带权限复制
cp -rp /data/apache-tomcat-test1/ /data/apache-tomcat-test2/

配置 server.xml 端口

你知道的,同一个服务器部署不同 tomcat 要设置不同的端口,不然会报端口冲突,所以我们只需要修改conf/server.xml中的其中前三个端口就行了。但它有四个分别是:

  • server port:该端口用于监听关闭tomcat的shutdown命令,默认为8005
  • connector http port:该端口用于监听http的请求,默认为8080
  • connector ajp port:该端口用于监听ajp( apache jserv protocol )协议上的请求,通常用于整合apache server等其他http服务器,默认为8009
  • redirect port:重定向端口,出现在connector配置中,如果该connector仅支持非ssl的普通http请求,那么该端口会把 https 的请求转发到这个redirect port指定的端口,默认为8443;

去掉注释的版本:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?xml version="1.0" encoding="utf-8"?>
<server port="8005" shutdown="shutdown">
 <listener classname="org.apache.catalina.startup.versionloggerlistener" />
 <listener classname="org.apache.catalina.core.aprlifecyclelistener" sslengine="on" />
 <listener classname="org.apache.catalina.core.jrememoryleakpreventionlistener" />
 <listener classname="org.apache.catalina.mbeans.globalresourceslifecyclelistener" />
 <listener classname="org.apache.catalina.core.threadlocalleakpreventionlistener" />
 <globalnamingresources>
 <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>
 <service name="catalina">
 <connector port="8080" protocol="http/1.1"
    connectiontimeout="20000"
    redirectport="8443" />
 <connector port="8009" protocol="ajp/1.3" redirectport="8443" />
 <engine name="catalina" defaulthost="localhost">
  <realm classname="org.apache.catalina.realm.lockoutrealm">
  <realm classname="org.apache.catalina.realm.userdatabaserealm"
    resourcename="userdatabase"/>
  </realm>
  <host name="localhost" appbase="webapps"
   unpackwars="true" autodeploy="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" />
  </host>
 </engine>
 </service>
</server>

tomcat-test1改为:

  • server port:9015
  • connector http port:9010
  • connector ajp port:9019

tomcat-test2改为:

  • server port:9025
  • connector http port:9020
  • connector ajp port:9029

修改标识:

?
1
2
echo "test1"> /data/apache-tomcat-test1/webapps/root/index.jsp
echo "test2"> /data/apache-tomcat-test2/webapps/root/index.jsp

修改完成,接着启动tomcat:

?
1
2
/data/apache-tomcat-test1/bin/tomcat-start.sh
/data/apache-tomcat-test2/bin/tomcat-start.sh

tomcat单机多实例的实现

curl的时候是比较慢的,因为还没启动完成。启动完之后就好了。

?
1
2
curl 127.0.0.1:9010
curl 127.0.0.1:9020

这里注意访问端口是connector http port对应的端口

4、后记

其实搭起来不太难,经过参考文章的思路,就是公用一个tomcat的lib和bin,这样子升级的时候替换lib即可,bin都同一用catalina_home的脚本,其实catalina_home下的bin下的start和shutdown脚本统一调用了catalina.sh,而单机多实例的则是巧妙运用了catalina.sh是通过环境中的catalina_home和catalina_base变量启动tomcat的,通过改变catalina_base的路径达到同一条脚本启动tomcat在不同目录下

5、问题

5.1、tomcat启动慢

tomcat单机多实例的实现  

可以看到因为生成session id用了1分06秒,太久了,导致应用deploying整体的时间大大增加,这个问题是可以解决的,可以再启动的时候增加jvm参数-djava.security.egd=file:/dev/./urandom,但是这样做应用产生随机数的能力被减弱,或者说随机不够均匀,对于经常使用加密的应用可能有安全影响。
修改一下启动脚本,添加了java_opts的设置,能使用java_opts,是因为catalina.sh会读出这个变量。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/bin/bash
##这里的catalina_base,是当前脚本的的父目录,如果不在catalina_base的子目录的话,记得修改
 
export catalina_base=$(cd $(dirname $0); cd .. ; pwd)
echo $catalina_base
 
tomcat_id=`ps aux |grep "java"|grep "dcatalina.base=$catalina_base "|grep -v "grep"|awk '{ print $2}'`
 
export java_opts="-djava.security.egd=file:/dev/./urandom";
 
if [ -n "$tomcat_id" ] ; then
echo "tomcat($tomcat_id) still running now , please shutdown it first";
 exit 2;
fi
 
tomcat_start_log=`$catalina_home/bin/startup.sh`
 
if [ "$?" = "0" ]; then
  echo "shell script: $0"
 echo "catalina_base: $catalina_base"
 echo "tomcat thread: $tomcat_id"
 echo "start succeed!!!"
else
 echo "$0 $catalina_base start failed"
 echo $tomcat_start_log
fi

5.2、远程ssh时,环境变量不生效问题

使用source命令刷新当前环境变量。

具体修改如下:

tomcat-start.sh :

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/bin/bash
##这里的catalina_base,是当前脚本的的父目录,如果不在catalina_base的子目录的话,记得修政
 
source /etc/profile
export catalina_base=$(cd $(dirname $0); cd .. ; pwd)
export java_opts="-djava.security.egd=file:/dev/./urandom";
tomcat_id=`ps aux |grep "java"|grep "dcatalina.base=$catalina_base "|grep -v "grep"|awk '{ print $2}'`
 
echo "----------------------------------"
echo "using catalina_base:$catalina_base"
echo "using catalina_home:$catalina_home"
echo "----------------------------------"
 
if [ -n "$tomcat_id" ] ; then
echo "tomcat($tomcat_id) still running now , please shutdown it first";
 exit 2;
fi
 
tomcat_start_log=`$catalina_home/bin/startup.sh`
 
if [ "$?" = "0" ]; then
    echo "shell script: $0"
 echo "tomcat thread: $tomcat_id"
 echo "start succeed!!!"
else
 echo "$0 $catalina_base start failed"
    echo "catalina_base: $catalina_base"
 echo $tomcat_start_log
fi

tomcat-stop.sh

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/bin/bash
## 这里的catalina_base,是当前脚本的的父目录,如果不在catalina_base的子目录的话,记得修政
 
source /etc/profile
export catalina_base=$(cd $(dirname $0); cd .. ; pwd)
tomcat_id=`ps aux |grep "java"|grep "[d]catalina.base=$catalina_base "|awk '{ print $2}'`
 
echo "----------------------------------"
echo "using catalina_base:$catalina_base"
echo "using catalina_home:$catalina_home"
echo "----------------------------------"
 
if [ -n "$tomcat_id" ] ; then
tomcat_stop_log=`$catalina_home/bin/shutdown.sh`
else
 echo "tomcat instance not found : $catalina_base"
 exit
fi
 
if [ "$?" = "0" ]; then
 echo "shell script: $0"
 echo "stop succeed!!!"
else
 echo "$0 $catalina_base stop failed"
    echo "catalina_base: $catalina_base"
 echo $tomcat_stop_log
fi

附上restart脚本:
tomcat-restart.sh :

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/bin/bash
 
source /etc/profile
export catalina_base=$(cd $(dirname $0); cd .. ; pwd)
green_color='\e[1;32m' #绿
res='\e[0m'
 
tomcat_id=`ps aux |grep "java"|grep "dcatalina.base=$catalina_base "|grep -v "grep"|awk '{ print $2}'`
 
sleep_time=1
 
echo "----------------------------------"
echo "using catalina_base:$catalina_base"
echo "using catalina_home:$catalina_home"
echo "----------------------------------"
 
if [ -n "$tomcat_id" ] ; then
 echo -e "${green_color}found tomcat instance in pid $tomcat_id , shutdown now!${res}";
 echo -e "${green_color}---------------start shutdown-------------------${res}"
 source $(dirname $0)/tomcat-stop.sh;
 echo -e "${green_color}--------------- end shutdown -------------------${res}"
fi
 
while [ -n "$tomcat_id" ]
do
 sleep $sleep_time
 echo wait "$sleep_time" s
 tomcat_id=`ps aux |grep "java"|grep "dcatalina.base=$catalina_base "|grep -v "grep"|awk '{ print $2}'`
done
 
echo -e "${green_color}---------------start startup-------------------${res}"
source $(dirname $0)/tomcat-start.sh
echo -e "${green_color}---------------end startup-------------------${res}"

参考博客:

聊聊 tomcat 的单机多实例

spring boot应用首次启动慢的问题

到此这篇关于tomcat单机多实例的实现的文章就介绍到这了,更多相关tomcat单机多实例内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/qq_26819733/article/details/84110648

延伸 · 阅读

精彩推荐
  • Tomcat一次tomcat源码启动控制台中文乱码的调试过程记录

    一次tomcat源码启动控制台中文乱码的调试过程记录

    平时在使用tomcat做一些服务的时候经常遇到各种乱码问题,下面这篇文章主要给大家介绍了一次tomcat源码启动控制台中文乱码的调试过程,需要的朋友可以...

    zhoutaoping199211852021-09-24
  • Tomcat如何查看tomcat的控制台输出的方法

    如何查看tomcat的控制台输出的方法

    这篇文章主要介绍了如何查看tomcat的控制台输出的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    CaiCaiNeo11932021-08-29
  • TomcatTomcat安装配置方法图文教程

    Tomcat安装配置方法图文教程

    这篇文章主要为大家详细介绍了Tomcat安装配置方法图文教程,java环境变量如何配置,Eclipse安装配置方法图文教程 ,为大家分享了三个教程,感兴趣的小伙...

    Tomcat教程网13292021-08-11
  • TomcatEclipse创建tomcat实现过程原理详解

    Eclipse创建tomcat实现过程原理详解

    这篇文章主要介绍了Eclipse创建tomcat实现过程原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以...

    海绵般汲取11642021-09-16
  • TomcatTomcat整体结构简单介绍

    Tomcat整体结构简单介绍

    这篇文章主要介绍了Tomcat整体结构简单介绍,Tomcat的本质是一个Servlet容器。一个Servlet能做的事情是:处理请求资源,并为客户端填充response对象,需要的朋友...

    叫我田露也行12302021-09-07
  • Tomcat解决Tomcat的maxPostSize属性的配置需要注意的问题

    解决Tomcat的maxPostSize属性的配置需要注意的问题

    这篇文章主要介绍了解决Tomcat的maxPostSize属性的配置需要注意的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋...

    life is wonderful12012021-09-13
  • TomcatTomcat服务器的安全设置

    Tomcat服务器的安全设置

    tomcat是一个开源Web服务器,基于Tomcat的Web运行效率高,可以在一般的硬件平台上流畅运行,因此,颇受Web站长的青睐。不过,在默认配置下其存在一定的安...

    IT专家网9002021-08-03
  • TomcatTomcat CentOS安装实现过程图解

    Tomcat CentOS安装实现过程图解

    这篇文章主要介绍了Tomcat CentOS安装实现过程图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考...

    agrin5842021-09-15