前言
当访问的网站用户越来越多时,一台服务器很难满足这么高的并发量,此时我们会想到多加几台服务器,怎样将一台服务器分配到多台服务器呢?比较简单的方式是使用nginx来实现分配多台服务器。
下面我tomc以at为例,使用nginx分配管理多个tomcat
负载均衡
负载均衡是建立在现有网络结构之上,他提供了一种廉价而有效透明的方法扩展网络设备和服务器的带宽,增加吞吐量,加强网络数据处理能力,提高网络的灵活性和可用性。负载均衡,意思就是分摊到多个操作单元上执行,例如Web服务器,FTP服务器,企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。
如果还是不懂的话,可以举个例子:
假设你是个妹子,你败家太厉害,以至于你的男友根本吃不消,于是乎你找了两个男朋友,一三五单号,二四六双号限行,从而减少一个男朋友所面临的压力,这叫负载均衡。
nginx的负载均衡策略有2种,第一种是轮询:也就是上面说的“两个男朋友,一三五单号,二四六双号限行”,看下图
另外一种是加权轮询:两个男友,一个是正牌的,权重比较大,一二四五;另外一个是备胎三六,权重比为2:1
如果是同一个用户,在服务器1上登录了,接着去连续访问页面时候,如果按上面的轮询策略就会一会在服务器1上访问,一会服务器2上访问,session不共享就会错乱了。
于是就有了Ip hash算法,对客户端请求的ip进行hash操作,然后根据hash结果将同一个客户端ip的请求分发给同一台服务器进行处理,可以解决session不共享的问题。
搭建多个tomcat环境
由于我这边只有一台服务器,为了方便练习,可以在一个服务器上搭建3个tomcat环境
- 先在/usr/local目录下新建一个tomcat目录
- wget下载apache-tomcat-8.5.35.tar.gz
- tar -zxf解压
- 解压后重命名apache-tomcat-1
- 同一目录下复制2个一样的apache-tomcat-2、apache-tomcat-3
[root@VM_0_11_centos ~]# cd /usr/local [root@VM_0_11_centos local]# mkdir tomcat [root@VM_0_11_centos local]# cd tomcat [root@VM_0_11_centos tomcat]#wget http://mirrors.hust.edu.cn/apache/tomcat/tomcat-8/v8.5.56/bin/apache-tomcat-8.5.56.tar.gz
[root@VM_0_11_centos tomcat]# tar apache-tomcat-8.5.56.tar.gz
# 下载解压后,复制三个一样的文件apache-tomcat-1、apache-tomcat-2、apache-tomcat-3 [root@VM_0_11_centos tomcat]# mv apache-tomcat-8.5.56 apache-tomcat-1 [root@VM_0_11_centos tomcat]# cp -r apache-tomcat-1 apache-tomcat-2 [root@VM_0_11_centos tomcat]# cp -r apache-tomcat-1 apache-tomcat-3 [root@VM_0_11_centos tomcat]# ls apache-tomcat-1 apache-tomcat-2 apache-tomcat-3 apache-tomcat-8.5.56.tar.gz
修改默认端口
tomcat默认都是在8080端口启动的,为了能让3个服务都能启动,就需要改启动端口,打开apache-tomcat-1/conf/server.xml目录编辑
[root@VM_0_11_centos tomcat]# vim apache-tomcat-1/conf/server.xml
找到以下三个地方,把端口改成跟之前不一样的,如下
//8011远程停服务端口
<Server port="8011" 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 library loader. Documentation at /docs/apr.html --> <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /> <!-- 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" />
//8081为http端口
<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="8081" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
/8021为AJP端口,Apache能通过AJP协议访问Tomcat的8006端口
<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="8021" protocol="AJP/1.3" redirectPort="8443" />
<!--
<Connector protocol="AJP/1.3"
address="::1"
port="8009"
redirectPort="8443" />
-->
<!-- 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 -->
apache-tomcat-2/conf/server.xml目录编辑
//8012远程停服务端口 <Server port="8012" shutdown="SHUTDOWN"> //8082为http端口 <Connector port="8082" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> //8022为AJP端口,Apache能通过AJP协议访问Tomcat的8006端口 <Connector port="8022" protocol="AJP/1.3" redirectPort="8443" />
apache-tomcat-3/conf/server.xml目录编辑
//8013远程停服务端口 <Server port="8013" shutdown="SHUTDOWN"> //8083为http端口 <Connector port="8083" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> //8023为AJP端口,Apache能通过AJP协议访问Tomcat的8006端口 <Connector port="8023" protocol="AJP/1.3" redirectPort="8443" />
改完之后,去云E腾讯云-安全组-配置规则-新增8081、8082、8083三个端口访问权限
接着去启动3个tomcat
[root@VM_0_11_centos conf]# cd /usr/local/tomcat/apache-tomcat-1/bin [root@VM_0_11_centos bin]# ./startup.sh Using CATALINA_BASE: /usr/local/tomcat/apache-tomcat-1 Using CATALINA_HOME: /usr/local/tomcat/apache-tomcat-1 Using CATALINA_TMPDIR: /usr/local/tomcat/apache-tomcat-1/temp Using JRE_HOME: /usr Using CLASSPATH: /usr/local/tomcat/apache-tomcat-1/bin/bootstrap.jar:/usr/local/tomcat/apache-tomcat-1/bin/tomcat-juli.jar Tomcat started. [root@VM_0_11_centos bin]# cd /usr/local/tomcat/apache-tomcat-2/bin [root@VM_0_11_centos bin]# ./startup.sh Using CATALINA_BASE: /usr/local/tomcat/apache-tomcat-2 Using CATALINA_HOME: /usr/local/tomcat/apache-tomcat-2 Using CATALINA_TMPDIR: /usr/local/tomcat/apache-tomcat-2/temp Using JRE_HOME: /usr Using CLASSPATH: /usr/local/tomcat/apache-tomcat-2/bin/bootstrap.jar:/usr/local/tomcat/apache-tomcat-2/bin/tomcat-juli.jar Tomcat started. [root@VM_0_11_centos bin]# cd /usr/local/tomcat/apache-tomcat-3/bin [root@VM_0_11_centos bin]# ./startup.sh Using CATALINA_BASE: /usr/local/tomcat/apache-tomcat-3 Using CATALINA_HOME: /usr/local/tomcat/apache-tomcat-3 Using CATALINA_TMPDIR: /usr/local/tomcat/apache-tomcat-3/temp Using JRE_HOME: /usr Using CLASSPATH: /usr/local/tomcat/apache-tomcat-3/bin/bootstrap.jar:/usr/local/tomcat/apache-tomcat-3/bin/tomcat-juli.jar Tomcat started.
停掉tomcat服务是在bin下执行./shutdown.sh
启动完成后,在浏览器上分别然后访问h8081
,8082
,8083,
会发现都可以访问到了。
为了验证方便,修改tomcat首页/usr/local/tomcat/apache-tomcat-1/webapps/ROOT,打开index.jsp文件,把Home 分别改成Home8081,Home8082,Home8083
nginx配置
前面一篇https://www.cnblogs.com/liushui0306/p/13177226.html在/usr/local/nginx/conf目录在nginx.conf配置里面把默认监听端口改成了82
配置单个tomcat:
当我们访问nginx对外端口82时,让nginx指向8081
#配置8081端口
[root@VM_0_11_centos ~]# vim /usr/local/nginx/conf/nginx.conf
#把location 这项改成proxy_pass http://49.233.x.x:8081;
注意后面有个分号
server { listen 82; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location / { proxy_pass http://49.233.xx.xx:8081; root html; index index.html index.htm; }
编辑完成后:wq保存退出,执行reload,重新加载nginx文件
[root@VM_0_11_centos sbin]# ./nginx -s reload
接着在浏览器输入http://49.233.x.x:82
就能访问到8081的tomcat首页了,之前是访问的nginx页面,说明监听成功
负载均衡配置方式
轮询访问
一台服务配置好了,接着把三个tomcat服务全部放到一块,让访问http://49.233.x.x:81
能自动分配到8081、8082、8083这三个服务器上,实现负载均衡.
vim /usr/local/nginx/conf/nginx.conf,将多个服务器ip地址填进去就可以了
upstream tomcats { server 49.233.xx.xx:8081; server 49.233.xx.xx:8082; server 49.233.xx.xx:8083; } server { listen 82; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location / { proxy_pass http://tomcats; root html; index index.html index.htm; }
编辑完成后:wq保存退出,执行reload,重新加载nginx文件
[root@VM_0_11_centos ~]# cd /usr/local/nginx/sbin
[root@VM_0_11_centos sbin]# ./nginx -s reload
接着在浏览器输入http://49.233.x.x:82
,多次刷新,会发现tomcat首页轮询显示Home8081、Home8082、Home8083
加权轮询
如果3台服务器的性能和配置不一样,我们希望访问某台服务器的权重加大,只需加一个参数就可以
upstream tomcats { server 49.233.216.185:8081 weight=2; server 49.233.216.185:8082 weight=4; server 49.233.216.185:8083 weight=4; } server { listen 82; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location / { proxy_pass http://tomcats; root html; index index.html index.htm; }
跟上面步骤一样,改完之后./nginx -s reload
,访问10次,会有4次出现Home8083
ip_hash解决session共享问题
涉及到不同的ip访问多个服务器会出现session不共享的问题,可以加个参数:ip_hash,就可以解决了
upstream tomcats { ip_hash; server 49.233.216.185:8081 weight=2; server 49.233.216.185:8082 weight=4; server 49.233.216.185:8083 weight=4; }
设置链接超时
location / { proxy_pass http://tomcats; proxy_connect_timeout 36000s; proxy_send_timeout 36000s; proxy_read_timeout 36000s; root html; index index.html index.htm; }
proxy_connect_timeout 为连接应用服务器的超时时间,单位为秒
proxy_send_timeout 为发送请求到应用服务器的超时时间,单位为秒
proxy_read_timeout 为等待应用服务器响应的超时时间,单位为秒
upstream模块
upstream模块主要负责负载均衡的配置,通过默认的轮询调度方式来分发请求到后端服务器,配置参数
-
ip_hash:指定请求调度算法,默认是weight权重轮询调度,可以指定
-
server host:port:分发服务器的列表配置
-
down:表示该主机暂停服务
-
max_fails:表示失败最大次数,超过失败最大次数暂停服务
-
fail_timeout:表示如果请求受理失败,暂停指定的时间之后重新发起请求
upstream name { ip_hash; server 192.168.x.xx:8080; server 192.168.x.xx:8081 down; server 192.168.x.xx:8082 max_fails=3; server 192.168.x.xx:8083 fail_timeout=20s; server 192.168.x.xx:8084 max_fails=3 fail_timeout=20s; }
到此为止负载均衡环境就脚本搭建完成,那么对外只需开放81端口,就可以了,8081,8082,8083这三个服务端口可以关掉,这样用户就感知到是只访问一个服务。
当然这个不是完美的,当81端口这个主机服务挂掉时候,那整个服务就挂了,所以需要有备机服务,在多个机器上搭建备机服务(和主机服务环境一致),同样可以设置权重
这样多个机器,其中某个服务机器挂了也不影响。