Nginx+Tomcat搭建集群环境
集群概述与架构介绍
Tomcat集群能带来什么:
- 提高服务的性能,例如计算处理能力、并发能力等,以及实现服务的高可用性
- 提供项目架构的横向扩展能力,增加集群中的机器就能提高集群的性能
Tomcat集群实现方式:
- Tomcat集群的实现方式有多种,最简单的就是通过Nginx负载进行请求转发来实现
Tomcat单机架构图:
可能看了上面的Tomcat单机的架构图后,会 ”想当然“ 的觉得Tomcat集群架构是这样子的:
这种 ”想当然“ 的Tomcat集群会带来什么问题:
- Session登录信息存储及读取的问题
- 服务器定时任务并发的问题
- ......
所以架构的演进并不是 ”想当然“ 的那么简单,当我们的架构随着业务的需求进行演进时,就可能会发生代码上的改动,以及其他各方面配置及机器的改动,并不是单纯的增加Tomcat机器就行了。因为架构的演进都不是一蹴而就的,编程是一个遇见问题解决问题的过程,所以我们不可能一下子就设计出一个完美的架构,而且也不存在完美的架构,只有合适的架构。
常见的Tomcat集群解决方案:
- 采用 nginx 中的 ip hash policy 来保持某个ip始终连接在某一个机器上
- 优点:可以不改变现有的技术架构,直接实现横向扩展,省事。但是缺陷也很明显,在实际的生产环境中,极少使用这种方式
- 缺点:1.单止服务器请求(负载)不均衡,这是完全依赖 ip hash 的结果。2.客户机ip动态变化频繁的情况下,无法进行服务,因为可能每次的ip hash都不一样,就无法始终保持只连接在同一台机器上。
- 采用redis或memchche等nosql数据库,实现一个缓存session的服务器,当请求过来的时候,所有的Tomcat Server都统一往这个服务器里读取session信息。这是企业中比较常用的一种解决方案,所以大致的Tomcat集群的架构图如下:
单机部署多个Tomcat实例(Linux)
由于考虑到在学习时,可能没有足够的机器资源去用多台机器部署多个Tomcat实例,所以本节将简单介绍一下如何在Linux系统环境下,单机部署多个Tomcat实例。多机就不介绍了,因为多机就是一台机器安装一个Tomcat就行了,不需要做额外的更改。
1.到Tomcat官网中,复制Tomcat的下载链接进行下载并解压到相应的目录下:
[root@study-01 /usr/local/src]# wget http://mirrors.hust.edu.cn/apache/tomcat/tomcat-9/v9.0.7/bin/apache-tomcat-9.0.7.tar.gz
[root@study-01 /usr/local/src]# tar -zxvf apache-tomcat-9.0.7.tar.gz -C /usr/local/
2.安装好Tomcat后,将Tomcat目录拷贝多份出来。并更改一下目录名称:
[root@study-01 /usr/local]# cp -r apache-tomcat-9.0.7 ./tomcat9-02
[root@study-01 /usr/local]# mv apache-tomcat-9.0.7 ./tomcat9-01
3.配置环境变量:
[root@study-01 ~]# vim /etc/profile # 在文件末尾增加如下内容
export CATALINA_BASE=/usr/local/tomcat9-01
export CATALINA_HOME=/usr/local/tomcat9-01
export TOMCAT_HOME=/usr/local/tomcat9-01
export CATALINA_2_BASE=/usr/local/tomcat9-02
export CATALINA_2_HOME=/usr/local/tomcat9-02
export TOMCAT_2_HOME=/usr/local/tomcat9-02
[root@study-01 ~]# source /etc/profile # 使配置文件生效
4.第一个Tomcat不需要动,只需要修改第二个Tomcat的相关配置,首先编辑第二个Tomcat安装目录中bin目录下的catalina.sh文件:
[root@study-01 ~]# cd /usr/local/tomcat9-02/bin/
[root@study-01 /usr/local/tomcat9-02/bin]# vim catalina.sh # 找到如下那行注释,在该注释下,增加两行配置
# OS specific support. $var _must_ be set to either true or false.
export CATALINA_BASE=$CATALINA_2_BASE
export CATALINA_HOME=$CATALINA_2_HOME
[root@study-01 /usr/local/tomcat9-02/bin]#
5.然后编辑第二个Tomcat安装目录中conf目录下的server.xml文件,在该文件中需要修改三个端口:
[root@study-01 /usr/local/tomcat9-02/bin]# cd ../conf/
[root@study-01 /usr/local/tomcat9-02/conf]# vim server.xml
# 第一个端口,Server port节点端口
<Server port="9005" shutdown="SHUTDOWN">
# 第二个端口,Connector port节点端口,也即是Tomcat访问端口
<Connector port="9080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" URIEncoding="UTF-8" />
# 第三个端口,Connector port节点端口
<Connector port="9009" protocol="AJP/1.3" redirectPort="8443" />
[root@study-01 /usr/local/tomcat9-02/conf]#
6.修改完成后,分别进入两个Tomcat的bin目录,执行脚本启动Tomcat:
# 启动Tomcat02
[root@study-01 /usr/local/tomcat9-02/conf]# cd ../bin/
[root@study-01 /usr/local/tomcat9-02/bin]# ./startup.sh
Using CATALINA_BASE: /usr/local/tomcat9-02
Using CATALINA_HOME: /usr/local/tomcat9-02
Using CATALINA_TMPDIR: /usr/local/tomcat9-02/temp
Using JRE_HOME: /usr/local/jdk1.8
Using CLASSPATH: /usr/local/tomcat9-02/bin/bootstrap.jar:/usr/local/tomcat9-02/bin/tomcat-juli.jar
Tomcat started.
# 启动Tomcat01
[root@study-01 /usr/local/tomcat9-02/bin]# cd ../../tomcat9-01/bin/
[root@study-01 /usr/local/tomcat9-01/bin]# ./startup.sh
Using CATALINA_BASE: /usr/local/tomcat9-01
Using CATALINA_HOME: /usr/local/tomcat9-01
Using CATALINA_TMPDIR: /usr/local/tomcat9-01/temp
Using JRE_HOME: /usr/local/jdk1.8
Using CLASSPATH: /usr/local/tomcat9-01/bin/bootstrap.jar:/usr/local/tomcat9-01/bin/tomcat-juli.jar
Tomcat started.
[root@study-01 /usr/local/tomcat9-01/bin]#
启动完成后,检查监听的端口号及进程:
[root@study-01 ~]# netstat -lntp |grep java
tcp6 0 0 :::8009 :::* LISTEN 2846/java
tcp6 0 0 127.0.0.1:9005 :::* LISTEN 2784/java
tcp6 0 0 :::8080 :::* LISTEN 2846/java
tcp6 0 0 :::9009 :::* LISTEN 2784/java
tcp6 0 0 :::9080 :::* LISTEN 2784/java
tcp6 0 0 127.0.0.1:8005 :::* LISTEN 2846/java
[root@study-01 ~]# ps aux |grep java
root 2784 5.6 1.5 7105356 123956 pts/0 Sl 06:24 0:06 /usr/local/jdk1.8/bin/java -Djava.util.logging.config.file=/usr/local/tomcat9-02/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /usr/local/tomcat9-02/bin/bootstrap.jar:/usr/local/tomcat9-02/bin/tomcat-juli.jar -Dcatalina.base=/usr/local/tomcat9-02 -Dcatalina.home=/usr/local/tomcat9-02 -Djava.io.tmpdir=/usr/local/tomcat9-02/temp org.apache.catalina.startup.Bootstrap start
root 2846 6.5 1.4 7105356 119712 pts/0 Sl 06:24 0:05 /usr/local/jdk1.8/bin/java -Djava.util.logging.config.file=/usr/local/tomcat9-01/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /usr/local/tomcat9-01/bin/bootstrap.jar:/usr/local/tomcat9-01/bin/tomcat-juli.jar -Dcatalina.base=/usr/local/tomcat9-01 -Dcatalina.home=/usr/local/tomcat9-01 -Djava.io.tmpdir=/usr/local/tomcat9-01/temp org.apache.catalina.startup.Bootstrap start
root 2904 0.0 0.0 112680 976 pts/0 S+ 06:25 0:00 grep --color=auto java
[root@study-01 ~]#
最后在浏览器上访问两个不同的端口,看看是否能访问到Tomcat默认的首页。如下:
至此,我们的单机部署多个Tomcat实例就完成了,如果想继续部署,依照此法继续即可。
注:不同的Tomcat实例使用的端口号在系统中必须不能重复,必须是系统没有使用的端口才行,不然会产生端口冲突。
Nginx负载均衡配置,常用策略,场景及特点简介
Nginx负载均衡配置及策略:
- 轮询(默认)
- 优点:实现简单
- 缺点:不考虑每台服务器的处理能力
- 配置示例如下: upstream www.xxx.com { # 需要负载的server列表 server www.xxx.com:8080; server www.xxx.com:9080; }
- 权重,使用的较多的策略
- 优点:考虑了每台服务器处理能力的不同,哪台机器性能高就给哪台机器的权重高一些
- 配置示例如下: upstream www.xxx.com { # 需要负载的server列表,weight表示权重,weight默认为1,如果多个配置权重的节点,比较相对值 server www.xxx.com:8080 weight=15; server www.xxx.com:9080 weight=10; }
- ip hash
- 优点:能实现同一个用户始终访问同一个服务器
- 缺点:根据 ip hash 不一定平均
- 配置示例如下: upstream www.xxx.com { ip_hash; # 需要负载的server列表 server www.xxx.com:8080; server www.xxx.com:9080; }
- url hash (第三方插件)
- 优点:能实现同一个服务访问同一个服务器,也就是根据url进行负载
- 缺点:和ip hash一样,根据 url hash 分配请求不一定平均,请求频繁的url会请求到同一台服务器上
- 配置示例如下(需要事先安装插件) upstream www.xxx.com { # 需要负载的server列表 server www.xxx.com:8080; server www.xxx.com:9080; hash $request_uri; }
- fair (第三方插件)
- 特点:按后端服务器的响应时间来分配请求,响应时间短的优先分配
- 配置示例如下(需要事先安装插件) upstream www.xxx.com { # 需要负载的server列表 server www.xxx.com:8080; server www.xxx.com:9080; fair; }
一些负载均衡参数简介:
upstream www.xxx.com {
ip_hash;
# 需要负载的server列表
server www.xxx.com:8080 down; # down表示当前的server暂时不参与负载
server www.xxx.com:9080 weight=2; # weight默认值为1,weight的值越大,负载的权重就越大
server www.xxx.com:7080 backup; # 其他所有的非backup机器,在down掉或者很忙的时候,才请求backup机器,也就是一个备用机器
server www.xxx.com:6080;
}
Nginx+Tomcat搭建集群
在上文中我们已经介绍了如何在单机上部署多个Tomcat实例,本节将介绍如何安装Nginx,并且使用Nginx+Tomcat搭建集群。
1.到nginx官网上获取下载链接,然后到Linux上下载并解压编译nginx:
[root@study-01 ~]# cd /usr/local/src/
[root@study-01 /usr/local/src]# wget http://nginx.org/download/nginx-1.14.0.tar.gz
[root@study-01 /usr/local/src]# tar -zxvf nginx-1.14.0.tar.gz
[root@study-01 /usr/local/src]# cd nginx-1.14.0
[root@study-01 /usr/local/src/nginx-1.14.0]# ./configure --prefix=/usr/local/nginx
[root@study-01 /usr/local/src/nginx-1.14.0]# echo $?
0
[root@study-01 /usr/local/src/nginx-1.14.0]# make && make install
[root@study-01 /usr/local/src/nginx-1.14.0]# echo $?
0
[root@study-01 /usr/local/src/nginx-1.14.0]# cd ../../nginx/
[root@study-01 /usr/local/nginx]# ls # 安装完成
conf html logs sbin
[root@study-01 /usr/local/nginx]#
2.创建nginx的主配置文件,因为我们不使用nginx自带的配置文件:
[root@study-01 /usr/local/nginx/conf]# mv nginx.conf nginx.conf.bak
[root@study-01 /usr/local/nginx/conf]# vim nginx.conf # 内容如下
user nobody nobody;
worker_processes 2;
error_log /usr/local/nginx/logs/nginx_error.log crit;
pid /usr/local/nginx/logs/nginx.pid;
worker_rlimit_nofile 51200;
events
{
use epoll;
worker_connections 6000;
}
http
{
include mime.types;
default_type application/octet-stream;
server_names_hash_bucket_size 3526;
server_names_hash_max_size 4096;
log_format combined_realip '$remote_addr $http_x_forwarded_for [$time_local]'
' $host "$request_uri" $status'
' "$http_referer" "$http_user_agent"';
sendfile on;
tcp_nopush on;
keepalive_timeout 30;
client_header_timeout 3m;
client_body_timeout 3m;
send_timeout 3m;
connection_pool_size 256;
client_header_buffer_size 1k;
large_client_header_buffers 8 4k;
request_pool_size 4k;
output_buffers 4 32k;
postpone_output 1460;
client_max_body_size 10m;
client_body_buffer_size 256k;
client_body_temp_path /usr/local/nginx/client_body_temp;
proxy_temp_path /usr/local/nginx/proxy_temp;
fastcgi_temp_path /usr/local/nginx/fastcgi_temp;
fastcgi_intercept_errors on;
tcp_nodelay on;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 8k;
gzip_comp_level 5;
gzip_http_version 1.1;
gzip_types text/plain application/x-javascript text/css text/htm
application/xml;
add_header Access-Control-Allow-Origin *;
include vhost/*.conf;
}
[root@study-01 /usr/local/nginx/conf]# mkdir ./vhost # 创建虚拟主机配置文件的存放目录
[root@study-01 /usr/local/nginx/conf]# cd vhost/
[root@study-01 /usr/local/nginx/conf/vhost]# vim www.xxx.com.conf # 创建虚拟主机配置文件,内容如下:
upstream 192.168.190.129 {
# 需要负载的server列表,可以直接使用ip
server 192.168.190.129:8080 weight=1;
server 192.168.190.129:9080 weight=3;
# server www.xxx.com:8080 weight=1;
# server www.xxx.com:9080 weight=3;
}
server{
listen 80;
autoindex on;
server_name 192.168.190;
access_log /usr/local/nginx/logs/access.log combined;
index index.html index.htm index.jsp;
location / {
proxy_pass http://192.168.190.129;
add_header Access-Control-Allow-Origin *;
}
}
[root@study-01 /usr/local/nginx/conf/vhost]#
3.检查nginx配置文件,显示没问题则启动nginx服务:
[root@study-01 /usr/local/nginx/conf/vhost]# cd ../../sbin/
[root@study-01 /usr/local/nginx/sbin]# ./nginx -t # 检查nginx配置文件
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@study-01 /usr/local/nginx/sbin]# ./nginx -c /usr/local/nginx/conf/nginx.conf # 启动nginx服务
[root@study-01 /usr/local/nginx/sbin]# netstat -lntp | grep nginx # 检查端口是否已监听
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 5676/nginx: master
[root@study-01 /usr/local/nginx/sbin]# ps aux |grep nginx # 检查nginx进程是否正常
root 5676 0.0 0.0 20492 624 ? Ss 19:57 0:00 nginx: master process ./nginx -c /usr/local/nginx/conf/nginx.conf
nobody 5677 0.0 0.0 22936 3220 ? S 19:57 0:00 nginx: worker process
nobody 5678 0.0 0.0 22936 3220 ? S 19:57 0:00 nginx: worker process
root 5683 0.0 0.0 112680 976 pts/0 S+ 19:58 0:00 grep --color=auto nginx
[root@study-01 /usr/local/nginx/sbin]#
4.启动两个Tomcat实例:
[root@study-01 ~]# cd /usr/local/tomcat9-01/bin/
[root@study-01 /usr/local/tomcat9-01/bin]# ./startup.sh
Using CATALINA_BASE: /usr/local/tomcat9-01
Using CATALINA_HOME: /usr/local/tomcat9-01
Using CATALINA_TMPDIR: /usr/local/tomcat9-01/temp
Using JRE_HOME: /usr/local/jdk1.8
Using CLASSPATH: /usr/local/tomcat9-01/bin/bootstrap.jar:/usr/local/tomcat9-01/bin/tomcat-juli.jar
Tomcat started.
[root@study-01 /usr/local/tomcat9-01/bin]# cd /usr/local/tomcat9-02/bin/
[root@study-01 /usr/local/tomcat9-02/bin]# ./startup.sh
Using CATALINA_BASE: /usr/local/tomcat9-02
Using CATALINA_HOME: /usr/local/tomcat9-02
Using CATALINA_TMPDIR: /usr/local/tomcat9-02/temp
Using JRE_HOME: /usr/local/jdk1.8
Using CLASSPATH: /usr/local/tomcat9-02/bin/bootstrap.jar:/usr/local/tomcat9-02/bin/tomcat-juli.jar
Tomcat started.
[root@study-01 /usr/local/tomcat9-02/bin]#
5.修改第二个Tomcat实例index.jsp文件内容,以作为两个Tomcat实例的区别,方便一会验证负载均衡是否已成功生效:
[root@study-01 ~]# vim /usr/local/tomcat9-02/webapps/ROOT/index.jsp
<div id="congrats" class="curved container">
<h2>I'm Tomcat 2</h2>
</div>
[root@study-01 ~]#
6.设置防火墙规则,开放80端口:
[root@study-01 ~]# firewall-cmd --zone=public --add-port=80/tcp --permanent
success
[root@study-01 ~]# firewall-cmd --reload
success
[root@study-01 ~]#
7.使用浏览器进行访问,验证nginx的负载均衡是否已成功生效:
如上,验证成功,我们配置的nginx的负载均衡成功。到此为止,我们的Tomcat集群环境就搭建完成了。
- HDU 2504 又见GCD(最大公约数与最小公倍数变形题)
- Selenium2+python自动化63-二次封装(click/send_kesy)
- Selenium2+python自动化65-js定位几种方法总结
- HDU 2502 月之数(二进制,规律)
- Tensorflow实战系列:手把手教你使用CNN进行图像分类(附完整代码)
- HDU 2503 a/b + c/d(最大公约数与最小公倍数,板子题)
- python接口自动化6-重定向(Location)
- 2017广东工业大学程序设计竞赛初赛 题解&源码(A,水 B,数学 C,二分 D,枚举 E,dp F,思维题 G,字符串处理 H,枚举)
- python接口自动化7-参数关联
- 深度学习GPU环境Ubuntu16.04+GTX1080+CUDA9+cuDNN7+TensorFlow1.6环境配置
- python接口自动化8-参数化
- HDU 2037 今年暑假不AC(贪心,区间更新,板子题)
- “玲珑杯”ACM比赛 Round #13 题解&源码
- 回溯算法入门及经典案例剖析(初学者必备宝典)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- django-模板之block(四)
- spring之添加后置处理器的bean的生命周期
- django-模板之URL标签(五)
- 【猫狗数据集】读取数据集的第二种方式
- django-模板之comment标签(六)
- 【猫狗数据集】对一张张图像进行预测(而不是测试集)
- 【猫狗数据集】pytorch训练猫狗数据集之创建数据集
- 【猫狗数据集】可视化resnet18的输出
- springmvc实例之修改雇员相关信息(四)
- 基于TypeScript封装Axios笔记(六)
- 蓝桥杯 k好数 java版
- 强烈推介的几个微信小程序开发小技巧,简单又实用
- 【pytorch-ssd目标检测】验证自己创建的数据集
- django-模板之自动转义autoescape(八)
- 【pytorch-ssd目标检测】测试自己创建的数据集