linux之负载均衡Nginx+多开Tomcat
在负载均衡之前,我们必须先了解Nginx。
nginx简介
Nginx就是一个高性能的HTTP和反向代理的web服务器。特点就是占用内存小,并发性能强。
Nginx可以作为静态页面的web服务器,同时支持CGI协议的动态语言(PHP).不支持Java、只能配置tomcat等服务器部署java程序,nginx代理tomcat的服务器。Nginx服务区可以支持最高5W个并发连接数(Tomcat一般支持1K-5K)。
Nginx反向代理
学习反向代理之前首先需要了解正向代理。所谓的正向代理举例说明就是在整个局域网外的所有网络资源视为一个庞大的资源库,局域网内的用户访问这些外部资源就需要一个正向代理服务器。正向代理最大的特点就是用户明确感知数据的来源。
而反向代理和正向代理最大的区别就是客户端对代理的无感知。客户端把请求交给反向代理服务器,而反向代理服务器把服务器的资源返回给哭护短,客户端是无法感知数据的来源。对于整个服务端的体系来说,客户端只需要知道代理服务器的IP而不知道真实提供数据的服务器的IP。这也是为了隐藏真实服务器的IP和端口。也是一种安全的手段。
说到这里,那么什么才是负载均衡呢?
负载均衡
将原本同一类型的请求集中在单一服务器的模式修改为多个同服务器处理同一类型请求。从而降低每台服务器的压力并且提升每次请求的响应时间。这种模式就是负载均衡。
了解完Nginx过后,接下来就是安装我们的Nginx
直接去官网下载即可:nginx.org 选择需要的版本进行下载
关于Nginx的详细步骤,可以进入主页文章linux安装Nginx教程,这里就不过多赘述了。
这里默认大家都已经安装好了。
Nginx的配置文件
nginx的配置文件位置在/usr/local/nginx/conf目录下,名字为nginx.conf
主要由三部分组成
1.全局配置块
从配置文件开始到events块之间的部分就是全局配置块的部分
这段主要配置nginx的一些全局配置,比如pid存在的位置,日志存放的日志,其中重点的配置就是worker_processes,此配置结合events块中的worker_connections来决定资产的最大的并发数量、但是不能随意修改需要根据硬件配置进行修改2.events配置块
主要配置的就是Nginx服务器和用户的网络连接。3.http配置块
3.1 http全局块
http配置开始到server块之间的配置部分
主要定义了引入文件的MIME类型,连接的超时时间等
3.2 server块
3.2.1 server全局块
主要配置了虚拟主题的监听的端口和IP地址
3.2.2 location快
可以同时存在多个。主要配置的就是请求和真实服务器之间的关系
实际操作
接下来我们需要提前准备好两个SSM项目,后面的步骤我会一步步教大家
克隆
首先打开我们的虚拟机,然后进入克隆
根据安装步骤一直下一步就好。
到这里需要创建完成克隆!!!创建上面的仅仅只是快捷方式,没有实际的克隆
建议不要放到C盘,改完名称过后,稍等片刻就能够克隆成功了。
创建成功之后,我们开启克隆的虚拟机
因为我们后续需要开启两个虚拟机,两个IP地址一样会有所冲突,所以我们需要修改一下这个虚拟机的IP地址。
这里教大家一个简单的方法,能够更快的修改IP地址
在这里可以直接手动修改IP地址,不需要和我一样,按照你自己修改的IP地址来也是可以的
修改之后,别忘了点击右上角的应用。
修改完然后再我们需要重启一下网络服务才能生效,所以我们回到主页面,右键打开终端
执行以下命令进行刷新网络
systemctl restart network.service
刷新过后,我们使用以下指令ifconfig看看IP地址是否已经正常修改
这里也是能够看到我们的IP已经成功修改
接下来打开我们的克隆前的虚拟机。
然后找到我们早已准备好的war包【-------也就是提前准备好的SSM项目】
打包(war)
【--------------------------要是不会打包没关系,这里会教大家如何打包,若是已经打包好,可以跳过打包步骤】
找到我们的项目,点击右侧的maven,双击install即可完成打包
同样的步骤,第二个项目也是如此,我就不过多赘述
那么现在有的小伙伴就会问了,打完包我们的war去哪了?
进入IDEA的setting之中,记住仓库地址
接下来就是根据仓库地址,去找我们的war包
根据pow.xml文件中的路径去寻找war包
不难发现我的路径在原本的仓库路径下,接上现在的路径,每个人的路径肯呢个不一样,所以请仔细查看自己仓库
我的路径是C:\Users\Administrator\.m2\repository\com\demo\JavaWeb-tomcat\1.0-SNAPSHOT
在这个文件夹下面可以找到项目所打成的war包
同样的方式,我们可以做出两份war包来。
反向代理
打开我们的Xftp,按照新的IP地址进行连接传输文件(也就是克隆之后的虚拟机)
修改完成之后,我们需要重启Tomcat服务
进入到Tomcat8/bin中,开启服务
cd opt/soft/tomcat8/bin/ 切换到Tomcat服务器下
./startup.sh 开启服务
通过浏览器测试一下是否可用就行。
如果出现猫咪,那就是克隆没什么问题。
接下来使用Nginx,也就是访问Nginx,他会自动给我们转发到Tomcat服务器上
首先进入到nginx目录的sbin/下开启Nginx服务器,如果开启过了,可以跳过此步骤
cd /usr/local/nginx/sbin/
./nginx
接着需要修改nginx配置
我们需要的是在第一个虚拟机中启用Nginx服务,然后经过修改配置文件,将访问路径转交给Tomcat
修改配置文件如下
#user nobody;
worker_processes 1;#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;#pid logs/nginx.pid;events {worker_connections 1024;
}http {include mime.types;default_type application/octet-stream;#log_format main '$remote_addr - $remote_user [$time_local] "$request" '# '$status $body_bytes_sent "$http_referer" '# '"$http_user_agent" "$http_x_forwarded_for"';#access_log logs/access.log main;sendfile on;#tcp_nopush on;#keepalive_timeout 0;keepalive_timeout 65;#gzip on;server {listen 80;server_name localhost;#这里是用来映射路径,也就是说当端口80监听到后会自动跳转 localhost#跳转结束后 我们需要的是将地址映射到新的地址中#也就是第二个虚拟机中的Tomcat访问地址location / {proxy_pass http://192.168.100.101:8080;}#charset koi8-r;#access_log logs/host.access.log main;#将原本默认的注释掉#location / {# root html;# index index.html index.htm;#}#error_page 404 /404.html;# redirect server error pages to the static page /50x.html#error_page 500 502 503 504 /50x.html;location = /50x.html {root html;}# proxy the PHP scripts to Apache listening on 127.0.0.1:80##location ~ \.php$ {# proxy_pass http://127.0.0.1;#}# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000##location ~ \.php$ {# root html;# fastcgi_pass 127.0.0.1:9000;# fastcgi_index index.php;# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;# include fastcgi_params;#}# deny access to .htaccess files, if Apache's document root# concurs with nginx's one##location ~ /\.ht {# deny all;#}}# another virtual host using mix of IP-, name-, and port-based configuration##server {# listen 8000;# listen somename:8080;# server_name somename alias another.alias;# location / {# root html;# index index.html index.htm;# }#}# HTTPS server##server {# listen 443 ssl;# server_name localhost;# ssl_certificate cert.pem;# ssl_certificate_key cert.key;# ssl_session_cache shared:SSL:1m;# ssl_session_timeout 5m;# ssl_ciphers HIGH:!aNULL:!MD5;# ssl_prefer_server_ciphers on;# location / {# root html;# index index.html index.htm;# }#}}
保存过后,需要重启Nginx服务器
./nginx -s stop
/.nginx
这时候我们就可以测试看看能不能通过访问Nginx到Tomcat中
这里我们能够清楚的看到通过192.168.100.100:80/ssm2访问到第二台虚拟机的tomcat部署的项目
这样一来,我们就部署成功了。
当然,这里也只是第一步,我们只是成功使用Nginx部署,然后让外部访问的时候,能够通过Nginx访问到Tomcat中的项目,也就是反向代理。
但要实现负载均衡还差点意思。
负载均衡前面已经说过,这里再强调一遍,用通熟易懂的话来讲,就是用户访问Nginx,信息量过大时,Tomcat负载较重,为了解决问题,提出负载均衡。
这个负载均衡也就是Nginx同时与多个Tomcat建立关系,通过合理的算法将负载平摊给各个Tomcat,增加响应效率。
那么接下来就需要在第二个虚拟机上部署多个Tomcat,我们以两个为例,再多了也都是一样的道理。
负载均衡
要想实现一台电脑同时部署多个Tomcat,其实也不难。
我们只需要将Tomcat多复制几台,然后开放端口不一致就可以,然后通过修改配置文件,让它实现负载均衡,根据一定的算法,访问不同的Tomcat
首先进入到我们的软件目录下【---提醒一下,这个是你自己放文件的路径】
cd /root/opt/soft/
接下来就是复制一份文件了,我们还是把Tomcat最初版留着,当做一个拷贝备份文件,我们通过指令创建两个Tomcat
cp -a tomcat8/ tomcat8080
cp -a tomcat8/ tomcat8081
后面是复制后的名字,你也可以和我的不一样,取什么名字随意
创建好后,我们需要修改他们两个的端口,否则多个Tomcat同时开启会出问题。
使用Xftp软件,进入到conf文件当中
然后编译server.xml文件,去修改端口
我们普通的Tomcat8就不在使用,而是作为一个备份文件,可以提前把它给关了。
将配置文件中的初始端口给修改即可
端口可以随意修改,当然还是超过1023以上的会更好。
<?xml version="1.0" encoding="UTF-8"?>
<!--Licensed to the Apache Software Foundation (ASF) under one or morecontributor license agreements. See the NOTICE file distributed withthis 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 withthe License. You may obtain a copy of the License athttp://www.apache.org/licenses/LICENSE-2.0Unless required by applicable law or agreed to in writing, softwaredistributed 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 andlimitations under the License.
-->
<!-- Note: A "Server" is not itself a "Container", so you may notdefine 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 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" /><!-- Global JNDI resourcesDocumentation at /docs/jndi-resources-howto.html--><GlobalNamingResources><!-- Editable user database that can also be used byUserDatabaseRealm 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 sharea 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 receivedand responses are returned. Documentation at :Java HTTP Connector: /docs/config/http.htmlJava AJP Connector: /docs/config/ajp.htmlAPR (HTTP/AJP) Connector: /docs/apr.htmlDefine a non-SSL/TLS HTTP/1.1 Connector on port 8080--><Connector port="8081" protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8444" /><!-- A "Connector" using the shared thread pool--><!--<Connector executor="tomcatThreadPool"port="8080" protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443" />--><!-- Define a SSL/TLS HTTP/1.1 Connector on port 8443This connector uses the NIO implementation. The defaultSSLImplementation will depend on the presence of the APR/nativelibrary and the useOpenSSL attribute of theAprLifecycleListener.Either JSSE or OpenSSL style configuration may be used regardless ofthe SSLImplementation selected. JSSE style configuration is used below.--><!--<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"maxThreads="150" SSLEnabled="true"><SSLHostConfig><Certificate certificateKeystoreFile="conf/localhost-rsa.jks"type="RSA" /></SSLHostConfig></Connector>--><!-- Define a SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2This connector uses the APR/native implementation which always usesOpenSSL for TLS.Either JSSE or OpenSSL style configuration may be used. OpenSSL styleconfiguration is used below.--><!--<Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"maxThreads="150" SSLEnabled="true" ><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 port="8010" protocol="AJP/1.3" redirectPort="8444" /><!-- An Engine represents the entry point (within Catalina) that processesevery request. The Engine implementation for Tomcat stand aloneanalyzes the HTTP headers included with the request, and passes themon 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 passwordsvia a brute-force attack --><Realm className="org.apache.catalina.realm.LockOutRealm"><!-- This Realm uses the UserDatabase configured in the global JNDIresources under the key "UserDatabase". Any editsthat are performed against this UserDatabase are immediatelyavailable for use by the Realm. --><Realm className="org.apache.catalina.realm.UserDatabaseRealm"resourceName="UserDatabase"/></Realm><Host name="localhost" appBase="webapps"unpackWARs="true" autoDeploy="true"><!-- SingleSignOn valve, share authentication between web applicationsDocumentation at: /docs/config/valve.html --><!--<Valve className="org.apache.catalina.authenticator.SingleSignOn" />--><!-- Access log processes all example.Documentation at: /docs/config/valve.htmlNote: The pattern used is equivalent to using pattern="common" --><Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"prefix="localhost_access_log" suffix=".txt"pattern="%h %l %u %t "%r" %s %b" /></Host></Engine></Service>
</Server>
我这里就是把原本的端口都加一,其他的都没怎么改变
然后另外一个Tomcat8080默认就行。
接下来我们只需要修改Nginx配置文件即可,前面使用反向代理的时候,我们是直接把映射路径给写死了,所以导致无法映射多个Tomcat,现在我们需要一个新的办法去解决。
再次进入到我们Xftp,修改Nginx配置
#user nobody;
worker_processes 1;#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;#pid logs/nginx.pid;events {worker_connections 1024;
}http {include mime.types;default_type application/octet-stream;#log_format main '$remote_addr - $remote_user [$time_local] "$request" '# '$status $body_bytes_sent "$http_referer" '# '"$http_user_agent" "$http_x_forwarded_for"';#access_log logs/access.log main;sendfile on;#tcp_nopush on;#keepalive_timeout 0;keepalive_timeout 65;#gzip on;#使用upstream可以实现负载均衡upstream healthserver{server 192.168.100.101:8080;server 192.168.100.101:8081;}server {#listen 80;#server_name localhost;listen 80;server_name 192.168.100.100;location / {#通过访问根目录映射到healthserver地址上#根据负载均衡的策略,会自动选择Tomcat服务器proxy_pass http://healthserver;}#这里是用来映射路径,也就是说当端口80监听到后会自动跳转 localhost#跳转结束后 我们需要的是将地址映射到新的地址中#也就是第二个虚拟机中的Tomcat访问地址#location / {# proxy_pass http://192.168.100.101:8080;#}#charset koi8-r;#access_log logs/host.access.log main;#将原本默认的注释掉#location / {# root html;# index index.html index.htm;#}#error_page 404 /404.html;# redirect server error pages to the static page /50x.html#error_page 500 502 503 504 /50x.html;location = /50x.html {root html;}# proxy the PHP scripts to Apache listening on 127.0.0.1:80##location ~ \.php$ {# proxy_pass http://127.0.0.1;#}# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000##location ~ \.php$ {# root html;# fastcgi_pass 127.0.0.1:9000;# fastcgi_index index.php;# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;# include fastcgi_params;#}# deny access to .htaccess files, if Apache's document root# concurs with nginx's one##location ~ /\.ht {# deny all;#}}# another virtual host using mix of IP-, name-, and port-based configuration##server {# listen 8000;# listen somename:8080;# server_name somename alias another.alias;# location / {# root html;# index index.html index.htm;# }#}# HTTPS server##server {# listen 443 ssl;# server_name localhost;# ssl_certificate cert.pem;# ssl_certificate_key cert.key;# ssl_session_cache shared:SSL:1m;# ssl_session_timeout 5m;# ssl_ciphers HIGH:!aNULL:!MD5;# ssl_prefer_server_ciphers on;# location / {# root html;# index index.html index.htm;# }#}}
修改完成过后,需要你将新建的两个Tomcat服务器启动,这些我就不演示了。
也就是cd 进入到文件夹bin目录下,然后执行./startup.sh命令即可打开
然后别忘了重启Nginx
(这里是第一个虚拟机)进入到usr/local/nginx/sbin目录下,执行./nginx命令重启服务(注意重启服务就是关闭再开启)
好了,接下来就是配置结束后所成功的页面
负载均衡策略
1.轮询(默认)
每个请求按照请求时间依次分配给不同的Tomcat服务器。
优点:当某个服务器宕机的时候会自动剔除集群2.权重
在配置负载均衡的时候可以设置权重,使用weight属性来给具体的服务器赋权。权重越大承担的请求越多3.ip_hash
每个请求都会根据请求的IP地址计算hash值分配给不同的服务器。这样就能保证同一个用户在不更改IP的情况下访问的永远是同一个服务器,这样就可以解决session问题。
upstream healthserver{
ip_hash;
server 192.168.100.101:8080;
server 192.168.100.101:8081;
}
4.
fair
按照tomcat处理请求的响应时间进行分配。响应时间越短优先分配
upstream healthserver{
server 192.168.100.101:8080;
server 192.168.100.101:8081;
fair;
}