今天的事件發生在後端
嚴格來說應該是Infra
原本正常的API服務
在導入nginx後
開始出現不明的502 Error Log
第一次導入新技術就出包
著實令我膽戰心驚

寫過.net的都知道
傳統的framework或是Web Form
都必須依賴IIS作為伺服器
並且做request log的收集

但是搬遷到.net core之後
因為跨平台的關係
通常就不再依賴IIS
而是使用內建的Kestrel server
搭配docker container
這樣一來就沒有地方紀錄request log

那是時候我查了半天
看起來主流是用nginx解決這個問題
在主管的同意之下
由我率先導入專案使用

除了收集log
還可以做reverse proxy
不需要再帶port號去打服務
可說是一舉多得

導入後一切平安
服務看起來也都正常
打開log記錄頁面一看
才赫然發現大約三四個小時
就會有一波502 Error Log
“no upstream available”

當下心情是滿緊張的
畢竟導入新技術出包
這個鍋沒人可以幫你背
只能硬著頭皮揪出問題在哪

我第一個懷疑的
就是nginx的config有誤
google了一下,有人說要把流量開大
但我們的docker主機沒幾個服務
不可能這樣就垮掉
否則nginx也不會成為主流了

既然server的log看不出什麼東西
我就想說去看看application的log
打開公司自架的DockStation
突然看到一個異樣
“start at 30 minutes ago”

最近沒有上版
服務怎麼會在30分鐘前重啟
這一下才驚覺
可能又錯怪人
問題應該和nginx沒有關係

打開服務的監控
果不其然,記憶體的形狀就跟山峰一樣
一路飆升至800MB
然後再滑下來
像是sin函數這樣
502-error-bug-event-0.png

因為我們的docker部屬指令
都有加上restart always
當記憶體超過限制時
就會自動重啟

所以那段時間nginx的error log
正是服務重啟的時候
知道問題了
但還是沒抓到root cause

好在memory leak這個問題
在local環境就可以重現
用postman迴圈打API
的確可以看見記憶體持續飆高

最後發現是 EF Core的DBContext注入方式有誤
改了一下就正常了
記憶體使用量穩定在250MB左右

再重新上一次code
確認記憶體使用正常
nginx也不再出現error log
順利解決問題

之前沒有發現這個問題
正是因為沒有IIS Log
而且呼叫端做了Try Catch
再加上這個不是重要的功能
少了一兩條用戶也不會發現
才會讓這個Bug存在這麼久

原本以為是問題的nginx
沒想到是面照妖鏡
真實反映那看似正常
卻大有問題的服務

下回預告
簡單的送出表單申請
竟然出現無法重現的Bug
靠著Log是否能夠還原事件

下一回
400 Error bug事件