場景
Nginx配置例項-負載均衡例項:平均訪問多臺伺服器:
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/103019576
以上實現Nginx的http協議的負載均衡,如果使用Nginx實現TCP協議的負載均衡比如配置Mysql的連線,可使用如下方式。
首先搭建兩臺mysql和一臺nginx的測試環境。這裡使用Docker Compose搭建。
注:
部落格:
https://blog.csdn.net/badao_liumang_qizhi
實現
1、測試環境搭建
Docker Compose中編排Nginx時yml的寫法
nginx:
image:
nginx:latest
privileged: true
ports:
- 100:100
volumes:
-
./nginx/etc/nginx.conf:/etc/nginx/nginx.conf
-
./nginx/logs:/var/log/nginx
-
./nginx/etc/conf.d:/etc/nginx/conf.d
注意這裡在docker-compose.yml所在的路徑下新建nginx目錄,並在目錄下新建etc和logs目錄
另外注意nginx做資料卷對映時不要直接講以上nginx的配置檔案ngin.conf進行對映,另外兩個目錄logs和conf.d可以直接進行對映。
需要先手動將nginx.conf配置檔案上傳至宿主機目錄下再啟動容器。
原因是不支援直接掛載檔案,只能掛載資料夾,想要掛載檔案,必須宿主機也要有對應的同名檔案。
如果強行直接掛載,則啟動容器後會提示
mounting "/root/nginx.conf" to rootfs at "/etc/nginx/nginx.conf" caused: mount through procfd: not a directory: unknown:
Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type.
那麼如何獲取nginx.conf資料卷對映的配置檔案?
先使用docker命令執行一個nginx容器,然後進入容器內部,將配置檔案複製出來即可。
docker中拉取nginx映象
docker pull nginx
docker中啟動nginx容器
docker run -d --name nginx nginx
docker中複製nginx容器內配置檔案到當前目錄
docker cp nginx:/etc/nginx/nginx.conf $PWD/
執行效果
配置檔案複製成功後就可以停掉並刪除容器了。
docker中停掉並刪除nginx容器
docker container stop nginx
docker container rm nginx上面nginx.conf複製到nginx/etc目錄下之後,需要授予許可權
chmod 777 nginx.conf
Docker Compose編排mysql時yml的寫法
mysql1:
image:
mysql:8.0
command: --lower_case_table_names=1
environment:
MYSQL_DATABASE: test
MYSQL_ROOT_PASSWORD: ABC@123!
MYSQL_ROOT_HOST: '%'
TZ: Asia/Shanghai
ports:
- "301:3306"
volumes:
-
./mysql1/data:/var/lib/mysql
這裡設定root密碼,並允許遠端連線,然後埠對映為301到容器內3306
同理再搭建一個mysql,對映埠302
mysql2:
image:
mysql:8.0
command: --lower_case_table_names=1
environment:
MYSQL_DATABASE: test
MYSQL_ROOT_PASSWORD: ABC@123!
MYSQL_ROOT_HOST: '%'
TZ: Asia/Shanghai
ports:
- "302:3306"
volumes:
-
./mysql2/data:/var/lib/mysql
2、使nginx與兩個mysql使用自定義網路方式互通
完整yml配置檔案
version: "3.8"
services:
mysql1:
image: mysql:8.0
command: --lower_case_table_names=1
environment:
MYSQL_DATABASE: test
MYSQL_ROOT_PASSWORD: ABC@123!
MYSQL_ROOT_HOST: '%'
TZ: Asia/Shanghai
ports:
- "301:3306"
volumes:
-
./mysql1/data:/var/lib/mysql
networks:
balancenet:
ipv4_address: 192.128.0.11
mysql2:
image: mysql:8.0
command: --lower_case_table_names=1
environment:
MYSQL_DATABASE: test
MYSQL_ROOT_PASSWORD: ABC@123!
MYSQL_ROOT_HOST: '%'
TZ: Asia/Shanghai
ports:
- "302:3306"
volumes:
-
./mysql2/data:/var/lib/mysql
networks:
balancenet:
ipv4_address: 192.128.0.12
nginx:
image:
nginx:latest
privileged: true
ports:
- 100:100
volumes:
-
./nginx/etc/nginx.conf:/etc/nginx/nginx.conf
-
./nginx/logs:/var/log/nginx
-
./nginx/etc/conf.d:/etc/nginx/conf.d
networks:
balancenet:
ipv4_address: 192.128.0.13
networks:
balancenet:
ipam:
config:
- subnet: 192.128.0.0/24
3、啟動測試環境
docker compose up
這裡不新增-d,便於檢視日誌。
確保無報錯,三個容器啟動成功
4、nginx配置修改實現tcp協議負載均衡
分別連線上面啟動的301和302的mysql,建立不同的資料庫名稱為301和302。
要實現連線nginx代理的100埠的mysql時,負載均衡的連線到兩個資料庫,可以透過檢視資料庫名稱進行結果驗證。
在 NGINX 的 stream 模組內使用 upstream 程式碼塊對 TCP 伺服器實施負載均衡。
上面容器內複製出來的nginx.conf的檔案未修改之前為
新增如下配置
stream{
upstream mysql{
server 192.128.0.11:3306 weight=1;
server 192.128.0.12:3306 weight=1;
}
server {
listen 100;
server_name 192.128.0.13;
proxy_pass mysql;
}
}
新增之後完整的nginx.conf檔案
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/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 /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
stream{
upstream mysql{
server 192.128.0.11:3306 weight=1;
server 192.128.0.12:3306 weight=1;
}
server {
listen 100;
server_name 192.128.0.13;
proxy_pass mysql;
}
}
上面的配置的 server 程式碼塊指示 NGINX 偵聽 TCP 埠 100,並在兩個 MySQL 資料庫讀取副本之間實施負載均衡。
上面兩個mysql的root密碼是一致,下面用mysql客戶端工具比如Navicat等使用同樣的密碼連線和關閉資料庫,驗證是否顯示不同
的資料庫名稱。
總結:
http 和 stream 上下文之間的主要區別在於它們在 OSI 模型的不同層上執行。
http 上下文在應用層(七層)執行,stream 在傳輸層(四層)執行。
這並不意味著 stream 上下文不能透過一些巧妙的指令碼獲得應用感知能力,
而是說 http 上下文是專門為了完全理解 HTTP 協議而設計的,
stream 上下文預設情況下只能對資料包進行路由和負載均衡。
TCP 負載均衡由 NGINX 的 stream 模組定義。
stream 模組與 HTTP 模組一樣,允許您定義上游(upstream)伺服器池並配置偵聽伺服器。
在配置伺服器偵聽給定埠時,您必須定義待偵聽的埠或者地址加埠(可選)。
然後您必須配置目標服務,無論這是連線另一個地址的直接反向代理還是上游資源池。
配置中有許多選項可以改變 TCP 連線反向代理的屬性,包括 SSL/TLS 驗證限制、超時和 keepalive 等。
這些代理選項的一些值可以是(或者包含)變數,例如下載速率、驗證 SSL/TLS 證書時使用的名稱等。
TCP 與 HTTP 負載均衡中的 upstream 指令非常相似,它們均將上游資源定義為伺服器,
配置格式同樣為 Unix 套接字、IP 或 FQDN,此外伺服器 weight 引數、最大連線數、DNS 解析器、
連線數緩增期以及判斷伺服器是啟用狀態、故障狀態還是備用模式的引數也都相似。