最近在協助同事將開發環境容器化(使用 Docker)時,發現一個有趣的現象:在 container 中執行 FastAPI server 時,print() 的輸出無法即時顯示在終端機上,但使用 logger 卻沒有這個問題。這篇文章就來簡單記錄一下這背後的原因。
先從緩衝區(Buffer)談起
緩衝區是一塊暫時儲存資料的記憶體空間,用來「暫存」資料,等到條件符合時再一次性地輸出或處理。這樣的設計可以減少 I/O 操作的頻率,提升效能。
以輸出到螢幕的 stdout buffering 為例,常見的緩衝模式有三種:
Fully Buffered(全緩衝)資料會先存到 buffer 中,直到 buffer 滿了才會一次性輸出。常見於輸出到檔案或管道(pipe)時。
Line Buffered(行緩衝)每當遇到換行符號(\n)時,才會把 buffer 的內容輸出。常見於輸出到終端機。
Unbuffered(無緩衝)資料會立即輸出,不經過緩衝區。常見於錯誤輸出(stderr)或明確設定為無緩衝的情況。