13.Tomcat架构实战

徐亮伟, 江湖人称标杆徐。多年互联网运维工作经验,曾负责过大规模集群架构自动化运维管理工作。擅长Web集群架构与自动化运维,曾负责国内某大型电商运维工作。
个人博客"徐亮伟架构师之路"累计受益数万人。

老男孩Linux云计算运维QQ交流群: 384467551 226199307
老男孩教育官网 http://www.oldboyedu.com

1.Tomcat快速安装

1.准备Java基础环境

[root@lb01 ~]# yum install java -y
[root@lb01 ~]# mkdir /server && cd /server

2.下载并安装Tomcat服务

[root@lb01 server]# wget http://mirror.bit.edu.cn/apache/tomcat/tomcat-9/v9.0.11/bin/apache-tomcat-9.0.11.tar.gz
[root@lb01 server]# tar xf apache-tomcat-9.0.11.tar.gz
[root@lb01 server]# ln -s /server/apache-tomcat-9.0.11 /server/tomcat-8080

3.启动Tomcat服务

[root@lb01 ~]# /server/tomcat-8080/bin/startup.sh
[root@lb01 ~]# netstat -lntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      28272/java
tcp        0      0 127.0.0.1:8005          0.0.0.0:*               LISTEN      28272/java
tcp        0      0 0.0.0.0:8009            0.0.0.0:*               LISTEN      28272/java

4.通过浏览器访问http://IP:800测试访问

2.Tomcat配置实战

3.Tomcat多个实例

4.Tomcat配置Https

Tomcat支持JKS格式证书,从Tomcat7开始也支持PFX格式证书,两种证书格式任选其一.

1、证书格式转换,在tomcat安装目录创建ssl目录,并将阿里云下载的证书全部拷贝该目录中。(如果是系统创建的CSR,请直接到第2步)

[root@lb01 ~]# mkdir /server/tomcat-8080/ssl
[root@lb01 ~]# cd /server/tomcat-8080/ssl
[root@lb01 ~]#   上传对应证书
[root@lb01 ssl]# unzip 1524377920931.zip

# 执行如下命令完成PFX格式转换命令,此处要设置PFX证书密码,请牢记
[root@lb01 ssl]# openssl pkcs12 -export -out 1524377920931.pfx -inkey 1524377920931.key -in 1524377920931.pem

2.修改tomcat安装目录中conf/server.xml

[root@lb01 ~]# vim /server/tomcat-8080/conf/server.xml
<!-- 1.修改Host name为nginx.bjstack.com -->
<Host name="nginx.bjstack.com"  appBase="webapps"
    unpackWARs="true" autoDeploy="true">

<!-- 2.修改redirectPort="8443"为redirectPort="443"-->
<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="443" />

<!-- 3.增加如下内容-->
<Connector port="443"
    protocol="org.apache.coyote.http11.Http11NioProtocol"
    maxThreads="150"
    SSLEnabled="true"
    scheme="https"
    secure="true"
    keystoreFile="ssl/1524377920931.pfx"
    keystoreType="PKCS12"
    keystorePass="123456"
    clientAuth="false"
    SSLProtocol="TLSv1+TLSv1.1+TLSv1.2"
    ciphers="TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA256"/>

3.重启Tomcat服务

[root@lb01 ~]# /server/apache-tomcat-9.0.11/bin/shutdown.sh
[root@lb01 ~]# /server/apache-tomcat-9.0.11/bin/startup.sh

[root@lb01 ~]# netstat -lntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      29331/java
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN      29331/java
tcp        0      0 127.0.0.1:8005          0.0.0.0:*               LISTEN      29331/java
tcp        0      0 0.0.0.0:8009            0.0.0.0:*               LISTEN      29331/java

4.使用浏览器访问https://IP可访问, 如果是http://IP则会访问失败

5.Tomcat+Nginx集群架构概述

  • Tomcat集群能带来什么
    • 1.提高服务的性能、并发能力、以及高可用性
    • 2.提高项目架构的扩展能力
  • Tomcat集群实现原理
    • 1.通过Nginx负载均衡进行请求转发
  • Tomcat集群架构演进

6.Tomcat+Nginx集群架构实战

实践环境

服务器系统 角色 外网IP 内网IP
CentOS 7.5 NginxProxy eth0:10.0.0.5 eth1:172.16.1.5
CentOS 7.5 Tomcat-Node1 eth1:172.16.1.7
CentOS 7.5 Tomcat-Node2 eth1:172.16.1.8
CentOS 7.5 Tomcat-Node3 eth1:172.16.1.9

1.Tomcat节点按如下安装好Tomcat即可

#1.准备`Java`基础环境
[root@lb01 ~]# yum install java -y
[root@lb01 ~]# mkdir /server && cd /server

#2.下载并安装`Tomcat`服务
[root@lb01 server]# wget http://mirror.bit.edu.cn/apache/tomcat/tomcat-9/v9.0.11/bin/apache-tomcat-9.0.11.tar.gz
[root@lb01 server]# tar xf apache-tomcat-9.0.11.tar.gz
[root@lb01 server]# ln -s /server/apache-tomcat-9.0.11 /server/tomcat-8080

2.安装NginxProxy

[root@lb01 ~]# cat /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1

[root@lb01 ~]# yum install nginx -y

3.准备Proxy相关优化参数文件

[root@lb01 ~]# cat /etc/nginx/proxy_params
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;

4.配置NginxProxy

[root@lb01 ~]# cat /etc/nginx/conf.d/proxy.conf.bak
upstream java {
    server 172.16.1.7:8080;
    server 172.16.1.8:8080;
    server 172.16.1.9:8080;
}

server {
    server_name nginx.bjstack.com;
    listen 80;
    location / {
        proxy_pass http://java;
        include proxy_params;
    }
}

7.Tomcat+Nginx集群实战Https

如需要Nginx+Tomcat架构支持Https, 仅需在NginxProxy配置证书即可

2.配置Nginx负载均衡支持Https证书即可

#1.创建ssl目录,并将证书存放至该目录即可
[root@lb01 ~]# mkdir /etc/nginx/ssl && /etc/nginx/ssl
[root@lb01 ~]# rz #上传证书

#2.配置Proxy调度策略以及支持https
[root@lb01 ~]# cat /etc/nginx/conf.d/proxy.conf
upstream java {
    server 172.16.1.7:8080;
    server 172.16.1.8:8080;
    server 172.16.1.9:8080;
}

server {
    server_name nginx.bjstack.com;
    listen 443;
        ssl on;
        ssl_certificate   ssl/1524377920931.pem;
        ssl_certificate_key  ssl/1524377920931.key;
        ssl_session_timeout 5m;
        location / {
            proxy_pass http://java;
            include proxy_params;
        }
}

server {
    server_name nginx.bjstack.com;
    listen 80;
    return 302 https://$server_name$request_uri;
}

#3.重启Nginx
[root@lb01 ~]# systemctl restart nginx

3.测试访问nginx.bjstack.com会强制跳转至https://nginx.bjstack.com

Tomcat+Nginx+Redis实现Session会话保持

在实际生产中,我们经常部署应用服务,在部署的过程中,要让用户无感知你的应用升级,这种方式可以通过负载均衡方式来实现灰度部署,如前些文章的Nginx方式来实现,通过负载均衡Nginx,更新某一台tomcat服务,再通知负载均衡Nginx,把Tomcat节点重新加载上去。依次这么做,把集群中的所有Tomcat都替换一次即可,就可以实现服务的灰度部署。

如何让用户无感知?就是要实现用户的会话是可以共享的,基于session共享的方式有如下几种:

1,使用数据库来存储session
2,使用cookie来存储session
3,使用redis来存储session
4,使用tomcat的session复制
5,使用mamcached来存储session

我们这里主讲解redis的方式来实现Tomcat的session共享。

我们的例子使用了一台Nginx做负载均衡,后端挂接了两台Tomcat,且每台Tomcat的Session会话都保存到Redis数据库中。其中,Nginx配置为non-sticky运行模式,也即每一个请求都可以被分配到集群中的任何节点。当要上线新代码时,只需简单地取下Tomcat实例,此时所有的访问用户会被路由到活动的Tomcat实例中去,而且由于会话数据都是保存在redis数据库中,所以活跃用户并不会受影响。当Tomcat更新完毕,又可以把此节点加入到Nginx中。

架构图如下:

主机规划

主机名 IP地址 服务
lb01-5 10.0.0.5,172.16.1.5 nginx-1.14
web01-7 172.16.1.7 Tomcat-9.0
web02-8 172.16.1.8 Tomcat-9.0
db01-51 172.16.1.51 Redis-3.2

在两台web上安装tomcat

//安装java环境
[root@web01-7 local]# yum -y install java
//下载tomcat安装包
[root@web01-7 local]# wget http://mirrors.shu.edu.cn/apache/tomcat/tomcat-9/v9.0.12/bin/apache-tomcat-9.0.12.tar.gz
[root@web01-7 local]# tar xf apache-tomcat-9.0.12.tar.gz
[root@web02-8 local]# mv apache-tomcat-9.0.12 tomcat
[root@web01-7 local]# echo "export CATALINA_HOME=/usr/local/tomcat" >> /etc/profile
[root@web01-7 local]# source /etc/profile
[root@web01-7 local]# sed -i '/Host name=/c   <Host name="jpress.sentinel.org"  appBase="webapps"' /usr/local/tomcat/conf/server.xml
[root@web01-7 local]# /usr/local/tomcat/bin/startup.sh 

搭建redis
安装redis,编写配置文件

[root@db01-51 ~]# cat /usr/local/redis/conf.d/master.conf 
bind 172.16.1.51 127.0.0.1
protected-mode yes
daemonize yes
dir /redis_data
dbfilename dump.rdb
save 900 1
save 300 10
save 60 10000
requirepass 123123
[root@db01-51 ~]# redis-server /usr/local/redis/conf.d/master.conf 
[root@db01-51 ~]# netstat -ntalp | grep redis
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      1173/redis-server 1 
tcp        0      0 172.16.1.51:6379        0.0.0.0:*               LISTEN      1173/redis-server 1

基础环境搭建完成之后我们开始正常的进行session会话保持
1,通过TomcatClusterRedisSessionManager,这种方式支持redis3.0的集群方式

下载TomcatRedisSessionManager-2.0.zip包,https://github.com/ran-jit/tomcat-cluster-redis-session-manager,放到$TOMCAT_HOMA/lib下,并解压

[root@web01-7 local]# cd tomcat/lib/
[root@web01-7 lib]# wget https://github.com/ran-jit/tomcat-cluster-redis-session-manager/releases/download/2.0.4/tomcat-cluster-redis-session-manager.zip
[root@web01-7 lib]# unzip tomcat-cluster-redis-session-manager.zip 
Archive:  tomcat-cluster-redis-session-manager.zip
   creating: tomcat-cluster-redis-session-manager/conf/
  inflating: tomcat-cluster-redis-session-manager/conf/redis-data-cache.properties  
   creating: tomcat-cluster-redis-session-manager/lib/
  inflating: tomcat-cluster-redis-session-manager/lib/commons-logging-1.2.jar  
  inflating: tomcat-cluster-redis-session-manager/lib/commons-pool2-2.4.2.jar  
  inflating: tomcat-cluster-redis-session-manager/lib/jedis-2.9.0.jar  
  inflating: tomcat-cluster-redis-session-manager/lib/tomcat-cluster-redis-session-manager-2.0.4.jar  
  inflating: tomcat-cluster-redis-session-manager/readMe.txt 

拷贝解压文件中lib文件到$TOMCAT_HOMA/lib下
bash
[root@web01-7 lib]# cp tomcat-cluster-redis-session-manager/lib/* ./

拷贝redis-data-cache.properties到$TOMCAT_HOMA/conf文件下

[root@web01-7 lib]# cp tomcat-cluster-redis-session-manager/conf/redis-data-cache.properties ../conf/

[root@web01-7 lib]# cat ../conf/redis-data-cache.properties     
//远端redis数据库的地址和端口
redis.hosts=172.16.1.51:6379
//远端redis数据库的连接密码
#- redis password (for stand-alone mode)
redis.password=123123
//是否支持集群,默认的是关闭
#- set true to enable redis cluster mode
redis.cluster.enabled=false
//连接redis的那个库
#- redis database (default 0)
#redis.database=0
//连接超时时间
#- redis connection timeout (default 2000)
#redis.timeout=2000

在$TOMCAT_HOMA/conf/context.xml文件中增加以下两行

//在这个<Context>标签里面配置
<Valve className="tomcat.request.session.redis.SessionHandlerValve" />
<Manager className="tomcat.request.session.redis.SessionManager" />

配置会话到期时间在$TOMCAT_HOMA/conf/web.xml

<session-config>
<session-timeout>60</session-timeout>
</session-config>

启动tomcat服务

[root@web01-7 lib]# /usr/local/tomcat/bin/startup.sh 

然后web01和web07配置是一模一样
测试,我们每次强刷他的sessionID都是一致的,所以我们认为他的session会话保持已经完成,你们也可以选择换个客户端的IP地址来测试

Tomcat-Session
https://github.com/ran-jit/tomcat-cluster-redis-session-manager
http://www.dczou.com/viemall/535.html