中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

網(wǎng)站設(shè)計(jì)畢業(yè)論文任務(wù)書(shū)撫順優(yōu)化seo

網(wǎng)站設(shè)計(jì)畢業(yè)論文任務(wù)書(shū),撫順優(yōu)化seo,c 做網(wǎng)站看什么書(shū),企業(yè)應(yīng)該如何進(jìn)行網(wǎng)站推廣Nginx高級(jí) 第一部分:擴(kuò)容 通過(guò)擴(kuò)容提升整體吞吐量 1.單機(jī)垂直擴(kuò)容:硬件資源增加 云服務(wù)資源增加 整機(jī):IBM、浪潮、DELL、HP等 CPU/主板:更新到主流 網(wǎng)卡:10G/40G網(wǎng)卡 磁盤(pán):SAS(SCSI) HDD(機(jī)械…

Nginx高級(jí) 第一部分:擴(kuò)容

通過(guò)擴(kuò)容提升整體吞吐量

1.單機(jī)垂直擴(kuò)容:硬件資源增加

云服務(wù)資源增加
整機(jī):IBM、浪潮、DELL、HP等
CPU/主板:更新到主流
網(wǎng)卡:10G/40G網(wǎng)卡
磁盤(pán):SAS(SCSI) HDD(機(jī)械)、HHD(混合)、SATA SSD、PCI-e SSD、 MVMe SSD
SSD
多副本機(jī)制
系統(tǒng)盤(pán)/熱點(diǎn)數(shù)據(jù)/數(shù)據(jù)庫(kù)存儲(chǔ)
HDD
冷數(shù)據(jù)存儲(chǔ)

2.水平擴(kuò)展:集群化

會(huì)話管理

Nginx高級(jí)負(fù)載均衡

ip_hash

hash $cookie_jsessionid;

hash $request_uri;

使用lua邏輯定向分發(fā)

Redis + SpringSession

   upstream httpds {ip_hash;server 192.168.44.102 ;server 192.168.44.103 ;}server {listen       80;server_name  localhost;location / {proxy_pass http://httpds;# root   html;}location ~*/(css|img|js) {root   /usr/local/nginx/html;}
使用sticky模塊完成對(duì)Nginx的負(fù)載均衡

使用參考

http://nginx.org/en/docs/http/ngx_http_upstream_module.html#sticky

tengine中有session_sticky模塊我們通過(guò)第三方的方式安裝在開(kāi)源版本中

sticky是第三方模塊,需要重新編譯Nginx,他可以對(duì)Nginx這種靜態(tài)文件服務(wù)器使用基于cookie的負(fù)載均衡

1.下載模塊

項(xiàng)目官網(wǎng)

https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/src/master/

另外一個(gè)版本

https://github.com/bymaximus/nginx-sticky-module-ng

下載

https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/get/1.2.6.zip

2.上傳解壓
3.重新編譯Nginx

依賴openssl-devel

進(jìn)到源碼目錄重新編譯

./configure --prefix=/usr/local/nginx --add-module=/root/nginx-goodies-nginx-sticky-module-ng-c78b7dd79d0d

執(zhí)行make

如遇報(bào)錯(cuò)修改源碼

外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳

打開(kāi) ngx_http_sticky_misc.c文件

在12行添加

#include <openssl/sha.h>
#include <openssl/md5.h>

備份之前的程序

mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old

把編譯好的Nginx程序替換到原來(lái)的目錄里

cp objs/nginx /usr/local/nginx/sbin/

升級(jí)檢測(cè)

make upgrade

檢查程序中是否包含新模塊

nginx -V

配置方法

upstream httpget {sticky name=route expires=6h;server 192.168.44.102;
server 192.168.44.103;
}

KeepAlive

在http協(xié)議header中可以看到當(dāng)前連接狀態(tài)

測(cè)試工具charles

下載地址

https://www.charlesproxy.com/assets/release/4.6.2/charles-proxy-4.6.2-win64.msi?k=fc1457e312

官網(wǎng)

https://www.charlesproxy.com

什么時(shí)候使用?

明顯的預(yù)知用戶會(huì)在當(dāng)前連接上有下一步操作

復(fù)用連接,有效減少握手次數(shù),尤其是https建立一次連接開(kāi)銷會(huì)更大

什么時(shí)候不用?

訪問(wèn)內(nèi)聯(lián)資源一般用緩存,不需要keepalive

長(zhǎng)時(shí)間的tcp連接容易導(dǎo)致系統(tǒng)資源無(wú)效占用

對(duì)客戶端使用keepalive

keepalive_time

限制keepalive保持連接的最大時(shí)間

1.19.10新功能

keepalive_timeout

用于設(shè)置Nginx服務(wù)器與客戶端保持連接的超時(shí)時(shí)間

用于踢出不活動(dòng)連接

keepalive_timeout = 0 即關(guān)閉

  • send_timeout 10; 10秒
  • send_timeout 10 10; 同時(shí)下發(fā)一個(gè)header 告訴瀏覽器

send_timeout

兩次向客戶端寫(xiě)操作之間的間隔 如果大于這個(gè)時(shí)間則關(guān)閉連接 默認(rèn)60s

此處有坑,注意耗時(shí)的同步操作有可能會(huì)丟棄用戶連接

該設(shè)置表示Nginx服務(wù)器與客戶端連接后,某次會(huì)話中服務(wù)器等待客戶端響應(yīng)超過(guò)10s,就會(huì)自動(dòng)關(guān)閉連接。

keepalive_request

默認(rèn)1000

單個(gè)連接中可處理的請(qǐng)求數(shù)

keepalive_disable

不對(duì)某些瀏覽器建立長(zhǎng)連接

默認(rèn)msie6

http {include       mime.types;default_type  application/octet-stream;sendfile        on;keepalive_timeout  65 65; #超過(guò)這個(gè)時(shí)間 沒(méi)有活動(dòng),會(huì)讓keepalive失效 keepalive_time 1h; # 一個(gè)tcp連接總時(shí)長(zhǎng),超過(guò)之后 強(qiáng)制失效send_timeout 60;# 默認(rèn)60s  此處有坑!! 系統(tǒng)中 若有耗時(shí)操作,超過(guò) send_timeout 強(qiáng)制斷開(kāi)連接。 注意:準(zhǔn)備過(guò)程中,不是傳輸過(guò)程keepalive_requests 1000;  #一個(gè)tcp復(fù)用中 可以并發(fā)接收的請(qǐng)求個(gè)數(shù)

對(duì)上游服務(wù)器使用keepalive

首先需要配置使用http1.1協(xié)議。以便建立更高效的傳輸,默認(rèn)使用http1.0,在http1.0中需要配置header才能

在Upstream中所配置的上游服務(wù)器默認(rèn)都是用短連接,即每次請(qǐng)求都會(huì)在完成之后斷開(kāi)

相關(guān)配置
upstream中配置

配置

keepalive 100;

向上游服務(wù)器的保留連接數(shù)

**keepalive_timeout **

連接保留時(shí)間

**keepalive_requests **

一個(gè)tcp復(fù)用中 可以并發(fā)接收的請(qǐng)求個(gè)數(shù)

server中配置
proxy_http_version 1.1;
配置http版本號(hào)
默認(rèn)使用http1.0協(xié)議,需要在request中增加”Connection: keep-alive“ header才能夠支持,而HTTP1.1默認(rèn)支持。
proxy_set_header Connection "";
清楚close信息

AB安裝

yum install httpd-tools

參數(shù)說(shuō)明:

  • -n 即requests,用于指定壓力測(cè)試總共的執(zhí)行次數(shù)。
  • -c 即concurrency,用于指定的并發(fā)數(shù)。
  • -t 即timelimit,等待響應(yīng)的最大時(shí)間(單位:秒)。
  • -b 即windowsize,TCP發(fā)送/接收的緩沖大小(單位:字節(jié))。
  • -p 即postfile,發(fā)送POST請(qǐng)求時(shí)需要上傳的文件,此外還必須設(shè)置-T參數(shù)。
  • -u 即putfile,發(fā)送PUT請(qǐng)求時(shí)需要上傳的文件,此外還必須設(shè)置-T參數(shù)。
  • -T 即content-type,用于設(shè)置Content-Type請(qǐng)求頭信息,例如:application/x-www-form-urlencoded,默認(rèn)值為text/plain。
  • -v 即verbosity,指定打印幫助信息的冗余級(jí)別。
  • -w 以HTML表格形式打印結(jié)果。
  • -i 使用HEAD請(qǐng)求代替GET請(qǐng)求。
  • -x 插入字符串作為table標(biāo)簽的屬性。
  • -y 插入字符串作為tr標(biāo)簽的屬性。
  • -z 插入字符串作為td標(biāo)簽的屬性。
  • -C 添加cookie信息,例如:“Apache=1234”(可以重復(fù)該參數(shù)選項(xiàng)以添加多個(gè))。
  • -H 添加任意的請(qǐng)求頭,例如:“Accept-Encoding: gzip”,請(qǐng)求頭將會(huì)添加在現(xiàn)有的多個(gè)請(qǐng)求頭之后(可以重復(fù)該參數(shù)選項(xiàng)以添加多個(gè))。
  • -A 添加一個(gè)基本的網(wǎng)絡(luò)認(rèn)證信息,用戶名和密碼之間用英文冒號(hào)隔開(kāi)。
  • -P 添加一個(gè)基本的代理認(rèn)證信息,用戶名和密碼之間用英文冒號(hào)隔開(kāi)。
  • -X 指定使用的和端口號(hào),例如:“126.10.10.3:88”。
  • -V 打印版本號(hào)并退出。
  • -k 使用HTTP的KeepAlive特性。
  • -d 不顯示百分比。
  • -S 不顯示預(yù)估和警告信息。
  • -g 輸出結(jié)果信息到gnuplot格式的文件中。
  • -e 輸出結(jié)果信息到CSV格式的文件中。
  • -r 指定接收到錯(cuò)誤信息時(shí)不退出程序。
  • -h 顯示用法信息,其實(shí)就是ab -help。
直連nginx
Server Software:        nginx/1.21.6
Server Hostname:        192.168.44.102
Server Port:            80Document Path:          /
Document Length:        16 bytesConcurrency Level:      30
Time taken for tests:   13.035 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Total transferred:      25700000 bytes
HTML transferred:       1600000 bytes
Requests per second:    7671.48 [#/sec] (mean)
Time per request:       3.911 [ms] (mean)
Time per request:       0.130 [ms] (mean, across all concurrent requests)
Transfer rate:          1925.36 [Kbytes/sec] receivedConnection Times (ms)min  mean[+/-sd] median   max
Connect:        0    0   0.4      0      12
Processing:     1    3   1.0      3      14
Waiting:        0    3   0.9      3      14
Total:          2    4   0.9      4      14Percentage of the requests served within a certain time (ms)50%      466%      475%      480%      490%      595%      598%      699%      7100%     14 (longest request)
反向代理
Server Software:        nginx/1.21.6
Server Hostname:        192.168.44.101
Server Port:            80Document Path:          /
Document Length:        16 bytesConcurrency Level:      30
Time taken for tests:   25.968 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Total transferred:      25700000 bytes
HTML transferred:       1600000 bytes
Requests per second:    3850.85 [#/sec] (mean)
Time per request:       7.790 [ms] (mean)
Time per request:       0.260 [ms] (mean, across all concurrent requests)
Transfer rate:          966.47 [Kbytes/sec] receivedConnection Times (ms)min  mean[+/-sd] median   max
Connect:        0    0   0.2      0      13
Processing:     3    8   1.4      7      22
Waiting:        1    7   1.4      7      22
Total:          3    8   1.4      7      22Percentage of the requests served within a certain time (ms)50%      766%      875%      880%      890%      995%     1098%     1299%     13100%     22 (longest request)
直連Tomcat
Server Software:        
Server Hostname:        192.168.44.105
Server Port:            8080Document Path:          /
Document Length:        7834 bytesConcurrency Level:      30
Time taken for tests:   31.033 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Total transferred:      804300000 bytes
HTML transferred:       783400000 bytes
Requests per second:    3222.38 [#/sec] (mean)
Time per request:       9.310 [ms] (mean)
Time per request:       0.310 [ms] (mean, across all concurrent requests)
Transfer rate:          25310.16 [Kbytes/sec] receivedConnection Times (ms)min  mean[+/-sd] median   max
Connect:        0    0   0.3      0      15
Processing:     0    9   7.8      7     209
Waiting:        0    9   7.2      7     209
Total:          0    9   7.8      7     209Percentage of the requests served within a certain time (ms)50%      766%      975%     1180%     1390%     1895%     2298%     2799%     36100%    209 (longest request)
nginx反向代理Tomcat + keepalive

Server Software:        nginx/1.21.6
Server Hostname:        192.168.44.101
Server Port:            80Document Path:          /
Document Length:        7834 bytesConcurrency Level:      30
Time taken for tests:   23.379 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Total transferred:      806500000 bytes
HTML transferred:       783400000 bytes
Requests per second:    4277.41 [#/sec] (mean)
Time per request:       7.014 [ms] (mean)
Time per request:       0.234 [ms] (mean, across all concurrent requests)
Transfer rate:          33688.77 [Kbytes/sec] receivedConnection Times (ms)min  mean[+/-sd] median   max
Connect:        0    0   0.2      0       9
Processing:     1    7   4.2      6     143
Waiting:        1    7   4.2      6     143
Total:          1    7   4.2      6     143Percentage of the requests served within a certain time (ms)50%      666%      775%      780%      790%      895%     1098%     1399%     16100%    143 (longest request)
nginx反向代理Tomcat
Server Software:        nginx/1.21.6
Server Hostname:        192.168.44.101
Server Port:            80Document Path:          /
Document Length:        7834 bytesConcurrency Level:      30
Time taken for tests:   33.814 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Total transferred:      806500000 bytes
HTML transferred:       783400000 bytes
Requests per second:    2957.32 [#/sec] (mean)
Time per request:       10.144 [ms] (mean)
Time per request:       0.338 [ms] (mean, across all concurrent requests)
Transfer rate:          23291.74 [Kbytes/sec] receivedConnection Times (ms)min  mean[+/-sd] median   max
Connect:        0    0   0.2      0       9
Processing:     1   10   5.5      9     229
Waiting:        1   10   5.5      9     229
Total:          1   10   5.5      9     229Percentage of the requests served within a certain time (ms)50%      966%     1075%     1180%     1190%     1395%     1498%     1799%     19100%    229 (longest request)

UpStream工作流程

proxy_pass 向上游服務(wù)器請(qǐng)求數(shù)據(jù)共有6個(gè)階段

  • 初始化
  • 與上游服務(wù)器建立連接
  • 向上游服務(wù)器發(fā)送請(qǐng)求
  • 處理響應(yīng)頭
  • 處理響應(yīng)體
  • 結(jié)束

set_header

設(shè)置header

proxy_connect_timeout

與上游服務(wù)器連接超時(shí)時(shí)間、快速失敗

proxy_send_timeout

定義nginx向后端服務(wù)發(fā)送請(qǐng)求的間隔時(shí)間(不是耗時(shí))。默認(rèn)60秒,超過(guò)這個(gè)時(shí)間會(huì)關(guān)閉連接

proxy_read_timeout

后端服務(wù)給nginx響應(yīng)的時(shí)間,規(guī)定時(shí)間內(nèi)后端服務(wù)沒(méi)有給nginx響應(yīng),連接會(huì)被關(guān)閉,nginx返回504 Gateway Time-out。默認(rèn)60秒

緩沖區(qū)

proxy_requset_buffering

是否完全讀到請(qǐng)求體之后再向上游服務(wù)器發(fā)送請(qǐng)求

proxy_buffering

是否緩沖上游服務(wù)器數(shù)據(jù)

proxy_buffers 32 64k;

緩沖區(qū)大小 32個(gè) 64k大小內(nèi)存緩沖塊

proxy_buffer_size

header緩沖區(qū)大小

proxy_requset_buffering on;
proxy_buffering on;proxy_buffer_size 64k;proxy_buffers 32 128k;
proxy_busy_buffers_size 8k;
proxy_max_temp_file_size 1024m;

proxy_temp_file_write_size 8k

當(dāng)啟用從代理服務(wù)器到臨時(shí)文件的響應(yīng)的緩沖時(shí),一次限制寫(xiě)入臨時(shí)文件的數(shù)據(jù)的大小。 默認(rèn)情況下,大小由proxy_buffer_size和proxy_buffers指令設(shè)置的兩個(gè)緩沖區(qū)限制。 臨時(shí)文件的最大大小由proxy_max_temp_file_size指令設(shè)置。

proxy_max_temp_file_size 1024m;

臨時(shí)文件最大值

proxy_temp_path

proxy_temp_path /spool/nginx/proxy_temp 1 2;

a temporary file might look like this:

/spool/nginx/proxy_temp/7/45/00000123457
對(duì)客戶端的限制

可配置位置

  • http
  • server
  • location

client_body_buffer_size

對(duì)客戶端請(qǐng)求中的body緩沖區(qū)大小

默認(rèn)32位8k 64位16k

如果請(qǐng)求體大于配置,則寫(xiě)入臨時(shí)文件

client_header_buffer_size

設(shè)置讀取客戶端請(qǐng)求體的緩沖區(qū)大小。 如果請(qǐng)求體大于緩沖區(qū),則將整個(gè)請(qǐng)求體或僅將其部分寫(xiě)入臨時(shí)文件。 默認(rèn)32位8K。 64位平臺(tái)16K。

client_max_body_size 1000M;

默認(rèn)1m,如果一個(gè)請(qǐng)求的大小超過(guò)配置的值,會(huì)返回413 (request Entity Too Large)錯(cuò)誤給客戶端

將size設(shè)置為0將禁用對(duì)客戶端請(qǐng)求正文大小的檢查。

client_body_timeout

指定客戶端與服務(wù)端建立連接后發(fā)送 request body 的超時(shí)時(shí)間。如果客戶端在指定時(shí)間內(nèi)沒(méi)有發(fā)送任何內(nèi)容,Nginx 返回 HTTP 408(Request Timed Out)

client_header_timeout

客戶端向服務(wù)端發(fā)送一個(gè)完整的 request header 的超時(shí)時(shí)間。如果客戶端在指定時(shí)間內(nèi)沒(méi)有發(fā)送一個(gè)完整的 request header,Nginx 返回 HTTP 408(Request Timed Out)。

client_body_temp_path path [level1 [level2 [level3`]]]

在磁盤(pán)上客戶端的body臨時(shí)緩沖區(qū)位置

client_body_in_file_only on;

把body寫(xiě)入磁盤(pán)文件,請(qǐng)求結(jié)束也不會(huì)刪除

client_body_in_single_buffer

盡量緩沖body的時(shí)候在內(nèi)存中使用連續(xù)單一緩沖區(qū),在二次開(kāi)發(fā)時(shí)使用$request_body讀取數(shù)據(jù)時(shí)性能會(huì)有所提高

client_header_buffer_size

設(shè)置讀取客戶端請(qǐng)求頭的緩沖區(qū)大小

如果一個(gè)請(qǐng)求行或者一個(gè)請(qǐng)求頭字段不能放入這個(gè)緩沖區(qū),那么就會(huì)使用large_client_header_buffers

large_client_header_buffers

默認(rèn)8k

反向代理中的容錯(cuò)機(jī)制

參考文檔

https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/

http://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_bind

proxy_timeout

重試機(jī)制

proxy_next_upstream

作用:

當(dāng)后端服務(wù)器返回指定的錯(cuò)誤時(shí),將請(qǐng)求傳遞到其他服務(wù)器。

error與服務(wù)器建立連接,向其傳遞請(qǐng)求或讀取響應(yīng)頭時(shí)發(fā)生錯(cuò)誤;

timeout在與服務(wù)器建立連接,向其傳遞請(qǐng)求或讀取響應(yīng)頭時(shí)發(fā)生超時(shí);

invalid_header服務(wù)器返回空的或無(wú)效的響應(yīng);

http_500服務(wù)器返回代碼為500的響應(yīng);

http_502服務(wù)器返回代碼為502的響應(yīng);

http_503服務(wù)器返回代碼為503的響應(yīng);

http_504服務(wù)器返回代碼504的響應(yīng);

http_403服務(wù)器返回代碼為403的響應(yīng);

http_404服務(wù)器返回代碼為404的響應(yīng);

http_429服務(wù)器返回代碼為429的響應(yīng);

不了解這個(gè)機(jī)制,在日常開(kāi)發(fā)web服務(wù)的時(shí)候,就可能會(huì)踩坑。

比如有這么一個(gè)場(chǎng)景:一個(gè)用于導(dǎo)入數(shù)據(jù)的web頁(yè)面,上傳一個(gè)excel,通過(guò)讀取、處理excel,向數(shù)據(jù)庫(kù)中插入數(shù)據(jù),處理時(shí)間較長(zhǎng)(如1分鐘),且為同步操作(即處理完成后才返回結(jié)果)。暫且不論這種方式的好壞,若nginx配置的響應(yīng)等待時(shí)間(proxy_read_timeout)為30秒,就會(huì)觸發(fā)超時(shí)重試,將請(qǐng)求又打到另一臺(tái)。如果處理中沒(méi)有考慮到重復(fù)數(shù)據(jù)的場(chǎng)景,就會(huì)發(fā)生數(shù)據(jù)多次重復(fù)插入!(當(dāng)然,這種場(chǎng)景,內(nèi)網(wǎng)可以通過(guò)機(jī)器名訪問(wèn)該服務(wù)器進(jìn)行操作,就可以繞過(guò)nginx了,不過(guò)外網(wǎng)就沒(méi)辦法了。)

獲取客戶端真實(shí)IP

X-Real-IP

額外模塊,不推薦使用

setHeader
proxy_set_header X-Forwarded-For $remote_addr;

Gzip

作用域 http, server, location

gzip on;

開(kāi)關(guān),默認(rèn)關(guān)閉

gzip_buffers 32 4k|16 8k

緩沖區(qū)大小

gzip_comp_level 1;

壓縮等級(jí) 1-9,數(shù)字越大壓縮比越高

gzip_http_version 1.1;

使用gzip的最小版本

gzip_min_length

設(shè)置將被gzip壓縮的響應(yīng)的最小長(zhǎng)度。 長(zhǎng)度僅由“Content-Length”響應(yīng)報(bào)頭字段確定。

gzip_proxied 多選

off 為不做限制

作為反向代理時(shí),針對(duì)上游服務(wù)器返回的頭信息進(jìn)行壓縮

expired - 啟用壓縮,如果header頭中包含 “Expires” 頭信息
no-cache - 啟用壓縮,如果header頭中包含 “Cache-Control:no-cache” 頭信息
no-store - 啟用壓縮,如果header頭中包含 “Cache-Control:no-store” 頭信息
private - 啟用壓縮,如果header頭中包含 “Cache-Control:private” 頭信息
no_last_modified - 啟用壓縮,如果header頭中不包含 “Last-Modified” 頭信息
no_etag - 啟用壓縮 ,如果header頭中不包含 “ETag” 頭信息
auth - 啟用壓縮 , 如果header頭中包含 “Authorization” 頭信息
any - 無(wú)條件啟用壓縮

gzip_vary on;

增加一個(gè)header,適配老的瀏覽器 Vary: Accept-Encoding

gzip_types

哪些mime類型的文件進(jìn)行壓縮

gzip_disable

禁止某些瀏覽器使用gzip

完整實(shí)例
  gzip on;gzip_buffers 16 8k;gzip_comp_level 6;gzip_http_version 1.1;gzip_min_length 256;gzip_proxied any;gzip_vary on;gzip_types text/plain application/x-javascript text/css application/xml;gzip_typestext/xml application/xml application/atom+xml application/rss+xml application/xhtml+xml image/svg+xmltext/javascript application/javascript application/x-javascripttext/x-json application/json application/x-web-app-manifest+jsontext/css text/plain text/x-componentfont/opentype application/x-font-ttf application/vnd.ms-fontobjectimage/x-icon;gzip_disable "MSIE [1-6]\.(?!.*SV1)";
HTTP/1.1 200
Server: nginx/1.21.6
Date: Wed, 18 May 2022 17:42:35 GMT
Content-Type: text/html;charset=utf-8
Content-Length: 7832
Connection: keep-alive
Keep-Alive: timeout=65

ngx_http_gunzip_module

幫助不支持gzip的客戶端解壓本地文件

http_gzip_static_module

需要重新編譯nginx

./configure --with-http_gzip_static_module

Brotli

安裝
  • 官網(wǎng)

    • https://github.com/google/ngx_brotli
    • https://codeload.github.com/google/brotli/tar.gz/refs/tags/v1.0.9
  • 下載 兩個(gè)項(xiàng)目

  • 解壓縮

模塊化編譯

./configure --with-compat --add-dynamic-module=/root/ngx_brotli-1.0.0rc --prefix=/usr/local/nginx/

--add-dynamic-module=brotli目錄
  • make

  • ngx_http_brotli_filter_module.so ngx_http_brotli_static_module.so拷貝到/usr/local/nginx/modules/

  • 復(fù)制nginx主程序

  • 配置文件中添加

load_module "/usr/local/nginx/modules/ngx_http_brotli_filter_module.so";
load_module "/usr/local/nginx/modules/ngx_http_brotli_static_module.so";
brotli on;brotli_static on;brotli_comp_level 6;brotli_buffers 16 8k;brotli_min_length 20;brotli_types text/plain text/css text/javascript application/javascript text/xml application/xml application/xml+rss application/json image/jpeg image/gif image/png;
  • 測(cè)試

默認(rèn)http協(xié)議是沒(méi)有br的

curl -H 'Accept-Encoding: gzip' -I http://localhost

合并客戶端請(qǐng)求

Concat模塊

Tengine

Nginx官方介紹

https://www.nginx.com/resources/wiki/modules/concat/

git地址

https://github.com/alibaba/nginx-http-concat

  • 安裝

下載源碼解壓縮編譯安裝

  • 配置
    concat on;concat_max_files 30;

資源靜態(tài)化

?高并發(fā)系統(tǒng)資源靜態(tài)化方案

?一致性問(wèn)題

?合并文件輸出

?集群文件同步

SSI合并服務(wù)器端文件

官方文檔

http://nginx.org/en/docs/http/ngx_http_ssi_module.html

配置

ssi_min_file_chunk

向磁盤(pán)存儲(chǔ)并使用sendfile發(fā)送,文件大小最小值

ssi_last_modified

是否保留lastmodified

ssi_silent_errors

不顯示邏輯錯(cuò)誤

ssi_value_length

限制腳本參數(shù)最大長(zhǎng)度

ssi_types

默認(rèn)text/html;如果需要其他mime類型 需要設(shè)置

include file
<!--# include file="footer.html" -->

靜態(tài)文件直接引用

include virtual

可以指向location,而不一定是具體文件

include wait

阻塞請(qǐng)求

include set

在virtual基礎(chǔ)上設(shè)置變量

set

設(shè)置臨時(shí)變量

block

可以聲明一個(gè)ssi的命令塊,里面可以包裹其他命令

config errmsg

在模板中配置報(bào)錯(cuò)情況

config timefmt

日期格式化

echo

直接輸出變量

  • var變量名稱
  • encoding 是否使用特殊編碼格式
  • default 變量沒(méi)有值的時(shí)候使用默認(rèn)值
if

邏輯判斷

rsync

https://www.samba.org/ftp/rsync/rsync.html

remote synchronize是一個(gè)遠(yuǎn)程數(shù)據(jù)同步工具,可通過(guò) LAN/WAN 快速同步多臺(tái)主機(jī)之間的文件。也可以使用 rsync 同步本地硬盤(pán)中的不同目錄。
rsync 是用于替代 rcp 的一個(gè)工具,rsync 使用所謂的 rsync算法 進(jìn)行數(shù)據(jù)同步,這種算法只傳送兩個(gè)文件的不同部分,而不是每次都整份傳送,因此速度相當(dāng)快。

rsync 基于inotify 開(kāi)發(fā)

Rsync有三種模式:

  • 本地模式(類似于cp命令)
  • 遠(yuǎn)程模式(類似于scp命令)
  • 守護(hù)進(jìn)程(socket進(jìn)程:是rsync的重要功能)

rsync 常用選項(xiàng)

選項(xiàng)含義
-a包含-rtplgoD
-r同步目錄時(shí)要加上,類似cp時(shí)的-r選項(xiàng)
-v同步時(shí)顯示一些信息,讓我們知道同步的過(guò)程
-l保留軟連接
-L加上該選項(xiàng)后,同步軟鏈接時(shí)會(huì)把源文件給同步
-p保持文件的權(quán)限屬性
-o保持文件的屬主
-g保持文件的屬組
-D保持設(shè)備文件信息
-t保持文件的時(shí)間屬性
–delete刪除DEST中SRC沒(méi)有的文件
–exclude過(guò)濾指定文件,如–exclude “l(fā)ogs”會(huì)把文件名包含logs的文件或者目錄過(guò)濾掉,不同步
-P顯示同步過(guò)程,比如速率,比-v更加詳細(xì)
-u加上該選項(xiàng)后,如果DEST中的文件比SRC新,則不同步
-z傳輸時(shí)壓縮
安裝

兩端安裝

yum install -y rsync

密碼文件

創(chuàng)建文件/etc/rsync.password

內(nèi)容

hello:123

修改權(quán)限

chmod 600 /etc/rsync.password

修改配置

auth users = sgg
secrets file = /etc/rsyncd.pwd
開(kāi)機(jī)啟動(dòng)

/etc/rc.local文件中添加

rsync --daemon
  • 修改權(quán)限

echo “sgg:111” >> /etc/rsyncd.passwd

查看遠(yuǎn)程目錄

rsync --list-only 192.168.44.104::www/

拉取數(shù)據(jù)到指定目錄

rsync -avz rsync://192.168.44.104:873/www

rsync -avz 192.168.44.104::www/ /root/w

使用SSH方式

rsync -avzP /usr/local/nginx/html/ root@192.168.44.105:/www/

客戶端免密

客戶端只放密碼

echo "111" >> /etc/rsyncd.passwd

此時(shí)在客戶端已經(jīng)可以配合腳本實(shí)現(xiàn)定時(shí)同步了

如何實(shí)現(xiàn)推送?

修改配置

rsync -avz --password-file=/etc/rsyncd.passwd.client /usr/local/nginx/html/ rsync://sgg@192.168.44.105:/www

--delete 刪除目標(biāo)目錄比源目錄多余文件

實(shí)時(shí)推送

推送端安裝inotify

依賴

yum install -y automake
wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
./configure --prefix=/usr/local/inotify
make && make install

監(jiān)控目錄

/usr/local/inotify/bin/inotifywait -mrq --timefmt '%Y-%m-%d %H:%M:%S' --format '%T %w%f %e' -e close_write,modify,delete,create,attrib,move //usr/local/nginx/html/
簡(jiǎn)單自動(dòng)化腳本
#!/bin/bash/usr/local/inotify/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f %e' -e close_write,modify,delete,create,attrib,move //usr/local/nginx/html/ | while read file
dorsync -az --delete --password-file=/etc/rsyncd.passwd.client /usr/local/nginx/html/ sgg@192.168.44.102::ftp/
done
inotify常用參數(shù)
參數(shù)說(shuō)明含義
-r–recursive#遞歸查詢目錄
-q–quiet#打印很少的信息,僅僅打印監(jiān)控事件信息
-m–monitor#始終保持事件監(jiān)聽(tīng)狀態(tài)
–excludei#排除文件或目錄時(shí),不區(qū)分大小寫(xiě)
–timefmt#指定事件輸出格式
–format#打印使用指定的輸出類似格式字符串
-e–event[ -e|–event … ]accessmodifyattribcloseopenmove_tomove createdeleteumount#通過(guò)此參數(shù)可以指定要監(jiān)控的事件 #文件或目錄被讀取#文件或目錄的內(nèi)容被修改#文件或目錄屬性被改變#文件或目錄封閉,無(wú)論讀/寫(xiě)模式#文件或目錄被打開(kāi)#文件或目錄被移動(dòng)至另外一個(gè)目錄#文件或目錄被移動(dòng)另一個(gè)目錄或從另一個(gè)目錄移動(dòng)至當(dāng)前目錄#文件或目錄被創(chuàng)建在當(dāng)前目錄#文件或目錄被刪除#文件系統(tǒng)被卸載

多級(jí)緩存

靜態(tài)資源緩存
瀏覽器緩存
什么時(shí)候可以用緩存?
  1. 不常改變的內(nèi)容
  2. 過(guò)期時(shí)間
  3. 針對(duì)post/get請(qǐng)求都可以
  4. 存儲(chǔ)位置
  5. 磁盤(pán)使用空間限制

觀察京東緩存及加載速度

  • deskcache

字面理解是從內(nèi)存中,其實(shí)也是字面的含義,這個(gè)資源是直接從內(nèi)存中拿到的,不會(huì)請(qǐng)求服務(wù)器一般已經(jīng)加載過(guò)該資源且緩存在了內(nèi)存當(dāng)中,當(dāng)關(guān)閉該頁(yè)面時(shí),此資源就被內(nèi)存釋放掉了,再次重新打開(kāi)相同頁(yè)面時(shí)不會(huì)出現(xiàn)from memory cache的情況

  • memorycache

是從磁盤(pán)當(dāng)中取出的,也是在已經(jīng)在之前的某個(gè)時(shí)間加載過(guò)該資源,不會(huì)請(qǐng)求服務(wù)器但是此資源不會(huì)隨著該頁(yè)面的關(guān)閉而釋放掉,因?yàn)槭谴嬖谟脖P(pán)當(dāng)中的,下次打開(kāi)仍會(huì)from disk cache

Age

是CDN添加的屬性表示在CDN中緩存了多少秒

via

用來(lái)標(biāo)識(shí)CDN緩存經(jīng)歷了哪些服務(wù)器,緩存是否命中,使用的協(xié)議

Nginx默認(rèn)緩存

Nginx版本不同會(huì)默認(rèn)配置

強(qiáng)制緩存與協(xié)商緩存

強(qiáng)制緩存:直接從本機(jī)讀取,不請(qǐng)求服務(wù)器

協(xié)商緩存:發(fā)送請(qǐng)求header中攜帶Last-Modified,服務(wù)器可能會(huì)返回304 Not Modified

瀏覽器強(qiáng)制緩存
cache-control

http1.1的規(guī)范,使用max-age表示文件可以在瀏覽器中緩存的時(shí)間以秒為單位

標(biāo)記類型功能
public響應(yīng)頭響應(yīng)的數(shù)據(jù)可以被緩存,客戶端和代理層都可以緩存
private響應(yīng)頭可私有緩存,客戶端可以緩存,代理層不能緩存(CDN,proxy_pass)
no-cache請(qǐng)求頭可以使用本地緩存,但是必須發(fā)送請(qǐng)求到服務(wù)器回源驗(yàn)證
no-store請(qǐng)求和響應(yīng)應(yīng)禁用緩存
max-age請(qǐng)求和響應(yīng)文件可以在瀏覽器中緩存的時(shí)間以秒為單位
s-maxage請(qǐng)求和響應(yīng)用戶代理層緩存,CDN下發(fā),當(dāng)客戶端數(shù)據(jù)過(guò)期時(shí)會(huì)重新校驗(yàn)
max-stale請(qǐng)求和響應(yīng)緩存最大使用時(shí)間,如果緩存過(guò)期,但還在這個(gè)時(shí)間范圍內(nèi)則可以使用緩存數(shù)據(jù)
min-fresh請(qǐng)求和響應(yīng)緩存最小使用時(shí)間,
must-revalidate請(qǐng)求和響應(yīng)當(dāng)緩存過(guò)期后,必須回源重新請(qǐng)求資源。比no-cache更嚴(yán)格。因?yàn)镠TTP 規(guī)范是允許客戶端在某些特殊情況下直接使用過(guò)期緩存的,比如校驗(yàn)請(qǐng)求發(fā)送失敗的時(shí)候。那么帶有must-revalidate的緩存必須校驗(yàn),其他條件全部失效。
proxy-revalidate請(qǐng)求和響應(yīng)和must-revalidate類似,只對(duì)CDN這種代理服務(wù)器有效,客戶端遇到此頭,需要回源驗(yàn)證
stale-while-revalidate響應(yīng)表示在指定時(shí)間內(nèi)可以先使用本地緩存,后臺(tái)進(jìn)行異步校驗(yàn)
stale-if-error響應(yīng)在指定時(shí)間內(nèi),重新驗(yàn)證時(shí)返回狀態(tài)碼為5XX的時(shí)候,可以用本地緩存
only-if-cached響應(yīng)那么只使用緩存內(nèi)容,如果沒(méi)有緩存 則504 getway timeout

在瀏覽器和服務(wù)器端驗(yàn)證文件是否過(guò)期的時(shí)候,瀏覽器在二次請(qǐng)求的時(shí)候會(huì)攜帶IF-Modified-Since屬性

Expires

過(guò)期時(shí)間

expires 30s;   #緩存30秒
expires 30m;  #緩存30分鐘   
expires 2h;     #緩存2小時(shí)
expires 30d;    #緩存30天
協(xié)商緩存
last-modified
etag

http1.1支持

在HTTP協(xié)議中If-Modified-Since和If-None-Match分別對(duì)應(yīng)Last-Modified和ETag

Entity Tag 的縮寫(xiě),中文譯過(guò)來(lái)就是實(shí)體標(biāo)簽的意思.

HTTP中并沒(méi)有指定如何生成ETag,哈希是比較理想的選擇。

在計(jì)算Etag的時(shí)候,會(huì)產(chǎn)生CPU的耗費(fèi),所以也可以用時(shí)間戳,但這樣直接使用Last-Modified即可。

ETag 用來(lái)校驗(yàn)用戶請(qǐng)求的資源是否有變化,作用和lastmodified很像,區(qū)別是lastmodified精確到秒,ETag可以用hash算法來(lái)生成更精確的比對(duì)內(nèi)容。

當(dāng)用戶首次請(qǐng)求資源的時(shí)候返回給用戶數(shù)據(jù)和200狀態(tài)碼并生成ETag,再次請(qǐng)求的時(shí)候服務(wù)器比對(duì)ETag,沒(méi)有發(fā)生變化的話返回304

Cache-Control直接是通過(guò)不請(qǐng)求來(lái)實(shí)現(xiàn),而ETag是會(huì)發(fā)請(qǐng)求的,只不過(guò)服務(wù)器根據(jù)請(qǐng)求的東西的內(nèi)容有無(wú)變化來(lái)判斷是否返回請(qǐng)求的資源

總結(jié):

cache-control expires 強(qiáng)制緩存

頁(yè)面首次打開(kāi),直接讀取緩存數(shù)據(jù),刷新,會(huì)向服務(wù)器發(fā)起請(qǐng)求

etag lastmodify 協(xié)商緩存

沒(méi)發(fā)生變化 返回304 不發(fā)送數(shù)據(jù)

last-modified 與ssi的沖突
瀏覽器緩存原則
  • 多級(jí)集群負(fù)載時(shí)last-modified必須保持一致

  • 還有一些場(chǎng)景下我們希望禁用瀏覽器緩存。比如輪訓(xùn)api上報(bào)數(shù)據(jù)數(shù)據(jù)

  • 瀏覽器緩存很難徹底禁用,大家的做法是加版本號(hào),隨機(jī)數(shù)等方法。

  • 只緩存200響應(yīng)頭的數(shù)據(jù),像3XX這類跳轉(zhuǎn)的頁(yè)面不需要緩存。

  • 對(duì)于js,css這類可以緩存很久的數(shù)據(jù),可以通過(guò)加版本號(hào)的方式更新內(nèi)容

  • 不需要強(qiáng)一致性的數(shù)據(jù),可以緩存幾秒

  • 異步加載的接口數(shù)據(jù),可以使用ETag來(lái)校驗(yàn)。

  • 在服務(wù)器添加Server頭,有利于排查錯(cuò)誤

  • 分為手機(jī)APP和Client以及是否遵循h(huán)ttp協(xié)議

  • 在沒(méi)有聯(lián)網(wǎng)的狀態(tài)下可以展示數(shù)據(jù)

  • 流量消耗過(guò)多

  • 提前下發(fā) 避免秒殺時(shí)同時(shí)下發(fā)數(shù)據(jù)造成流量短時(shí)間暴增

  • 兜底數(shù)據(jù) 在服務(wù)器崩潰和網(wǎng)絡(luò)不可用的時(shí)候展示

  • 臨時(shí)緩存 退出即清理

  • 固定緩存 展示框架這種,可能很長(zhǎng)時(shí)間不會(huì)更新,可用隨客戶端下發(fā)

    • 首頁(yè)有的時(shí)候可以看做是框架 應(yīng)該禁用緩存,以保證加載的資源都是最新的
  • 父子連接 頁(yè)面跳轉(zhuǎn)時(shí)有一部分內(nèi)容不需要重新加載,可用從父菜單帶過(guò)來(lái)

  • 預(yù)加載 某些邏輯可用判定用戶接下來(lái)的操作,那么可用異步加載那些資源

  • 漂亮的加載過(guò)程 異步加載 先展示框架,然后異步加載內(nèi)容,避免主線程阻塞

GEOip

1 下載數(shù)據(jù)庫(kù)

官網(wǎng)需注冊(cè)登錄

下載數(shù)據(jù)庫(kù)

maxmind.com

2 安裝依賴
官方git

https://github.com/maxmind/libmaxminddb

下載后執(zhí)行編譯安裝之后

$ echo /usr/local/lib  >> /etc/ld.so.conf.d/local.conf 
$ ldconfig
Nginx模塊

https://github.com/leev/ngx_http_geoip2_module

更完整的配置可參考官方文檔

http://nginx.org/en/docs/http/ngx_http_geoip_module.html#geoip_proxy

Nginx配置
    geoip2 /root/GeoLite2-ASN_20220524/GeoLite2-ASN.mmdb {
$geoip2_country_code country iso_code;}
add_header country $geoip2_country_code;

正向代理與反向代理緩存

正向代理配置
proxy_pass $scheme://$host$request_uri;
resolver 8.8.8.8;
代理https請(qǐng)求

需要第三方模塊

https://github.com/chobits/ngx_http_proxy_connect_module

配置

 server {listen                         3128;# dns resolver used by forward proxyingresolver                       8.8.8.8;# forward proxy for CONNECT requestproxy_connect;proxy_connect_allow            443 563;proxy_connect_connect_timeout  10s;proxy_connect_read_timeout     10s;proxy_connect_send_timeout     10s;# forward proxy for non-CONNECT requestlocation / {proxy_pass http://$host;proxy_set_header Host $host;}}

proxy緩存

官網(wǎng)解釋

http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache

配置
http模塊:
proxy_cache_path /ngx_tmp levels=1:2 keys_zone=test_cache:100m inactive=1d max_size=10g ;
location模塊:
add_header  Nginx-Cache "$upstream_cache_status";
proxy_cache test_cache;
proxy_cache_valid 168h;

proxy_cache_use_stale

默認(rèn)off

在什么時(shí)候可以使用過(guò)期緩存

可選error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | http_429 | off

proxy_cache_background_update

默認(rèn)off

運(yùn)行開(kāi)啟子請(qǐng)求更新過(guò)期的內(nèi)容。同時(shí)會(huì)把過(guò)期的內(nèi)容返回給客戶端

proxy_no_cache proxy_cache_bypass

指定什么時(shí)候不使用緩存而直接請(qǐng)求上游服務(wù)器

proxy_no_cache $cookie_nocache $arg_nocache$arg_comment;
proxy_no_cache $http_pragma    $http_authorization;

如果這些變量如果存在的話不為空或者不等于0,則不使用緩存

proxy_cache_convert_head

默認(rèn) on

是否把head請(qǐng)求轉(zhuǎn)換成get請(qǐng)求后再發(fā)送給上游服務(wù)器 以便緩存body里的內(nèi)容

如果關(guān)閉 需要在 cache key 中添加 $request_method 以便區(qū)分緩存內(nèi)容

proxy_cache_lock

默認(rèn)off

緩存更新鎖

proxy_cache_lock_age

默認(rèn)5s

緩存鎖超時(shí)時(shí)間

斷點(diǎn)續(xù)傳緩存 range

當(dāng)有完整的content-length之后即可斷點(diǎn)續(xù)傳

在反向代理服務(wù)器中需向后傳遞header

proxy_set_header Range $http_range;

proxy_cache_key中增加range

proxy_cache_max_range_offset

range最大值,超過(guò)之后不做緩存,默認(rèn)情況下 不需要對(duì)單文件較大的資源做緩存

proxy_cache_methods

默認(rèn) head get

proxy_cache_min_uses

默認(rèn)1

被請(qǐng)求多少次之后才做緩存

proxy_cache_path

path 指定存儲(chǔ)目錄

以cache_key取md5值

  • levels=1:2

目錄層級(jí)數(shù)及目錄名稱位數(shù)

取mdb5后幾位

TMPFS

  • use_temp_path

默認(rèn)創(chuàng)建緩存文件時(shí),先向緩沖區(qū)創(chuàng)建臨時(shí)文件,再移動(dòng)到緩存目錄

是否使用緩沖區(qū)

  • inactive

指定時(shí)間內(nèi)未被訪問(wèn)過(guò)的緩存將被刪除

緩存清理

purger

需要第三方模塊支持

https://github.com/FRiCKLE/ngx_cache_purge

配置

location ~ /purge(/.*) {proxy_cache_purge  test_cache  $1;}自定義cachekeyproxy_cache_key $uri;

proxy_cache_key

默認(rèn)$scheme$proxy_host$request_uri

緩存的key

proxy_cache_revalidate

如果緩存過(guò)期了,向上游服務(wù)器發(fā)送“If-Modified-Since” and “If-None-Match來(lái)驗(yàn)證是否改變,如果沒(méi)有就不需要重新下載資源了

proxy_cache_valid

可以針對(duì)不容http狀態(tài)碼設(shè)置緩存過(guò)期時(shí)間

不設(shè)置狀態(tài)碼會(huì)默認(rèn)200, 301, 302

proxy_cache_valid 200 302 10m;
proxy_cache_valid 301      1h;
proxy_cache_valid any      1m;

any指其他任意狀態(tài)碼

第二部分 高效

Nginx內(nèi)存緩存

strace

一般應(yīng)用為靜態(tài)文件元數(shù)據(jù)信息緩存

sendfile執(zhí)行過(guò)程

epoll_wait(8, [{EPOLLIN, {u32=1904243152, u64=140709327827408}}, {EPOLLIN, {u32=1904242704, u64=140709327826960}}], 512, 25215) = 2
recvfrom(10, "GET / HTTP/1.1\r\nHost: 192.168.44"..., 1024, 0, NULL, NULL) = 475
stat("/usr/local/nginx//html/index.html", {st_mode=S_IFREG|0644, st_size=1429, ...}) = 0
open("/usr/local/nginx//html/index.html", O_RDONLY|O_NONBLOCK) = 11
fstat(11, {st_mode=S_IFREG|0644, st_size=1429, ...}) = 0
writev(10, [{iov_base="HTTP/1.1 200 OK\r\nServer: nginx/1"..., iov_len=263}], 1) = 263
sendfile(10, 11, [0] => [1429], 1429)   = 1429
write(4, "192.168.44.1 - - [27/May/2022:14"..., 193) = 193
close(11) 

open_file_cache

open_file_cache max=500 inactive=60s
open_file_cache_min_uses 1; 
open_file_cache_valid 60s; 
open_file_cache_errors on

max緩存最大數(shù)量,超過(guò)數(shù)量后會(huì)使用LRU淘汰

inactive 指定時(shí)間內(nèi)未被訪問(wèn)過(guò)的緩存將被刪除

pen_file_cache_min_uses

被訪問(wèn)到多少次后會(huì)開(kāi)始緩存

open_file_cache_valid

間隔多長(zhǎng)時(shí)間去檢查文件是否有變化

open_file_cache_errors

對(duì)錯(cuò)誤信息是否緩存

Nginx外置緩存緩存

http://nginx.org/en/docs/http/ngx_http_memcached_module.html

error_page

指定狀態(tài)碼

	error_page 404 =302 http://www.atguigu.com;

默認(rèn)指向location

匿名location

nginx + memcached

memcached安裝

yum -y install memcached

默認(rèn)配置文件在

/etc/sysconfig/memcached

查看狀態(tài)

memcached-tool 127.0.0.1:11211  stats
nginx配置
    upstream backend {#   server 192.168.44.102 weight=8 down;server 192.168.44.104:8080;}location / {set            $memcached_key "$uri?$args";memcached_pass 127.0.0.1:11211;add_header X-Cache-Satus HIT;add_header Content-Type 'text/html; charset=utf-8'; # 強(qiáng)制響應(yīng)數(shù)據(jù)格式為html# root   html;}

nginx + redis

Redis安裝

7.0下載地址

https://codeload.github.com/redis/redis/tar.gz/refs/tags/7.0.0

安裝
依賴
yum install -y tcl-devel解壓
make
make install 

redis2-nginx-module

redis2-nginx-module是一個(gè)支持 Redis 2.0 協(xié)議的 Nginx upstream 模塊,它可以讓 Nginx 以非阻塞方式直接防問(wèn)遠(yuǎn)方的 Redis 服務(wù),同時(shí)支持 TCP 協(xié)議和 Unix Domain Socket 模式,并且可以啟用強(qiáng)大的 Redis 連接池功能。

https://www.nginx.com/resources/wiki/modules/redis2/

https://github.com/openresty/redis2-nginx-module

redis快速安裝

yum install epel-release
yum install -y redis

redis2-nginx-module 安裝

test
location = /foo {default_type text/html;redis2_query auth 123123;set $value 'first';redis2_query set one $value;redis2_pass 192.168.199.161:6379;}
get
location = /get {default_type text/html;redis2_pass 192.168.199.161:6379;redis2_query auth 123123;set_unescape_uri $key $arg_key;  # this requires ngx_set_miscredis2_query get $key;}
set
# GET /set?key=one&val=first%20valuelocation = /set {default_type text/html;redis2_pass 192.168.199.161:6379;redis2_query auth 123123;set_unescape_uri $key $arg_key;  # this requires ngx_set_miscset_unescape_uri $val $arg_val;  # this requires ngx_set_miscredis2_query set $key $val;}
pipeline
     set $value 'first';redis2_query set one $value;redis2_query get one;redis2_query set one two;redis2_query get one;redis2_query del key1;
list
    redis2_query lpush key1 C;redis2_query lpush key1 B;redis2_query lpush key1 A;redis2_query lrange key1 0 -1;
集群
upstream redis_cluster {server 192.168.199.161:6379;server 192.168.199.161:6379;}location = /redis {default_type text/html;redis2_next_upstream error timeout invalid_response;redis2_query get foo;redis2_pass redis_cluster;}

Stream模塊

http://nginx.org/en/docs/stream/ngx_stream_core_module.html

限流

QPS限制

官方文檔

http://nginx.org/en/docs/http/ngx_http_limit_req_module.html

測(cè)試工具

https://jmeter.apache.org/

配置

limit_req_zone $binary_remote_addr zone=test:10m rate=15r/s;
limit_req zone=req_zone_wl burst=20 nodelay;

日志

ngx_http_log_module

http://nginx.org/en/docs/http/ngx_http_log_module.html

ngx_http_empty_gif_module

http://nginx.org/en/docs/http/ngx_http_empty_gif_module.html

json
log_format  ngxlog json '{"timestamp":"$time_iso8601",''"source":"$server_addr",''"hostname":"$hostname",''"remote_user":"$remote_user",''"ip":"$http_x_forwarded_for",''"client":"$remote_addr",''"request_method":"$request_method",''"scheme":"$scheme",''"domain":"$server_name",''"referer":"$http_referer",''"request":"$request_uri",''"requesturl":"$request",''"args":"$args",''"size":$body_bytes_sent,''"status": $status,''"responsetime":$request_time,''"upstreamtime":"$upstream_response_time",''"upstreamaddr":"$upstream_addr",''"http_user_agent":"$http_user_agent",''"http_cookie":"$http_cookie",''"https":"$https"''}';
errorlog

http://nginx.org/en/docs/ngx_core_module.html#error_log

日志分割

1.腳本

2.Logrotate

重試機(jī)制

http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_next_upstream

max_fails

最大失敗次數(shù)

0為標(biāo)記一直可用,不檢查健康狀態(tài)

fail_timeout

失敗時(shí)間

當(dāng)fail_timeout時(shí)間內(nèi)失敗了max_fails次,標(biāo)記服務(wù)不可用

fail_timeout時(shí)間后會(huì)再次激活次服務(wù)

proxy_next_upstream

proxy_next_upstream_timeout

重試最大超時(shí)時(shí)間

proxy_next_upstream_tries

重試次數(shù),包括第一次

proxy_next_upstream_timeout時(shí)間內(nèi)允許proxy_next_upstream_tries次重試

主動(dòng)健康檢查

tengine版

https://github.com/yaoweibin/nginx_upstream_check_module

nginx商業(yè)版

http://nginx.org/en/docs/http/ngx_http_upstream_hc_module.html

配置

      upstream backend {#   server 192.168.44.102 weight=8 down;server 192.168.44.104:8080;server 192.168.44.105:8080;check interval=3000 rise=2 fall=5 timeout=1000 type=http;check_http_send "HEAD / HTTP/1.0\r\n\r\n";check_http_expect_alive http_2xx http_3xx;}location /status {check_status;access_log off;}location / {proxy_pass http://backend;root   html;}

Openresty

Lua

Lua 是由巴西里約熱內(nèi)盧天主教大學(xué)(Pontifical Catholic University of Rio de Janeiro)里的一個(gè)研究小組于1993年開(kāi)發(fā)的一種輕量、小巧的腳本語(yǔ)言,用標(biāo)準(zhǔn) C 語(yǔ)言編寫(xiě),其設(shè)計(jì)目的是為了嵌入應(yīng)用程序中,從而為應(yīng)用程序提供靈活的擴(kuò)展和定制功能。

官網(wǎng):http://www.lua.org/

IDE

EmmyLua插件

https://github.com/EmmyLua/IntelliJ-EmmyLua

https://emmylua.github.io/zh_CN/

LDT 基于eclipse

https://www.eclipse.org/ldt/

Lua基礎(chǔ)語(yǔ)法

hello world
print("hello world!")
保留關(guān)鍵字

and break do else elseif end false for function if in local nil not or repeat return then true until while

注釋
-- 兩個(gè)減號(hào)是行注釋--[[這是塊注釋這是塊注釋.--]]
變量
數(shù)字類型

Lua的數(shù)字只有double型,64bits

你可以以如下的方式表示數(shù)字

num = 1024num = 3.0num = 3.1416num = 314.16e-2num = 0.31416E1num = 0xffnum = 0x56
字符串

可以用單引號(hào),也可以用雙引號(hào)

也可以使用轉(zhuǎn)義字符‘\n’ (換行), ‘\r’ (回車), ‘\t’ (橫向制表), ‘\v’ (縱向制表), ‘\’ (反斜杠), ‘\”‘ (雙引號(hào)), 以及 ‘\” (單引號(hào))等等

下面的四種方式定義了完全相同的字符串(其中的兩個(gè)中括號(hào)可以用于定義有換行的字符串)

a = 'alo\n123"'a = "alo\n123\""a = '\97lo\10\04923"'a = [[alo123"]]
空值

C語(yǔ)言中的NULL在Lua中是nil,比如你訪問(wèn)一個(gè)沒(méi)有聲明過(guò)的變量,就是nil

布爾類型

只有nil和false是 false

數(shù)字0,‘’空字符串(’\0’)都是true

作用域

lua中的變量如果沒(méi)有特殊說(shuō)明,全是全局變量,那怕是語(yǔ)句塊或是函數(shù)里。

變量前加local關(guān)鍵字的是局部變量。

控制語(yǔ)句
while循環(huán)
local i = 0local max = 10while i <= max doprint(i)i = i +1end
if-else
local function main()local age = 140local sex = 'Male'if age == 40 and sex =="Male" thenprint(" 男人四十一枝花 ")elseif age > 60 and sex ~="Female" thenprint("old man!!")elseif age < 20 thenio.write("too young, too simple!\n")elseprint("Your age is "..age)endend-- 調(diào)用
main()
for循環(huán)
sum = 0for i = 100, 1, -2 dosum = sum + iend
函數(shù)
function myPower(x,y)return      y+xendpower2 = myPower(2,3)print(power2)
function newCounter()local i = 0return function()     -- anonymous functioni = i + 1return iend
endc1 = newCounter()print(c1())  --> 1print(c1())  --> 2print(c1())
返回值
name, age,bGay = "yiming", 37, false, "yimingl@hotmail.com"print(name,age,bGay)
function isMyGirl(name)return name == 'xiao6' , name
endlocal bol,name = isMyGirl('xiao6')print(name,bol)
Table

key,value的鍵值對(duì) 類似 map

local function main()
dog = {name='111',age=18,height=165.5}dog.age=35print(dog.name,dog.age,dog.height)print(dog)
end
main()
數(shù)組
local function main()
arr = {"string", 100, "dog",function() print("wangwang!") return 1 end}print(arr[4]())
end
main()
遍歷
arr = {"string", 100, "dog",function() print("wangwang!") return 1 end}for k, v in pairs(arr) doprint(k, v)
end
成員函數(shù)
local function main()person = {name='旺財(cái)',age = 18}function  person.eat(food)print(person.name .." eating "..food)end
person.eat("骨頭")
end
main()

Openresty Nginx + Lua

Nginx是一個(gè)主進(jìn)程配合多個(gè)工作進(jìn)程的工作模式,每個(gè)進(jìn)程由單個(gè)線程來(lái)處理多個(gè)連接。

在生產(chǎn)環(huán)境中,我們往往會(huì)把cpu內(nèi)核直接綁定到工作進(jìn)程上,從而提升性能。

安裝

預(yù)編譯安裝

以CentOS舉例 其他系統(tǒng)參照:http://openresty.org/cn/linux-packages.html

你可以在你的 CentOS 系統(tǒng)中添加 openresty 倉(cāng)庫(kù),這樣就可以便于未來(lái)安裝或更新我們的軟件包(通過(guò) yum update 命令)。運(yùn)行下面的命令就可以添加我們的倉(cāng)庫(kù):

? yum install yum-utils

? yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo

然后就可以像下面這樣安裝軟件包,比如 openresty:

? yum install openresty

如果你想安裝命令行工具 resty,那么可以像下面這樣安裝 openresty-resty 包:

? sudo yum install openresty-resty

源碼編譯安裝
下載

http://openresty.org/cn/download.html

最小版本基于nginx1.21

./configure

然后在進(jìn)入 openresty-VERSION/ 目錄, 然后輸入以下命令配置:

./configure

默認(rèn), --prefix=/usr/local/openresty 程序會(huì)被安裝到/usr/local/openresty目錄。

依賴 gcc openssl-devel pcre-devel zlib-devel

安裝:yum install gcc openssl-devel pcre-devel zlib-devel postgresql-devel

您可以指定各種選項(xiàng),比如

./configure --prefix=/opt/openresty \--with-luajit \--without-http_redis2_module \--with-http_iconv_module \--with-http_postgres_module

試著使用 ./configure --help 查看更多的選項(xiàng)。

make && make install

服務(wù)命令
啟動(dòng)

Service openresty start

停止

Service openresty stop

檢查配置文件是否正確

Nginx -t

重新加載配置文件

Service openresty reload

查看已安裝模塊和版本號(hào)

Nginx -V

測(cè)試lua腳本

在Nginx.conf 中寫(xiě)入location /lua {default_type text/html;content_by_lua 'ngx.say("<p>Hello, World!</p>")';}

lua-nginx-module

創(chuàng)建配置文件lua.conf
   server {listen       80;server_name  localhost;location /lua {default_type text/html;content_by_lua_file conf/lua/hello.lua;}
}
在Nginx.conf下引入lua配置

include lua.conf;

創(chuàng)建外部lua腳本

conf/lua/hello.lua

內(nèi)容:

ngx.say("<p>Hello, World!</p>")

獲取Nginx uri中的單一變量
    location /nginx_var {default_type text/html;content_by_lua_block {ngx.say(ngx.var.arg_a)}}
獲取Nginx uri中的所有變量
local uri_args = ngx.req.get_uri_args()  for k, v in pairs(uri_args) do  if type(v) == "table" then  ngx.say(k, " : ", table.concat(v, ", "), "<br/>")  else  ngx.say(k, ": ", v, "<br/>")  end  
end
在處理http請(qǐng)求時(shí)還可以使用
  • set_by_lua

修改nginx變量

  • rewrite_by_lua

修改uri

  • access_by_lua

訪問(wèn)控制

  • header_filter_by_lua

修改響應(yīng)頭

  • boy_filter_by_lua

修改響應(yīng)體

  • log_by_lua

日志

代碼熱部署
lua_code_cache off
獲取Nginx請(qǐng)求頭信息
local headers = ngx.req.get_headers()                         ngx.say("Host : ", headers["Host"], "<br/>")  ngx.say("user-agent : ", headers["user-agent"], "<br/>")  ngx.say("user-agent : ", headers.user_agent, "<br/>")for k,v in pairs(headers) do  if type(v) == "table" then  ngx.say(k, " : ", table.concat(v, ","), "<br/>")  else  ngx.say(k, " : ", v, "<br/>")  end  end  
獲取post請(qǐng)求參數(shù)
ngx.req.read_body()  ngx.say("post args begin", "<br/>")  local post_args = ngx.req.get_post_args()  for k, v in pairs(post_args) do  if type(v) == "table" then  ngx.say(k, " : ", table.concat(v, ", "), "<br/>")  else  ngx.say(k, ": ", v, "<br/>")  end  
end
http協(xié)議版本
ngx.say("ngx.req.http_version : ", ngx.req.http_version(), "<br/>")
請(qǐng)求方法
ngx.say("ngx.req.get_method : ", ngx.req.get_method(), "<br/>")  
原始的請(qǐng)求頭內(nèi)容
ngx.say("ngx.req.raw_header : ",  ngx.req.raw_header(), "<br/>")  
body內(nèi)容體
ngx.say("ngx.req.get_body_data() : ", ngx.req.get_body_data(), "<br/>")

Nginx緩存

Nginx全局內(nèi)存緩存
lua_shared_dict shared_data 1m;local shared_data = ngx.shared.shared_data  local i = shared_data:get("i")  if not i then  i = 1  shared_data:set("i", i)  ngx.say("lazy set i ", i, "<br/>")  
end  i = shared_data:incr("i", 1)  ngx.say("i=", i, "<br/>")
lua-resty-lrucache

Lua 實(shí)現(xiàn)的一個(gè)簡(jiǎn)單的 LRU 緩存,適合在 Lua 空間里直接緩存較為復(fù)雜的 Lua 數(shù)據(jù)結(jié)構(gòu):它相比 ngx_lua 共享內(nèi)存字典可以省去較昂貴的序列化操作,相比 memcached 這樣的外部服務(wù)又能省去較昂貴的 socket 操作

https://github.com/openresty/lua-resty-lrucache

引用lua文件

content_by_lua_block {require("my/cache").go()}

自定義函數(shù)

local _M = {}lrucache = require "resty.lrucache"c, err = lrucache.new(200)  -- allow up to 200 items in the cache
ngx.say("count=init")if not c thenerror("failed to create the cache: " .. (err or "unknown"))
endfunction _M.go()count = c:get("count")c:set("count",100)
ngx.say("count=", count, " --<br/>")if not count then  c:set("count",1)ngx.say("lazy set count ", c:get("count"), "<br/>")  elsec:set("count",count+1)ngx.say("count=", count, "<br/>")
endend
return _M

打開(kāi)lua_code_cache

lua-resty-redis訪問(wèn)redis

https://github.com/openresty/lua-resty-redis

常用方法
local res, err = red:get("key")local res, err = red:lrange("nokey", 0, 1)ngx.say("res:",cjson.encode(res))
創(chuàng)建連接
red, err = redis:new()ok, err = red:connect(host, port, options_table?)
timeout
red:set_timeout(time)
keepalive
red:set_keepalive(max_idle_timeout, pool_size)
close
ok, err = red:close()
pipeline
red:init_pipeline()results, err = red:commit_pipeline()
認(rèn)證
    local res, err = red:auth("foobared")if not res thenngx.say("failed to authenticate: ", err)return
end
  local redis = require "resty.redis"local red = redis:new()red:set_timeouts(1000, 1000, 1000) -- 1 seclocal ok, err = red:connect("127.0.0.1", 6379)if not ok thenngx.say("failed to connect: ", err)returnendok, err = red:set("dog", "an animal")if not ok thenngx.say("failed to set dog: ", err)returnendngx.say("set result: ", ok)local res, err = red:get("dog")if not res thenngx.say("failed to get dog: ", err)returnendif res == ngx.null thenngx.say("dog not found.")returnendngx.say("dog: ", res)
redis-cluster支持

https://github.com/steve0511/resty-redis-cluster

redis2-nginx-module

redis2-nginx-module是一個(gè)支持 Redis 2.0 協(xié)議的 Nginx upstream 模塊,它可以讓 Nginx 以非阻塞方式直接防問(wèn)遠(yuǎn)方的 Redis 服務(wù),同時(shí)支持 TCP 協(xié)議和 Unix Domain Socket 模式,并且可以啟用強(qiáng)大的 Redis 連接池功能。

test
location = /foo {default_type text/html;redis2_query auth 123123;set $value 'first';redis2_query set one $value;redis2_pass 192.168.199.161:6379;}
get
location = /get {default_type text/html;redis2_pass 192.168.199.161:6379;redis2_query auth 123123;set_unescape_uri $key $arg_key;  # this requires ngx_set_miscredis2_query get $key;}
set
# GET /set?key=one&val=first%20valuelocation = /set {default_type text/html;redis2_pass 192.168.199.161:6379;redis2_query auth 123123;set_unescape_uri $key $arg_key;  # this requires ngx_set_miscset_unescape_uri $val $arg_val;  # this requires ngx_set_miscredis2_query set $key $val;}
pipeline
     set $value 'first';redis2_query set one $value;redis2_query get one;redis2_query set one two;redis2_query get one;redis2_query del key1;
list
    redis2_query lpush key1 C;redis2_query lpush key1 B;redis2_query lpush key1 A;redis2_query lrange key1 0 -1;
集群
upstream redis_cluster {server 192.168.199.161:6379;server 192.168.199.161:6379;}location = /redis {default_type text/html;redis2_next_upstream error timeout invalid_response;redis2_query get foo;redis2_pass redis_cluster;}

lua-resty-mysql

https://github.com/openresty/lua-resty-mysql

local mysql = require "resty.mysql"local db, err = mysql:new()if not db thenngx.say("failed to instantiate mysql: ", err)returnenddb:set_timeout(1000) -- 1 seclocal ok, err, errcode, sqlstate = db:connect{host = "192.168.44.211",port = 3306,database = "zhangmen",user = "root",password = "111111",charset = "utf8",max_packet_size = 1024 * 1024,}ngx.say("connected to mysql.<br>")local res, err, errcode, sqlstate = db:query("drop table if exists cats")if not res thenngx.say("bad result: ", err, ": ", errcode, ": ", sqlstate, ".")returnendres, err, errcode, sqlstate =db:query("create table cats ".. "(id serial primary key, ".. "name varchar(5))")if not res thenngx.say("bad result: ", err, ": ", errcode, ": ", sqlstate, ".")returnendngx.say("table cats created.")res, err, errcode, sqlstate =db:query("select * from t_emp")if not res thenngx.say("bad result: ", err, ": ", errcode, ": ", sqlstate, ".")returnendlocal cjson = require "cjson"ngx.say("result: ", cjson.encode(res))local ok, err = db:set_keepalive(10000, 100)if not ok thenngx.say("failed to set keepalive: ", err)returnend

模板實(shí)時(shí)渲染 lua-resty-template

https://github.com/bungle/lua-resty-template

如果學(xué)習(xí)過(guò)JavaEE中的servlet和JSP的話,應(yīng)該知道JSP模板最終會(huì)被翻譯成Servlet來(lái)執(zhí)行;

而lua-resty-template模板引擎可以認(rèn)為是JSP,其最終會(huì)被翻譯成Lua代碼,然后通過(guò)ngx.print輸出。

lua-resty-template大體內(nèi)容有:

l 模板位置:從哪里查找模板;

l 變量輸出/轉(zhuǎn)義:變量值輸出;

l 代碼片段:執(zhí)行代碼片段,完成如if/else、for等復(fù)雜邏輯,調(diào)用對(duì)象函數(shù)/方法;

l 注釋:解釋代碼片段含義;

l include:包含另一個(gè)模板片段;

l 其他:lua-resty-template還提供了不需要解析片段、簡(jiǎn)單布局、可復(fù)用的代碼塊、宏指令等支持。

基礎(chǔ)語(yǔ)法

l {(include_file)}:包含另一個(gè)模板文件;

l {* var *}:變量輸出;

l {{ var }}:變量轉(zhuǎn)義輸出;

l {% code %}:代碼片段;

l {# comment #}:注釋;

l {-raw-}:中間的內(nèi)容不會(huì)解析,作為純文本輸出;

lua代碼熱加載

在http模塊中加入

lua_code_cache off;

reload后Nginx會(huì)提示影響性能,記得在生產(chǎn)環(huán)境中關(guān)掉。

外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳

測(cè)試

一、初始化

-- Using template.new
local template = require "resty.template"
local view = template.new "view.html"
view.message = "Hello, World!"
view:render()-- Using template.render
-- template.render("view.html", { message = "Hel11lo, Worl1d!" })

二、執(zhí)行函數(shù),得到渲染之后的內(nèi)容

local func = template.compile("view.html")  local content = func(context)  ngx.say("xx:",content) 
模板文件存放位置
nginx.conf中配置
set $template_root /usr/local/openresty/nginx/tmp;

resty.template.html

local template = require("resty.template")
local html = require "resty.template.html"template.render([[
<ul>
{% for _, person in ipairs(context) do %}{*html.li(person.name)*} --
{% end %}
</ul>
<table>
{% for _, person in ipairs(context) do %}<tr data-sort="{{(person.name or ""):lower()}}">{*html.td{ id = person.id }(person.name)*}</tr>
{% end %}
</table>]], {{ id = 1, name = "Emma"},{ id = 2, name = "James" },{ id = 3, name = "Nicholas" },{ id = 4 }
})

模板內(nèi)容

<!DOCTYPE html>
<html>
<body><h1>{{message}}</h1>
</body>
</html>

多值傳入

template.caching(false)
local template = require("resty.template")
local context = {name = "lucy",age = 50,
}
template.render("view.html", context)

模板內(nèi)容

<!DOCTYPE html>
<html>
<body><h1>name:{{name}}</h1><h1>age:{{age}}</h1>
</body>
</html>

模板管理與緩存

模板緩存:默認(rèn)開(kāi)啟,開(kāi)發(fā)環(huán)境可以手動(dòng)關(guān)閉

template.caching(true)

模板文件需要業(yè)務(wù)系統(tǒng)更新與維護(hù),當(dāng)模板文件更新后,可以通過(guò)模板版本號(hào)或消息通知Openresty清空緩存重載模板到內(nèi)存中

template.cache = {}

完整頁(yè)面

local template = require("resty.template")
template.caching(false)
local context = {title = "測(cè)試",name = "lucy",description = "<script>alert(1);</script>",age = 40,hobby = {"電影", "音樂(lè)", "閱讀"},score = {語(yǔ)文 = 90, 數(shù)學(xué) = 80, 英語(yǔ) = 70},score2 = {{name = "語(yǔ)文", score = 90},{name = "數(shù)學(xué)", score = 80},{name = "英語(yǔ)", score = 70},}
}template.render("view.html", context)

模板

{(header.html)}  <body>  {# 不轉(zhuǎn)義變量輸出 #}  姓名:{* string.upper(name) *}<br/>  {# 轉(zhuǎn)義變量輸出 #}  簡(jiǎn)介:{{description}}簡(jiǎn)介:{* description *}<br/>  {# 可以做一些運(yùn)算 #}  年齡: {* age + 10 *}<br/>  {# 循環(huán)輸出 #}  愛(ài)好:  {% for i, v in ipairs(hobby) do %}  {% if v == '電影' then  %} - xxoo{%else%}  - {* v *} 
{% end %}  {% end %}<br/>  成績(jī):  {% local i = 1; %}  {% for k, v in pairs(score) do %}  {% if i > 1 then %},{% end %}  {* k *} = {* v *}  {% i = i + 1 %}  {% end %}<br/>  成績(jī)2:  {% for i = 1, #score2 do local t = score2[i] %}  {% if i > 1 then %},{% end %}  {* t.name *} = {* t.score *}  {% end %}<br/>  {# 中間內(nèi)容不解析 #}  {-raw-}{(file)}{-raw-}  
{(footer.html)}  

layout 布局統(tǒng)一風(fēng)格

使用模板內(nèi)容嵌套可以實(shí)現(xiàn)全站風(fēng)格同一布局

lua

local template = require "resty.template"

一、

local layout   = template.new "layout.html"layout.title   = "Testing lua-resty-template"layout.view    = template.compile "view.html" { message = "Hello, World!" }layout:render()

二、

template.render("layout.html", {title = "Testing lua-resty-template",msg = "type=2",view  = template.compile "view.html" { message = "Hello, World!" }})

三、

此方式重名變量值會(huì)被覆蓋

local view     = template.new("view.html", "layout.html")view.title     = "Testing lua-resty-template"view.msg = "type=3"view.message   = "Hello, World!"view:render()

四、

可以區(qū)分一下

local layout   = template.new "layout.html"layout.title   = "Testing lua-resty-template"layout.msg = "type=4"local view     = template.new("view.html", layout)view.message   = "Hello, World!"view:render()
layout.html
<!DOCTYPE html><html><head>?    <title>{{title}}</title></head><h1>layout</h1><body>?    {*view*}</body></html>
view.html·

msg:{{message}}

多級(jí)嵌套

lua

local view     = template.new("view.html", "layout.html")view.title     = "Testing lua-resty-template"view.message   = "Hello, World!"view:render()view.html{% layout="section.html" %}

msg:{{message}}

section.html

? {view} - sss

layout.html

? {?{title}}

layout {{msg}}

? {view}

Redis緩存+mysql+模板輸出

lua

  cjson = require "cjson"
sql="select * from t_emp"local redis = require "resty.redis"local red = redis:new()red:set_timeouts(1000, 1000, 1000) -- 1 seclocal ok, err = red:connect("127.0.0.1", 6379)if not ok thenngx.say("failed to connect: ", err)returnendlocal res, err = red:get(sql)if not res thenngx.say("failed to get sql: ", err)returnendif res == ngx.null thenngx.say("sql"..sql.." not found.")--mysql查詢
local mysql = require "resty.mysql"local db, err = mysql:new()if not db thenngx.say("failed to instantiate mysql: ", err)returnenddb:set_timeout(1000) -- 1 seclocal ok, err, errcode, sqlstate = db:connect{host = "192.168.44.211",port = 3306,database = "zhangmen",user = "root",password = "111111",charset = "utf8",max_packet_size = 1024 * 1024,}ngx.say("connected to mysql.<br>")res, err, errcode, sqlstate =db:query(sql)if not res thenngx.say("bad result: ", err, ": ", errcode, ": ", sqlstate, ".")returnend--ngx.say("result: ", cjson.encode(res))ok, err = red:set(sql, cjson.encode(res))if not ok thenngx.say("failed to set sql: ", err)returnendngx.say("set result: ", ok)returnendlocal template = require("resty.template")
template.caching(false)
local context = {title = "測(cè)試",name = "lucy",description = "<script>alert(1);</script>",age = 40,hobby = {"電影", "音樂(lè)", "閱讀"},score = {語(yǔ)文 = 90, 數(shù)學(xué) = 80, 英語(yǔ) = 70},score2 = {{name = "語(yǔ)文", score = 90},{name = "數(shù)學(xué)", score = 80},{name = "英語(yǔ)", score = 70},},zhangmen=cjson.decode(res)}template.render("view.html", context)

模板


{(header.html)}  <body>  {# 不轉(zhuǎn)義變量輸出 #}  姓名:{* string.upper(name) *}<br/>  {# 轉(zhuǎn)義變量輸出 #}  年齡: {* age + 10 *}<br/>  {# 循環(huán)輸出 #}  愛(ài)好:  {% for i, v in ipairs(hobby) do %}  {% if v == '電影' then  %} - xxoo{%else%}  - {* v *} 
{% end %}  {% end %}<br/>  成績(jī):  {% local i = 1; %}  {% for k, v in pairs(score) do %}  {% if i > 1 then %},{% end %}  {* k *} = {* v *}  {% i = i + 1 %}  {% end %}<br/>  成績(jī)2:  {% for i = 1, #score2 do local t = score2[i] %}  {% if i > 1 then %},{% end %}  {* t.name *} = {* t.score *}  {% end %}<br/>  {# 中間內(nèi)容不解析 #}  {-raw-}{(file)}{-raw-}  掌門(mén):
{* zhangmen *}{% for i = 1, #zhangmen do local z = zhangmen[i] %}  {* z.deptId *},{* z.age *},{* z.name *},{* z.empno *},<br>{% end %}<br/>  {(footer.html)}  

Lua 開(kāi)源項(xiàng)目

WAF

https://github.com/unixhot/waf

https://github.com/loveshell/ngx_lua_waf

l 防止 SQL 注入,本地包含,部分溢出,fuzzing 測(cè)試,XSS/SSRF 等 Web 攻擊

l 防止 Apache Bench 之類壓力測(cè)試工具的攻擊

l 屏蔽常見(jiàn)的掃描黑客工具,掃描器

l 屏蔽圖片附件類目錄執(zhí)行權(quán)限、防止 webshell 上傳

l 支持 IP 白名單和黑名單功能,直接將黑名單的 IP 訪問(wèn)拒絕

l 支持 URL 白名單,將不需要過(guò)濾的 URL 進(jìn)行定義

l 支持 User-Agent 的過(guò)濾、支持 CC 攻擊防護(hù)、限制單個(gè) URL 指定時(shí)間的訪問(wèn)次數(shù)

l 支持支持 Cookie 過(guò)濾,URL 與 URL 參數(shù)過(guò)濾

l 支持日志記錄,將所有拒絕的操作,記錄到日志中去

Kong 基于Openresty的流量網(wǎng)關(guān)

https://konghq.com/

https://github.com/kong/kong

Kong 基于 OpenResty,是一個(gè)云原生、快速、可擴(kuò)展、分布式的微服務(wù)抽象層(Microservice Abstraction Layer),也叫 API 網(wǎng)關(guān)(API Gateway),在 Service Mesh 里也叫 API 中間件(API Middleware)。

Kong 開(kāi)源于 2015 年,核心價(jià)值在于高性能和擴(kuò)展性。從全球 5000 強(qiáng)的組織統(tǒng)計(jì)數(shù)據(jù)來(lái)看,Kong 是現(xiàn)在依然在維護(hù)的,在生產(chǎn)環(huán)境使用最廣泛的 API 網(wǎng)關(guān)。

Kong 宣稱自己是世界上最流行的開(kāi)源微服務(wù) API 網(wǎng)關(guān)(The World’s Most Popular Open Source Microservice API Gateway)。

核心優(yōu)勢(shì):

l 可擴(kuò)展:可以方便的通過(guò)添加節(jié)點(diǎn)水平擴(kuò)展,這意味著可以在很低的延遲下支持很大的系統(tǒng)負(fù)載。

l 模塊化:可以通過(guò)添加新的插件來(lái)擴(kuò)展 Kong 的能力,這些插件可以通過(guò) RESTful Admin API 來(lái)安裝和配置。

l 在任何基礎(chǔ)架構(gòu)上運(yùn)行:Kong 可以在任何地方都能運(yùn)行,比如在云或混合環(huán)境中部署 Kong,單個(gè)或全球的數(shù)據(jù)中心。

APISIX

ABTestingGateway

https://github.com/CNSRE/ABTestingGateway

ABTestingGateway 是一個(gè)可以動(dòng)態(tài)設(shè)置分流策略的網(wǎng)關(guān),關(guān)注與灰度發(fā)布相關(guān)領(lǐng)域,基于 Nginx 和 ngx-lua 開(kāi)發(fā),使用 Redis 作為分流策略數(shù)據(jù)庫(kù),可以實(shí)現(xiàn)動(dòng)態(tài)調(diào)度功能。

ABTestingGateway 是新浪微博內(nèi)部的動(dòng)態(tài)路由系統(tǒng) dygateway 的一部分,目前已經(jīng)開(kāi)源。在以往的基于 Nginx 實(shí)現(xiàn)的灰度系統(tǒng)中,分流邏輯往往通過(guò) rewrite 階段的 if 和 rewrite 指令等實(shí)現(xiàn),優(yōu)點(diǎn)是性能較高,缺點(diǎn)是功能受限、容易出錯(cuò),以及轉(zhuǎn)發(fā)規(guī)則固定,只能靜態(tài)分流。ABTestingGateway 則采用 ngx-lua,通過(guò)啟用 lua-shared-dict 和 lua-resty-lock 作為系統(tǒng)緩存和緩存鎖,系統(tǒng)獲得了較為接近原生 Nginx 轉(zhuǎn)發(fā)的性能。

l 支持多種分流方式,目前包括 iprange、uidrange、uid 尾數(shù)和指定uid分流

l 支持多級(jí)分流,動(dòng)態(tài)設(shè)置分流策略,即時(shí)生效,無(wú)需重啟

l 可擴(kuò)展性,提供了開(kāi)發(fā)框架,開(kāi)發(fā)者可以靈活添加新的分流方式,實(shí)現(xiàn)二次開(kāi)發(fā)

l 高性能,壓測(cè)數(shù)據(jù)接近原生 Nginx 轉(zhuǎn)發(fā)

l 灰度系統(tǒng)配置寫(xiě)在 Nginx 配置文件中,方便管理員配置

l 適用于多種場(chǎng)景:灰度發(fā)布、AB 測(cè)試和負(fù)載均衡等

http://www.risenshineclean.com/news/59696.html

相關(guān)文章:

  • 群暉ds1817做網(wǎng)站國(guó)外網(wǎng)站制作
  • 銅川公司做網(wǎng)站企業(yè)查詢系統(tǒng)官網(wǎng)
  • 南通網(wǎng)站優(yōu)化營(yíng)銷渠道模式有哪些
  • 做淘寶聯(lián)盟網(wǎng)站要多少錢(qián)建設(shè)網(wǎng)頁(yè)
  • 公司營(yíng)銷網(wǎng)站制作下載百度官方網(wǎng)站
  • 淫穢色情網(wǎng)站境外的南寧網(wǎng)站建設(shè)
  • 母嬰網(wǎng)站建設(shè)初衷如何免費(fèi)注冊(cè)網(wǎng)站平臺(tái)
  • 2023貴陽(yáng)疫情最新消息今天seo營(yíng)銷名詞解釋
  • 天河區(qū)做網(wǎng)站上海搜索關(guān)鍵詞排名
  • 怎樣搭建網(wǎng)站百度廣告推廣怎么做
  • 手機(jī)怎么做網(wǎng)站添加背景音樂(lè)重慶黃埔seo整站優(yōu)化
  • 零食天堂專做零食推薦的網(wǎng)站公關(guān)
  • 南京網(wǎng)站搭建公司網(wǎng)絡(luò)推廣公司專業(yè)網(wǎng)絡(luò)
  • 太原建站模板廠家seo的優(yōu)點(diǎn)
  • 網(wǎng)站建設(shè)分配人員方案汽車網(wǎng)站建設(shè)方案
  • 哪個(gè)網(wǎng)站做照片書(shū)最好看深圳競(jìng)價(jià)排名網(wǎng)絡(luò)推廣
  • 內(nèi)容展示類網(wǎng)站企業(yè)品牌推廣方案
  • wordpress主題推薦深圳seo網(wǎng)站推廣方案
  • 廣告公司企業(yè)簡(jiǎn)介seo 推廣教程
  • 網(wǎng)站設(shè)計(jì)一般包括什么免費(fèi)的api接口網(wǎng)站
  • 江門(mén)網(wǎng)站建設(shè)推廣關(guān)鍵詞優(yōu)化seo多少錢(qián)一年
  • 網(wǎng)站開(kāi)發(fā)公司會(huì)計(jì)科目中小企業(yè)網(wǎng)絡(luò)營(yíng)銷現(xiàn)狀
  • 電商平臺(tái)圖片素材seo平臺(tái)是什么意思
  • 沈陽(yáng)世紀(jì)興網(wǎng)站制作泰州seo網(wǎng)絡(luò)公司
  • 零代碼建站平臺(tái)免費(fèi)推廣網(wǎng)站視頻
  • 介紹做ppt高大上圖表的網(wǎng)站西安網(wǎng)站搭建
  • top后綴做網(wǎng)站好不好互聯(lián)網(wǎng)公司排名
  • 施工企業(yè)安全生產(chǎn)責(zé)任制度seo教程網(wǎng)站優(yōu)化
  • 印度喜歡用什么框架做外貿(mào)網(wǎng)站南京網(wǎng)站設(shè)計(jì)
  • 百度網(wǎng)站推廣費(fèi)用多少錢(qián)福建網(wǎng)站建設(shè)制作