動態服務器的問題,往往就是並發能l力太弱,常常需要多台動態服務器一起提供服務。但是如何把並發的壓力分攤,這就是需要調度,采用一定的調度策略,將請求分發給不同的服務器,這就是Load Balance負載均衡。
1、負載均衡規划和准備
負載均衡各主機的網絡與規划
IP | 主機名 | 服務 | 軟件 |
10.0.0.141 | herine | 調度器 | Nginx |
10.0.0.175 | herine-web | Tomcat1 | JDK8、Tomcat9 |
10.0.0.176 | herine-web-node | Tomcat2 | JDK8、Tomcat9 |
在調度器上的實現域名解析:vim /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 10.0.0.175 harlan-web 10.0.0.176 harlan-web-node
2、Tomcat主機准備
在tomcat1和tomcat2節點上conf/server.xml
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="access" suffix=".log" pattern='%a %h %l "-" %t "%r" %s %b %D "%{Referer}i" "%{X-Forwarded-For}i" "%{User-Agent}i"' /> <Context path="/" docBase="/data/webapps/ROOT" debug="0" reloadable="true"></Context>
在tomcat1和tomcat2節點上/data/webapps/ROOT/index.jsp
<%@ page import="java.util.*" %> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>lbjsptest</title> </head> <body> <div>On <%=request.getServerName() %></div> <div><%=request.getLocalAddr() + ":" + request.getLocalPort() %></div> <div>SessionID = <span style="color:blue"><%=session.getId() %></span></div> <%=new Date()%> </body> </html>
Tomcat1(10.0.0.175)的配置是否正確
[root@herine ~]# curl -I 10.0.0.175 HTTP/1.1 200 Set-Cookie: JSESSIONID=39E7E70DFDE6567DA77504DEFC45758F; Path=/; HttpOnly Content-Type: text/html;charset=UTF-8 Content-Language: zh-CN Transfer-Encoding: chunked Date: Thu, 17 Sep 2020 06:12:45 GMT
Tomcat2(10.0.0.176)的配置是否正確
[root@herine ~]# curl -I 10.0.0.176 HTTP/1.1 200 Set-Cookie: JSESSIONID=FFB77376E2C24B63C725399E8A710205; Path=/; HttpOnly Content-Type: text/html;charset=UTF-8 Content-Language: zh-CN Transfer-Encoding: chunked Date: Thu, 17 Sep 2020 06:12:50 GMT
由上可知,兩台的Tomcat主機准備正確,訪問正常。
3、Nginx實現后端tomcat的負載均衡調度
1、配置Nginx的配置文件:vim /etc/nginx/nginx.conf
worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; upstream tomcat-pools{ server 10.0.0.175; server 10.0.0.176; } server { listen 80; server_name www.harlan-web.io; location / { proxy_pass http://tomcat-pools; include proxy.conf; } } }
2、配置負載配置文件:vim /etc/nginx/proxy.conf
proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; proxy_buffer_size 4K; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k;
重啟Nginx
systemctl restart nginx
通過瀏覽器打開:www.harlan-web.io
多次刷新后,可以看到每次刷新后,主機不一樣,而且SessionID也會不一樣。
Session會話
當瀏覽器第一次HTTP請求服務器端時,在服務器端產生一個隨機值既SessionID發送給瀏覽器,瀏覽器端收到后會保持這個sessionID在Cookie當中,這個Cookie值一般不能持久存儲,瀏覽器關閉就消失。瀏覽器在每一次提交HTTP請求的時候會把這個SessionID傳給服務器,服務器端就可以通過對比知道誰了。
- session通常會保存在服務器端內存,如果沒有持久化,則容易丟失。
- session會定時過期,過期后瀏覽器再訪問,服務端發現沒有此ID,將給瀏覽器端重新發新的SessionID
- 更新瀏覽器也將重新獲取新的sessionID
在upstream中使用ip_hash指令,使用客戶端IP地址Hash
worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; upstream tomcat-pools{ ip_hash; #啟動源地址hash server 10.0.0.175; server 10.0.0.176; } server { listen 80; server_name www.harlan-web.io; location / { proxy_pass http://tomcat-pools; include proxy.conf; } } }
再次重啟Nginx
systemctl restart nginx
接下來,打開瀏覽器:www.harlan-web.io,通過瀏覽器看到主機不變,sessionID也不變。
當關閉掉Tomcat2(10.0.0.176)的tomcat服務器后,再次刷新瀏覽器,有如下變化:
雖然,上述的方法實現客戶端在一段時間內找同一台Tomcat,從而避免切換后導致session丟失。但是如果tomcat節點掛掉,那么session依舊丟失。
推薦使用session共享服務器。使用redis、memcached做共享的session服務器。