HTTP Status Code 實戰相關的小技巧

很久很久很久沒寫博客了,趁着最近搗鼓的一次分享,將分享內容順帶總結成一篇小博客。話很少說,Let's fighting!javascript

關於 HTTP 狀態碼,相信大部分小夥伴並不陌生。前端

  • ajax 對接後臺的接口返回 200
  • 後臺接口報錯了返回了 500
  • 前端面試常常被問到的 304
  • 網頁找不到了返回 404
  • 更多...

顯而易見,HTTP 狀態碼「潛伏」在咱們平常工做的許多許多小細節中,那勞煩各位親再細想一下,你對 HTTP 狀態碼,足夠熟悉嗎?java

舉幾個例子nginx

  • 後臺返回了 5xx 狀態碼,都是後臺的鍋嗎?
  • 有沒有留意過啥時候會返回 1xx 開頭的狀態碼?
  • 永久重定向和臨時重定向表現出來的差別是什麼?

帶着這幾個例子,結合小弟我平常工做中的一些實踐,浪咱們一塊兒 look 一 look,HTTP 狀態碼在實戰中,有沒有神奇功效?面試

案例 1,如何利用 50四、502 狀態碼進行更精準的「甩鍋」

假設在 S 公司中,有如下這幾個角色:ajax

  • 小 A,咱們的前端小夥伴,負責頁面開發以及調用後端數據
  • 小 B,後端小夥伴,使用 go 搭建了整個業務後臺
  • 小 G,運維筒子,負責把先後端項目搗鼓成 docker 容器部署上線

場景 1,某一天,小 A 發現了內部開發環境中,後臺接口返回了 504 狀態碼,並在返回的錯誤描述中看到了「Timeout」的關鍵字。因而小 A 質問小 B,大家後臺有 Bug!docker

脆弱的小 B 受不了質疑,回覆:「你的 Bug 才叫 504,你天天寫的都是 504!」express

本着實事求是(甩鍋要有理有據)的態度,小 A 開始了推演。咱們的目的很簡單:證實服務器掛了。後端

首先,梳理一下服務器掛了能有幾種可能:瀏覽器

  1. 服務器直接 dang 機
  2. 服務器活着,可是內部某個環節出了問題,致使不響應請求
  3. 後臺同窗接口寫錯了,調用的目標接口非法或不存在
  4. 代理服務器掛了(例如 Nginx)
  5. more...

小 A 順着梳理出來的這些可能,隨手用 express + nginx 搭建了一套環境,開始了逐一模擬排查。

// express 中,建立一個路由
//...省略其餘代碼

router.get('/hello', (req, res) => {
  res.end('hello');
});
//...
複製代碼
# nginx 中,添加一個路由配置
server {
    listen       80;
    server_name  ooo.test.com; # 本地host配的一個域名:127.0.0.1 ooo.test.com
    #charset koi8-r;
    access_log  /usr/local/etc/nginx/log/host.access.log  main;
	location / {
	    proxy_pass   http://127.0.0.1:3000/;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header REMOTE-HOST $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header X-Forwarded-Url  "$scheme://$host$request_uri";
            proxy_read_timeout 3; #爲了更快看到效果,添加3秒超時設置(nginx默認爲1分鐘)
	}
}
複製代碼

接下來開始模擬各類場景:

  1. 正常訪問http://ooo.test.com/hello

    測試結果:符合預期,返回200而且成功打印「hello」

  2. 模擬服務器dang機,關閉express服務,再訪問 ooo.test.com/hello

    測試結果:返回502 Bad Gateway

  3. 服務器活着,可是內部某個環節出了問題,致使不響應請求。咱們改一下代碼,將接口返回去掉,代碼以下。啓動express服務,再訪問網頁

    router.get('/hello', (req, res) => {
      //res.end('hello');
    });
    複製代碼

    測試結果:loading3秒後,顯示504Gateway Time-out

  4. 後臺同窗接口寫錯了,調用的目標接口非法或不存在。這個比較簡單,參數錯誤返回400、未登陸返回40一、pathname錯誤返回404,就不進行模擬了。

  5. 代理服務器掛了(例如 Nginx)。nginx、網關服務器通常只作數據轉發,掛掉的可能性微乎極微。咱們能夠試着把nginx關了,訪問網頁。

經過以上測試,咱們能夠直觀的發現:

  • 502: 服務器dang機,代理服務器沒法訪問業務服務
  • 504: 服務器內部異常,代理服務器訪問業務超時未響應

接下來小A拿着測試結論找到了小B同窗,脅迫小B同窗進行排查定位並發現後臺服務內存泄漏,致使接口未響應。「甩鍋」完成!

案例2,臨時重定向與永久重定向

面試的時候,有時我會問同窗們,知道301和302狀態碼的區別嗎?他們分別會在什麼場景下被用到?大部分同窗都能回答,一個是臨時重定向,一個是永久重定向。但再多的,就沒有了。話很少說,咱們先來藉助代碼,看一下臨時重定向與永久重定向在瀏覽器上表現出來的差別。

// 仍是剛剛那個express的項目


router.get('/hello', (req, res) => {
	//301,將這個路徑永久重定向到百度
	res.writeHead(301, { Location: 'http://www.baidu.com/' }); 
	res.end();
})
複製代碼

OK,重啓一下express,訪問http://ooo.test.com/hello。

能夠看到返回了301的狀態碼,頁面成功跳轉到了百度。細心的同窗還會發現,多刷新幾回頁面,301狀態碼後面還會帶着(from disk cache),這個有啥用呢?咱們作兩個嘗試:

  1. 修改代碼,將重定向地址改成http://www.google.com
  2. 直接關閉express服務

沒錯,結果就是,不管你作了任何改動,訪問http://ooo.test.com/hello,都仍是打開了百度首頁。這就是永久緩存的「魅力」所在了——from disk cache!永久緩存將重定向信息緩存到了你的瀏覽器中,除非你清除瀏覽器緩存,不然不管你服務怎麼變動,對你來講,對不起,都無濟於事。因此這也是永久緩存的可怕之處~ 慎用慎用。

相對而言,臨時緩存便安全得多。咱們把上面的代碼作一下稍微的修改:

router.get('/hello', (req, res) => {
	//302,將這個路徑臨時重定向到百度
	res.writeHead(302, { Location: 'http://www.baidu.com/' }); 
	res.end();
})
複製代碼

打開瀏覽器訪問http://ooo.test.com/hello,會發現成功跳轉到百度,觀察控制檯;再次訪問http://ooo.test.com/hello,再觀察express輸出多控制檯日誌。

會發現每次訪問/hello, 服務器都會收到一個請求,因此瀏覽器並不會緩存臨時重定向的數據。這也就是臨時重定向和永久重定向表現上的本質差別啦~

**小結,**舉了兩個簡單的小例子,分別說明了狀態碼在協助咱們定位問題、功能實現上的起到的小做用。寫的不對的,歡迎各位同志予以批判!有其餘想了解的狀態碼使用場景,也歡迎留言一塊兒探討一波噢!

@Author: _Jay.Lam

相關文章
相關標籤/搜索