最近用nginx來提供一些靜態(tài)文件作為配置。nginx從1.3.3版起就支持etag了,默認就可以生效,配置文件更改后可以通過etag的變化來讓瀏覽器拉取新的配置,還是挺方便的。但是在測試環(huán)境部署后,卻發(fā)現(xiàn)了問題:測試環(huán)境的nginx有兩個節(jié)點,前面再放個負載均衡器,輪詢訪問到不同的服務器上,此時發(fā)現(xiàn)請求相同的靜態(tài)文件時,返回的etag卻不同,瀏覽器每次請求都會返回個200,而不是304,沒有緩存的效果了。
到網上查了下nginx etag的算法,才發(fā)現(xiàn),nginx是通過文件的大小和文件的修改時間來計算etag的,nginx的源碼中ngx_http_set_etag函數(shù)中有這樣的代碼:
etag->value.len = ngx_sprintf(etag->value.data, "\"%xT-%xO\"",
r->headers_out.last_modified_time,
r->headers_out.content_length_n)
- etag->value.data;
r->headers_out.etag = etag;
這樣看來,兩個nginx返回的etag不同,可能就是因為兩邊文件的修改時間不同。
變更文件的修改時間還是挺容易的,可以直接用touch命令。在touch命令的man文檔中描述了-t參數(shù)的用法:
-t STAMP
use [[CC]YY]MMDDhhmm[.ss] instead of current time
那么在兩個節(jié)點上都用以下的命令就可以將文件的修改時間都設置為2022年2月25日13:13分了:
touch -t 202202251313 myconf.json
如果要用python寫代碼的話,可以用os.utime來設置文件的修改時間:
import os
os.utime('myconf.json', (1645806368, 1645806368))
此時再進行下測試,兩個節(jié)點上nginx返回的etag就一致了,第二次請求的時候就可以看到響應是304而不是200了。
原文:https://knktc.com/2022/02/26/nginx-etag-different-in-2-nodes/
參考文檔: