<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Upstream on Tarragon</title><link>https://tarrragon.github.io/blog/tags/upstream/</link><description>Recent content in Upstream on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Fri, 03 Jul 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/upstream/index.xml" rel="self" type="application/rss+xml"/><item><title>nginx 實務配置</title><link>https://tarrragon.github.io/blog/devops/01-load-balancing/nginx-configuration/</link><pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/devops/01-load-balancing/nginx-configuration/</guid><description>&lt;p>nginx 當反向代理的核心是一個 &lt;code>upstream&lt;/code> 區塊加 &lt;code>proxy_pass&lt;/code>：&lt;code>upstream&lt;/code> 定義後端群組跟分散策略，&lt;code>proxy_pass&lt;/code> 把請求轉過去。最小配置很短，但真正決定線上行為的是三個判讀點——用哪種負載分散方法、健康檢查怎麼配、timeout 怎麼串。其中開源 nginx 有一個最容易踩的限制：主動健康檢查是商業版功能，這一點不知道會讓人以為配了主動探測、實際上根本沒生效。&lt;/p>
&lt;p>以下配置在 nginx 1.30.3（stable）上以 &lt;code>nginx -t&lt;/code> 驗證過語法。&lt;/p>
&lt;h2 id="upstream-與負載分散方法">upstream 與負載分散方法&lt;/h2>
&lt;p>&lt;code>upstream&lt;/code> 區塊列出後端伺服器，並用一個指令選負載分散方法。預設是 round-robin（不寫任何方法指令就是它）；&lt;code>least_conn&lt;/code> 送給當前連線數最少的後端；&lt;code>ip_hash&lt;/code> 依 client IP 固定分配；&lt;code>hash $key consistent&lt;/code> 是加了 &lt;code>consistent&lt;/code> 參數的一致性雜湊。這些方法對應 &lt;a href="https://tarrragon.github.io/blog/devops/01-load-balancing/load-balancing-algorithms/" data-link-title="負載分散演算法" data-link-desc="在 round-robin、least-connections、IP hash、consistent hash 之間選負載分散演算法時，用請求成本是否均勻、實例是否同質、需不需要親和性當判準">負載分散演算法&lt;/a> 講的選擇，nginx 只是把它們寫成一行指令。&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nginx" data-lang="nginx">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="k">upstream&lt;/span> &lt;span class="s">api&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> &lt;span class="kn">least_conn&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> &lt;span class="kn">server&lt;/span> &lt;span class="n">10.0.1.11&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="mi">8080&lt;/span> &lt;span class="s">max_fails=3&lt;/span> &lt;span class="s">fail_timeout=15s&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> &lt;span class="kn">server&lt;/span> &lt;span class="n">10.0.1.12&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="mi">8080&lt;/span> &lt;span class="s">max_fails=3&lt;/span> &lt;span class="s">fail_timeout=15s&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> &lt;span class="kn">server&lt;/span> &lt;span class="n">10.0.1.13&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="mi">8080&lt;/span> &lt;span class="s">backup&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl"> &lt;span class="kn">keepalive&lt;/span> &lt;span class="mi">32&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl">&lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>server&lt;/code> 行上的參數各有用途。&lt;code>backup&lt;/code> 標記的後端平時不接流量，只在其他後端都不可用時才頂上——當降級備援用。&lt;code>keepalive 32&lt;/code> 讓 nginx 對後端維持一個連線池、重用連線，省下每個請求都重新握手的成本；高流量下這個設定對延遲影響明顯。&lt;code>weight=N&lt;/code>（未在上例）給規格不同的後端配權重，對應加權輪流。&lt;/p>
&lt;h2 id="被動健康檢查開源版的健康檢查">被動健康檢查：開源版的健康檢查&lt;/h2>
&lt;p>開源 nginx 的健康檢查是被動的，靠 &lt;code>server&lt;/code> 行上的 &lt;code>max_fails&lt;/code> 跟 &lt;code>fail_timeout&lt;/code> 兩個參數。語意是：在 &lt;code>fail_timeout&lt;/code> 這段時間內，轉發給某個後端的請求失敗達到 &lt;code>max_fails&lt;/code> 次，nginx 就把這個後端標記為不可用、停送 &lt;code>fail_timeout&lt;/code> 秒，之後再試探性地放流量回去。上例的 &lt;code>max_fails=3 fail_timeout=15s&lt;/code> 表示 15 秒內失敗 3 次就暫停這個後端 15 秒。&lt;/p>
&lt;p>被動探測的機制是從轉發的真實流量觀察失敗、不額外發探測請求，&lt;code>max_fails&lt;/code> 就是「觀察到幾次失敗才摘除」的門檻。這種機制的盲點、以及跟主動探測的完整對照，在 &lt;a href="https://tarrragon.github.io/blog/devops/01-load-balancing/health-check-routing/" data-link-title="健康檢查路由設計" data-link-desc="設計負載平衡的健康檢查時，釐清被動與主動探測的差別、interval 與 threshold 怎麼定出兩個時間窗口、以及為什麼 LB 顯示 healthy 不等於服務可服務">健康檢查路由設計&lt;/a> 展開，這裡只確立 nginx 開源版用的是被動機制。&lt;/p>
&lt;h2 id="gotcha主動-health_check-是商業版功能">gotcha：主動 health_check 是商業版功能&lt;/h2>
&lt;p>想在 nginx 上配主動健康檢查（定時對後端 &lt;code>/healthz&lt;/code> 探測、不靠真實流量），會發現 &lt;code>health_check&lt;/code> 這個指令在開源版根本不存在。在 nginx 1.30.3 上放一個 &lt;code>health_check&lt;/code> 指令跑 &lt;code>nginx -t&lt;/code>，直接報 &lt;code>[emerg] unknown directive &amp;quot;health_check&amp;quot;&lt;/code>、配置測試失敗——它是 nginx Plus（商業訂閱）才有的指令。這個限制不知道的話，很容易照著某些教學把 &lt;code>health_check&lt;/code> 寫進去、以為配了主動探測，實際上配置根本載入不了，或在別處抄來的 Plus 配置直接讓 nginx 起不來。&lt;/p>
&lt;p>開源版要主動探測有兩條路：一是裝第三方模組（如 &lt;code>nginx_upstream_check_module&lt;/code>），要重新編譯 nginx，維護成本較高；二是不在 nginx 內做，改用外部探測——一個獨立的定時器對後端探測，探到不健康就從服務發現或配置裡摘掉。多數情況下，被動的 &lt;code>max_fails&lt;/code> 加上外部的主動探測，就覆蓋了「後端回應了但一直出錯」跟「後端整個沒回應」兩種失效，不必為了主動探測上商業版。&lt;/p>
&lt;h2 id="proxy-header-陷阱後端看到的來源-ip">proxy header 陷阱：後端看到的來源 IP&lt;/h2>
&lt;p>&lt;code>proxy_pass&lt;/code> 轉發時，如果不主動設 header，後端看到的來源 IP 會是 nginx 的 IP、而不是真實客戶端的——因為連線是 nginx 發起的。這會讓後端的存取日誌、限流、地理判斷全部失準，全世界的請求看起來都來自 nginx 那台。修法是明確把原始資訊放進 header：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nginx" data-lang="nginx">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="k">location&lt;/span> &lt;span class="s">/&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> &lt;span class="kn">proxy_pass&lt;/span> &lt;span class="s">http://api&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> &lt;span class="kn">proxy_set_header&lt;/span> &lt;span class="s">Host&lt;/span> &lt;span class="nv">$host&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> &lt;span class="kn">proxy_set_header&lt;/span> &lt;span class="s">X-Forwarded-For&lt;/span> &lt;span class="nv">$proxy_add_x_forwarded_for&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> &lt;span class="kn">proxy_connect_timeout&lt;/span> &lt;span class="s">5s&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl"> &lt;span class="kn">proxy_read_timeout&lt;/span> &lt;span class="s">30s&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl"> &lt;span class="kn">proxy_next_upstream&lt;/span> &lt;span class="s">error&lt;/span> &lt;span class="s">timeout&lt;/span> &lt;span class="s">http_502&lt;/span> &lt;span class="s">http_503&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">8&lt;/span>&lt;span class="cl">&lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>proxy_set_header Host $host&lt;/code> 保留原始的 host header（否則後端收到的 Host 會是 upstream 名稱，依 host 分辨虛擬主機的後端會錯亂）。&lt;code>X-Forwarded-For $proxy_add_x_forwarded_for&lt;/code> 把真實客戶端 IP 附進去、且保留鏈上前面的代理紀錄，後端要讀真實 IP 就從這個 header 取。&lt;/p>
&lt;h2 id="timeout-與重試">timeout 與重試&lt;/h2>
&lt;p>&lt;code>proxy_connect_timeout&lt;/code> 是 nginx 連到後端的逾時、&lt;code>proxy_read_timeout&lt;/code> 是等後端回應的逾時。這兩個要放進 &lt;a href="https://tarrragon.github.io/blog/devops/01-load-balancing/reverse-proxy-responsibilities/" data-link-title="反向代理的職責" data-link-desc="釐清反向代理在單一入口後面承擔哪些職責、TLS 終止與路由怎麼設計、以及一條請求路徑上的 timeout 為什麼要由外到內遞減時回來讀">反向代理職責&lt;/a> 講的 timeout 層級串聯裡看——nginx 這層的 timeout 要大於它後面的應用層、小於它前面的客戶端層，否則會出現外層先放棄、內層還在做白工。&lt;/p>
&lt;p>&lt;code>proxy_next_upstream&lt;/code> 決定一個後端失敗時要不要把請求重試到下一個後端。上例的 &lt;code>error timeout http_502 http_503&lt;/code> 表示連線錯誤、逾時、後端回 502/503 時自動重試下一台。這個機制對讀請求很有用（一台壞了自動換一台），但對非冪等的寫請求要謹慎——如果一個 POST 已經被後端處理了、只是回應在傳輸中逾時，重試會讓這個 POST 執行第二次。要重試非冪等請求前，得先確認後端有冪等保護（例如靠 idempotency key 去重），否則把 &lt;code>POST&lt;/code> 放進 &lt;code>proxy_next_upstream&lt;/code> 的重試條件會製造重複寫入。&lt;/p></description><content:encoded><![CDATA[<p>nginx 當反向代理的核心是一個 <code>upstream</code> 區塊加 <code>proxy_pass</code>：<code>upstream</code> 定義後端群組跟分散策略，<code>proxy_pass</code> 把請求轉過去。最小配置很短，但真正決定線上行為的是三個判讀點——用哪種負載分散方法、健康檢查怎麼配、timeout 怎麼串。其中開源 nginx 有一個最容易踩的限制：主動健康檢查是商業版功能，這一點不知道會讓人以為配了主動探測、實際上根本沒生效。</p>
<p>以下配置在 nginx 1.30.3（stable）上以 <code>nginx -t</code> 驗證過語法。</p>
<h2 id="upstream-與負載分散方法">upstream 與負載分散方法</h2>
<p><code>upstream</code> 區塊列出後端伺服器，並用一個指令選負載分散方法。預設是 round-robin（不寫任何方法指令就是它）；<code>least_conn</code> 送給當前連線數最少的後端；<code>ip_hash</code> 依 client IP 固定分配；<code>hash $key consistent</code> 是加了 <code>consistent</code> 參數的一致性雜湊。這些方法對應 <a href="/blog/devops/01-load-balancing/load-balancing-algorithms/" data-link-title="負載分散演算法" data-link-desc="在 round-robin、least-connections、IP hash、consistent hash 之間選負載分散演算法時，用請求成本是否均勻、實例是否同質、需不需要親和性當判準">負載分散演算法</a> 講的選擇，nginx 只是把它們寫成一行指令。</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nginx" data-lang="nginx"><span class="line"><span class="ln">1</span><span class="cl"><span class="k">upstream</span> <span class="s">api</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">    <span class="kn">least_conn</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">    <span class="kn">server</span> <span class="n">10.0.1.11</span><span class="p">:</span><span class="mi">8080</span> <span class="s">max_fails=3</span> <span class="s">fail_timeout=15s</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">    <span class="kn">server</span> <span class="n">10.0.1.12</span><span class="p">:</span><span class="mi">8080</span> <span class="s">max_fails=3</span> <span class="s">fail_timeout=15s</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">    <span class="kn">server</span> <span class="n">10.0.1.13</span><span class="p">:</span><span class="mi">8080</span> <span class="s">backup</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl">    <span class="kn">keepalive</span> <span class="mi">32</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><p><code>server</code> 行上的參數各有用途。<code>backup</code> 標記的後端平時不接流量，只在其他後端都不可用時才頂上——當降級備援用。<code>keepalive 32</code> 讓 nginx 對後端維持一個連線池、重用連線，省下每個請求都重新握手的成本；高流量下這個設定對延遲影響明顯。<code>weight=N</code>（未在上例）給規格不同的後端配權重，對應加權輪流。</p>
<h2 id="被動健康檢查開源版的健康檢查">被動健康檢查：開源版的健康檢查</h2>
<p>開源 nginx 的健康檢查是被動的，靠 <code>server</code> 行上的 <code>max_fails</code> 跟 <code>fail_timeout</code> 兩個參數。語意是：在 <code>fail_timeout</code> 這段時間內，轉發給某個後端的請求失敗達到 <code>max_fails</code> 次，nginx 就把這個後端標記為不可用、停送 <code>fail_timeout</code> 秒，之後再試探性地放流量回去。上例的 <code>max_fails=3 fail_timeout=15s</code> 表示 15 秒內失敗 3 次就暫停這個後端 15 秒。</p>
<p>被動探測的機制是從轉發的真實流量觀察失敗、不額外發探測請求，<code>max_fails</code> 就是「觀察到幾次失敗才摘除」的門檻。這種機制的盲點、以及跟主動探測的完整對照，在 <a href="/blog/devops/01-load-balancing/health-check-routing/" data-link-title="健康檢查路由設計" data-link-desc="設計負載平衡的健康檢查時，釐清被動與主動探測的差別、interval 與 threshold 怎麼定出兩個時間窗口、以及為什麼 LB 顯示 healthy 不等於服務可服務">健康檢查路由設計</a> 展開，這裡只確立 nginx 開源版用的是被動機制。</p>
<h2 id="gotcha主動-health_check-是商業版功能">gotcha：主動 health_check 是商業版功能</h2>
<p>想在 nginx 上配主動健康檢查（定時對後端 <code>/healthz</code> 探測、不靠真實流量），會發現 <code>health_check</code> 這個指令在開源版根本不存在。在 nginx 1.30.3 上放一個 <code>health_check</code> 指令跑 <code>nginx -t</code>，直接報 <code>[emerg] unknown directive &quot;health_check&quot;</code>、配置測試失敗——它是 nginx Plus（商業訂閱）才有的指令。這個限制不知道的話，很容易照著某些教學把 <code>health_check</code> 寫進去、以為配了主動探測，實際上配置根本載入不了，或在別處抄來的 Plus 配置直接讓 nginx 起不來。</p>
<p>開源版要主動探測有兩條路：一是裝第三方模組（如 <code>nginx_upstream_check_module</code>），要重新編譯 nginx，維護成本較高；二是不在 nginx 內做，改用外部探測——一個獨立的定時器對後端探測，探到不健康就從服務發現或配置裡摘掉。多數情況下，被動的 <code>max_fails</code> 加上外部的主動探測，就覆蓋了「後端回應了但一直出錯」跟「後端整個沒回應」兩種失效，不必為了主動探測上商業版。</p>
<h2 id="proxy-header-陷阱後端看到的來源-ip">proxy header 陷阱：後端看到的來源 IP</h2>
<p><code>proxy_pass</code> 轉發時，如果不主動設 header，後端看到的來源 IP 會是 nginx 的 IP、而不是真實客戶端的——因為連線是 nginx 發起的。這會讓後端的存取日誌、限流、地理判斷全部失準，全世界的請求看起來都來自 nginx 那台。修法是明確把原始資訊放進 header：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nginx" data-lang="nginx"><span class="line"><span class="ln">1</span><span class="cl"><span class="k">location</span> <span class="s">/</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">    <span class="kn">proxy_pass</span> <span class="s">http://api</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">    <span class="kn">proxy_set_header</span> <span class="s">Host</span> <span class="nv">$host</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">    <span class="kn">proxy_set_header</span> <span class="s">X-Forwarded-For</span> <span class="nv">$proxy_add_x_forwarded_for</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">    <span class="kn">proxy_connect_timeout</span> <span class="s">5s</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl">    <span class="kn">proxy_read_timeout</span> <span class="s">30s</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">7</span><span class="cl">    <span class="kn">proxy_next_upstream</span> <span class="s">error</span> <span class="s">timeout</span> <span class="s">http_502</span> <span class="s">http_503</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">8</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><p><code>proxy_set_header Host $host</code> 保留原始的 host header（否則後端收到的 Host 會是 upstream 名稱，依 host 分辨虛擬主機的後端會錯亂）。<code>X-Forwarded-For $proxy_add_x_forwarded_for</code> 把真實客戶端 IP 附進去、且保留鏈上前面的代理紀錄，後端要讀真實 IP 就從這個 header 取。</p>
<h2 id="timeout-與重試">timeout 與重試</h2>
<p><code>proxy_connect_timeout</code> 是 nginx 連到後端的逾時、<code>proxy_read_timeout</code> 是等後端回應的逾時。這兩個要放進 <a href="/blog/devops/01-load-balancing/reverse-proxy-responsibilities/" data-link-title="反向代理的職責" data-link-desc="釐清反向代理在單一入口後面承擔哪些職責、TLS 終止與路由怎麼設計、以及一條請求路徑上的 timeout 為什麼要由外到內遞減時回來讀">反向代理職責</a> 講的 timeout 層級串聯裡看——nginx 這層的 timeout 要大於它後面的應用層、小於它前面的客戶端層，否則會出現外層先放棄、內層還在做白工。</p>
<p><code>proxy_next_upstream</code> 決定一個後端失敗時要不要把請求重試到下一個後端。上例的 <code>error timeout http_502 http_503</code> 表示連線錯誤、逾時、後端回 502/503 時自動重試下一台。這個機制對讀請求很有用（一台壞了自動換一台），但對非冪等的寫請求要謹慎——如果一個 POST 已經被後端處理了、只是回應在傳輸中逾時，重試會讓這個 POST 執行第二次。要重試非冪等請求前，得先確認後端有冪等保護（例如靠 idempotency key 去重），否則把 <code>POST</code> 放進 <code>proxy_next_upstream</code> 的重試條件會製造重複寫入。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>這些方法各適合什麼流量型態 → <a href="/blog/devops/01-load-balancing/load-balancing-algorithms/" data-link-title="負載分散演算法" data-link-desc="在 round-robin、least-connections、IP hash、consistent hash 之間選負載分散演算法時，用請求成本是否均勻、實例是否同質、需不需要親和性當判準">負載分散演算法</a></li>
<li>被動與主動健康檢查的完整對照、閾值怎麼定 → <a href="/blog/devops/01-load-balancing/health-check-routing/" data-link-title="健康檢查路由設計" data-link-desc="設計負載平衡的健康檢查時，釐清被動與主動探測的差別、interval 與 threshold 怎麼定出兩個時間窗口、以及為什麼 LB 顯示 healthy 不等於服務可服務">健康檢查路由設計</a></li>
<li>timeout 為什麼要由外到內遞減 → <a href="/blog/devops/01-load-balancing/reverse-proxy-responsibilities/" data-link-title="反向代理的職責" data-link-desc="釐清反向代理在單一入口後面承擔哪些職責、TLS 終止與路由怎麼設計、以及一條請求路徑上的 timeout 為什麼要由外到內遞減時回來讀">反向代理的職責</a></li>
<li>雲端 LB 上等價的 listener、target group、健康檢查怎麼用 IaC 描述 → <a href="/blog/infra/05-core-services/loadbalancer-alb/" data-link-title="入口上 IaC — ALB、TLS 與健康檢查" data-link-desc="Application Load Balancer 的 listener、target group、健康檢查閾值設計，以及用 ACM 把 TLS 憑證的簽發、驗證與掛載整條鏈寫進版本控制">infra：入口上 IaC</a></li>
</ul>
]]></content:encoded></item></channel></rss>