Linux-Nginx負載均衡與代理

来源:https://www.cnblogs.com/world-of-yuan/archive/2023/02/22/17145890.html
-Advertisement-
Play Games

Nginx負載均衡與代理 一、代理概述 代理:外賣/中介/中間商 用戶無法直接做某些事情,通過中介進行處理,這個中介就是代理 用戶 >代理 >web節點,後面只有一個節點,一般使用的是nginx代理功能即可,後面如果有多個節點(也就是集群)的話,需要使用nginx負載均衡功能 二、代理分類 | 代理 ...


Nginx負載均衡與代理

一、代理概述

代理:外賣/中介/中間商 用戶無法直接做某些事情,通過中介進行處理,這個中介就是代理

用戶--->代理--->web節點,後面只有一個節點,一般使用的是nginx代理功能即可,後面如果有多個節點(也就是集群)的話,需要使用nginx負載均衡功能

二、代理分類

代理分類 方向 應用
正向代理 用戶(伺服器)--->代理--->外部(某網站) 伺服器通過代理實現共用上網/訪問某個網站
反向代理 用戶(app/瀏覽器)--->代理--->網站伺服器(WEB) 給網站設置個統一入口,後面是網站集群

三、極速上手指南

1.環境概述

角色 主機名 ip
代理 lb01 10.0.0.5/172.16.1.5
web web01 10.0.0.7/172.16.1.7
功能變數名稱 proxy.cn
站點目錄 /app/code/proxy/index.html
#配置nginx源
[root@lb01 ~]# cat /etc/yum.repos.d/nginx.repo 
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
#安裝nginx
[root@lb01 ~]# yum -y install nginx

2.環境準備

2.1 web伺服器

#配置代理使用的子配置文件
[root@web01 ~]# cat /etc/nginx/conf.d/proxy.cn.conf 
server{
	listen 80;
	server_name proxy.cn;
	root /app/code/proxy;
	error_log  /var/log/nginx/proxy.cn-error.log notice;
	access_log  /var/log/nginx/proxy.cn-access.log  main;

	location /{
		index index.html;
	
	}
	
}

#配置首頁文件
[root@web01 ~]# cat /app/code/proxy/index.html 
web01.proxy.cn

#測試web伺服器
[root@web01 ~]# curl -H Host:proxy.cn http://10.0.0.7
web01.proxy.cn

2.2 lb01代理伺服器

不需要配置站點目錄,僅僅配置轉發即可proxy_pass

[root@lb01 ~]# cat /etc/nginx/conf.d/proxy.cn.conf 
server{
	listen 80;
	server_name proxy.cn;
	error_log  /var/log/nginx/proxy.cn-error.log notice;
        access_log  /var/log/nginx/proxy.cn-access.log  main;
	
	location / {
		proxy_pass http://10.0.0.7;
		proxy_set_header Host $http_host;
		proxy_set_header X-Forwarded-For $remote_addr;	
	}

}

#測試代理
[root@lb01 ~]# curl -H Host:proxy.cn http://10.0.0.5
web01.proxy.cn

補充

proxy_pass指令: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass

四、代理案例

4.1 web有多個虛擬主機故障案例

故障現象:

web伺服器有多個虛擬主機的時候,通過代理訪問web出現異常,訪問的不是我們想要的虛擬主機

原因:

代理向後端web節點發出請求的時候,請求頭中的Host,唄修改成ip地址形式

相當於代理通過ip地址訪問web伺服器,只顯示預設的虛擬主機了

解決:

修改代理到web的請求頭,Host部分

proxy_set_header Host $http_host;



server{
	listen 80;
	server_name proxy.cn;
	error_log  /var/log/nginx/proxy.cn-error.log notice;
        access_log  /var/log/nginx/proxy.cn-access.log  main;
	
	location / {
		proxy_pass http://10.0.0.7;				#這一行的作用是,請求傳遞給指定的節點
		proxy_set_header Host $http_host;		#加了這一行,就會修改Host,不加的話,傳過去就是ip
	}
}

補充:

$http_host 是nginx的變數之一,用於取出Host的內容(功能變數名稱)

4.2 web記錄用戶真實的ip地址

現象:用戶請求經過代理,然後訪問web,web伺服器沒有記錄真實的客戶端的ip地址,而是記錄了代理的ip

解決:

在代理上面修改請求頭,最後在web伺服器上記錄真實的ip地址

proxy_set_header X-Forwarded-For $remote_addr;	


server{
	listen 80;
	server_name proxy.cn;
	error_log  /var/log/nginx/proxy.cn-error.log notice;
        access_log  /var/log/nginx/proxy.cn-access.log  main;
	
	location / {
		proxy_pass http://10.0.0.7;
		proxy_set_header Host $http_host;
		proxy_set_header X-Forwarded-For $remote_addr;	#加了這一行用來記錄真實的ip
	}
}

image

補充:

$proxy_add_x_forwarded_for  
變數相當於$remote_addr 客戶ip地址.
多層代理的時候,會記錄每個代理的ip地址.相當於記錄了多個$remote_addr

XFF頭的內容需要通過$http_x_forwarded_for變數獲取並寫入到日誌中.


#實際應用:
server{
	listen 80;
	server_name nginxconf.cn;
	error_log  /var/log/nginx/nginxconf.cn-error.log notice;
     access_log  /var/log/nginx/nginxconf.cn-access.log  main;

	location / {
		proxy_pass http://10.0.0.7;
		proxy_set_header Host $http_host;
		proxy_set_header X-Real-Ip $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;	#訪問日誌識別的是XFF
	}
}

4.3 負載均衡案例 部署nginxconf站點並訪問

4.3.1 環境要求

主機名 說明
lb01 10.0.0.5/172.16.1.5
web01 10.0.0.7/172.16.1.7
web02 10.0.0.8/172.16.1.8
功能變數名稱 nginxconf.cn
站點目錄 /app/code/nginxconf

4.3.2 web伺服器準備

[root@web01 ~]# cat /etc/nginx/conf.d/nginxconf.cn.conf 
server{
	listen 80;
	server_name nginxconf.cn;
	root /app/code/nginxconf;
	error_log  /var/log/nginx/nginxconf.cn-error.log notice;
	access_log  /var/log/nginx/nginxconf.cn-access.log  main;

	location /{
		index index.html;
	}
	
}

#上傳代碼並解析到這個目錄
鏈接:https://pan.baidu.com/s/1_WMsGUzzKoP53rrsjO8n2w 
提取碼:ulzj 
--來自百度網盤超級會員V6的分享
[root@web01 ~]# ll /app/code/nginxconf/
total 1992
-rw-r--r-- 1 root root 230532 Sep 16 11:23 banner.png
-rw-r--r-- 1 root root 625553 Sep 16 11:23 banner.svg
drwxr-xr-x 2 root root     21 Sep 16 11:23 css
drwxr-xr-x 2 root root    300 Sep 16 11:23 fonts
-rw-r--r-- 1 root root     19 Feb 13 17:17 index.html
-rw-r--r-- 1 root root 116972 Feb 13 17:16 index.html.bak
drwxr-xr-x 2 root root    195 Sep 16 11:23 js
-rw-r--r-- 1 root root 328581 Sep 16 11:23 nginx.png
-rw-r--r-- 1 root root 269221 Sep 16 11:23 nginx.svg
-rw-r--r-- 1 root root 447599 Sep 16 11:23 report.html
-rw-r--r-- 1 root root     26 Sep 16 11:23 robots.txt


#註:web01和web02的配置一樣,拷過去即可

4.3.3 負載均衡配置

upstream nginxconf_pools{
	server 10.0.0.7:80;
	server 10.0.0.8:80;	

}

server{
	listen 80;
	server_name nginxconf.cn;
	error_log  /var/log/nginx/nginxconf.cn-error.log notice;
        access_log  /var/log/nginx/nginxconf.cn-access.log  main;
	
	location / {
		proxy_pass http://nginxconf_pools;
		proxy_set_header Host $http_host;
		proxy_set_header X-Real-Ip $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;	
	}
}

註意事項

upstream與server是同一級

#測試
#修改了index.html測試一下
[root@web01 ~]# cat /app/code/nginxconf/index.html
web01 nginxconf.cn
[root@web02 ~/php]# cat /app/code/nginxconf/index.html
web02 nginxconf.cn
[root@lb01 ~]# curl -H Host:nginxconf.cn http://10.0.0.5
web01 nginxconf.cn
[root@lb01 ~]# curl -H Host:nginxconf.cn http://10.0.0.5
web02 nginxconf.cn
[root@lb01 ~]# curl -H Host:nginxconf.cn http://10.0.0.5
web01 nginxconf.cn
[root@lb01 ~]# curl -H Host:nginxconf.cn http://10.0.0.5
web02 nginxconf.cn

4.4 練習

1. 1台web+資料庫+存儲: lnmp連接nfs存儲
2. 2台webb+資料庫+存儲: lnmp連接nfs存儲
3. lb01+2台web+資料庫+存儲:小型網站集群.

#啟動nginx和php
[root@web01 ~]# groupadd -g 888 www
[root@web01 ~]# useradd -u 888 -g 888 -s /sbin/nologin -M www
[root@web01 ~]# id www
[root@web01 ~]# grep www /etc/nginx/nginx.conf 
user  www;
[root@web01 ~]# ps -ef |grep nginx
root      34264      1  0 07:25 ?        00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
www       51175  34264  0 20:37 ?        00:00:00 nginx: worker process

[root@web01 ~]# grep -n  www /etc/php-fpm.d/www.conf
1:; Start a new pool named 'www'.
2:[www]
8:user = www			#修改這一行
10:group = www			#修改這一行
[root@web01 ~]# systemctl restart php-fpm
[root@web01 ~]# ps -ef|grep php-fpm
root      51287      1  0 20:40 ?        00:00:00 php-fpm: master process (/etc/php-fpm.conf)
www       51288  51287  0 20:40 ?        00:00:00 php-fpm: pool www
www       51289  51287  0 20:40 ?        00:00:00 php-fpm: pool www
www       51290  51287  0 20:40 ?        00:00:00 php-fpm: pool www
www       51291  51287  0 20:40 ?        00:00:00 php-fpm: pool www
www       51292  51287  0 20:40 ?        00:00:00 php-fpm: pool www

#nfs創建共用
[root@nfs ~]# groupadd -g 888 www
[root@nfs ~]#  useradd -u 888 -g 888 -s /sbin/nologin -M www
[root@nfs ~]# id www
uid=888(www) gid=888(www) groups=888(www)
[root@nfs ~]# mkdir /data/wordpress
[root@nfs ~]# chown -R www.www /data/wordpress/
[root@nfs ~]# cat /etc/exports
/data/wordpress 172.16.1.0/24(rw,all_squash,anonuid=888,anongid=888)
root@nfs ~]# systemctl reload nfs
[root@nfs ~]# showmount -e
Export list for nfs:
/data/wordpress 172.16.1.0/24

#web01掛載
[root@web01 ~]# mount -t nfs 172.16.1.31:/data/wordpress /app/code/blog/wp-content/uploads
[root@web01 ~]# df -h
172.16.1.31:/data/wordpress   17G  2.0G   15G  12% /app/code/blog/wp-content/uploads

#web01打包代碼
[root@web01 /app/code]# tar zcf blog.tar.gz  blog/ 
[root@web01 /app/code]# scp blog.tar.gz 10.0.0.8:/app/code

#web02解壓代碼併進行掛載
[root@web02 /app/code]# tar xf blog.tar.gz 
[root@web02 /app/code]# ll
total 24624
drwxr-xr-x 5 nginx nginx     4096 Feb 13 10:56 blog
[root@web02 /app/code]# yum -y install nfs-utils
[root@web02 /app/code]# mount -t nfs 172.16.1.31:/data/wordpress /app/code/blog/wp-content/uploads
[root@web02 /app/code]# df -h
172.16.1.31:/data/wordpress   17G  2.0G   16G  12% /app/code/blog/wp-content/uploads

#拷貝web01的配置文件
[root@web02 /etc/nginx/conf.d]# scp 10.0.0.7:/etc/nginx/conf.d/blog.cn.conf .
[root@web02 /etc/nginx/conf.d]# cat blog.cn.conf
server{
          listen 80;
	  server_name blog.cn;
	  root /app/code/blog;
	  error_log /var/log/nginx/blog-error.log notice ; 
	  access_log /var/log/nginx/blog-access.log main;
	  
	  location / {
		index  index.php;
	  }

	  location ~*  \.php$ {
		#傳遞給php
		fastcgi_pass   127.0.0.1:9000;
		fastcgi_index  index.php;
		#下麵內容需要修改
		#fastcgi_param  SCRIPT_FILENAME  /app/code/blog$fastcgi_script_name;
		fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
		include        fastcgi_params;
	  }
}

[root@web02 /etc/nginx/conf.d]# systemctl reload nginx
[root@web02 /etc/nginx/conf.d]# systemctl restart php-fpm
#測試網站是否啟動
[root@web02 /etc/nginx/conf.d]# curl -H Host:blog.cn http://10.0.0.8


[root@lb01 ~]# cat /etc/nginx/conf.d/blog.cn.conf
upstream blog_pools{
	server 10.0.0.7:80;
	server 10.0.0.8:80;	

}

server{
	listen 80;
	server_name blog.cn;
	error_log  /var/log/nginx/nginxconf.cn-error.log notice;
        access_log  /var/log/nginx/nginxconf.cn-access.log  main;
	
	location / {
		proxy_pass http://blog_pools;
		proxy_set_header Host $http_host;
		proxy_set_header X-Real-Ip $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;	
	}
}

2023/02/13 21:14:38 [warn] 51175#51175: *587 a client request body is buffered to a temporary file /var/cache/nginx/client_temp/0000000009, client: 10.0.0.5, server: blog.cn, request: "POST /index.php?rest_route=%2Fwp%2Fv2%2Fmedia&_locale=user HTTP/1.0", host: "blog.cn", referrer: "http://blog.cn/wp-admin/post.php?post=9&action=edit"

#圖片太大解決方法
[root@web01 ~]# cat /etc/nginx/nginx.conf 
client_max_body_size 50M;
client_body_buffer_size 50M;


[root@web01 ~]# vim /etc/php.ini
upload_max_filesize = 30M

#頁面錯亂
[root@lb01 ~]# cat /etc/nginx/conf.d/blog.cn.conf
fastcgi_buffering on;
fastcgi_buffers 64 64k;

五、負載均衡vs反向代理

內容 共同點 區別 服務
負載均衡 用戶的請求分發到後端節點上 用戶--->lb--->web
lb負載均衡做的是數據轉發,不會產生新的請求,1個請求1個響應
lvs
反向代理 用戶的請求分發到後端節點上 中間有個中介,用戶--->中介---->web 2個請求2個響應
代理代替用戶去找web伺服器
nginx/tengine/openresty

六、負載均衡模塊的選項

upstream模塊 server指令支持的選項

選項 說明 應用場景
weight 權重,根據權重nginx分配請求 如果web的服務端配置不同,根據配置分配比例
max_fails nginx具備一些健康檢查功能,指定失敗的次數,超過這個次數就認為節點掛了 一般情況下可以設置1-3.緩存業務可以設置為10
fail_timeout 認為節點掛了後,間隔多久再次檢查健康情況,預設是10s 根據要求設置時間即可,可以長些。30/60s
backup 備胎伺服器,其他所有伺服器都掛了,才啟用 使用的時候要考慮雪崩的情況
upstrem pools {
	server 10.0.0.7:80  weight=1 max_fails=3 fail_timeout=10s;
	server 10.0.0.8:80  weight=1 max_fails=3 fail_timeout=10s;
	server 10.0.0.9:80 backup;
}

七、案例: wordpress接入負載均衡

php安裝包與wordpress源碼包:

鏈接:https://pan.baidu.com/s/1xJiUD4s7X7LhpX_d7gFLCA
提取碼:8amh
--來自百度網盤超級會員V6的分享

1. nfs存儲

[root@nfs ~]# groupadd -g 888 www
[root@nfs ~]# useradd -u 888 -g 888 -s /sbin/nologin -M www
[root@nfs ~]# cat /etc/exports
/data/wordpress 172.16.1.0/24(rw,all_squash,anonuid=888,anongid=888)
[root@nfs ~]# systemctl reload nfs
[root@nfs ~]# mkdir -p /data/wordpress
[root@nfs ~]# chown -R www.www /data/wordpress
[root@nfs ~]# showmount -e
Export list for nfs:
/data/wordpress 172.16.1.0/24

2. db資料庫

[root@db01 ~]# mysql -uroot -p1
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 843
Server version: 5.5.68-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> create database wordpress;
MariaDB [(none)]> grant all on wordpress.* to 'wordpress'@'172.16.1.%' identified by '1';
MariaDB [(none)]> select user,host from mysql.user
    -> ;
+-----------+------------+
| user      | host       |
+-----------+------------+
| root      | 127.0.0.1  |
| test      | 172.16.1.% |
| wordpress | 172.16.1.% |
| root      | ::1        |
| root      | localhost  |
| test      | localhost  |
+-----------+------------+
6 rows in set (0.00 sec)

3. web01

[root@web01 ~]# groupadd -g 888 www
[root@web01 ~]# useradd -u 888 -g 888 -s /sbin/nologin -M www
[root@web01 ~]# id www
uid=888(www) gid=888(www) groups=888(www)
[root@web01 ~]# grep www /etc/nginx/nginx.conf 
user  www;
[root@web01 ~]# systemctl reload nginx

[root@web01 ~]# grep www /etc/php-fpm.d/www.conf 
; Start a new pool named 'www'.
[www]
user = www
group = www
[root@web01 ~]# systemctl reload php-fpm
[root@web01 ~]# ps -ef|grep www
www       51519  34264  0 14:57 ?        00:00:00 nginx: worker process
www       51587  33436  0 14:58 ?        00:00:00 php-fpm: pool www
www       51588  33436  0 14:58 ?        00:00:00 php-fpm: pool www
www       51589  33436  0 14:58 ?        00:00:00 php-fpm: pool www
www       51590  33436  0 14:58 ?        00:00:00 php-fpm: pool www
www       51591  33436  0 14:58 ?        00:00:00 php-fpm: pool www

[root@web01 /etc/nginx/conf.d]# cat wordpress.cn.conf 
server{
      listen 80;
	  server_name wordpress.cn;
	  root /app/code/wordpress;
	  error_log /var/log/nginx/wordpress-error.log notice ; 
	  access_log /var/log/nginx/wordpress-access.log main;
	  
	  location / {
		index  index.php;
	  }

	  location ~*  \.php$ {
		#傳遞給php
		fastcgi_pass   127.0.0.1:9000;
		fastcgi_index  index.php;
	    fastcgi_buffering on;
	    fastcgi_buffers 64 64k;

		#下麵內容需要修改
		#fastcgi_param  SCRIPT_FILENAME  /app/code/blog$fastcgi_script_name;
		fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
		include        fastcgi_params;
	  }
}
[root@web01 ~]# systemctl reload nginx

[root@web01 ~]# unzip wordpress-6.1.1.zip  -d /app/code/
[root@web01 ~]# chown -R www.www /app/code/wordpress/


#C:\Windows\System32\drivers\etc\hosts添加解析
10.0.0.7 wordpress.cn

#瀏覽器訪問wordpress.cn
#進行配置資料庫

#創建圖片的上傳路徑
[root@web01 ~]# mkdir /app/code/wordpress/wp-content/uploads
[root@web01 ~]# mount -t nfs 172.16.1.31:/data/wordpress /app/code/wordpress/wp-content/uploads
[root@web01 ~]# df -h |grep uploads
172.16.1.31:/data/wordpress   17G  2.0G   15G  12% /app/code/wordpress/wp-content/uploads

#瀏覽器上傳圖片,發現nfs有這個圖片了
[root@nfs ~]# tree /data/wordpress/
/data/wordpress/
└── 2023
    └── 02
        ├── cat-150x150.jpg
        ├── cat-258x300.jpg
        └── cat.jpg

2 directories, 3 files

4. web02

[root@web02 ~]# groupadd -g 888 www
[root@web02 ~]# useradd -u 888 -g 888 -s /sbin/nologin -M www
[root@web02 ~]# id www
uid=888(www) gid=888(www) groups=888(www)
[root@web02 ~]# scp 10.0.0.7:/root/php72w-all.tar.gz .
[root@web02 ~]# tar xf php72w-all.tar.gz 
[root@web02 ~]# yum -y localinstall *.rpm
[root@web02 ~]# grep www /etc/php-fpm.d/www.conf 
; Start a new pool named 'www'.
[www]
user = www
group = www
[root@web02 ~]# systemctl start php-fpm
[root@web02 ~]# systemctl enable php-fpm

[root@web02 ~]# grep www /etc/nginx/nginx.conf 
user  www;
[root@web02 ~]# systemctl enable nginx
[root@web02 ~]# systemctl start nginx
[root@web02 ~]# ps -ef |grep www
www        4065   4064  0 15:11 ?        00:00:00 nginx: worker process
www        4101   4100  0 15:12 ?        00:00:00 php-fpm: pool www
www        4102   4100  0 15:12 ?        00:00:00 php-fpm: pool www
www        4103   4100  0 15:12 ?        00:00:00 php-fpm: pool www
www        4104   4100  0 15:12 ?        00:00:00 php-fpm: pool www
www        4105   4100  0 15:12 ?        00:00:00 php-fpm: pool www

#複製web01的配置文件
[root@web02 /etc/nginx/conf.d]# scp 10.0.0.7:/etc/nginx/conf.d/wordpress.cn.conf .
[root@web02 ~]# systemctl reload nginx

#在web01打包代碼
[root@web01 ~]# tar zcf ~/wordpress-no-uploads.tar.gz   /app/code/wordpress --exclude=/app/code/wordpress/wp-content/uploads

#從web01拷貝代碼,並解壓
[root@web02 ~]# scp 10.0.0.7:/root/wordpress-no-uploads.tar.gz .
[root@web02 ~]# tar xf wordpress-no-uploads.tar.gz  -C /
[root@web02 ~]# cd /app/code/wordpress/
[root@web02 /app/code/wordpress]# ll
total 228
-rw-r--r--  1 www www   405 Feb  6  2020 index.php
-rw-r--r--  1 www www 19915 Jan  1  2022 license.txt
-rw-r--r--  1 www www  7389 Sep 17 06:27 readme.html
-rw-r--r--  1 www www  7205 Sep 17 07:13 wp-activate.php
drwxr-xr-x  9 www www  4096 Nov 16 03:03 wp-admin
-rw-r--r--  1 www www   351 Feb  6  2020 wp-blog-header.php
-rw-r--r--  1 www www  2338 Nov 10  2021 wp-comments-post.php
-rw-rw-rw-  1 www www  3277 Feb 14 15:04 wp-config.php
-rw-r--r--  1 www www  3001 Dec 14  2021 wp-config-sample.php
drwxr-xr-x  7 www www    99 Feb 14 15:06 wp-content
-rw-r--r--  1 www www  5543 Sep 20 23:44 wp-cron.php
drwxr-xr-x 27 www www 12288 Nov 16 03:03 wp-includes
-rw-r--r--  1 www www  2494 Mar 20  2022 wp-links-opml.php
-rw-r--r--  1 www www  3985 Sep 19 16:59 wp-load.php
-rw-r--r--  1 www www 49135 Sep 20 06:26 wp-login.php
-rw-r--r--  1 www www  8522 Oct 17 19:06 wp-mail.php
-rw-r--r--  1 www www 24587 Sep 26 18:17 wp-settings.php
-rw-r--r--  1 www www 34350 Sep 17 08:35 wp-signup.php
-rw-r--r--  1 www www  4914 Oct 17 19:22 wp-trackback.php
-rw-r--r--  1 www www  3236 Jun  9  2020 xmlrpc.php

#掛載目錄
[root@web02 /app/code/wordpress]# yum -y install nfs-utils
[root@web02 /app/code/wordpress]# mount -t nfs 172.16.1.31:/data/wordpress /app/code/wordpress/wp-content/uploads
[root@web02 /app/code/wordpress]# df -h |grep uploads
172.16.1.31:/data/wordpress   17G  2.0G   15G  12% /app/code/wordpress/wp-content/uploads

#C:\Windows\System32\drivers\etc\hosts修改解析
10.0.0.8 wordpress.cn

#瀏覽器訪問wordpress.cn
#圖片顯示正常,證明,web02沒問題

5. lb

[root@lb01 /etc/nginx/conf.d]# cat wordpress.cn.conf 
upstream wordpress_pools{
	server 10.0.0.7:80;
	server 10.0.0.8:80;	

}
server{
	listen 80;
	server_name wordpress.cn;
	error_log  /var/log/nginx/wordpress.cn-error.log notice;
        access_log  /var/log/nginx/wordpress.cn-access.log  main;
	
	location / {
		proxy_pass http://wordpress_pools;
		proxy_set_header Host $http_host;

		proxy_set_header X-Real-Ip $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;	
	}
}

[root@lb01 /etc/nginx/conf.d]# systemctl reload nginx

#C:\Windows\System32\drivers\etc\hosts修改解析
10.0.0.5 wordpress.cn

#瀏覽器訪問wordpress.cn
#圖片顯示正常,證明,lb沒問題

八、會話保持

1.概述

用戶的請求,登錄的請求,經過負載均衡後落到後面的web伺服器上,登錄的狀態/信息也會記錄在web伺服器上,就會導致不通的web伺服器上,登錄狀態不統一,造成用戶頻繁需要登錄

技術點 共同點 區別 其他
cookie 存放用戶的信息,登錄信息 存放在客戶端瀏覽器 伺服器給客戶端響應,進行設置set-cookie,未來
再次訪問攜帶著cookie訪問服務端
session 存放用戶的信息,登錄信息 存放在服務端 瀏覽器cookie與服務端的session對應

F12查看cookie

image

3.會話保持方案

  • 登錄狀態寫入cookie中(wordpress)
  • cookie+session方式 + 統一存放session伺服器(會話保持伺服器)
  • 通過認證服務實現Oauth 2.0(使用token方式)
  • ip_hash方法
  • 通過redis實現phpmyadmin/kodbox會話共用.

4.部署phpmyadmin

phpmyadmin安裝包:

鏈接:https://pan.baidu.com/s/1D9U9oyri3lkZRNriYqj1gA
提取碼:amvr
--來自百度網盤超級會員V6的分享

4.1 db

MariaDB [(none)]> grant all on *.* to 'phpmyadmin'@'172.16.1.%' identified by '1';

4.2 web01

[root@web01 ~]# unzip  phpMyAdmin-5.2.1-all-languages.zip  -d /app/code/
[root@web01 /app/code]# mv phpMyAdmin-5.2.1-all-languages/ phpMyAdmin/
[root@web01 /app/code]# chown -R www.www phpMyAdmin/
[root@web01 /etc/nginx/conf.d]# cat phpmyadmin.cn.conf 
server{
          listen 80;
	  server_name phpmyadmin.cn;
	  root /app/code/phpMyAdmin;			#註意目錄名字
	  error_log /var/log/nginx/phpmyadmin-error.log notice ; 
	  access_log /var/log/nginx/phpmyadmin-access.log main;
	  
	  location / {
		index  index.php;
	  }

	  location ~*  \.php$ {
		#傳遞給php
		fastcgi_pass   127.0.0.1:9000;
		fastcgi_index  index.php;
	        fastcgi_buffering on;
	        fastcgi_buffers 64 64k;

		#下麵內容需要修改
		#fastcgi_param  SCRIPT_FILENAME  /app/code/blog$fastcgi_script_name;
		fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
		include        fastcgi_params;
	  }
}
[root@web01 /etc/nginx/conf.d]# systemctl reload nginx
#瀏覽器訪問http://phpmyadmin.cn/,提示下麵的問題
phpMyAdmin - Error
Error during session start; please check your PHP and/or webserver log file and configure your PHP installation properly. Also ensure that cookies are enabled in your browser.

session_start(): open(SESSION_FILE, O_RDWR) failed: Permission denied (13)

session_start(): Failed to read session data: files (path: /var/lib/php/session)

#原因:/var/lib/php/session沒有許可權
#解決:[root@web01 /etc/nginx/conf.d]# chown -R www.www /var/lib/php/session
#不提示了,還是進不去,是因為phpmyadmin預設訪問的是本地資料庫
解決方法:
[root@web01 /app/code/phpMyAdmin]# cp  config.sample.inc.php  config.inc.php 
[root@web01 /app/code/phpMyAdmin]# grep host config.inc.php
$cfg['Servers'][$i]['host'] = '172.16.1.51';   #修改這一行的ip


#瀏覽器訪問http://phpmyadmin.cn/,輸入新建的用戶名和密碼進去了

4.3 web02

#拷貝web01的代碼
[root@web02 /app/code]# scp -r 10.0.0.7:/app/code/phpMyAdmin/ .
[root@web02 /app/code]# chown -R www.www phpMyAdmin/
#拷貝web01的nginx配置
[root@web02 /etc/nginx/conf.d]# scp 10.0.0.7:/etc/nginx/conf.d/phpmyadmin.cn.conf .
[root@web02 /etc/nginx/conf.d]# systemctl reload nginx

[root@web02 /etc/nginx/conf.d]# chown -R www.www /var/lib/php/session

4.4 部署redis

[root@db01 ~]# yum -y install redis
[root@db01 ~]# grep -n 172.16.1.51 /etc/redis.conf 
61:bind 127.0.0.1 172.16.1.51
[root@db01 ~]# systemctl start redis
[root@db01 ~]# systemctl enable redis
#systemctl enable now redis
[root@db01 ~]# ss -lnutp |grep redis
tcp    LISTEN     0      128    172.16.1.51:6379                  *:*                   users:(("redis-server",pid=10772,fd=5))
tcp    LISTEN     0      128    127.0.0.1:6379                  *:*                   users:(("redis-server",pid=10772,fd=4))

4.5 lb配置文件

[root@lb01 /etc/nginx/conf.d]# cat phpmyadmin.cn.conf 
upstream phpmyadmin_pools{
	server 10.0.0.7:80;
	server 10.0.0.8:80;	

}
server{
	listen 80;
	server_name phpmyadmin.cn;
	error_log  /var/log/nginx/phpmyadmin.cn-error.log notice;
        access_log  /var/log/nginx/phpmyadmin.cn-access.log  main;
	
	location / {
		proxy_pass http://phpmyadmin_pools;
		proxy_set_header Host $http_host;

		proxy_set_header X-Real-Ip $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;	
	}
}

[root@lb01 /etc/nginx/conf.d]# systemctl reload nginx

4.6 php配置文件指定會話存放位置

#創建新的子配置文件
[root@web01 /etc/php-fpm.d]# egrep -v '^$|;' www.conf >session.conf
[root@web01 /etc/php-fpm.d]# cat session.conf 
[session]						#修改名字
user = www
group = www
listen = 127.0.0.1:9001			#修改埠號
listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
slowlog = /var/log/php-fpm/www-slow.log
php_admin_value[error_log] = /var/log/php-fpm/www-error.log
php_admin_flag[log_errors] = on
php_value[session.save_handler] = redis			#修改為redis
php_value[session.save_path]    = tcp://172.16.1.51:6379  #修改為redis的地址
php_value[soap.wsdl_cache_dir]  = /var/lib/php/wsdlcache
#檢查配置文件是否有問題
[root@web01 /etc/php-fpm.d]# php-fpm -t
[14-Feb-2023 16:17:31] NOTICE: configuration file /etc/php-fpm.conf test is successful
[root@web01 /etc/php-fpm.d]# systemctl reload php-fpm
[root@web01 /etc/php-fpm.d]# cat /etc/nginx/conf.d/phpmyadmin.cn.conf 
server{
          listen 80;
	  server_name phpmyadmin.cn;
	  root /app/code/phpMyAdmin;
	  error_log /var/log/nginx/phpmyadmin-error.log notice ; 
	  access_log /var/log/nginx/phpmyadmin-access.log main;
	  
	  location / {
		index  index.php;
	  }

	  location ~*  \.php$ {
		#傳遞給php
		fastcgi_pass   127.0.0.1:9001;    #修改埠號
		fastcgi_index  index.php;
	        fastcgi_buffering on;
	        fastcgi_buffers 64 64k;

		#下麵內容需要修改
		#fastcgi_param  SCRIPT_FILENAME  /app/code/blog$fastcgi_script_name;
		fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
		include        fastcgi_params;


	  }
}
[root@web01 /etc/php-fpm.d]# systemctl reload nginx

#web02配置
[root@web02 /etc/nginx/conf.d]# scp 10.0.0.7:/etc/nginx/conf.d/phpmyadmin.cn.conf .
[root@web02 /etc/nginx/conf.d]# systemctl reload nginx

[root@web02 /etc/php-fpm.d]# scp 10.0.0.7:/etc/php-fpm.d/session.conf .
[root@web02 /etc/php-fpm.d]# systemctl reload php-fpm

九、輪詢演算法

1. 概述

決定負載均衡如何把請求分發給後端節點,這種分發的方式就是輪詢演算法

2.輪詢演算法

演算法 說明
rr輪詢 round robin 輪詢,預設的迴圈訪問
wrr 加權輪詢,在輪詢的基礎上增加權重的功能,server 中 weight 就是加權輪詢
ip_hash ip哈希,只要客戶端ip一樣,就會一直訪問同一個後端節點。(用戶請求與web伺服器綁定)
解決會話保持/會話共用 可能導致負載不均
xxx_hash url_hash 只要用戶訪問的url相同,就訪問相同的web伺服器
緩存伺服器:靜態資源緩存
least_conn 最小連接數:lc演算法,也可以配合上權重, weight wlc權重的最小連接數
一致性hash演算法
#ip_hash
upstream nginxconf_pools{
    ip_hash;
	server 10.0.0.7:80;
	server 10.0.0.8:80;	

}
server{
	listen 80;
	server_name nginxconf.cn;
	error_log  /var/log/nginx/nginxconf.cn-error.log notice;
        access_log  /var/log/nginx/nginxconf.cn-access.log  main;
	
	location / {
		proxy_pass http://nginxconf_pools;
		proxy_set_header Host $http_host;
		proxy_set_header X-Real-Ip $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;	
	}
}


#url_hash
hash $request_uri;

十、案例:對負載均衡進行狀態檢查

負載均衡狀態檢查模塊: ngx_http_upstream_check_module

預設nginx沒有安裝,是一個第三方的模塊,需要編譯安裝nginx添加這個模塊

#找一臺沒有nginx的機器
#編譯安裝tengine,生成nginx命令,替代lb上的nginx的命令


安裝依賴
./configure 配置(生成Makefile) 指定各種位置,否則就會安裝到/usr/local/
make        編譯(根據Makefile進行編譯-->生成對應的命令)
make install 創建目錄,複製文件..

#安裝依賴
yum install -y pcre-devel   openssl-devel 

#配置的步驟
./configure  --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie'  --add-module=modules/ngx_http_upstream_check_module  --add-module=modules/ngx_http_upstream_session_sticky_module/


#進行編譯
make -j 1  #cpu核心總數決定. 加速編譯

#最後的安裝(略)
不需要執行make install
我們不需要在當前主機安裝tengine

#檢查編譯後生成的命令即可
./objs/nginx -V

#替換nginx命令步驟
[root@lb01 ~]# ll nginx 
-rwxr-xr-x 1 root root 10544592 Feb 17 10:29 nginx
[root@lb01 ~]# mv /sbin/nginx /sbin/nginx.1.22
[root@lb01 ~]# cp nginx /sbin/
[root@lb01 ~]# ll /sbin/nginx
-rwxr-xr-x 1 root root 10544592 Feb 17 10:31 /sbin/nginx
[root@lb01 ~]# pkill  nginx
[root@lb01 ~]# nginx -V
Tengine version: Tengine/2.3.3
nginx version: nginx/1.18.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) 
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' --add-module=modules/ngx_http_upstream_check_module --add-module=modules/ngx_http_upstream_session_sticky_module/
[root@lb01 ~]# systemctl start nginx
[root@lb01 ~]# ps -ef|grep nginx
root       8836      1  0 10:32 ?        00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
www        8837   8836  0 10:32 ?        00:00:00 nginx: worker process
root       8839   8689  0 10:32 pts/0    00:00:00 grep --color=auto nginx

[root@lb01 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: [emerg] mkdir() "/var/cache/nginx/client_temp" failed (2: No such file or directory)
nginx: configuration file /etc/nginx/nginx.conf test failed
#創建這個文件即可
upstream admin_pools {
   server 10.0.0.7:80;
   server 10.0.0.8:80;
   # #     檢查間隔 ms 成功2次,存活 失敗5次認為掛了 超時時間 ms 檢查類型
   check interval=3000 rise=2 fall=5 timeout=1000 type=http;
   #請求方法 URI (uri最好反應業務是否正常,找開發寫個頁面)
   check_http_send "HEAD / HTTP/1.0\r\n\r\n";
   check_http_expect_alive http_2xx http_3xx;
}

server {
  listen 80;
  server_name admin.cn;
  error_log /var/log/nginx/admin-error.log notice ; 
  access_log /var/log/nginx/admin-access.log main;

  location / {
     proxy_pass http://admin_pools;
     proxy_set_header  Host $http_host;
     proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;

  }
  location /admin_status  {
    check_status;
    access_log off; 
    allow 10.0.0.1;
    allow 172.16.1.0/24;
    deny all;

  }

}
upstream_check模塊指令說明
check 指定檢查頻率,失敗幾次,成功幾次,檢查間隔,檢查方式
check_http_send 通過http方式發出請求報文,請求報文起始行,請求方法,請求的URI,請求協議(預設的是ip方式訪問)
check_http_expect_alive 收到指定的狀態碼,就認為是存活的
check_status 開啟負載均衡狀態檢查功能,web頁面。

註意: 如果後端web有多個虛擬主機.

upstream check進行訪問的時候預設使用的ip方式進行訪問.

在發出http請求的時候指定功能變數名稱

check_http_send "HEAD / HTTP/1.0\r\nHost: lb.cn\r\n\r\n";

十一、案例:nginx平滑升級

步驟
準備好新的nginx命令(已經測試的)
把當前環境的nginx的命令備份,使用新的替換
通過kill命令向當前運行nginx發出信號,準備被替代 -USR2 pid 把當前運行的nginx的pid文件改個名,使用新的nginx命令啟動nginx進程
測試調試,關閉舊的nginx進程即可
#查看測試好的nginx
[root@web01 ~]# ll |grep nginx
-rwxr-xr-x  1 root root 10544592 Feb 19 13:37 nginx

#查看當前nginx版本
[root@web01 ~]# nginx -v
nginx version: nginx/1.22.1
#查看當前nginx的pid
[root@web01 ~]# cat /var/run/nginx.pid*
63374

#備份nginx命令
[root@web01 ~]# mv /sbin/nginx /sbin/nginx-v1.22.0
#移動命令到nginx目錄
[root@web01 ~]# mv nginx /sbin/nginx
#查看移動後的命令
[root@web01 ~]# nginx -v
Tengine version: Tengine/2.3.3
nginx version: nginx/1.18.0


#準備新老交替 生成新的pid文件和重命名的pid文件
[root@web01 ~]# kill -USR2 `cat /var/run/nginx.pid`
[root@web01 ~]# ll /var/run/nginx.pid*
-rw-r--r-- 1 root root 6 Feb 19 13:42 /var/run/nginx.pid
-rw-r--r-- 1 root root 6 Feb 17 11:07 /var/run/nginx.pid.oldbin

[root@web01 ~]# ps -ef|grep nginx
root      63374      1  0 07:42 ?        00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
www       68981  63374  0 12:45 ?        00:00:00 nginx: worker process
root      70281  63374  0 13:42 ?        00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
www       70282  70281  0 13:42 ?        00:00:00 nginx: worker process

#殺死舊的進程
[root@web01 ~]# kill 63374
#就剩下新的進程文件和新的進程
[root@web01 ~]# ps -ef|grep nginx
root      70281      1  0 13:42 ?        00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
www       70282  70281  0 13:42 ?        00:00:00 nginx: worker process
root      70327  69777  0 13:44 pts/1    00:00:00 grep --color=auto nginx
[root@web01 ~]# ll /var/run/nginx.pid*
-rw-r--r-- 1 root root 6 Feb 19 13:42 /var/run/nginx.pid


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 近期,業務調整,需要內網讀取數據後存入到外網,同時,其他伺服器也需要讀取數據,於是我又盯上了RabbitMQ。在展開業務代碼前,先看下RabbitMQ整體架構,可以看到Exchange和隊列是多對多關係。 下麵,我們詳細說說RabbitMQ的隊列模式:簡單隊列、工作隊列、發佈訂閱模式、路由模式、主題 ...
  • Net 內置記憶體緩存 asp.net 中是有緩存的實現:HttpContext.Cache,緩存的數據是放到 Web 伺服器的進程 記憶體里。 在控制台、WinForm、子線程、SignalR 等不支持 HttpContext 的地方還可以使用 MemoryCache.Default(System.R ...
  • FTP作為日常工作學習中,非常重要的一個文件傳輸存儲空間,想必大家都非常的熟悉了,那麼如何快速的實現文件的上傳下載功能呢,本文以一個簡單的小例子,簡述如何通過FluentFTP實現文件的上傳和下載功能。僅供學習分享使用,如有不足之處,還請指正。 ...
  • 大家好,我是沙漠盡頭的狼。 本文先拋出以下問題,請在文中尋找答案,可在評論區回答: 什麼是API攔截? 一個方法被很多地方調用,怎麼在不修改這個方法源碼情況下,記錄這個方法調用的前後時間? 同2,不修改源碼的情況下,怎麼對方法的參數進行校正(篡改)? 同3,不修改源碼的情況下,怎麼對方法的返回值進行 ...
  • 一:背景 1. 講故事 一直在追這個系列的朋友應該能感受到,我給這個行業中無數的陌生人分析過各種dump,終於在上周有位老同學找到我,還是個大妹子,必須有求必應 😁😁😁。 妹子公司的系統最近在某次升級之後,在高峰期會遇到 CPU 爆高的現象,有些單位你懂的,很強勢,所以就苦逼了程式媛,不管怎麼 ...
  • 1. Ioc 與 DI Ioc 和DI 這兩個詞大家都應該比較熟悉,這兩者已經在各種開發語言各種框架中普遍使用,成為框架中的一種基本設施了。 Ioc 是控制反轉, Inversion of Control 的縮寫,DI 是依賴註入,Inject Dependency 的縮寫。 所謂控制反轉,反轉的是 ...
  • 概述 面臨一個複雜對象的創建工作,通常由各個部分的子對象用一定的演算法構成。子部件(對象)比較多,對象不能當作一個完整的對象或者產品使用(郵件:發件人,收件人、抄送人、主題、郵件內容)子部件需要按照一定的順序賦值才有一定的意義,在某個子部件沒有賦值之前,另一個子部件就無法賦值。 類圖 註:該類圖來源網 ...
  • 車家號作為一個PGC平臺,聚合了全網大多數汽車行業的專家及意見領袖,每天為用戶提供大量的汽車類優質內容。用戶日瀏覽量在幾千萬級,後端的介面也承載億級的日訪問量。 車家號WEB、API、後臺管理等系統採用 .net4.5進行開發。一直以來為用戶及調用方提供了穩定的服務。由於其只能運行於W... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...