<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>指南 on bouine</title><link>https://bouine.org/v0.4/zh/docs/guides/</link><description>Recent content in 指南 on bouine</description><generator>Hugo</generator><language>zh</language><atom:link href="https://bouine.org/v0.4/zh/docs/guides/index.xml" rel="self" type="application/rss+xml"/><item><title>从 NGINX 迁移</title><link>https://bouine.org/v0.4/zh/docs/guides/nginx-migration/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://bouine.org/v0.4/zh/docs/guides/nginx-migration/</guid><description>&lt;h2 id="directive-mapping"&gt;Directive mapping&lt;/h2&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;NGINX directive&lt;/th&gt;
 &lt;th&gt;bouine config&lt;/th&gt;
 &lt;th&gt;Notes&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;proxy_cache_path ... max_size=1g&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;storage.hot_max_bytes: 1GiB&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;bouine uses in-RAM storage, no filesystem levels&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;proxy_cache_path ... keys_zone=api:10m&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Not needed&lt;/td&gt;
 &lt;td&gt;bouine manages shard count automatically (&lt;code&gt;N=NumCPU&lt;/code&gt;)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;proxy_cache_valid 200 60s&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;routes[].cache.ttl_default: 60s&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Per-route, respects &lt;code&gt;Cache-Control&lt;/code&gt; by default&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;proxy_cache_valid 404 10s&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;routes[].cache.negative_ttl: 10s&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Negative caching for error responses&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;proxy_cache_use_stale error http_500 http_502 http_503 http_504&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;routes[].cache.stale_if_error: 30s&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Serves stale on origin 5xx or timeout&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;proxy_cache_background_update on&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;routes[].cache.stale_while_revalidate: 10s&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Background revalidation while serving stale&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;proxy_cache_revalidate on&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Built-in&lt;/td&gt;
 &lt;td&gt;Conditional requests (&lt;code&gt;If-None-Match&lt;/code&gt;, &lt;code&gt;If-Modified-Since&lt;/code&gt;)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;proxy_cache_key $scheme$host$request_uri&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Automatic&lt;/td&gt;
 &lt;td&gt;xxhash128 of scheme+host+path+sorted query&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;proxy_cache_key $scheme$host$request_uri$http_accept&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;cache.key.include_headers: [Accept]&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Explicit header keying&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;proxy_ignore_headers Vary&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;cache.key.include_headers: [...]&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Explicit header keying instead of Vary&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;proxy_no_cache $variable&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;routes[].cache.enabled: false&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Per-route disable&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;proxy_cache_bypass $variable&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Not needed&lt;/td&gt;
 &lt;td&gt;Use route matching to separate cached/uncached&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;proxy_cache_lock on&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Built-in (request collapsing)&lt;/td&gt;
 &lt;td&gt;Single-flight per cache key&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;proxy_cache_lock_timeout 5s&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Built-in&lt;/td&gt;
 &lt;td&gt;Subscribers wait for leader fetch&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;proxy_cache_min_uses 3&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Not needed&lt;/td&gt;
 &lt;td&gt;bouine caches on first response (RFC 9111)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;add_header X-Cache-Status $upstream_cache_status&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Built-in&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;X-Cache&lt;/code&gt; header (HIT, MISS, STALE, BYPASS, REVALIDATED)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;proxy_next_upstream error timeout&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;upstream_pools[].health.passive&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Passive health checks with outlier ejection&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="key-differences"&gt;Key differences&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;No zone configuration&lt;/strong&gt; — bouine manages memory automatically with SIEVE eviction&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No filesystem cache&lt;/strong&gt; — bouine uses in-RAM hot tier + mmap warm tier (no &lt;code&gt;proxy_cache_path&lt;/code&gt; on disk)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Clustering built-in&lt;/strong&gt; — NGINX requires third-party modules for cache sharing; bouine has gossip + peer fetch&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RFC 9111 native&lt;/strong&gt; — bouine implements the spec directly, not via directives&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Observability built-in&lt;/strong&gt; — Prometheus &lt;code&gt;/metrics&lt;/code&gt;, structured JSON access logs with &lt;code&gt;cache_status&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No &lt;code&gt;proxy_pass&lt;/code&gt; needed&lt;/strong&gt; — upstream pools are declared separately and referenced by name in routes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Declarative config&lt;/strong&gt; — no &lt;code&gt;if&lt;/code&gt; blocks, no &lt;code&gt;map&lt;/code&gt; directives, no embedded Lua&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="example-api-gateway"&gt;Example: API gateway&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;NGINX:&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>从 Varnish 迁移</title><link>https://bouine.org/v0.4/zh/docs/guides/varnish-migration/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://bouine.org/v0.4/zh/docs/guides/varnish-migration/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Status:&lt;/strong&gt; Stable for production use. Assumes familiarity with VCL and bouine&amp;rsquo;s YAML configuration model.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="quick-reference"&gt;Quick reference&lt;/h2&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Varnish concept&lt;/th&gt;
 &lt;th&gt;bouine equivalent&lt;/th&gt;
 &lt;th&gt;Notes&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;VCL subroutines&lt;/td&gt;
 &lt;td&gt;declarative YAML config&lt;/td&gt;
 &lt;td&gt;bouine uses config, not code&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;vcl_recv&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;routes[].match&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;routing and request matching&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;vcl_hash&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;automatic cache key (&lt;code&gt;xxhash64&lt;/code&gt;)&lt;/td&gt;
 &lt;td&gt;scheme + host + path + query + method&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;vcl_backend_fetch&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;upstream_pools[]&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;backend pool config&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;vcl_backend_response&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;origin &lt;code&gt;Cache-Control&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;bouine honors RFC 9111 strictly&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;beresp.ttl&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;cache.ttl_default&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;overridden by origin headers&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;beresp.grace&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;cache.stale_while_revalidate&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;SWR semantics&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;ban()&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;admin API &lt;code&gt;POST /v1/ban&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;HTTP-based invalidation API&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;purge&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;admin API &lt;code&gt;POST /v1/purge&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;exact-match invalidation&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Varnish log (&lt;code&gt;-g request&lt;/code&gt;)&lt;/td&gt;
 &lt;td&gt;structured JSON logs (stdout)&lt;/td&gt;
 &lt;td&gt;pipe to any log aggregator&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;varnishstat&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;/metrics&lt;/code&gt; (Prometheus)&lt;/td&gt;
 &lt;td&gt;Prometheus-compatible metrics&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;VSM/shared memory&lt;/td&gt;
 &lt;td&gt;in-process memory&lt;/td&gt;
 &lt;td&gt;no mmap, no VSM files&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="1-conceptual-mapping"&gt;1. Conceptual mapping&lt;/h2&gt;
&lt;h3 id="the-big-picture"&gt;The big picture&lt;/h3&gt;
&lt;p&gt;Varnish is a &lt;strong&gt;programmable cache&lt;/strong&gt; — you write VCL to define cache behavior.
bouine is a &lt;strong&gt;declarative cache&lt;/strong&gt; — you write YAML to describe routes, backends,
and cache policies, and bouine implements RFC 9111 rigorously.&lt;/p&gt;</description></item><item><title>反向代理示例</title><link>https://bouine.org/v0.4/zh/docs/guides/reverse-proxies/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://bouine.org/v0.4/zh/docs/guides/reverse-proxies/</guid><description>&lt;h2 id="bouine-in-front-of-caddy"&gt;bouine in front of Caddy&lt;/h2&gt;
&lt;p&gt;Caddy typically serves static files or acts as a reverse proxy itself. Deploy bouine in front of Caddy to add caching without modifying Caddy&amp;rsquo;s config.&lt;/p&gt;</description></item><item><title>容量规划</title><link>https://bouine.org/v0.4/zh/docs/guides/capacity-planning/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://bouine.org/v0.4/zh/docs/guides/capacity-planning/</guid><description>&lt;h2 id="step-1-estimate-your-working-set"&gt;Step 1: Estimate your working set&lt;/h2&gt;
&lt;p&gt;The &lt;strong&gt;working set&lt;/strong&gt; is the total size of responses that need to stay cached for acceptable hit rates.&lt;/p&gt;



&lt;div class="expressive-code"&gt;
 &lt;figure class="frame not-content"&gt;
 &lt;figcaption class="header"&gt;
 &lt;span class="title"&gt;&lt;/span&gt;
 &lt;/figcaption&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;working_set ≈ unique_cacheable_urls × avg_response_size&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
 &lt;/figure&gt;
&lt;/div&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Workload&lt;/th&gt;
 &lt;th&gt;Typical working set&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;REST API (100k endpoints, 2 KiB avg)&lt;/td&gt;
 &lt;td&gt;~200 MiB&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;E-commerce catalog (1M products, 5 KiB avg)&lt;/td&gt;
 &lt;td&gt;~5 GiB&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Static site / CDN (50k assets, 50 KiB avg)&lt;/td&gt;
 &lt;td&gt;~2.5 GiB&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Media-heavy site (10k pages, 200 KiB avg)&lt;/td&gt;
 &lt;td&gt;~2 GiB&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;If you cannot estimate, start with 2 GiB and monitor &lt;code&gt;bouine_hot_store_bytes / bouine_hot_store_max_bytes&lt;/code&gt;. If it stays above 0.9 consistently, double &lt;code&gt;hot_max_bytes&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>基准测试</title><link>https://bouine.org/v0.4/zh/docs/guides/benchmarks/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://bouine.org/v0.4/zh/docs/guides/benchmarks/</guid><description>&lt;blockquote&gt;
&lt;h2 id="disclaimer"&gt;Disclaimer&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Benchmarks are synthetic.&lt;/strong&gt; They measure isolated behavior in artificial conditions.
Production workloads have different allocation patterns, concurrency levels, GC
pressure, network conditions, and hardware. The Varnish and NGINX configurations used
in these tests could likely be improved — a differently tuned Varnish or NGINX may
produce different results. Benchmarking is genuinely hard, and these numbers should be
treated as directional indicators, not as definitive performance claims.&lt;/p&gt;</description></item><item><title>Production readiness checklist</title><link>https://bouine.org/v0.4/zh/docs/guides/production-checklist/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://bouine.org/v0.4/zh/docs/guides/production-checklist/</guid><description>&lt;p&gt;Before deploying bouine to production, verify each item below. Items
are grouped by area. Skip items that don&amp;rsquo;t apply to your deployment.&lt;/p&gt;
&lt;h2 id="tls-and-network-security"&gt;TLS and network security&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Data-plane TLS configured (if terminating HTTPS at bouine)&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Cluster mTLS enabled (cert + key + CA bundle for peer-to-peer)&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Admin port not exposed externally (NetworkPolicy or firewall)&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Admin token set via Secret or environment variable (not auto-generated)&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &lt;code&gt;insecure_skip_verify&lt;/code&gt; is not set in any upstream pool TLS config&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Hop-by-hop headers stripped (handled automatically by bouine)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="resource-sizing"&gt;Resource sizing&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &lt;code&gt;resources.limits.memory&lt;/code&gt; set and GOMEMLIMIT auto-computed (Helm chart does this)&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &lt;code&gt;hot_max_bytes&lt;/code&gt; sized to fit in RAM without GC pressure (default: 75% of GOMEMLIMIT)&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Warm tier PVC sized for working set (&lt;code&gt;warmVolume.size&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &lt;code&gt;warm_max_bytes&lt;/code&gt; set below PVC capacity to leave headroom&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &lt;code&gt;max_object_size&lt;/code&gt; configured per route to reject oversized responses&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &lt;code&gt;max_response_bytes&lt;/code&gt; configured to prevent memory exhaustion from large bodies&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="cluster-and-high-availability"&gt;Cluster and high availability&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &lt;code&gt;replicaCount &amp;gt;= 3&lt;/code&gt; for quorum&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &lt;code&gt;podDisruptionBudget.enabled: true&lt;/code&gt; with &lt;code&gt;minAvailable &amp;gt;= 2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Topology spread constraints set across zones&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &lt;code&gt;hop_limit&lt;/code&gt; configured (default 2 is fine for most deployments)&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &lt;code&gt;terminationGracePeriodSeconds &amp;gt;= 40&lt;/code&gt; to allow graceful drain&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &lt;code&gt;minReadySeconds &amp;gt;= 30&lt;/code&gt; to let the ring converge before traffic&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="caching-policy"&gt;Caching policy&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Every route has &lt;code&gt;ttl_default&lt;/code&gt; set explicitly&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &lt;code&gt;stale_while_revalidate&lt;/code&gt; configured for routes that can serve stale&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &lt;code&gt;stale_if_error&lt;/code&gt; configured for origin-outage resilience&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &lt;code&gt;negative_ttl&lt;/code&gt; set for routes that return errors (prevents error storms)&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &lt;code&gt;jitter_percent &amp;gt; 0&lt;/code&gt; to prevent synchronized revalidation bursts&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &lt;code&gt;allow_set_cookie&lt;/code&gt; is off unless you explicitly need Set-Cookie caching&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Cache key configuration reviewed (query param stripping, header includes)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="upstream-and-origin"&gt;Upstream and origin&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Active health checks enabled per pool&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Passive health checks enabled (&lt;code&gt;consecutive_5xx&lt;/code&gt;, &lt;code&gt;eject_for&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Upstream connection timeout and response header timeout configured&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &lt;code&gt;max_connections&lt;/code&gt; set per pool to prevent FD exhaustion&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Hedged requests enabled for latency-sensitive routes&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="observability"&gt;Observability&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Prometheus scraping enabled (ServiceMonitor or PodMonitor)&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Grafana dashboards imported (RED, storage, cluster, ops)&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Alerting rules deployed (hit rate, error rate, peer fetch, warm tier)&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; OpenTelemetry tracing endpoint configured (or disabled explicitly)&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Access log sampling rate appropriate (default 1:100 for 200s)&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &lt;code&gt;pprof_enabled&lt;/code&gt; is off in production (default)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="kubernetes-deployment"&gt;Kubernetes deployment&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Helm chart deployed with production values (&lt;code&gt;values-production.yaml&lt;/code&gt; as base)&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &lt;code&gt;NetworkPolicy.enabled: true&lt;/code&gt; to isolate admin and cluster ports&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &lt;code&gt;serviceAccount.automount: false&lt;/code&gt; (bouine doesn&amp;rsquo;t need K8s API access)&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Probes configured: startup (30 min budget), readiness (&lt;code&gt;/readyz&lt;/code&gt;), liveness (&lt;code&gt;/healthz&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Rolling update strategy: &lt;code&gt;maxUnavailable: 1&lt;/code&gt; for sequential pod restarts&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Config changes deployed via rolling update (no live config reload)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="operations"&gt;Operations&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Purge and ban workflows documented for on-call&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Runbook accessible (see 

&lt;a class="link link--text" href="https://bouine.org/v0.4/zh/docs/operations/"&gt;operations docs&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Backup strategy for warm tier (PVC snapshots or rebuild from origin)&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Drain procedure tested (&lt;code&gt;/drain&lt;/code&gt; endpoint + preStop hook)&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Config file stored in version control&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Service Mesh 兼容性</title><link>https://bouine.org/v0.4/zh/docs/guides/service-mesh/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://bouine.org/v0.4/zh/docs/guides/service-mesh/</guid><description>&lt;p&gt;bouine works with any service mesh that operates at L4/L7. The main
consideration is the double-TLS problem: if the mesh enforces mTLS
between sidecars, bouine must either terminate TLS itself or let the
sidecar handle it.&lt;/p&gt;</description></item></channel></rss>