有一個朋友開發的手機app,把大量文件都保存在騰訊雲COS上,而後經過CDN分發。 最近有一個特殊的需求,但願經過CVM來提供部分COS文件的訪問。由於服務器用的是Nginx,因此事情也很簡單: 1 到COS的管理頁面上查詢一下內網訪問域名 nginx
2 給nginx增長一個標準的upstream配置,上游指向騰訊雲COS的內網域名服務器
照理說,配置好域名解析就能夠開始工做了。可是一開始工做就出現很奇怪的現象:下載開始很快,隨後變得很慢,最終有很大機率失敗。網絡
首先排除網絡緣由的可能性。登陸服務器用wget經過訪問本機localhost驗證: 現象就是前面都下載的飛快,到了最後一部分就忽然下載不動了。app
打開nginx的error_log,發現了upstream timed out (Connection timed out)錯誤 負載均衡
再排除COS有問題的可能性: 代理
如今問題就很詭異了:上游沒有問題,通過反向代理後文件的前面一大部分也都沒有問題,就是最後一小截文件要等待好久好久,而且發生了upstream timed out超時。blog
經過肥龍找到了熟悉nginx的ares同窗協助抓包,才定位到了這個問題:開發
這裏的UA是wget,wget默認使用的是http1.0協議。當前服務器使用的nginx是1.0.15這個比較古老的穩定版,還不支持 proxy_http_version 1.1這樣的參數(要到1.1.4版本之後才支持)。因此也是採用http1.0協議代理了請求。get
照理說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上,致使了這個問題的出現。
【騰訊雲的1001種玩法】Nginx + Tomcat 負載均衡配置詳解