<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>文档 on gobrave - 生物信息学分析平台</title><link>https://gobravedev.github.io/gobrave-doc/zh/docs/</link><description>Recent content in 文档 on gobrave - 生物信息学分析平台</description><generator>Hugo</generator><language>zh</language><lastBuildDate>Wed, 12 Aug 2026 00:00:00 +0800</lastBuildDate><atom:link href="https://gobravedev.github.io/gobrave-doc/zh/docs/index.xml" rel="self" type="application/rss+xml"/><item><title>快速开始</title><link>https://gobravedev.github.io/gobrave-doc/zh/docs/quick-start/</link><pubDate>Wed, 12 Aug 2026 00:00:00 +0800</pubDate><guid>https://gobravedev.github.io/gobrave-doc/zh/docs/quick-start/</guid><description>&lt;h2 id="概述"&gt;概述&lt;/h2&gt;
&lt;p&gt;本文帮助你在几分钟内本地启动 gobrave，使用默认 Go 服务入口。&lt;/p&gt;
&lt;h2 id="前置条件"&gt;前置条件&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Go 1.25 或更高版本&lt;/li&gt;
&lt;li&gt;可访问数据库：SQLite（默认）、MySQL 或 PostgreSQL&lt;/li&gt;
&lt;li&gt;若需要容器化分析运行时，请准备 Docker、k8s 或 k3s&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="1-克隆并进入项目"&gt;1. 克隆并进入项目&lt;/h2&gt;
&lt;div class="code-block"&gt;
 &lt;button class="code-copy" type="button" hidden aria-label="Copy code to clipboard"&gt;
 &lt;span class="code-copy-label" aria-hidden="true"&gt;Copy&lt;/span&gt;
 &lt;/button&gt;
 &lt;div class="highlight"&gt;&lt;div style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git clone https://github.com/gobravedev/gobrave.git
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cd gobrave&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;/div&gt;&lt;h2 id="2-创建运行配置"&gt;2. 创建运行配置&lt;/h2&gt;
&lt;div class="code-block"&gt;
 &lt;button class="code-copy" type="button" hidden aria-label="Copy code to clipboard"&gt;
 &lt;span class="code-copy-label" aria-hidden="true"&gt;Copy&lt;/span&gt;
 &lt;/button&gt;
 &lt;div class="highlight"&gt;&lt;div style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cp config.example.yml config.yml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;/div&gt;&lt;p&gt;至少请确认：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;database.*&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;container.runtime&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;storage.base_dir&lt;/code&gt;（可选但建议设置）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="3-启动服务"&gt;3. 启动服务&lt;/h2&gt;
&lt;div class="code-block"&gt;
 &lt;button class="code-copy" type="button" hidden aria-label="Copy code to clipboard"&gt;
 &lt;span class="code-copy-label" aria-hidden="true"&gt;Copy&lt;/span&gt;
 &lt;/button&gt;
 &lt;div class="highlight"&gt;&lt;div style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;go run ./cmd/server&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;/div&gt;&lt;p&gt;默认监听：&lt;/p&gt;</description></item><item><title>配置说明</title><link>https://gobravedev.github.io/gobrave-doc/zh/docs/configuration/</link><pubDate>Wed, 12 Aug 2026 00:00:00 +0800</pubDate><guid>https://gobravedev.github.io/gobrave-doc/zh/docs/configuration/</guid><description>&lt;h2 id="概述"&gt;概述&lt;/h2&gt;
&lt;p&gt;gobrave 配置加载遵循“默认值 -&amp;gt; config.yml -&amp;gt; CLI 覆盖”的合并顺序。&lt;/p&gt;
&lt;h2 id="解析优先级"&gt;解析优先级&lt;/h2&gt;
&lt;p&gt;配置优先级如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;程序内置默认值&lt;/li&gt;
&lt;li&gt;&lt;code&gt;config.yml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;CLI 参数（如 &lt;code&gt;--port&lt;/code&gt;、&lt;code&gt;--db-driver&lt;/code&gt;、&lt;code&gt;--runtime&lt;/code&gt;）&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="配置文件位置"&gt;配置文件位置&lt;/h2&gt;
&lt;p&gt;启动时配置路径解析顺序：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;--config&lt;/code&gt; CLI 参数&lt;/li&gt;
&lt;li&gt;对 &lt;code&gt;config.yml&lt;/code&gt; 的外部路径解析&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="核心配置段"&gt;核心配置段&lt;/h2&gt;
&lt;h3 id="server"&gt;&lt;code&gt;server&lt;/code&gt;&lt;/h3&gt;
&lt;div class="code-block"&gt;
 &lt;button class="code-copy" type="button" hidden aria-label="Copy code to clipboard"&gt;
 &lt;span class="code-copy-label" aria-hidden="true"&gt;Copy&lt;/span&gt;
 &lt;/button&gt;
 &lt;div class="highlight"&gt;&lt;div style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt;3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7ee787"&gt;server&lt;/span&gt;:&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;host&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;0.0.0.0&lt;/span&gt;&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;port&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;8082&lt;/span&gt;&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;log_path&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;logs/server.log&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;/div&gt;&lt;h3 id="database"&gt;&lt;code&gt;database&lt;/code&gt;&lt;/h3&gt;
&lt;div class="code-block"&gt;
 &lt;button class="code-copy" type="button" hidden aria-label="Copy code to clipboard"&gt;
 &lt;span class="code-copy-label" aria-hidden="true"&gt;Copy&lt;/span&gt;
 &lt;/button&gt;
 &lt;div class="highlight"&gt;&lt;div style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt;3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt;4
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt;5
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt;6
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt;7
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt;8
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7ee787"&gt;database&lt;/span&gt;:&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;driver&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;sqlite&lt;/span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#8b949e;font-style:italic"&gt;# sqlite | mysql | postgres&lt;/span&gt;&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;host&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;127.0.0.1&lt;/span&gt;&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;port&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;&amp;#34;5432&amp;#34;&lt;/span&gt;&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;user&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;postgres&lt;/span&gt;&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;password&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;name&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;postgres&lt;/span&gt;&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;ssl_mode&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;disable&lt;/span&gt;&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;path&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#8b949e;font-style:italic"&gt;# sqlite 使用&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;/div&gt;&lt;h3 id="container"&gt;&lt;code&gt;container&lt;/code&gt;&lt;/h3&gt;
&lt;div class="code-block"&gt;
 &lt;button class="code-copy" type="button" hidden aria-label="Copy code to clipboard"&gt;
 &lt;span class="code-copy-label" aria-hidden="true"&gt;Copy&lt;/span&gt;
 &lt;/button&gt;
 &lt;div class="highlight"&gt;&lt;div style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt; 1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt; 2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt; 3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt; 4
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt; 5
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt; 6
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt; 7
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt; 8
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt; 9
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt;10
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt;11
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt;12
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt;13
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt;14
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7ee787"&gt;container&lt;/span&gt;:&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;runtime&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;docker&lt;/span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#8b949e;font-style:italic"&gt;# docker | k8s | k3s&lt;/span&gt;&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;kubernetes&lt;/span&gt;:&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;namespace&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;default&lt;/span&gt;&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;kubeconfig&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;in_cluster&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#79c0ff"&gt;false&lt;/span&gt;&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;refresh_image_status_on_start&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#79c0ff"&gt;true&lt;/span&gt;&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;recover_running_dag_on_start&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#79c0ff"&gt;true&lt;/span&gt;&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;cleanup_dag_node_containers_before_start&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#79c0ff"&gt;true&lt;/span&gt;&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;delete_container_on_node_success&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#79c0ff"&gt;true&lt;/span&gt;&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;dag_node_cleanup_on_failed&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;stop&lt;/span&gt;&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;dag_node_cleanup_on_dag_finished&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;delete&lt;/span&gt;&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;create_queue_max_concurrency&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;3&lt;/span&gt;&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#7ee787"&gt;create_queue_max_pending&lt;/span&gt;:&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#a5d6ff"&gt;50&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;/div&gt;&lt;h3 id="route"&gt;&lt;code&gt;route&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;route.registry&lt;/code&gt; 用于控制路由注册策略：&lt;/p&gt;</description></item><item><title>系统架构</title><link>https://gobravedev.github.io/gobrave-doc/zh/docs/architecture/</link><pubDate>Wed, 12 Aug 2026 00:00:00 +0800</pubDate><guid>https://gobravedev.github.io/gobrave-doc/zh/docs/architecture/</guid><description>&lt;h2 id="概述"&gt;概述&lt;/h2&gt;
&lt;p&gt;gobrave 是一个模块化的 Go 后端，核心围绕项目级生信工作流、数据资产与容器化执行。&lt;/p&gt;
&lt;h2 id="高层组件"&gt;高层组件&lt;/h2&gt;
&lt;pre class="mermaid"&gt;flowchart TD
 UI[Web / API 客户端] --&amp;gt; API[GIN Router &amp;#43; Handlers]
 API --&amp;gt; APP[应用服务层]
 APP --&amp;gt; DOM[领域管理层]
 DOM --&amp;gt; RT[容器运行时注册表]
 DOM --&amp;gt; REPO[仓储层]
 REPO --&amp;gt; DB[(MySQL/Postgres/SQLite)]

 APP --&amp;gt; BUS[内存事件总线]
 BUS --&amp;gt; WK[Outbox 分发器 &amp;#43; Workers]
 WK --&amp;gt; RT&lt;/pre&gt;
&lt;h2 id="启动期组装"&gt;启动期组装&lt;/h2&gt;
&lt;p&gt;服务启动时会构建依赖注入容器并完成接线：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;配置加载器&lt;/li&gt;
&lt;li&gt;数据库连接&lt;/li&gt;
&lt;li&gt;仓储实现&lt;/li&gt;
&lt;li&gt;领域 manager/service&lt;/li&gt;
&lt;li&gt;容器运行时注册表&lt;/li&gt;
&lt;li&gt;Router 与 Handler&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;该模式既保证单可执行部署，又保留模块替换能力。&lt;/p&gt;
&lt;h2 id="关键子系统"&gt;关键子系统&lt;/h2&gt;
&lt;h3 id="api-层"&gt;API 层&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Gin Router 按领域注册路由（auth、project、data、workflow、container、store）&lt;/li&gt;
&lt;li&gt;API 版本前缀：&lt;code&gt;/api/v1&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="数据与领域层"&gt;数据与领域层&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;基于 GORM 的仓储持久化&lt;/li&gt;
&lt;li&gt;明确的所有权边界：project、dataset、sample、file、workflow、analysis&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="容器运行时层"&gt;容器运行时层&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;运行时抽象支持：&lt;code&gt;docker&lt;/code&gt;、&lt;code&gt;k8s&lt;/code&gt;、&lt;code&gt;k3s&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;将运行时事件统一映射为稳定的容器生命周期状态&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="事件与异步执行层"&gt;事件与异步执行层&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;内存事件总线用于领域事件分发&lt;/li&gt;
&lt;li&gt;Outbox + Worker 模式提供可恢复的异步生命周期执行&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="实时通信层"&gt;实时通信层&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;支持 &lt;code&gt;ws&lt;/code&gt; 和 &lt;code&gt;sse&lt;/code&gt; 两种传输&lt;/li&gt;
&lt;li&gt;支持每用户连接上限与 ACK 重试控制&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="请求到执行路径"&gt;请求到执行路径&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;客户端调用 API。&lt;/li&gt;
&lt;li&gt;Handler 校验并调用 service/manager。&lt;/li&gt;
&lt;li&gt;Service 持久化状态变更。&lt;/li&gt;
&lt;li&gt;异步操作写入 outbox。&lt;/li&gt;
&lt;li&gt;Worker 执行运行时操作并回发事件。&lt;/li&gt;
&lt;li&gt;Manager 对账状态并推送实时更新。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="设计目标"&gt;设计目标&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;单二进制部署，降低运维摩擦&lt;/li&gt;
&lt;li&gt;运行时无关的容器生命周期管理&lt;/li&gt;
&lt;li&gt;借助对账与持久化 outbox 保障重启安全&lt;/li&gt;
&lt;li&gt;项目中心化数据模型，适配 DAG 工作流执行&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>容器管理</title><link>https://gobravedev.github.io/gobrave-doc/zh/docs/containers/</link><pubDate>Wed, 12 Aug 2026 00:00:00 +0800</pubDate><guid>https://gobravedev.github.io/gobrave-doc/zh/docs/containers/</guid><description>&lt;h2 id="概述"&gt;概述&lt;/h2&gt;
&lt;p&gt;gobrave 通过统一的容器管理模型，支撑交互式应用会话与工作流运行任务。&lt;/p&gt;
&lt;h2 id="运行时后端"&gt;运行时后端&lt;/h2&gt;
&lt;p&gt;通过 &lt;code&gt;container.runtime&lt;/code&gt; 配置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;docker&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;k8s&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;k3s&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;运行时选择由容器运行时注册表统一解析。&lt;/p&gt;
&lt;h2 id="主要实体"&gt;主要实体&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;容器镜像：镜像元数据与拉取策略&lt;/li&gt;
&lt;li&gt;容器模板：可复用启动定义&lt;/li&gt;
&lt;li&gt;App Session：基于模板创建的用户会话环境&lt;/li&gt;
&lt;li&gt;容器实例：运行时生命周期状态记录&lt;/li&gt;
&lt;li&gt;Outbox 事件：可恢复的异步生命周期请求&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="核心-api-分组"&gt;核心 API 分组&lt;/h2&gt;
&lt;h3 id="镜像与模板"&gt;镜像与模板&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/container/image/*&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/container/template/*&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="app-session-生命周期"&gt;App Session 生命周期&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/container/app-session/create&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/container/app-session/start&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/container/app-session/stop&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/container/app-session/delete&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="运行时监控"&gt;运行时监控&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/container/runtime/monitoring/list&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/container/queue/status&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/container/outbox/list-by-page&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="生命周期模型"&gt;生命周期模型&lt;/h2&gt;
&lt;p&gt;典型流程：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;从模板创建会话。&lt;/li&gt;
&lt;li&gt;解析运行时并创建工作负载。&lt;/li&gt;
&lt;li&gt;持久化 runtime ID 与实例状态。&lt;/li&gt;
&lt;li&gt;监听运行时事件（&lt;code&gt;started&lt;/code&gt;、&lt;code&gt;failed&lt;/code&gt;、&lt;code&gt;exited&lt;/code&gt;、&lt;code&gt;deleted&lt;/code&gt;）。&lt;/li&gt;
&lt;li&gt;触发状态迁移并执行清理策略。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="队列与并发控制"&gt;队列与并发控制&lt;/h2&gt;
&lt;p&gt;容器创建受以下配置约束：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;container.create_queue_max_concurrency&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;container.create_queue_max_pending&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;用于在突发负载下保护运行时资源。&lt;/p&gt;
&lt;h2 id="清理策略"&gt;清理策略&lt;/h2&gt;
&lt;p&gt;DAG 节点所属容器可通过以下配置调整清理行为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;container.delete_container_on_node_success&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;container.dag_node_cleanup_on_failed&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;container.dag_node_cleanup_on_dag_finished&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="运行建议"&gt;运行建议&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;保持运行时监控开启并纳入可观测体系。&lt;/li&gt;
&lt;li&gt;在共享集群中使用保守的创建并发配置。&lt;/li&gt;
&lt;li&gt;根据调试需求与存储成本选择清理策略。&lt;/li&gt;
&lt;li&gt;使用 Kubernetes 模式时，结合 &lt;code&gt;/zh/docs/k8s-runtime-architecture&lt;/code&gt; 阅读。&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>数据管理</title><link>https://gobravedev.github.io/gobrave-doc/zh/docs/data/</link><pubDate>Wed, 12 Aug 2026 00:00:00 +0800</pubDate><guid>https://gobravedev.github.io/gobrave-doc/zh/docs/data/</guid><description>&lt;h2 id="概述"&gt;概述&lt;/h2&gt;
&lt;p&gt;gobrave 采用项目中心化数据模型，目标是让工作流输入组装可追溯、可复现。&lt;/p&gt;
&lt;h2 id="核心数据对象"&gt;核心数据对象&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Dataset：生物数据资产的逻辑集合&lt;/li&gt;
&lt;li&gt;Sample：样本元数据记录&lt;/li&gt;
&lt;li&gt;File：文件元数据记录&lt;/li&gt;
&lt;li&gt;关系：&lt;/li&gt;
&lt;li&gt;project &amp;lt;-&amp;gt; dataset&lt;/li&gt;
&lt;li&gt;dataset &amp;lt;-&amp;gt; sample&lt;/li&gt;
&lt;li&gt;dataset &amp;lt;-&amp;gt; file&lt;/li&gt;
&lt;li&gt;sample &amp;lt;-&amp;gt; file&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="api-范围"&gt;API 范围&lt;/h2&gt;
&lt;p&gt;数据接口位于 &lt;code&gt;/api/v1&lt;/code&gt;，按资源分组：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/data/dataset/*&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/data/project-dataset/*&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/data/file/*&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/data/sample/*&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/data/dataset-file/*&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/data/sample-file/*&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/data/dataset-sample/*&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="典型数据流程"&gt;典型数据流程&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;创建项目。&lt;/li&gt;
&lt;li&gt;创建数据集。&lt;/li&gt;
&lt;li&gt;注册样本与文件。&lt;/li&gt;
&lt;li&gt;绑定样本/文件角色（例如 FASTQ_R1、FASTQ_R2）。&lt;/li&gt;
&lt;li&gt;建立 dataset 关联关系。&lt;/li&gt;
&lt;li&gt;在工作流中按关系解析输入。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="与工作流的集成"&gt;与工作流的集成&lt;/h2&gt;
&lt;p&gt;工作流引擎可从托管数据中解析结构化输入：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;样本集合&lt;/li&gt;
&lt;li&gt;按样本聚合的角色分组文件&lt;/li&gt;
&lt;li&gt;独立参考文件&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因此可实现模板化工作流，同时保留项目级数据追踪能力。&lt;/p&gt;
&lt;h2 id="数据一致性说明"&gt;数据一致性说明&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;关系对象依赖后端生成 ID 进行关联。&lt;/li&gt;
&lt;li&gt;删除与更新会经过 repository/service 层校验。&lt;/li&gt;
&lt;li&gt;大型项目建议优先使用分页列表接口。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="最佳实践"&gt;最佳实践&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;批量导入前先定义统一的文件角色体系。&lt;/li&gt;
&lt;li&gt;用明确分析目标划分 dataset 边界。&lt;/li&gt;
&lt;li&gt;优先使用 project 作用域接口避免跨项目泄漏。&lt;/li&gt;
&lt;li&gt;保持工作流输入契约与数据角色命名一致。&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>容器队列监控</title><link>https://gobravedev.github.io/gobrave-doc/zh/docs/container-monitoring/</link><pubDate>Tue, 11 Aug 2026 00:00:00 +0800</pubDate><guid>https://gobravedev.github.io/gobrave-doc/zh/docs/container-monitoring/</guid><description>&lt;h2 id="概述"&gt;概述&lt;/h2&gt;
&lt;p&gt;本文档说明 gobrave 如何暴露容器创建队列健康状态、各监控字段的含义，以及队列状态在系统内部的计算方式。&lt;/p&gt;
&lt;p&gt;该监控接口主要服务于运维与前端轮询场景，用于回答以下问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;队列模式是否启用&lt;/li&gt;
&lt;li&gt;当前有多少创建并发槽位被占用&lt;/li&gt;
&lt;li&gt;还有多少创建请求在等待&lt;/li&gt;
&lt;li&gt;当前配置的并发上限和排队上限是多少&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="架构"&gt;架构&lt;/h2&gt;
&lt;pre class="mermaid"&gt;flowchart LR
 subgraph Client[客户端层]
 UI[Web UI / 运维脚本];
 end;

 subgraph API[接口层]
 H[ContainerHandler.GetQueueStatus];
 end;

 subgraph Worker[队列层]
 W[ContainerCreateWorker];
 QS[QueueStatus];
 end;

 subgraph Data[数据层]
 DB[(ContainerInstance &amp;#43; OutboxEvent)];
 end;

 UI --&amp;gt;|GET /container/queue/status| H;
 H --&amp;gt;|QueueStatus call| W;
 W --&amp;gt; QS;
 QS --&amp;gt;|CountContainerInstanceByStatuses| DB;
 QS --&amp;gt;|CountPendingOutboxEventsByType ContainerCreateRequest| DB;
 H --&amp;gt;|JSON response| UI;&lt;/pre&gt;
&lt;h3 id="启动期接线如何保障容错与指标准确性"&gt;启动期接线如何保障容错与指标准确性&lt;/h3&gt;
&lt;p&gt;队列监控能力依赖于依赖注入容器中的显式启动接线。
这些接线不仅让队列状态可观测，也让状态在重启后可恢复、可校正。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;通过 DI 注入监控注册表，并在全局激活。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;注册 &lt;code&gt;MonitoringRegistry&lt;/code&gt; provider，当前默认实现为内存版。&lt;/li&gt;
&lt;li&gt;通过 &lt;code&gt;SetMonitoringRegistry&lt;/code&gt; 注入运行时监控路径，确保全局只有一个监控真值来源。&lt;/li&gt;
&lt;li&gt;因为是 DI 驱动，后续可替换为 Redis 等实现而无需改队列 API。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;启动运行时对账器，形成持续修复闭环。&lt;/p&gt;</description></item><item><title>容器工作队列系统</title><link>https://gobravedev.github.io/gobrave-doc/zh/docs/container-worker/</link><pubDate>Tue, 11 Aug 2026 00:00:00 +0800</pubDate><guid>https://gobravedev.github.io/gobrave-doc/zh/docs/container-worker/</guid><description>&lt;h2 id="概述"&gt;概述&lt;/h2&gt;
&lt;p&gt;gobrave 使用基于 outbox 模式的工作队列来异步管理所有容器生命周期操作。所有操作 — &lt;strong&gt;创建&lt;/strong&gt;、&lt;strong&gt;启动&lt;/strong&gt;、&lt;strong&gt;停止&lt;/strong&gt;、&lt;strong&gt;删除&lt;/strong&gt; — 不再直接调用容器运行时（Docker/K8s），而是通过 &lt;code&gt;ContainerCreateWorker&lt;/code&gt; 入队，由事件总线异步处理。&lt;/p&gt;
&lt;p&gt;该设计提供：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;并发控制&lt;/strong&gt; — 通过信号量限制同时创建的容器数量。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;容错能力&lt;/strong&gt; — 失败的操作通过 outbox 模式自动重试。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;一致的状态机&lt;/strong&gt; — 所有操作遵循统一的 FSM 驱动的生命周期。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;解耦&lt;/strong&gt; — HTTP 处理函数立即返回，容器操作在后台执行。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="架构"&gt;架构&lt;/h2&gt;
&lt;h3 id="核心组件架构图"&gt;核心组件架构图&lt;/h3&gt;
&lt;pre class="mermaid"&gt;flowchart LR
 subgraph API[API 层]
 H[HTTP Handlers]
 end

 subgraph Core[控制层]
 M[ContainerManager\nCreateByTemplate / Start / Stop / Delete / OnEvent]
 D[OutboxDispatcher\n轮询 pending outbox]
 W[ContainerCreateWorker\n处理 create/start/stop/delete 请求]
 R[RunRuntimeReconciler\n定时恢复监控]
 end

 subgraph Data[数据层]
 DB[(ContainerInstance &amp;#43; OutboxEvent &amp;#43; ContainerEvent)]
 end

 subgraph Runtime[运行时层]
 RT[Docker / Kubernetes Runtime]
 end

 H --&amp;gt;|用户请求| M
 M --&amp;gt;|事务写入实例 &amp;#43; outbox 请求| DB

 D --&amp;gt;|拉取 pending 请求| DB
 D --&amp;gt;|发布 Outbox*RequestEvent| W

 W --&amp;gt;|执行 Create/Start/Stop/Delete| RT
 RT --&amp;gt;|ContainerStarted/Exited/Failed/...| M
 M --&amp;gt;|FSM 转换 &amp;#43; 事件落库| DB

 R --&amp;gt;|RecoverRuntimeMonitoring| RT
 R --&amp;gt;|扫描运行中实例| DB&lt;/pre&gt;
&lt;p&gt;该图展示了三个关键闭环：&lt;/p&gt;</description></item><item><title>重启后运行时监控恢复</title><link>https://gobravedev.github.io/gobrave-doc/zh/docs/runtime-monitor-recovery/</link><pubDate>Tue, 11 Aug 2026 00:00:00 +0800</pubDate><guid>https://gobravedev.github.io/gobrave-doc/zh/docs/runtime-monitor-recovery/</guid><description>&lt;h2 id="概述"&gt;概述&lt;/h2&gt;
&lt;p&gt;本文说明 gobrave 在进程重启后，如何恢复运行时生命周期监控。&lt;/p&gt;
&lt;p&gt;当前恢复路径基于：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ContainerManager.RunRuntimeReconciler(...)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ContainerManager.RecoverRuntimeMonitoring(...)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;运行时 &lt;code&gt;Monitor(ctx, runtimeID)&lt;/code&gt; 实现&lt;/li&gt;
&lt;li&gt;进程全局 &lt;code&gt;MonitoringRegistry&lt;/code&gt; 幂等保护&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;目标是为可恢复的容器实例重新附加监控，并让运行时事件继续进入正常状态迁移管道。&lt;/p&gt;
&lt;h2 id="为什么需要恢复"&gt;为什么需要恢复&lt;/h2&gt;
&lt;p&gt;服务重启后，内存中的监控 goroutine 会丢失。
如果不执行恢复，运行时状态可能已经变化，但持久化的 &lt;code&gt;ContainerInstance&lt;/code&gt; 状态仍然陈旧。&lt;/p&gt;
&lt;h2 id="启动与周期性恢复"&gt;启动与周期性恢复&lt;/h2&gt;
&lt;p&gt;系统启动时，依赖注入会触发：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ContainerManager.RunRuntimeReconciler(context.Background(), 600*time.Second)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;RunRuntimeReconciler&lt;/code&gt; 会执行：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;启动时立即恢复一次&lt;/li&gt;
&lt;li&gt;按配置间隔进行周期恢复&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;若 &lt;code&gt;interval &amp;lt;= 0&lt;/code&gt;，reconciler 会回退到 &lt;code&gt;300s&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;每次恢复都会调用 &lt;code&gt;RecoverRuntimeMonitoring&lt;/code&gt;，其处理步骤为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;读取持久化 &lt;code&gt;ContainerInstance&lt;/code&gt; 记录&lt;/li&gt;
&lt;li&gt;过滤可进行监控恢复的记录&lt;/li&gt;
&lt;li&gt;根据实例运行时信息解析运行时实现&lt;/li&gt;
&lt;li&gt;对运行中实例按需回填运行时 inspect 信息&lt;/li&gt;
&lt;li&gt;当运行时支持 &lt;code&gt;RuntimeMonitor&lt;/code&gt; 时调用 &lt;code&gt;Monitor(ctx, runtimeID)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;按实例记录恢复成功或失败日志，并继续扫描后续实例&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可恢复状态包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;creating&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;paused&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;running&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;failed&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;runtime ID 为空的实例会被跳过。&lt;/p&gt;
&lt;h2 id="monitoringregistry-的作用"&gt;MonitoringRegistry 的作用&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;MonitoringRegistry&lt;/code&gt; 用于监控 goroutine 成员管理并防止重复 watcher：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;MarkIfNotMonitoring(runtimeID)&lt;/code&gt; 通过原子方式仅在未监控时标记&lt;/li&gt;
&lt;li&gt;对同一 runtime ID 的重复恢复调用是安全且幂等的&lt;/li&gt;
&lt;li&gt;watcher 退出或订阅完成时调用 &lt;code&gt;UnmarkRuntimeMonitoring(runtimeID)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RuntimeMonitoringSnapshot()&lt;/code&gt; 暴露 runtime ID 到计数的映射，便于诊断&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因此，reconciler 可以重复运行而不会创建重复的活跃监控器。&lt;/p&gt;</description></item><item><title>Kubernetes 运行时架构</title><link>https://gobravedev.github.io/gobrave-doc/zh/docs/k8s-runtime-architecture/</link><pubDate>Wed, 12 Aug 2026 00:00:00 +0800</pubDate><guid>https://gobravedev.github.io/gobrave-doc/zh/docs/k8s-runtime-architecture/</guid><description>&lt;h2 id="概述"&gt;概述&lt;/h2&gt;
&lt;p&gt;本文说明 gobrave 当前使用的 Kubernetes 运行时架构。&lt;/p&gt;
&lt;p&gt;该实现基于以下代码：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;internal/container_runtime/kubernetes/runtime.go&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;internal/container_runtime/kubernetes/monitor_v2.go&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;运行时支持两类工作负载：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;deployment&lt;/code&gt;（长运行服务）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;job&lt;/code&gt;（一次性执行任务）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="架构目标"&gt;架构目标&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;在大规模场景下保持运行时监控高效。&lt;/li&gt;
&lt;li&gt;避免同一个 runtime ID 启动重复监控循环。&lt;/li&gt;
&lt;li&gt;将 Kubernetes 工作负载状态转换为稳定的 gobrave 运行时事件。&lt;/li&gt;
&lt;li&gt;让用户侧生命周期行为保持可预测（&lt;code&gt;start&lt;/code&gt;、&lt;code&gt;stop&lt;/code&gt;、&lt;code&gt;delete&lt;/code&gt;、&lt;code&gt;logs&lt;/code&gt;、&lt;code&gt;inspect&lt;/code&gt;）。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="高层流程"&gt;高层流程&lt;/h2&gt;
&lt;pre class="mermaid"&gt;flowchart TD
 A[Create ContainerSpec] --&amp;gt; B[KubernetesRuntime.Create]
 B --&amp;gt; C{WorkloadKind}
 C --&amp;gt;|deployment| D[Create Deployment]
 C --&amp;gt;|job| E[Create Job]
 D --&amp;gt; F[Optional Service -svc]
 D --&amp;gt; G[Return runtimeID]
 E --&amp;gt; G

 H[Start or Recovery] --&amp;gt; I[KubernetesRuntime.Monitor]
 I --&amp;gt; J{MarkIfNotMonitoring}
 J --&amp;gt;|already monitoring| K[Return idempotently]
 J --&amp;gt;|new| L[Start shared informers once]
 L --&amp;gt; M[Register subscription kind namespace name]
 M --&amp;gt; N[Deployment or Job events]
 N --&amp;gt; O[Emit RuntimeEvent]
 O --&amp;gt; P[ContainerManager state transition]&lt;/pre&gt;
&lt;h2 id="runtime-id-模型"&gt;Runtime ID 模型&lt;/h2&gt;
&lt;p&gt;Runtime ID 编码格式为：&lt;/p&gt;</description></item><item><title>Event Bus 订阅者（event_handlers）</title><link>https://gobravedev.github.io/gobrave-doc/zh/docs/event-bus-subscribers/</link><pubDate>Tue, 11 Aug 2026 00:00:00 +0800</pubDate><guid>https://gobravedev.github.io/gobrave-doc/zh/docs/event-bus-subscribers/</guid><description>&lt;h2 id="概述"&gt;概述&lt;/h2&gt;
&lt;p&gt;本文说明通过 &lt;code&gt;event_handlers&lt;/code&gt; 依赖注入分组订阅到共享事件总线的所有处理器，以及它们面向用户的架构职责。&lt;/p&gt;
&lt;p&gt;该分组中已注册的订阅者为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;NewRouteRegistryHandler&lt;/li&gt;
&lt;li&gt;NewAppSessionEventHandler&lt;/li&gt;
&lt;li&gt;NewDagRuntimeEventNotifier&lt;/li&gt;
&lt;li&gt;ContainerCreateWorker&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;系统启动时会遍历 &lt;code&gt;event_handlers&lt;/code&gt; 分组并调用 &lt;code&gt;bus.Subscribe(handler)&lt;/code&gt;，将这些处理器统一订阅到总线上。&lt;/p&gt;
&lt;h2 id="订阅架构"&gt;订阅架构&lt;/h2&gt;
&lt;pre class="mermaid"&gt;flowchart LR
 subgraph Startup[启动装配]
 C[BuildContainer]
 G[event_handlers 分组]
 B[event.Bus]
 end

 subgraph Subscribers[订阅者]
 R[RouteRegistryHandler\nNewRouteRegistryHandler]
 A[AppSessionEventHandler\nNewAppSessionEventHandler]
 D[DagRuntimeEventNotifier\nNewDagRuntimeEventNotifier]
 W[ContainerCreateWorker]
 end

 subgraph Producers[主要事件生产者]
 O[OutboxDispatcher]
 M[ContainerManager / Runtime Events]
 DG[DAG Runtime]
 end

 C --&amp;gt; G
 C --&amp;gt; B
 G --&amp;gt;|逐个 handler 注册| B

 O --&amp;gt;|OutboxCreateRequestEvent\nOutboxStartRequestEvent\nOutboxStopRequestEvent\nOutboxDeleteRequestEvent| B
 M --&amp;gt;|ContainerEvent| B
 DG --&amp;gt;|dag.RuntimeEvent| B

 B --&amp;gt; R
 B --&amp;gt; A
 B --&amp;gt; D
 B --&amp;gt; W&lt;/pre&gt;
&lt;h2 id="各订阅者作用"&gt;各订阅者作用&lt;/h2&gt;
&lt;h3 id="1-newrouteregistryhandler"&gt;1) NewRouteRegistryHandler&lt;/h3&gt;
&lt;p&gt;核心作用：将 App Session 容器生命周期与外部路由记录保持同步。&lt;/p&gt;</description></item><item><title>Node Completion Bootstrap 架构</title><link>https://gobravedev.github.io/gobrave-doc/zh/docs/node-completion-bootstrap/</link><pubDate>Tue, 11 Aug 2026 00:00:00 +0800</pubDate><guid>https://gobravedev.github.io/gobrave-doc/zh/docs/node-completion-bootstrap/</guid><description>&lt;h2 id="概述"&gt;概述&lt;/h2&gt;
&lt;p&gt;NodeCompletionBootstrap 是用于启动装配的基础组件，负责保证 DAG 分析节点在其运行容器进入终态后能够被最终收敛（finalize）。&lt;/p&gt;
&lt;p&gt;它通过以下方式把基础设施关注点与 DAG 编排业务解耦：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;构建并注入 NodeCompletionCoordinator（含清理策略）&lt;/li&gt;
&lt;li&gt;将 coordinator 订阅到容器生命周期事件总线&lt;/li&gt;
&lt;li&gt;启动后台轮询兜底收敛循环&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;即使发生进程重启、事件漏投或短暂总线抖动，也能保证节点状态最终一致。&lt;/p&gt;
&lt;h2 id="架构图"&gt;架构图&lt;/h2&gt;
&lt;pre class="mermaid"&gt;flowchart LR
 subgraph Startup[启动装配]
 C[DI Container Build]
 B[NodeCompletionBootstrap]
 BUS[event.Bus]
 end

 subgraph Coordinator[收敛引擎]
 N[NodeCompletionCoordinator]
 P[轮询循环 每2秒]
 EH[事件处理 ContainerStopped 或 ContainerFailed]
 end

 subgraph Data[数据层]
 CR[(ContainerInstance Repository)]
 AR[(AnalysisNode Repository)]
 end

 subgraph Runtime[节点最终化]
 RE[RuntimeEngine CompleteNode]
 PUB[发布 DAG RuntimeEvent]
 end

 subgraph Cleanup[容器清理]
 CM[ContainerManager Stop 或 Delete]
 CFG[container 配置策略]
 end

 C --&amp;gt; B
 B --&amp;gt;|Subscribe| BUS
 B --&amp;gt;|启动 goroutine| N

 BUS --&amp;gt; EH
 N --&amp;gt; EH
 N --&amp;gt; P

 EH --&amp;gt; CR
 P --&amp;gt; CR
 CR --&amp;gt; AR
 AR --&amp;gt; RE
 RE --&amp;gt; PUB

 CFG --&amp;gt; B
 B --&amp;gt; CM
 N --&amp;gt;|节点失败时| CM
 N --&amp;gt;|节点成功且开启时| CM&lt;/pre&gt;
&lt;h2 id="启动时序"&gt;启动时序&lt;/h2&gt;
&lt;p&gt;服务启动时：&lt;/p&gt;</description></item><item><title>Outbox 分发器与 Worker 并发控制</title><link>https://gobravedev.github.io/gobrave-doc/zh/docs/outbox-dispatcher-worker-concurrency/</link><pubDate>Tue, 11 Aug 2026 00:00:00 +0800</pubDate><guid>https://gobravedev.github.io/gobrave-doc/zh/docs/outbox-dispatcher-worker-concurrency/</guid><description>&lt;h2 id="概述"&gt;概述&lt;/h2&gt;
&lt;p&gt;本文说明 &lt;code&gt;RunOutboxDispatcher&lt;/code&gt;、&lt;code&gt;OutboxDispatcher&lt;/code&gt; 与 &lt;code&gt;ContainerCreateWorker&lt;/code&gt; 如何协同，为 &lt;code&gt;ContainerInstance&lt;/code&gt; 实现队列背压与运行时并发控制。&lt;/p&gt;
&lt;p&gt;核心目标：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;限制同时执行的容器创建/启动操作数量（&lt;code&gt;maxConcurrency&lt;/code&gt;）。&lt;/li&gt;
&lt;li&gt;限制可排队等待的创建请求数量（&lt;code&gt;maxPending&lt;/code&gt;）。&lt;/li&gt;
&lt;li&gt;通过 &lt;code&gt;OutboxEvent&lt;/code&gt; + 事件总线保持请求异步化。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="组件与职责"&gt;组件与职责&lt;/h2&gt;
&lt;h3 id="runoutboxdispatcher"&gt;&lt;code&gt;RunOutboxDispatcher&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;在 goroutine 中启动分发循环。&lt;/li&gt;
&lt;li&gt;异步调用 &lt;code&gt;dispatcher.Start(context.Background())&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block"&gt;
 &lt;button class="code-copy" type="button" hidden aria-label="Copy code to clipboard"&gt;
 &lt;span class="code-copy-label" aria-hidden="true"&gt;Copy&lt;/span&gt;
 &lt;/button&gt;
 &lt;div class="highlight"&gt;&lt;div style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#737679"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff7b72"&gt;func&lt;/span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#d2a8ff;font-weight:bold"&gt;RunOutboxDispatcher&lt;/span&gt;(dispatcher&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#ff7b72;font-weight:bold"&gt;*&lt;/span&gt;OutboxDispatcher)&lt;span style="color:#6e7681"&gt; &lt;/span&gt;{&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;&lt;span style="color:#ff7b72"&gt;go&lt;/span&gt;&lt;span style="color:#6e7681"&gt; &lt;/span&gt;dispatcher.&lt;span style="color:#d2a8ff;font-weight:bold"&gt;Start&lt;/span&gt;(context.&lt;span style="color:#d2a8ff;font-weight:bold"&gt;Background&lt;/span&gt;())&lt;span style="color:#6e7681"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;/div&gt;&lt;h3 id="outboxdispatcher"&gt;&lt;code&gt;OutboxDispatcher&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;轮询待处理 outbox 记录（&lt;code&gt;ListPendingOutboxEvent&lt;/code&gt;）。&lt;/li&gt;
&lt;li&gt;发布前将每个请求标记为 &lt;code&gt;processing&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;向事件总线发布类型化请求事件：
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;OutboxCreateRequestEvent&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OutboxStartRequestEvent&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OutboxStopRequestEvent&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OutboxDeleteRequestEvent&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="containercreateworker"&gt;&lt;code&gt;ContainerCreateWorker&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;订阅上述总线事件。&lt;/li&gt;
&lt;li&gt;异步处理 create/start/stop/delete。&lt;/li&gt;
&lt;li&gt;对 create/start 请求通过 &lt;code&gt;acquireCapacityAndTransition&lt;/code&gt; 做容量检查。&lt;/li&gt;
&lt;li&gt;成功后将 outbox 标记为 &lt;code&gt;sent&lt;/code&gt;，可重试失败则回退为 &lt;code&gt;pending&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="事件总线流程"&gt;事件总线流程&lt;/h2&gt;
&lt;pre class="mermaid"&gt;flowchart LR
 A[API / Manager enqueue] --&amp;gt; B[(go_outbox_event)]
 B --&amp;gt; C[OutboxDispatcher poll]
 C --&amp;gt; D[mark processing]
 D --&amp;gt; E[event.Bus publish]
 E --&amp;gt; F[ContainerCreateWorker Handle]
 F --&amp;gt; G{capacity &amp;#43; state valid?}
 G -- yes --&amp;gt; H[create or start container]
 G -- no --&amp;gt; I[keep request for retry]
 H --&amp;gt; J[mark outbox sent]
 I --&amp;gt; K[mark outbox pending]
 K --&amp;gt; C&lt;/pre&gt;
&lt;h2 id="containerinstance-状态与排队行为"&gt;&lt;code&gt;ContainerInstance&lt;/code&gt; 状态与排队行为&lt;/h2&gt;
&lt;h3 id="创建请求路径"&gt;创建请求路径&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;创建 API 在同一个 DB 事务内完成队列检查与入队。&lt;/li&gt;
&lt;li&gt;事务会检查待处理创建请求数是否超过 &lt;code&gt;maxPending&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;若待处理创建请求已大于等于 &lt;code&gt;maxPending&lt;/code&gt;，事务返回错误并回滚，因此不会创建 &lt;code&gt;ContainerInstance&lt;/code&gt; 和 &lt;code&gt;OutboxEvent&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;若可接受，同一事务写入：&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ContainerInstance{status: pending}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OutboxEvent{Type: ContainerCreateRequest, Status: pending}&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="5"&gt;
&lt;li&gt;&lt;code&gt;OutboxDispatcher&lt;/code&gt; 发布 &lt;code&gt;OutboxCreateRequestEvent&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ContainerCreateWorker&lt;/code&gt; 处理事件并调用 &lt;code&gt;acquireCapacityAndTransition&lt;/code&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="容量判定maxconcurrency"&gt;容量判定（&lt;code&gt;maxConcurrency&lt;/code&gt;）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Worker 会统计当前占用并发槽位的活跃容器实例。&lt;/li&gt;
&lt;li&gt;若活跃数小于 &lt;code&gt;maxConcurrency&lt;/code&gt;，允许迁移，容器进入 &lt;code&gt;creating&lt;/code&gt;，随后进入 &lt;code&gt;running&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;若活跃数大于等于 &lt;code&gt;maxConcurrency&lt;/code&gt;，本轮拒绝容量，请求不会执行。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;拒绝时结果：&lt;/p&gt;</description></item></channel></rss>