OpenResty + Lua:在 AI 時代重看一個老派選擇

OpenResty 不是新東西,它就是 nginx 綁上 LuaJIT,讓你在 request 生命週期的各個階段插 Lua。這套我用了好幾年,當 API gateway、當 datafeed 的前置層。會在 2026 又把它拿出來講,不是懷舊,是因為在 AI 幫忙寫 code 的這個前提下,它那個老架構忽然變得很合理。

老派戰場:薄、可控、吃資源少

先講實戰,免得聽起來像在推銷。我最有感的一次,是把一個原本跑在重量級 runtime 上的閘道改成 OpenResty,C 寫底層、Lua 寫業務邏輯,同樣的吞吐,資源大概吃到原本的十分之一。不是魔法,是因為這套的分工很清楚:連線管理、TLS、buffer 這些髒活 nginx 用 C 處理掉,你只在 access_by_luacontent_by_lua 這些階段補上自己的判斷。業務邏輯輕薄一層貼在一個本身就很會處理連線的核心上。

細節都在這些地方。client_max_body_size 沒設好,大 payload 直接被擋在門外,或是吃進記憶體把 worker 撐爆。長連線不要每個 request 重連下游,init_worker_by_lua 開一次連線池,worker 生命週期內共用,MySQL 那種短連線成本高的尤其有感。跑在 Docker 裡記得用 host network,bridge 那層 NAT 在高流量下會折掉一截效能,這種折損平常看不出來,壓測才會現形。這些不是教科書知識,是上線之後被流量教出來的。

報表那種場景也接過。OpenResty 在前面收、聚合、限流,後面接 Cassandra 落地,中間那層用 Lua 寫,改起來比動整包服務快得多。它的最適場景很清楚:一層薄薄的、責任單一、靠近網路。

為什麼 2026 又回頭看它

這幾年現代框架的抽象越疊越厚。前端後端都一樣,一個功能底下藏著好幾層 convention、好幾種寫法,同一件事在不同專案能長出完全不同的樣子。這些抽象是為「人類的手指」設計的,目的是讓人少打字、少重複。問題是當寫 code 的主力慢慢變成 AI,這套前提就鬆了。

風格碎片化對 AI 是負擔。同一個框架,這個專案這樣配、那個專案那樣配,AI 要先猜你站在哪個慣例上,才能往下寫。Lua 跟 C 剛好相反,語義單一、風格固定,能做的事情少,寫法的分歧也少。AI 處理這種語言,比處理一個生態龐大、寫法發散的語言穩得多,因為它不太需要猜,照著語言原本的規則寫就會對。

我的想法是:與其教 AI 模仿人類去操作一個臃腫的框架,不如給它一個語法簡潔、邊界清楚的環境,讓業務邏輯整合成一個可預測的封閉核心。OpenResty 的階段式 hook 剛好提供了這種結構,每個階段該做什麼很明確,Lua 又沒有那麼多花樣。把核心整理俐落,AI 在裡面動,你 review 起來也輕鬆,因為它能跑歪的空間本身就小。

但底層還是要自己掌握。Lua 的 metatable 就是它整個物件模型的底,__index__newindex 這些 metamethod 決定了查找與賦值怎麼走。你可以讓 AI 幫你寫上層業務,但這層協議自己要懂,不然哪天行為跟你想的不一樣,你會連從哪查起都不知道。AI 友善不等於你可以放手不看底層,恰好相反,底層越清楚,你越敢讓它在上層自由發揮。

它的限制

OpenResty 不是萬靈丹。協程要自己管,ngx.thread 那套用不好,會出現你以為平行其實堵住的狀況;穩定性也得小心,一段 Lua 塞住整個 worker 就一起卡死。它不適合拿來扛複雜的有狀態業務,那種東西放後面,讓 OpenResty 專心做它擅長的薄層。

它確實老,但在「薄、可控、AI 友善」這個方向上,這個老架構很合適。抽象不深,每層責任清楚,語言不耍花樣,這些特質放在 2026 看,反而比那些越長越厚的框架更耐看。如果想快速起手,我放了一個 2026 年的範本在 openresty-template,跟之前那個 docker 範本一樣,clone 下來就能開始試。

重點整理

  • OpenResty 的價值在分工清楚:髒活交給 nginx 的 C 核心,業務只薄薄一層 Lua 貼上去,資源吃得少。
  • 實戰細節都在邊界:client_max_body_sizeinit_worker_by_lua 連線池、Docker host network,這些上線才學得到。
  • 現代框架的抽象是為人類手指設計的,風格碎片化在 AI 輔助下反而是負擔。
  • Lua 跟 C 語義單一、風格固定,AI 不用猜慣例,把業務整合成封閉核心比較好 review。
  • AI 友善不等於放手;metatable 這種底層協議自己要懂,底層越清楚才越敢讓 AI 在上層動。

觀點 Sheng,內文 Claude 協助 · 列入 20260613 blog 翻新計劃,新漆未乾。