解決Nginx多節(jié)點上相同靜態(tài)文件的etag不同的問題

最近用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;

完整的源碼可參考:https://github.com/nginx/nginx/blob/1f01183b9e6658749934313fd72f7f16c1918b54/src/http/ngx_http_core_module.c#L1673

這樣看來,兩個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/

參考文檔:

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容