最近用nginx來(lái)提供一些靜態(tài)文件作為配置。nginx從1.3.3版起就支持etag了迈勋,默認(rèn)就可以生效勉耀,配置文件更改后可以通過(guò)etag的變化來(lái)讓瀏覽器拉取新的配置,還是挺方便的粗蔚。但是在測(cè)試環(huán)境部署后尝偎,卻發(fā)現(xiàn)了問(wèn)題:測(cè)試環(huán)境的nginx有兩個(gè)節(jié)點(diǎn),前面再放個(gè)負(fù)載均衡器鹏控,輪詢?cè)L問(wèn)到不同的服務(wù)器上致扯,此時(shí)發(fā)現(xiàn)請(qǐng)求相同的靜態(tài)文件時(shí),返回的etag卻不同当辐,瀏覽器每次請(qǐng)求都會(huì)返回個(gè)200抖僵,而不是304,沒(méi)有緩存的效果了缘揪。
到網(wǎng)上查了下nginx etag的算法耍群,才發(fā)現(xiàn),nginx是通過(guò)文件的大小和文件的修改時(shí)間來(lái)計(jì)算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;
這樣看來(lái)蹈垢,兩個(gè)nginx返回的etag不同,可能就是因?yàn)閮蛇呂募男薷臅r(shí)間不同呻征。
變更文件的修改時(shí)間還是挺容易的耘婚,可以直接用touch命令。在touch命令的man文檔中描述了-t參數(shù)的用法:
-t STAMP
use [[CC]YY]MMDDhhmm[.ss] instead of current time
那么在兩個(gè)節(jié)點(diǎn)上都用以下的命令就可以將文件的修改時(shí)間都設(shè)置為2022年2月25日13:13分了:
touch -t 202202251313 myconf.json
如果要用python寫(xiě)代碼的話陆赋,可以用os.utime來(lái)設(shè)置文件的修改時(shí)間:
import os
os.utime('myconf.json', (1645806368, 1645806368))
此時(shí)再進(jìn)行下測(cè)試沐祷,兩個(gè)節(jié)點(diǎn)上nginx返回的etag就一致了,第二次請(qǐng)求的時(shí)候就可以看到響應(yīng)是304而不是200了攒岛。
原文:https://knktc.com/2022/02/26/nginx-etag-different-in-2-nodes/
參考文檔: