版權聲明:本文由黃希彤 原創文章,轉載請註明出處:
文章原文連接:https://www.qcloud.com/community/article/668639001484812620nginx
來源:騰雲閣 https://www.qcloud.com/community服務器
有一個朋友開發的手機app,把大量文件都保存在騰訊雲COS上,而後經過CDN分發。
最近有一個特殊的需求,但願經過CVM來提供部分COS文件的訪問。由於服務器用的是Nginx,因此事情也很簡單:
1 到COS的管理頁面上查詢一下內網訪問域名
網絡
2 給nginx增長一個標準的upstream配置,上游指向騰訊雲COS的內網域名app
照理說,配置好域名解析就能夠開始工做了。可是一開始工做就出現很奇怪的現象:下載開始很快,隨後變得很慢,最終有很大機率失敗。3d
首先排除網絡緣由的可能性。登陸服務器用wget經過訪問本機localhost驗證:
現象就是前面都下載的飛快,到了最後一部分就忽然下載不動了。代理
打開nginx的error_log,發現了upstream timed out (Connection timed out)錯誤
blog
再排除COS有問題的可能性:
開發
如今問題就很詭異了:上游沒有問題,通過反向代理後文件的前面一大部分也都沒有問題,就是最後一小截文件要等待好久好久,而且發生了upstream timed out超時。get
經過肥龍找到了熟悉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上,致使了這個問題的出現。