Nginx反向代理騰訊雲COS的一個坑


版權聲明:本文由黃希彤    原創文章,轉載請注明出處: 
文章原文鏈接:https://www.qcloud.com/community/article/668639001484812620

來源:騰雲閣 https://www.qcloud.com/community

 

有一個朋友開發的手機app,把大量文件都保存在騰訊雲COS上,然后通過CDN分發。
最近有一個特殊的需求,希望通過CVM來提供部分COS文件的訪問。因為服務器用的是Nginx,所以事情也很簡單:
1 到COS的管理頁面上查詢一下內網訪問域名

2 給nginx增加一個標准的upstream配置,上游指向騰訊雲COS的內網域名

照理說,配置好域名解析就可以開始工作了。但是一開始工作就出現很奇怪的現象:下載開始很快,隨后變得很慢,最終有很大概率失敗。

首先排除網絡原因的可能性。登錄服務器用wget通過訪問本機localhost驗證:

現象就是前面都下載的飛快,到了最后一部分就突然下載不動了。

打開nginx的error_log,發現了upstream timed out (Connection timed out)錯誤

再排除COS有問題的可能性:

現在問題就很詭異了:上游沒有問題,經過反向代理后文件的前面一大部分也都沒有問題,就是最后一小截文件要等待很久很久,並且發生了upstream timed out超時。

通過肥龍找到了熟悉nginx的ares同學協助抓包,才定位到了這個問題:

這里的UA是wget,wget默認使用的是http1.0協議。當前服務器使用的nginx是1.0.15這個比較古老的穩定版,還不支持 proxy_http_version 1.1這樣的參數(要到1.1.4版本以后才支持)。所以也是采用http1.0協議代理了請求。

照理說innercos服務接到這樣的請求應該按照http1.0的方式返回數據,但是我們看到服務器返回了 HTTP/1.1 200 OK 。也就是說不管客戶端支持什么http版本cos服務總是用http1.1協議來工作。

http1.1有一個重要的特性是keep-alive,也就是說http數據傳輸完畢后TCP連接繼續保持一段時間不斷開,可以給后續的http請求重用。而http1.0的客戶端原則上並不知道http1.1的這套原理。所以對於這個老版本的Nginx來講,它收到完整的數據以后,看到TCP鏈接一直沒有斷開,以為upstream還有話說,就一直掛在那里,等上游繼續送數據,直到上游連接超時,才在error_log里面記錄一個timed out錯誤,然后斷開下游的連接。

把proxy_buffering 關掉讓上下游直接對上話可以繞過這個問題,但是有附帶的損失。更好的辦法是把nginx升級到1.1.4以上的版本,並且開啟proxy_http_version 1.1 。

至此圓滿解決。

總結一下,騰訊雲COS的后台服務假設客戶端都支持http1.1協議,對http1.0協議沒有做很好的兼容,而騰訊雲CVM提供的帶Nginx的系統鏡像里面的Nginx版本又有點兒老舊了,proxy還只能工作在http1.0上,導致了這個問題的出現。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM