搜尋
首頁運維NginxDebian下搭建Nginx和Tomcat伺服器實現負載平衡的方法

負載平衡的基本概念

負載平衡(load balancing)是一種電腦網路技術,用來在多個電腦(電腦叢集)、網路連線、cpu、磁碟驅動器或其他資源中分配負載,以達到優化資源使用、最大化吞吐率、最小化回應時間、同時避免過載的目的。

使用具有負載平衡的多個伺服器元件,取代單一的元件,可以透過冗餘提高可靠性。負載平衡服務通常是由專用軟體和硬體來完成。

負載平衡最重要的一個應用是利用多台伺服器提供單一服務,有時也稱之為伺服器農場。通常,負載平衡主要應用於web網站,大型的internet relay chat網絡,高流量的文件下載網站,nntp(network news transfer protocol)服務和dns服務。現在負載平衡器也開始支援資料庫服務,稱為資料庫負載平衡器。

對於互聯網服務,負載平衡器通常是一個軟體程序,這個程序偵聽一個外部端口,互聯網用戶可以通過這個端口來訪問服務,而作為負載平衡器的軟體會將用戶的請求轉發給後台內網伺服器,內網伺服器將請求的回應傳回給負載平衡器,負載平衡器再將回應傳送到用戶,這樣就向網際網路用戶隱藏了內網結構,阻止了用戶直接存取後台(內網)伺服器,使得伺服器更加安全,可以阻止對核心網路堆疊和運行在其它連接埠服務的攻擊。

當所有後台伺服器發生故障時,有些負載平衡器會提供一些特殊的功能來處理這種情況。例如轉發請求到一個備用的負載平衡器、顯示一條關於服務中斷的訊息等。負載平衡器讓it團隊可以顯著提高容錯能力。它可以自動提供大量的容量以處理任何應用程式流量的增加或減少。

在下面我們就來看看如何建立具備負載平衡能力的nginx tomcat伺服器組合:

0.前期準備

使用debian環境。安裝nginx(預設安裝),一個web項目,安裝tomcat(預設安裝)等。

1.一份nginx.conf設定檔

# 定义nginx运行的用户 和 用户组 如果对应服务器暴露在外面的话建议使用权限较小的用户 防止被入侵
# user www www;
#nginx进程数, 建议设置为等于cpu总核心数
worker_processes 8;
#开启全局错误日志类型
error_log /var/log/nginx/error.log info;
#进程文件
pid /var/run/nginx.pid;
#一个nginx进程打开的最多文件描述数目 建议与ulimit -n一致
#如果面对高并发时 注意修改该值 ulimit -n 还有部分系统参数 而并非这个单独确定
worker_rlimit_nofile 65535;
events{
 #使用epoll模型提高性能
 use epoll;
 #单个进程最大连接数
 worker_connections 65535;
}
http{
 #扩展名与文件类型映射表
 include mime.types;
 #默认类型
 default_type application/octet-stream;
 sendfile on;
 tcp_nopush on;
 tcp_nodelay on;
 keepalive_timeout 65;
 types_hash_max_size 2048;
 #日志
 access_log /var/log/nginx/access.log;
 error_log /var/log/nginx/error.log;
 #gzip 压缩传输
 gzip on;
 gzip_min_length 1k; #最小1k
 gzip_buffers 16 64k;
 gzip_http_version 1.1;
 gzip_comp_level 6;
 gzip_types text/plain application/x-javascript text/css application/xml application/javascript;
 gzip_vary on;
 #负载均衡组
 #静态服务器组
 upstream static.zh-jieli.com {
 server 127.0.0.1:808 weight=1;
 }
 #动态服务器组
 upstream zh-jieli.com {
 server 127.0.0.1:8080;
 #server 192.168.8.203:8080;
 }
 #配置代理参数
 proxy_redirect off;
 proxy_set_header host $host;
 proxy_set_header x-real-ip $remote_addr;
 proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;
 client_max_body_size 10m;
 client_body_buffer_size 128k;
 proxy_connect_timeout 65;
 proxy_send_timeout 65;
 proxy_read_timeout 65;
 proxy_buffer_size 4k;
 proxy_buffers 4 32k;
 proxy_busy_buffers_size 64k;
 #缓存配置
 proxy_cache_key '$host:$server_port$request_uri';
 proxy_temp_file_write_size 64k;
 proxy_temp_path /dev/shm/jielierp/proxy_temp_path;
 proxy_cache_path /dev/shm/jielierp/proxy_cache_path levels=1:2 keys_zone=cache_one:200m inactive=5d max_size=1g;
 proxy_ignore_headers x-accel-expires expires cache-control set-cookie;
server{
 listen 80;
 server_name erp.zh-jieli.com;
 location / {
 index index; #默认主页为 /index
 #proxy_pass http://jieli;
 }
 location ~ .*\.(js|css|ico|png|jpg|eot|svg|ttf|woff) {
 proxy_cache cache_one;
 proxy_cache_valid 200 304 302 5d;
 proxy_cache_valid any 5d;
 proxy_cache_key '$host:$server_port$request_uri';
 add_header x-cache '$upstream_cache_status from $host';
 proxy_pass http:
//static.zh-jieli.com;
 #所有静态文件直接读取硬盘
 # root /var/lib/tomcat7/webapps/jielierp/web-inf ;
 expires 30d; #缓存30天
 }
 #其他页面反向代理到tomcat容器
 location ~ .*$ {
 index index;
 proxy_pass http:
//zh-jieli.com;
 }
 }
 server{
 listen 808;
 server_name static;
 location / {
}
 location ~ .*\.(js|css|ico|png|jpg|eot|svg|ttf|woff) {
 #所有静态文件直接读取硬盘
 root /var/lib/tomcat7/webapps/jielierp/web-inf ;
 expires 30d; #缓存30天
 }
 }
}

基本上設定這個文件,就可以實作負載了。但是裡面的各種關係要了解就比較麻煩了。

2.基礎講解

現在假使有一台電腦192.168.8.203這台電腦,上面部署了tomcat,裡面8080埠有j2ee的服務,透過瀏覽器可以正常瀏覽網頁。現在有一個問題tomcat是比較全面的web容器,對靜態網頁的處理,應該是比較費資源的,特別是每次都要從磁碟讀取靜態頁面,然後再回傳。這中間會消耗tomcat的資源,可能會使那些動態頁面解析效能影響。秉承linux哲學,一個軟體只做一件事的原則。 tomcat就應該只處理jsp動態頁面。這裡就用到以前了解的nginx來進行反向代理。第一步代理,實現動靜網頁分離。這個很簡單的。

worker_processes 8;
 
 pid /var/run/nginx.pid;
 
 worker_rlimit_nofile 65535;
 
 events{
 use epoll;
 worker_connections 65535;
 }
 
 http{
 include mime.types;
 default_type application/octet-stream;
 sendfile on;
 tcp_nopush on;
 tcp_nodelay on;
 keepalive_timeout 65;
 types_hash_max_size 2048;
proxy_redirect off;
 proxy_set_header host $host;
 proxy_set_header x-real-ip $remote_addr;
 proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;
 client_max_body_size 10m;
 client_body_buffer_size 128k;
 proxy_connect_timeout 65;
 proxy_send_timeout 65;
 proxy_read_timeout 65;
 proxy_buffer_size 4k;
 proxy_buffers 4 32k;
 proxy_busy_buffers_size 64k;
 
 server{
 listen 80;
 server_name xxx.com;
 location / {
 index index; 
 }
 location ~ .*\.(js|css|ico|png|jpg|eot|svg|ttf|woff) {
 proxy_pass http:
//192.168.8.203:8080;
 expires 30d; 
 }
 location ~ .*$ {
 index index;
 proxy_pass http:
//192.168.8.203:8080;
 }
 }
 }

worker_processes 8;
pid /var/run/nginx.pid;
worker_rlimit_nofile 65535;
events{
 use epoll;
 worker_connections 65535;
 }
http{
 include mime.types;
 default_type application/octet-stream;
 sendfile on;
 tcp_nopush on;
 tcp_nodelay on;
 keepalive_timeout 65;
 types_hash_max_size 2048;
proxy_redirect off;
 proxy_set_header host $host;
 proxy_set_header x-real-ip $remote_addr;
 proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;
 client_max_body_size 10m;
 client_body_buffer_size 128k;
 proxy_connect_timeout 65;
 proxy_send_timeout 65;
 proxy_read_timeout 65;
 proxy_buffer_size 4k;
 proxy_buffers 4 32k;
 proxy_busy_buffers_size 64k;
server{
 listen 80;
 server_name xxx.com;
 location / {
 index index;
 }
 location ~ .*\.(js|css|ico|png|jpg|eot|svg|ttf|woff) {
 proxy_pass http:
//192.168.8.203:8080;
 expires 30d;
 }
 location ~ .*$ {
 index index;
 proxy_pass http:
//192.168.8.203:8080;
 }
 }
 }

修改nginx的設定檔 /etc/nginx/nginx.conf 預設有個設定檔的。其實大部分都差不多,關鍵還是server段的設定。這裡我設定server段如上所示,其他段複製就可以了。 server段裡面的解釋如下:第35行為監聽本機80埠。 37-39行表示預設主頁,這裡的預設主頁我是index.jsp 對應到我專案中是一個index。這裡依需求可以改為

index index.jsp index.html index.htm index.php

具體可參考其他文章。關鍵的第40行,這個是正規匹配,網路上也有很多介紹。這裡符合我專案中用到的所有靜態網頁後綴。第41行是代理地址。這裡我代理到我的web應用程式。 expires 30d快取為30天,這裡的快取是對應到前端頁面,使用者的cache-control字段,

Debian下搭建Nginx和Tomcat伺服器實現負載平衡的方法

第44行中那個正規是匹配無後綴的頁面。我專案中jsp頁面是無字尾的。這裡可以根據需要進行修改。同樣代理到192.168.8.203:8080這裡。到這裡你可能會問,我艹,這有毛意思啊?當然不是這樣了。簡單的實作靜動分離,我們可以把第41行進行修改,改為

root  /var/lib/tomcat7/webapps/jielierp/web-inf

表示不代理,直接從本地磁碟拿。透過查tomcat日誌可以看到靜態頁面是沒有訪問到的。但這又有一個問題。這樣的彈性不好,對下面要講到的記憶體快取和叢集部署來說都是不友善的,所以又有了下面的這種寫法。再寫一個server段。

server{
 listen 808;
 server_name static;
 location / {
}
location ~ .*\.(js|css|ico|png|jpg|eot|svg|ttf|woff) {
 #所有静态文件直接读取硬盘
 root /var/lib/tomcat7/webapps/jielierp/web-inf ;
 expires 30d; #缓存30天
 }
 }

這次監聽808端口,然後上上面的程式碼41行就可以修改為 proxy_pass http://192.168.8.203:808了,到這裡就實現了動靜分離了。如果多台伺服器,就修改對應的ip就可以了。如果發現連線不上的,要檢查防火牆,權限等外部問題,這個設定是這樣的。

如果单纯这样的话,我们会发现页面直接传输过于占用带宽。对应web的优化,这里想到的是通过对页面进行gzip压缩,然后传到用户那里,再解压,这样可以有效的减少带宽。这里就会用到nginx 的gzip模块了。默认的nginx是集成有gzip模块的。只需在http段增加下面配置即可。

gzip on;
 gzip_min_length 1k; #最小1k
 gzip_buffers 16 64k;
 gzip_http_version 1.1;
 gzip_comp_level 6;
 gzip_types text/plain application/x-javascript text/css application/xml application/javascript;
 gzip_vary on;

给个首页看看效果

Debian下搭建Nginx和Tomcat伺服器實現負載平衡的方法

不要在意请求数不一样,那两个请求是谷歌插件来的。不用觉得我在骗你。

作为假使有很多人访问的网站来说,缓存肯定是很重要的东西了。一开始是想通过插件,让nginx和redis进行合成,然后nginx使用redis来缓存的,但是发现配置起来很麻烦,还要自己下载插件,重新编译nginx,比较麻烦,所以这里觉得用nginx自带的缓存也是不错的选择。虽然效率比不上redis,但是有还是比没有好。nginx默认的缓存是磁盘文件系统的缓存,而不是像redis那样的内存级别的缓存。一开始我以为nginx就只有这样。后来查了写资料,才知道是我太天真了,对linux不是很了解导致的。linux的一切皆文件。原来我们可以把文件缓存到内存对应的linux文件系统中。我说的可能比较难以理解,请自行搜索/dev/shm 这个文件目录。我们把文件缓存到这个文件目录里,其实就相当与内存的缓存了。只不过还是靠文件系统管理。所以比不上自定义格式的redis那样的内存缓存。

在http段进行基本配置

#缓存配置
proxy_cache_key '$host:$server_port$request_uri';
proxy_temp_file_write_size 64k;
proxy_temp_path /dev/shm/jielierp/proxy_temp_path;
proxy_cache_path /dev/shm/jielierp/proxy_cache_path levels=1:2 keys_zone=cache_one:200m inactive=5d max_size=1g;
proxy_ignore_headers x-accel-expires expires cache-control set-cookie;

location ~ .*\.(js|css|ico|png|jpg|eot|svg|ttf|woff) {
 proxy_cache cache_one;
 proxy_cache_valid 200 304 302 5d;
 proxy_cache_valid any 5d;
 proxy_cache_key '$host:$server_port$request_uri';
 add_header x-cache '$upstream_cache_status from $host';
 proxy_pass http:
//192.168.8.203:808;
expires 30d; #缓存30天
 }

经过这两个的配置就基本能实现了,这里说几个注意项,也是困扰我很久的问题。上面第一段代码第6行,proxy_ignore_headers 如果web项目中的html的head头里面指定

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">

这些不缓存的话,就要加上proxy_ignore_headers的配置项了。还有一点就是/dev/shm下面的文件系统权限默认只给root用户,所以要chmod 777 -r /dev/shm 这样不是很安全的做法,如果实际上线可以给定某个用户组,关于用户组的设置是配置的第一行

user www www;

上面第二段代码的第6行是增加一个header字段方便查看是否击中缓存。

我们rm -rf /dev/shm/jielierp/proxy_* 下面的所有文件(注意这里如果是进行多次测试的话要nginx -s reload 重新读取配置或重启服务,因为你rm -rf只是删除了缓存文件,但是缓存的结构信息还在nginx进程里面,结构还在,如果不重启的话,是会出现访问不到的)

Debian下搭建Nginx和Tomcat伺服器實現負載平衡的方法

所以要记得重启哦。下面是运行效果

第一次访问

Debian下搭建Nginx和Tomcat伺服器實現負載平衡的方法

第二次访问,在浏览器中ctrl+shift+r 强制刷新

Debian下搭建Nginx和Tomcat伺服器實現負載平衡的方法

到这里就可以看到效果了。我们查看一下/dev/shm这个里面

Debian下搭建Nginx和Tomcat伺服器實現負載平衡的方法

到这里已经快结束了。最后也是比较关键的一个技术点,就是集群,集群,集群。这个就要用到upstream了,看到最开头的配置文件了吗,就是那个

#负载均衡组
#静态服务器组
upstream static {
 server 127.0.0.1:808 weight=1;
 server 192.168.8.203:808 weight=1;
}

#动态服务器组
upstream dynamic {
 server 127.0.0.1:8080;
 #server 192.168.8.203:8080;
}

上面那个就是集群组了。upstream是关键字,static 和 dynamic是两个服务器集群组的名称。以第一个为例,server 127.0.0.1:808 是服务器地址,后面的weight=1 是权重。有多个就写多个。亲测试过,集群中的一个坏了,不影响系统运行。至于更多的轮询规则,可以参考网上更多的资料。这里不多说。至于怎么使用呢? proxy_pass http://192.168.8.203:808 改为 proxy_pass http://static; 这样即可实现均衡。

到这里就结束了。把上面各个部分根据自己需求配置起来就可以实现单机房负载均衡了。 上面这种做法有一个缺点就是在前面的那一台nginx如果当机,后面所以机器就失去了被访问的能力了,所以需要在前面实现多个nginx多机房的负载。关于这个就是另外一个话题了。目前还没有研究。以后有机会再说了。

上面动态服务器组如果是那种需要保存用户状态的话,会有问题,就是session问题,比如我在server1进行登录后,下一次动态服务器组进行轮询后可能分配到server2,就会造成要重新登录。治标的办法是,配置轮询规则,根据用户请求的ip进行hash,然后分配对应的服务器。具体配置如下:

upstream dynamic{
ip_hash;
server 127.0.0.1:8080;
server 192.168.0.203:8080;
}

这样就可以实现一个用户对应一个服务器节点。这样就不会有重复登录的问题。另一种治本的办法是,利用缓存系统进行session的统一存储管理。

以上是Debian下搭建Nginx和Tomcat伺服器實現負載平衡的方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:亿速云。如有侵權,請聯絡admin@php.cn刪除
NGINX單元:架構及其工作原理NGINX單元:架構及其工作原理Apr 23, 2025 am 12:18 AM

NGINXUnit通過其模塊化架構和動態重配置功能提高了應用的性能和可管理性。 1)模塊化設計包括主控進程、路由器和應用進程,支持高效管理和擴展。 2)動態重配置允許在運行時無縫更新配置,適用於CI/CD環境。 3)多語言支持通過動態加載語言運行時實現,提升了開發靈活性。 4)高性能通過事件驅動模型和異步I/O實現,即使在高並發下也保持高效。 5)安全性通過隔離應用進程提高,減少應用間相互影響。

使用NGINX單元:部署和管理應用程序使用NGINX單元:部署和管理應用程序Apr 22, 2025 am 12:06 AM

NGINXUnit可用於部署和管理多種語言的應用。 1)安裝NGINXUnit。 2)配置它以運行不同類型的應用,如Python和PHP。 3)利用其動態配置功能進行應用管理。通過這些步驟,你可以高效地部署和管理應用,提升項目效率。

NGINX與Apache:Web服務器的比較分析NGINX與Apache:Web服務器的比較分析Apr 21, 2025 am 12:08 AM

NGINX更适合处理高并发连接,而Apache更适合需要复杂配置和模块扩展的场景。1.NGINX以高性能和低资源消耗著称,适合高并发。2.Apache以稳定性和丰富的模块扩展闻名,适合复杂配置需求。

NGINX單元的優勢:靈活性和性能NGINX單元的優勢:靈活性和性能Apr 20, 2025 am 12:07 AM

NGINXUnit通過其動態配置和高性能架構提升應用的靈活性和性能。 1.動態配置允許在不重啟服務器的情況下調整應用配置。 2.高性能體現在事件驅動和非阻塞架構以及多進程模型上,能夠高效處理並發連接和利用多核CPU。

NGINX與Apache:性能,可伸縮性和效率NGINX與Apache:性能,可伸縮性和效率Apr 19, 2025 am 12:05 AM

NGINX和Apache都是強大的Web服務器,各自在性能、可擴展性和效率上有獨特的優勢和不足。 1)NGINX在處理靜態內容和反向代理時表現出色,適合高並發場景。 2)Apache在處理動態內容時表現更好,適合需要豐富模塊支持的項目。選擇服務器應根據項目需求和場景來決定。

終極攤牌:nginx vs. apache終極攤牌:nginx vs. apacheApr 18, 2025 am 12:02 AM

NGINX適合處理高並發請求,Apache適合需要復雜配置和功能擴展的場景。 1.NGINX採用事件驅動、非阻塞架構,適用於高並發環境。 2.Apache採用進程或線程模型,提供豐富的模塊生態系統,適合複雜配置需求。

nginx行動:示例和現實應用程序nginx行動:示例和現實應用程序Apr 17, 2025 am 12:18 AM

NGINX可用於提升網站性能、安全性和可擴展性。 1)作為反向代理和負載均衡器,NGINX可優化後端服務和分擔流量。 2)通過事件驅動和異步架構,NGINX高效處理高並發連接。 3)配置文件允許靈活定義規則,如靜態文件服務和負載均衡。 4)優化建議包括啟用Gzip壓縮、使用緩存和調整worker進程。

NGINX單元:支持不同的編程語言NGINX單元:支持不同的編程語言Apr 16, 2025 am 12:15 AM

NGINXUnit支持多種編程語言,通過模塊化設計實現。 1.加載語言模塊:根據配置文件加載相應模塊。 2.應用啟動:調用語言運行時執行應用代碼。 3.請求處理:將請求轉發給應用實例。 4.響應返回:將處理後的響應返回給客戶端。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版