<?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>Proxy_read_timeout on Ambertu</title><link>https://ambertu.com/tags/proxy_read_timeout/</link><description>Recent content in Proxy_read_timeout on Ambertu</description><generator>Hugo</generator><language>zh-CN</language><copyright>2026 Ambertu · 粤ICP备18071259号</copyright><lastBuildDate>Fri, 04 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://ambertu.com/tags/proxy_read_timeout/index.xml" rel="self" type="application/rss+xml"/><item><title>大模型 API 中转的超时与重试：一次 504 可能让你双倍计费</title><link>https://ambertu.com/posts/llm-api-timeout-retry-double-billing/</link><pubDate>Fri, 04 Sep 2026 00:00:00 +0000</pubDate><guid>https://ambertu.com/posts/llm-api-timeout-retry-double-billing/</guid><description>nginx 的 proxy_read_timeout 默认 60 秒，而长上下文生成常常超过它。超时返回 504 后客户端 SDK 会自动重试，上游却已经生成并计费——一次超时变成两次账单。本文拆解这条链路并给出正确的超时分层。</description><content:encoded><![CDATA[<p>nginx 的 <code>proxy_read_timeout</code> 默认是 <strong>60 秒</strong>，而长上下文或推理模型的单次生成经常超过这个数。超时之后 nginx 返回 504，看起来只是&quot;一次失败&quot;——但真实后果比这严重：<strong>上游很可能已经把生成做完并计了费，而客户端 SDK 收到 504 会自动重试，于是上游又生成一次、又计一次费。</strong></p>
<p>客户端最终只拿到一个响应，你的账单上是两笔。更麻烦的是这件事在监控里几乎看不出来：错误率只涨了一点，成本却在悄悄翻倍。</p>
<h2 id="先纠正一个常见的误解">先纠正一个常见的误解.</h2>
<p>网上很多文章会告诉你 nginx 的 <code>proxy_next_upstream</code> 会把超时请求转给下一个上游、导致重复计费。<strong>这个说法对 LLM API 来说是不准确的</strong>，值得先说清楚，否则你会去改一个本来没问题的配置。</p>
<p><code>proxy_next_upstream</code> 的默认值确实是 <code>error timeout</code>，但 nginx 从 <strong>1.9.13</strong> 起有一条额外规则：</p>
<blockquote>
<p>非幂等方法（POST、LOCK、PATCH）的请求，<strong>一旦已经发送给上游，就不会</strong>再转给下一台服务器——除非你显式加上 <code>non_idempotent</code> 选项。</p>
</blockquote>
<p>LLM 的 chat completions 走的是 POST，所以 nginx 默认行为是安全的。<strong>真正的重复计费来源有两个，都不是 nginx 的默认配置：</strong></p>
<ol>
<li><strong>有人手工加了 <code>non_idempotent</code></strong>——一些&quot;提升可用性&quot;的高可用教程会教这个，在普通 Web 服务上无害，在按 token 计费的接口上是直接烧钱。</li>
<li><strong>客户端 SDK 自己在重试</strong>——这是绝大多数情况的元凶。OpenAI 官方 Python SDK 的 <code>max_retries</code> <strong>默认是 2</strong>，重试触发条件包含连接错误、408、409、429 和所有 5xx。nginx 吐的 504 正好落在 5xx 里。</li>
</ol>
<h2 id="双倍计费是怎么发生的">双倍计费是怎么发生的</h2>
<figure>
<svg viewBox="0 0 820 340" role="img" aria-label="时序图：客户端请求经 nginx 转发给上游，上游生成耗时 75 秒；nginx 在 60 秒时触发 proxy_read_timeout 返回 504，但上游继续生成完并计费；客户端 SDK 收到 504 后自动重试，上游第二次生成并再次计费，最终客户端得到一个响应而产生两笔账单" style="width:100%;height:auto;color:currentColor">
  <defs>
    <marker id="t1" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto">
      <path d="M 0 1 L 10 5 L 0 9 z" fill="currentColor"/>
    </marker>
  </defs>
  <g font-family="monospace" font-size="11" fill="currentColor">
    <text x="40" y="16" text-anchor="middle">客户端</text>
    <text x="300" y="16" text-anchor="middle">nginx</text>
    <text x="600" y="16" text-anchor="middle">上游 API</text>
  </g>
  <line x1="40"  y1="26" x2="40"  y2="300" stroke="currentColor" stroke-width="1" opacity="0.3" stroke-dasharray="3 4"/>
  <line x1="300" y1="26" x2="300" y2="300" stroke="currentColor" stroke-width="1" opacity="0.3" stroke-dasharray="3 4"/>
  <line x1="600" y1="26" x2="600" y2="300" stroke="currentColor" stroke-width="1" opacity="0.3" stroke-dasharray="3 4"/>
  <g font-family="monospace" font-size="9.5" fill="currentColor">
    <!-- t0 -->
    <text x="0" y="52" opacity="0.6">t=0s</text>
    <line x1="40" y1="48" x2="296" y2="48" stroke="currentColor" stroke-width="1.2" marker-end="url(#t1)"/>
    <line x1="300" y1="48" x2="596" y2="48" stroke="currentColor" stroke-width="1.2" marker-end="url(#t1)"/>
    <text x="450" y="41" text-anchor="middle" opacity="0.7">POST /v1/chat/completions</text>
    <!-- generating 1 -->
    <rect x="586" y="56" width="28" height="70" fill="currentColor" opacity="0.2"/>
    <text x="626" y="80">生成中</text>
    <text x="626" y="94" opacity="0.7">第 1 次</text>
    <text x="626" y="112" font-weight="bold">已计费 ①</text>
    <!-- timeout -->
    <text x="0" y="136" opacity="0.6">t=60s</text>
    <line x1="296" y1="132" x2="44" y2="132" stroke="currentColor" stroke-width="1.4" marker-end="url(#t1)"/>
    <text x="170" y="125" text-anchor="middle" font-weight="bold">504 Gateway Timeout</text>
    <text x="170" y="146" text-anchor="middle" opacity="0.7">proxy_read_timeout 到点</text>
    <text x="626" y="140" opacity="0.7">上游不知道</text>
    <text x="626" y="154" opacity="0.7">nginx 放弃了，</text>
    <text x="626" y="168" opacity="0.7">继续把生成做完</text>
    <!-- retry -->
    <text x="0" y="196" opacity="0.6">t=60s</text>
    <line x1="40" y1="192" x2="296" y2="192" stroke="currentColor" stroke-width="1.4" marker-end="url(#t1)"/>
    <line x1="300" y1="192" x2="596" y2="192" stroke="currentColor" stroke-width="1.4" marker-end="url(#t1)"/>
    <text x="450" y="185" text-anchor="middle" font-weight="bold">SDK 自动重试（max_retries=2）</text>
    <!-- generating 2 -->
    <rect x="586" y="200" width="28" height="70" fill="currentColor" opacity="0.2"/>
    <text x="626" y="224">生成中</text>
    <text x="626" y="238" opacity="0.7">第 2 次</text>
    <text x="626" y="256" font-weight="bold">又计费 ②</text>
    <!-- success -->
    <text x="0" y="288" opacity="0.6">t=135s</text>
    <line x1="596" y1="284" x2="304" y2="284" stroke="currentColor" stroke-width="1.2" marker-end="url(#t1)"/>
    <line x1="296" y1="284" x2="44" y2="284" stroke="currentColor" stroke-width="1.2" marker-end="url(#t1)"/>
    <text x="170" y="277" text-anchor="middle" opacity="0.7">200 OK</text>
  </g>
  <line x1="0" y1="306" x2="800" y2="306" stroke="currentColor" stroke-width="1" opacity="0.2"/>
  <text x="0" y="326" font-size="10.5" font-family="monospace" fill="currentColor" font-weight="bold">客户端拿到 1 个响应 · 账单上 2 笔 · 监控里只是错误率轻微上升</text>
</svg>
<figcaption>
链条的关键一环是<strong>上游并不知道 nginx 已经放弃</strong>——它按自己的节奏把生成做完。是否计费取决于供应商策略，
但<strong>安全假设是"已经计了"</strong>：连接中断后仍收费的供应商很常见，你无法事后核对。
</figcaption>
</figure>
<h2 id="流式请求几乎不会撞上这个问题">流式请求几乎不会撞上这个问题</h2>
<p>这是很多人不知道的一点，也是&quot;默认就该用流式&quot;的一个纯运维理由。<code>proxy_read_timeout</code> 的官方定义是：</p>
<blockquote>
<p>该超时只作用于<strong>两次连续读操作之间</strong>，而不是整个响应的传输时长。</p>
</blockquote>
<p>所以：</p>
<ul>
<li><strong>非流式请求</strong>：从发出到收到完整 JSON，中间是一个长长的空隙。生成花 75 秒，就是一个 75 秒的读间隔 → 撞上 60 秒超时。</li>
<li><strong>流式请求</strong>：token 一个接一个到达，每两次读之间只隔几百毫秒 → 无论总时长多久都不会触发超时。</li>
</ul>
<figure>
<svg viewBox="0 0 780 220" role="img" aria-label="对比图：非流式请求在整个生成期间没有任何数据到达，形成一个 75 秒的读间隔从而在 60 秒处触发超时；流式请求每几百毫秒到达一个 token，读间隔始终很小，永不触发超时" style="width:100%;height:auto;color:currentColor">
  <text x="0" y="14" font-size="10.5" font-family="monospace" fill="currentColor" opacity="0.6">nginx 眼中的「两次读操作之间的间隔」</text>
  <!-- timeout threshold -->
  <line x1="130" y1="30" x2="130" y2="180" stroke="currentColor" stroke-width="0" />
  <line x1="530" y1="26" x2="530" y2="186" stroke="currentColor" stroke-width="1.4" stroke-dasharray="5 4"/>
  <text x="538" y="40" font-size="9.5" font-family="monospace" fill="currentColor" font-weight="bold">60s 超时线</text>
  <g font-family="monospace" font-size="10.5" fill="currentColor">
    <text x="0" y="66">非流式</text>
    <line x1="130" y1="70" x2="700" y2="70" stroke="currentColor" stroke-width="1" opacity="0.25"/>
    <rect x="130" y="60" width="10" height="20" fill="currentColor" opacity="0.75"/>
    <rect x="620" y="60" width="80" height="20" fill="currentColor" opacity="0.4"/>
    <path d="M 142 90 L 616 90" stroke="currentColor" stroke-width="1.2" marker-end="url(#t1)"/>
    <text x="370" y="106" text-anchor="middle" font-size="9.5" font-weight="bold">一个 75s 的读间隔 → 在 60s 处被切断</text>
    <text x="0" y="152">流式</text>
    <line x1="130" y1="156" x2="700" y2="156" stroke="currentColor" stroke-width="1" opacity="0.25"/>
  </g>
  <g fill="currentColor" opacity="0.75">
    <rect x="130" y="146" width="8" height="20"/><rect x="152" y="146" width="8" height="20"/>
    <rect x="174" y="146" width="8" height="20"/><rect x="196" y="146" width="8" height="20"/>
    <rect x="218" y="146" width="8" height="20"/><rect x="240" y="146" width="8" height="20"/>
    <rect x="262" y="146" width="8" height="20"/><rect x="284" y="146" width="8" height="20"/>
    <rect x="306" y="146" width="8" height="20"/><rect x="328" y="146" width="8" height="20"/>
    <rect x="350" y="146" width="8" height="20"/><rect x="372" y="146" width="8" height="20"/>
    <rect x="394" y="146" width="8" height="20"/><rect x="416" y="146" width="8" height="20"/>
    <rect x="438" y="146" width="8" height="20"/><rect x="460" y="146" width="8" height="20"/>
    <rect x="482" y="146" width="8" height="20"/><rect x="504" y="146" width="8" height="20"/>
    <rect x="548" y="146" width="8" height="20"/><rect x="570" y="146" width="8" height="20"/>
    <rect x="592" y="146" width="8" height="20"/><rect x="614" y="146" width="8" height="20"/>
    <rect x="636" y="146" width="8" height="20"/><rect x="658" y="146" width="8" height="20"/>
  </g>
  <text x="130" y="188" font-size="9.5" font-family="monospace" fill="currentColor" font-weight="bold">每个间隔都远小于 60s → 穿过超时线也毫发无伤</text>
  <text x="0" y="212" font-size="10" font-family="monospace" fill="currentColor" opacity="0.6">本图为示意，用于说明超时的计量方式</text>
</svg>
<figcaption>
同一个总时长、同一个超时配置，结果完全不同。<strong>非流式请求才是超时的重灾区。</strong>
如果你的中转站还有大量非流式调用，这就是优先要治的地方——而不是一味把超时往上调。
</figcaption>
</figure>
<h2 id="正确的超时分层">正确的超时分层</h2>
<p>关键是<strong>区分&quot;连不上&quot;和&quot;生成慢&quot;</strong>：前者应该快速失败，后者必须耐心等。用一个统一的大数字把三个超时都拉长，是把两种完全不同的故障混在一起处理。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nginx" data-lang="nginx"><span class="line"><span class="cl"><span class="k">location</span> <span class="s">/v1/</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kn">proxy_pass</span> <span class="s">http://upstream_pool</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 连不上 → 快速失败。请求还没发出去，此时重试是安全的
</span></span></span><span class="line"><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="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 发送请求体 → 大 prompt 也就几百 KB，给足但不必夸张
</span></span></span><span class="line"><span class="cl">    <span class="kn">proxy_send_timeout</span>     <span class="s">60s</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 读响应 → 生成慢是正常的，不是故障。这里必须放宽
</span></span></span><span class="line"><span class="cl">    <span class="kn">proxy_read_timeout</span>     <span class="s">600s</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># LLM 是非幂等的：绝不要开 non_idempotent
</span></span></span><span class="line"><span class="cl">    <span class="c1"># 保守起见连 timeout 重试也去掉，只保留连接阶段的重试
</span></span></span><span class="line"><span class="cl">    <span class="kn">proxy_next_upstream</span>    <span class="s">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kn">proxy_next_upstream_tries</span> <span class="mi">2</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kn">proxy_next_upstream_timeout</span> <span class="s">10s</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 流式必须配套，否则响应被攒起来又变回一个长读间隔
</span></span></span><span class="line"><span class="cl">    <span class="kn">proxy_buffering</span>        <span class="no">off</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kn">gzip</span>                   <span class="no">off</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kn">proxy_http_version</span>     <span class="mi">1</span><span class="s">.1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kn">proxy_set_header</span>       <span class="s">Connection</span> <span class="s">&#34;&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><figure>
<svg viewBox="0 0 740 200" role="img" aria-label="超时分层示意：连接超时 5 秒对应连不上的情况且重试安全，发送超时 60 秒，读取超时 600 秒对应生成慢的情况不应视为故障，客户端 SDK 重试次数应设为 0 或 1" style="width:100%;height:auto;color:currentColor">
  <text x="0" y="14" font-size="10.5" font-family="monospace" fill="currentColor" opacity="0.6">按故障性质分层，而不是统一拉长</text>
  <g font-family="monospace" font-size="10.5" fill="currentColor">
    <rect x="0" y="30" width="700" height="34" fill="none" stroke="currentColor" stroke-width="1.3"/>
    <text x="12" y="52">proxy_connect_timeout</text>
    <text x="200" y="52" font-weight="bold">5s</text>
    <text x="250" y="52" opacity="0.7">连不上 → 快速失败</text>
    <text x="500" y="52" opacity="0.7">请求未发出，重试安全 ✓</text>
    <rect x="0" y="72" width="700" height="34" fill="none" stroke="currentColor" stroke-width="1.3"/>
    <text x="12" y="94">proxy_send_timeout</text>
    <text x="200" y="94" font-weight="bold">60s</text>
    <text x="250" y="94" opacity="0.7">上传 prompt</text>
    <text x="500" y="94" opacity="0.7">已发出，重试即重复计费 ⚠</text>
    <rect x="0" y="114" width="700" height="34" fill="currentColor" fill-opacity="0.1" stroke="currentColor" stroke-width="1.5"/>
    <text x="12" y="136">proxy_read_timeout</text>
    <text x="200" y="136" font-weight="bold">600s</text>
    <text x="250" y="136" opacity="0.7">生成慢 → 不是故障</text>
    <text x="500" y="136" font-weight="bold">这一层千万别按 60s 算 ⚠</text>
    <rect x="0" y="156" width="700" height="34" fill="none" stroke="currentColor" stroke-width="1.3" stroke-dasharray="4 3"/>
    <text x="12" y="178">SDK max_retries</text>
    <text x="200" y="178" font-weight="bold">0 或 1</text>
    <text x="250" y="178" opacity="0.7">客户端侧</text>
    <text x="500" y="178" opacity="0.7">默认 2，是双倍计费主因</text>
  </g>
</svg>
<figcaption>灰底那一行是唯一需要显著放宽的；虚线那一行不在服务端，<strong>但它才是账单翻倍的直接原因</strong>，容易被漏掉。</figcaption>
</figure>
<h2 id="客户端侧要做的事">客户端侧要做的事</h2>
<p>服务端配对了，客户端如果还在盲目重试，问题只是变少而不是消失。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">openai</span> <span class="kn">import</span> <span class="n">OpenAI</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">client</span> <span class="o">=</span> <span class="n">OpenAI</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">base_url</span><span class="o">=</span><span class="s2">&#34;https://your-gateway/v1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">api_key</span><span class="o">=</span><span class="s2">&#34;...&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">max_retries</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>   <span class="c1"># 默认是 2，对按 token 计费的接口必须显式关掉</span>
</span></span><span class="line"><span class="cl">    <span class="n">timeout</span><span class="o">=</span><span class="mf">600.0</span><span class="p">,</span>   <span class="c1"># 客户端超时也要放宽，否则轮到它先放弃</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span></code></pre></div><p>关掉自动重试之后，重试逻辑要自己写，并且<strong>只在明确安全的错误上重试</strong>：</p>
<table>
	<thead>
			<tr>
					<th>错误</th>
					<th>能否重试</th>
					<th>原因</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>连接失败 / DNS 失败</td>
					<td><strong>可以</strong></td>
					<td>请求没发出去，上游没开始生成</td>
			</tr>
			<tr>
					<td><code>429</code> 限流</td>
					<td><strong>可以</strong></td>
					<td>上游明确拒绝了，没有生成</td>
			</tr>
			<tr>
					<td><code>400</code> 参数错误</td>
					<td>不该重试</td>
					<td>重试一万次也是同样结果</td>
			</tr>
			<tr>
					<td><code>401</code> / <code>403</code></td>
					<td>不该重试</td>
					<td>凭据问题</td>
			</tr>
			<tr>
					<td><code>504</code> / <code>502</code></td>
					<td><strong>危险</strong></td>
					<td>上游可能已经生成完了，重试就是第二笔账单</td>
			</tr>
			<tr>
					<td>流式中途断开</td>
					<td><strong>危险</strong></td>
					<td>已经生成了一部分，且已产生费用</td>
			</tr>
	</tbody>
</table>
<h2 id="更彻底的办法在中转层做请求去重">更彻底的办法：在中转层做请求去重</h2>
<p>如果你控制中转层（自建 new-api 之类就是这种情况），可以在网关上加一层短窗口去重，把重复计费在源头掐掉：</p>
<p>思路是给每个请求算一个指纹——模型名 + 消息体 + 关键参数的哈希——配上客户端标识，在 Redis 里存一个几十秒的短 key。窗口内出现相同指纹时，不再打上游，直接返回上一次的结果或一个明确的&quot;重复请求&quot;错误。</p>
<p>这个做法的取舍要讲清楚：</p>
<ul>
<li><strong>好处</strong>：无论客户端怎么重试，上游只被打一次，账单可控。</li>
<li><strong>代价</strong>：LLM 本身是有随机性的（temperature &gt; 0 时同样输入本该有不同输出），去重会让窗口内的重复请求拿到相同结果。对聊天场景通常无害，对&quot;故意重新生成一次&quot;的功能就是 bug。</li>
<li><strong>所以</strong>：窗口要短（几十秒量级），并且给客户端一个显式绕过的办法（比如一个请求头或一个随机 nonce 参数）。</li>
</ul>
<h2 id="怎么发现自己已经在被双倍计费">怎么发现自己已经在被双倍计费</h2>
<p>从日志里找证据，不用等账单。特征是：<strong>同一客户端在很短时间内发出内容完全相同的请求，且其中至少一个返回了 504。</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># 找 504：如果这个数不是 0，就值得往下查</span>
</span></span><span class="line"><span class="cl">awk <span class="s1">&#39;$9==504 {print $1, $7}&#39;</span> /var/log/nginx/access.log <span class="p">|</span> sort <span class="p">|</span> uniq -c <span class="p">|</span> sort -rn <span class="p">|</span> head
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 找 504 之后紧跟着重试的模式：同 IP、同路径、几秒内连续多次</span>
</span></span><span class="line"><span class="cl">awk <span class="s1">&#39;$9==504 || $9==200 {print $1, $4, $9, $7}&#39;</span> /var/log/nginx/access.log <span class="se">\
</span></span></span><span class="line"><span class="cl">  <span class="p">|</span> grep <span class="s1">&#39;/v1/chat/completions&#39;</span> <span class="p">|</span> tail -50
</span></span></code></pre></div><p>更可靠的信号是把<strong>上游用量与自己记录的成功响应数对账</strong>：如果上游统计的请求数明显高于你返回给客户端的成功数，差额基本就是被白烧掉的重试。</p>
<h2 id="相关阅读">相关阅读</h2>
<ul>
<li><a href="/posts/llm-api-sse-proxy-buffering/">反代把大模型 API 的 SSE 流式响应缓冲了：五个缓冲点与三层排查法</a> —— 本文说流式不容易超时，前提是流式真的没被缓冲掉</li>
<li><a href="/posts/caddy-vs-nginx-api-gateway-tls/">Caddy 还是 nginx 给 API 中转做反代：证书自动化是决定性差异</a> —— 另一类会让全部请求一起失败的运维故障</li>
<li><a href="/posts/new-api-binary-vs-docker/">new-api 部署选型：2G 小内存机器上裸二进制比 Docker 省多少</a> —— 超时配置所在的那层反代怎么部署</li>
<li><a href="/posts/api-gateway-database-choice-small-vps/">给 API 中转站选数据库：SQLite / MySQL / PostgreSQL 在小机器上的取舍</a> —— 本文说的&quot;拿用量日志对账&quot;，那张表本身也会变成问题</li>
</ul>
]]></content:encoded></item></channel></rss>