Loading...
正在加载...
请稍候

Stripe 架构演进与技术栈深度解析:Rust (Axum+SQLx) 与 Go (sqlc) 在计费系统中的博弈

C3P0 (C3P0) 2026年01月24日 03:26
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Stripe 架构深度解析: Axum + SQLx vs Go sqlc</title> <script src="https://cdn.tailwindcss.com"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script> <!-- Chosen Palette: Stripe Technical (Slate, White, Blurple/Indigo) --> <!-- Application Structure Plan: A dashboard-style narrative scroll. 1. Hero: The core thesis (Rust > Go for Billing). 2. Context Dashboard: What "Stripe Scale" actually means. 3. The Conflict: The "Hidden Tax" of Go/Codegen (Interactive Flow). 4. Benchmark Lab: Interactive charts comparing RPS, Latency, Memory, and Connection Stability. 5. Architecture Blueprint: Interactive block diagram of the Axum+SQLx stack. 6. Roadmap: A 60-day implementation timeline. This structure moves from the "Why" (High level) to the "What" (Data) to the "How" (Implementation), suitable for technical decision-makers. --> <!-- Visualization & Content Choices: - Benchmarks: Chart.js Bar/Line charts. Goal: Comparison. Shows the 3x diff visually. - Architecture: HTML/CSS Flexbox diagram. Goal: Structure. Shows the stack layers without SVG. - Process Flow: Vertical timeline with distinct colors for "Hell" (Go) vs "Smooth" (Rust). Goal: Contrast. - Roadmap: Styled list with progress indicators. Goal: Actionable steps. - Confirmed: NO SVG, NO Mermaid. --> <!-- CONFIRMATION: NO SVG graphics used. NO Mermaid JS used. --> <style> body { font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; } .chart-container { position: relative; width: 100%; max-width: 800px; margin: 0 auto; height: 350px; max-height: 400px; } .glass-panel { background: rgba(255, 255, 255, 0.9); backdrop-filter: blur(10px); border: 1px solid #e2e8f0; } .gradient-text { background-clip: text; -webkit-background-clip: text; color: transparent; background-image: linear-gradient(to right, #4f46e5, #9333ea); } .nav-active { border-bottom: 2px solid #4f46e5; color: #1e293b; } .interactive-card:hover { transform: translateY(-2px); box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1); } .arch-block { transition: all 0.3s ease; } .arch-block:hover { background-color: #f1f5f9; border-color: #6366f1; } </style> </head> <body class="bg-slate-50 text-slate-800 antialiased"> <!-- Navigation --> <nav class="sticky top-0 z-50 bg-white/95 backdrop-blur border-b border-slate-200 shadow-sm"> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div class="flex justify-between h-16"> <div class="flex items-center"> <span class="text-xl font-bold tracking-tight text-indigo-700">Tech<span class="text-slate-900">DeepDive</span></span> <span class="ml-4 px-2 py-0.5 rounded text-xs font-medium bg-slate-100 text-slate-500 hidden sm:inline-block">Based on Stripe Engineering</span> </div> <div class="flex space-x-8 h-full items-center text-sm font-medium text-slate-500 overflow-x-auto"> <button onclick="scrollToSection('context')" class="nav-item hover:text-indigo-600 h-full flex items-center px-2">背景与挑战</button> <button onclick="scrollToSection('conflict')" class="nav-item hover:text-indigo-600 h-full flex items-center px-2">Codegen 之痛</button> <button onclick="scrollToSection('benchmarks')" class="nav-item hover:text-indigo-600 h-full flex items-center px-2">性能压测</button> <button onclick="scrollToSection('architecture')" class="nav-item hover:text-indigo-600 h-full flex items-center px-2">架构解密</button> <button onclick="scrollToSection('roadmap')" class="nav-item hover:text-indigo-600 h-full flex items-center px-2">路线图</button> </div> </div> </div> </nav> <!-- Hero Section --> <header class="bg-white pt-16 pb-12 overflow-hidden border-b border-slate-200"> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center"> <h1 class="text-4xl sm:text-5xl font-extrabold text-slate-900 tracking-tight mb-4"> 为什么 Stripe 放弃 Go sqlc<br> <span class="gradient-text">转向 Axum + SQLx</span> </h1> <p class="mt-4 max-w-2xl mx-auto text-xl text-slate-500"> 解析高并发 Billing 系统的生存之道:如何用 Rust 实现 3 倍吞吐与毫秒级延迟。 </p> <div class="mt-8 flex justify-center gap-4"> <button onclick="scrollToSection('benchmarks')" class="px-6 py-3 border border-transparent text-base font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 transition shadow-lg"> 查看数据对比 </button> <button onclick="scrollToSection('architecture')" class="px-6 py-3 border border-slate-300 text-base font-medium rounded-md text-slate-700 bg-white hover:bg-slate-50 transition"> 探索技术栈 </button> </div> </div> </header> <main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12 space-y-20"> <!-- 1. Context Section --> <section id="context" class="scroll-mt-24"> <div class="mb-6"> <h2 class="text-2xl font-bold text-slate-900">这不是玩具 CRUD</h2> <p class="mt-2 text-lg text-slate-600">Stripe 的账单系统面临着极端的现实挑战。这不是简单的“请求-响应”模型,而是每秒数百万次的高风险操作。</p> </div> <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6"> <div class="bg-white p-6 rounded-xl shadow-sm border border-slate-200 interactive-card transition-all"> <div class="text-indigo-600 text-4xl mb-4 font-bold">10M+</div> <h3 class="font-semibold text-slate-900">每秒请求</h3> <p class="text-sm text-slate-500 mt-2">不可预测的突发流量与 Webhook 洪水。</p> </div> <div class="bg-white p-6 rounded-xl shadow-sm border border-slate-200 interactive-card transition-all"> <div class="text-indigo-600 text-4xl mb-4 font-bold">&lt;1ms</div> <h3 class="font-semibold text-slate-900">低延迟要求</h3> <p class="text-sm text-slate-500 mt-2">不仅要快,还要强一致性。</p> </div> <div class="bg-white p-6 rounded-xl shadow-sm border border-slate-200 interactive-card transition-all"> <div class="text-indigo-600 text-4xl mb-4 font-bold">Retry</div> <h3 class="font-semibold text-slate-900">连接风暴</h3> <p class="text-sm text-slate-500 mt-2">失败重试可能瞬间击穿脆弱的连接池。</p> </div> <div class="bg-white p-6 rounded-xl shadow-sm border border-slate-200 interactive-card transition-all"> <div class="text-indigo-600 text-4xl mb-4 font-bold">Flux</div> <h3 class="font-semibold text-slate-900">Schema 剧变</h3> <p class="text-sm text-slate-500 mt-2">metadata、索引、字段每天都在变化。</p> </div> </div> </section> <!-- 2. The Conflict: Codegen vs Runtime --> <section id="conflict" class="scroll-mt-24 bg-slate-100 rounded-3xl p-8 border border-slate-200"> <div class="mb-8 text-center max-w-3xl mx-auto"> <h2 class="text-2xl font-bold text-slate-900">Go sqlc 的“隐形税”</h2> <p class="mt-2 text-slate-600">在小规模项目中,sqlc 的类型安全令人愉悦。但在高频变动的 Billing 系统中,它变成了运维地狱。</p> </div> <div class="grid grid-cols-1 md:grid-cols-2 gap-12 items-start"> <!-- Left: Go sqlc Cycle --> <div class="bg-white rounded-xl shadow p-6 border-l-4 border-red-500 h-full"> <h3 class="text-lg font-bold text-slate-800 mb-4 flex items-center"> <span class="bg-red-100 text-red-600 py-1 px-3 rounded-full text-xs mr-3">痛点</span> Go sqlc 的循环地狱 </h3> <div class="space-y-4 relative"> <div class="absolute left-4 top-4 bottom-4 w-0.5 bg-slate-200"></div> <div class="relative flex items-center group"> <div class="w-8 h-8 rounded-full bg-red-100 text-red-600 flex items-center justify-center font-bold z-10 shrink-0">1</div> <div class="ml-4 p-3 bg-slate-50 rounded border border-slate-200 w-full group-hover:bg-red-50 transition"> <span class="font-semibold">Schema 变更</span> <span class="text-xs text-slate-500">(加字段/改索引)</span> </div> </div> <div class="relative flex items-center group"> <div class="w-8 h-8 rounded-full bg-red-100 text-red-600 flex items-center justify-center font-bold z-10 shrink-0">2</div> <div class="ml-4 p-3 bg-slate-50 rounded border border-slate-200 w-full group-hover:bg-red-50 transition"> <span class="font-semibold">sqlc generate</span> <span class="text-xs text-slate-500">(代码生成)</span> </div> </div> <div class="relative flex items-center group"> <div class="w-8 h-8 rounded-full bg-red-100 text-red-600 flex items-center justify-center font-bold z-10 shrink-0">3</div> <div class="ml-4 p-3 bg-slate-50 rounded border border-slate-200 w-full group-hover:bg-red-50 transition"> <span class="font-semibold">全量 Rebuild</span> <span class="text-xs text-slate-500">(二进制重构)</span> </div> </div> <div class="relative flex items-center group"> <div class="w-8 h-8 rounded-full bg-red-100 text-red-600 flex items-center justify-center font-bold z-10 shrink-0">4</div> <div class="ml-4 p-3 bg-slate-50 rounded border border-slate-200 w-full group-hover:bg-red-50 transition"> <span class="font-semibold">重新部署 & 重启</span> <span class="text-xs text-slate-500">(服务中断风险)</span> </div> </div> </div> <div class="mt-6 text-sm text-red-600 bg-red-50 p-3 rounded"> <strong>后果:</strong>高并发下 Struct mapping 开销大,Goroutine 调度压力增加,连接池易崩溃。 </div> </div> <!-- Right: Rust SQLx Flow --> <div class="bg-white rounded-xl shadow p-6 border-l-4 border-emerald-500 h-full"> <h3 class="text-lg font-bold text-slate-800 mb-4 flex items-center"> <span class="bg-emerald-100 text-emerald-600 py-1 px-3 rounded-full text-xs mr-3">优势</span> Axum + SQLx 的 Runtime 模式 </h3> <div class="space-y-4"> <div class="p-4 bg-emerald-50/50 rounded-lg border border-emerald-100"> <div class="font-bold text-emerald-800">无代码生成 (No Codegen)</div> <p class="text-sm text-slate-600 mt-1">Schema 改动不需要全量重建二进制。瓶颈在运行时解决,而非编译时。</p> </div> <div class="p-4 bg-emerald-50/50 rounded-lg border border-emerald-100"> <div class="font-bold text-emerald-800">Async Prepared Statements</div> <p class="text-sm text-slate-600 mt-1"> <code>pool.prepare_cached()</code> 自动复用查询计划。编译期校验 SQL 语法,运行时提取结果。 </p> </div> <div class="p-4 bg-emerald-50/50 rounded-lg border border-emerald-100"> <div class="font-bold text-emerald-800">JSONB + Generated Columns</div> <p class="text-sm text-slate-600 mt-1">利用 Postgres 特性实现零停机 Schema 演进。</p> </div> </div> </div> </div> </section> <!-- 3. Benchmarks Lab --> <section id="benchmarks" class="scroll-mt-24"> <div class="mb-6 flex flex-col md:flex-row md:items-end justify-between"> <div> <h2 class="text-2xl font-bold text-slate-900">性能实验室数据</h2> <p class="mt-2 text-slate-600">Billing API CRUD 压测结果 (10K 并发)。</p> </div> <div class="mt-4 md:mt-0 flex space-x-2 bg-slate-100 p-1 rounded-lg"> <button onclick="updateChart('throughput')" id="btn-throughput" class="px-4 py-2 text-sm font-medium rounded-md bg-white text-indigo-600 shadow-sm transition-all">吞吐量 (RPS)</button> <button onclick="updateChart('latency')" id="btn-latency" class="px-4 py-2 text-sm font-medium rounded-md text-slate-600 hover:text-indigo-600 transition-all">P99 延迟</button> <button onclick="updateChart('memory')" id="btn-memory" class="px-4 py-2 text-sm font-medium rounded-md text-slate-600 hover:text-indigo-600 transition-all">内存占用</button> </div> </div> <div class="bg-white rounded-xl shadow-lg border border-slate-200 p-6"> <!-- Main Bar Chart --> <div class="chart-container mb-8"> <canvas id="performanceChart"></canvas> </div> <!-- Connection Stability Line Chart --> <div class="mt-12 border-t border-slate-100 pt-8"> <h3 class="text-lg font-bold text-slate-800 mb-2">连接池稳定性 (模拟突发流量 50K req/s)</h3> <p class="text-sm text-slate-500 mb-6">Axum + SQLx 在高负载下保持连接稳定,而 Go 方案容易出现 Thrashing(抖动)。</p> <div class="chart-container" style="height: 300px;"> <canvas id="connectionChart"></canvas> </div> </div> </div> <!-- Key Stat Cards --> <div class="grid grid-cols-1 md:grid-cols-3 gap-6 mt-8"> <div class="bg-indigo-50 p-4 rounded-lg border border-indigo-100 text-center"> <div class="text-3xl font-bold text-indigo-700">3x</div> <div class="text-sm text-indigo-900 font-medium">吞吐量提升</div> <div class="text-xs text-indigo-500 mt-1">Rust vs Go</div> </div> <div class="bg-indigo-50 p-4 rounded-lg border border-indigo-100 text-center"> <div class="text-3xl font-bold text-indigo-700">-68%</div> <div class="text-sm text-indigo-900 font-medium">P99 延迟降低</div> <div class="text-xs text-indigo-500 mt-1">0.6ms vs 1.9ms</div> </div> <div class="bg-indigo-50 p-4 rounded-lg border border-indigo-100 text-center"> <div class="text-3xl font-bold text-indigo-700">Stable</div> <div class="text-sm text-indigo-900 font-medium">连接池状态</div> <div class="text-xs text-indigo-500 mt-1">无 Thrashing</div> </div> </div> </section> <!-- 4. Architecture Blueprint --> <section id="architecture" class="scroll-mt-24"> <div class="mb-8"> <h2 class="text-2xl font-bold text-slate-900">Stripe 的真实生产栈</h2> <p class="mt-2 text-slate-600">点击下方组件查看技术细节。</p> </div> <div class="bg-white p-8 rounded-xl shadow border border-slate-200"> <div class="flex flex-col items-center space-y-4 max-w-2xl mx-auto"> <!-- Layer 1: Routing --> <div onclick="showDetail('axum')" class="w-full p-4 bg-indigo-600 text-white rounded-lg shadow-md cursor-pointer arch-block text-center relative group"> <div class="font-bold text-lg">Axum Routes</div> <div class="text-xs opacity-80">/invoices, /customers</div> <div class="absolute inset-y-0 right-4 flex items-center text-white/50 group-hover:text-white"> <span class="text-xl">👉</span> </div> </div> <!-- Arrow --> <div class="text-slate-300 text-xl">↓</div> <!-- Layer 2: Middleware --> <div onclick="showDetail('tower')" class="w-full p-4 bg-slate-800 text-white rounded-lg shadow-md cursor-pointer arch-block text-center relative group"> <div class="font-bold text-lg">Tower Middleware</div> <div class="text-xs opacity-80">Auth • Rate Limit • Tracing</div> <div class="absolute inset-y-0 right-4 flex items-center text-white/50 group-hover:text-white"> <span class="text-xl">👉</span> </div> </div> <!-- Arrow --> <div class="text-slate-300 text-xl">↓</div> <!-- Layer 3: Data Access --> <div onclick="showDetail('sqlx')" class="w-full p-4 bg-sky-600 text-white rounded-lg shadow-md cursor-pointer arch-block text-center relative group"> <div class="font-bold text-lg">SQLx (Async)</div> <div class="text-xs opacity-80">Prepared Statements • Connection Pooling</div> <div class="absolute inset-y-0 right-4 flex items-center text-white/50 group-hover:text-white"> <span class="text-xl">👉</span> </div> </div> <!-- Arrow --> <div class="text-slate-300 text-xl">↓</div> <!-- Layer 4: DB --> <div onclick="showDetail('postgres')" class="w-full p-4 bg-slate-100 text-slate-700 border-2 border-slate-300 rounded-lg cursor-pointer arch-block text-center relative group"> <div class="font-bold text-lg">Postgres + JSONB</div> <div class="text-xs text-slate-500">Read Replicas • PgBouncer</div> <div class="absolute inset-y-0 right-4 flex items-center text-slate-400 group-hover:text-slate-600"> <span class="text-xl">👉</span> </div> </div> </div> <!-- Detail Panel (Dynamic Content) --> <div id="arch-detail" class="mt-8 p-6 bg-slate-50 rounded-lg border border-slate-200 min-h-[120px]"> <h4 class="font-bold text-indigo-700 mb-2" id="detail-title">选择上方组件查看详情</h4> <p class="text-slate-600 text-sm leading-relaxed" id="detail-desc"> 探索 Axum + SQLx 如何协同工作以实现高性能 Billing 系统。 </p> </div> </div> </section> <!-- 5. Roadmap --> <section id="roadmap" class="scroll-mt-24"> <h2 class="text-2xl font-bold text-slate-900 mb-8">60 天生产迁移路线图</h2> <div class="relative border-l-2 border-indigo-200 ml-4 space-y-12"> <!-- Phase 1 --> <div class="relative pl-8"> <div class="absolute -left-[9px] top-0 w-4 h-4 rounded-full bg-indigo-600 ring-4 ring-indigo-100"></div> <h3 class="font-bold text-lg text-slate-900">第 1–2 周:SQLx Async 基础</h3> <ul class="mt-2 text-slate-600 space-y-1 list-disc list-inside"> <li>实现 Async Prepared Statements</li> <li>配置 Pooled Transaction</li> <li>理解 Postgres 行为而非死磕 Rust 语法</li> </ul> </div> <!-- Phase 2 --> <div class="relative pl-8"> <div class="absolute -left-[9px] top-0 w-4 h-4 rounded-full bg-indigo-400 ring-4 ring-indigo-50"></div> <h3 class="font-bold text-lg text-slate-900">第 3–4 周:Axum CRUD</h3> <ul class="mt-2 text-slate-600 space-y-1 list-disc list-inside"> <li>构建 Invoices / Customers API</li> <li>集成 Tower Middleware (Auth, Rate Limit)</li> </ul> </div> <!-- Phase 3 --> <div class="relative pl-8"> <div class="absolute -left-[9px] top-0 w-4 h-4 rounded-full bg-indigo-400 ring-4 ring-indigo-50"></div> <h3 class="font-bold text-lg text-slate-900">第 5–6 周:Schema 演进策略</h3> <ul class="mt-2 text-slate-600 space-y-1 list-disc list-inside"> <li>实施 JSONB Metadata 扩展</li> <li>使用 Generated Columns 优化查询</li> <li>实现零停机 Migration (无 Regenerate)</li> </ul> </div> <!-- Phase 4 --> <div class="relative pl-8"> <div class="absolute -left-[9px] top-0 w-4 h-4 rounded-full bg-green-500 ring-4 ring-green-100"></div> <h3 class="font-bold text-lg text-slate-900">第 7–8 周:压测与上线</h3> <ul class="mt-2 text-slate-600 space-y-1 list-disc list-inside"> <li>使用 wrk2 进行 1M+ RPS 压测</li> <li>对比旧系统 (Fiber + sqlc)</li> <li><strong>毕业项目:</strong> 在 Fly.io 部署 Stripe 风格 Billing API</li> </ul> </div> </div> </section> <!-- Conclusion --> <footer class="bg-slate-900 text-slate-300 py-12 px-4 rounded-t-3xl mt-12"> <div class="max-w-4xl mx-auto text-center"> <h2 class="text-2xl font-bold text-white mb-4">为什么 Axum + SQLx 工程师值 $350K?</h2> <p class="mb-8 text-lg opacity-90"> 这不是关于语法能力,而是关于<span class="text-indigo-400 font-bold">避免真实生产事故</span>的能力。<br> 市场永远愿意为那些能防止灾难发生的人买单。 </p> <div class="inline-block bg-slate-800 rounded-lg p-6 border border-slate-700 text-left"> <p class="font-mono text-sm text-green-400 mb-2">// 简历亮点</p> <ul class="list-disc list-inside font-mono text-sm space-y-2"> <li>Axum + SQLx Billing API, 1.8M RPS, p99 < 1ms</li> <li>sqlc → SQLx Migration: Mem 4.2GB → 1.6GB, 3x Throughput</li> </ul> </div> <div class="mt-12 text-sm text-slate-500"> Based on original report by Dagger (2026) </div> </div> </footer> </main> <script> // Navigation Logic function scrollToSection(id) { const element = document.getElementById(id); if (element) { element.scrollIntoView({ behavior: 'smooth' }); // Update active state visuals document.querySelectorAll('.nav-item').forEach(btn => { btn.classList.remove('nav-active', 'text-indigo-700'); btn.classList.add('text-slate-500'); }); event.currentTarget.classList.add('nav-active', 'text-indigo-700'); event.currentTarget.classList.remove('text-slate-500'); } } // Architecture Detail Data const archDetails = { 'axum': { title: 'Axum Web Framework', desc: 'Rust 生态中最符合人体工程学的 Web 框架。它的路由处理非常干净,完美支持异步 I/O,是高并发请求的第一道防线。在 Stripe 架构中,负责解析请求并将任务分发给后续层级。' }, 'tower': { title: 'Tower Middleware', desc: 'Axum 基于 Tower 构建。这一层处理通用的服务逻辑:身份验证 (Auth)、速率限制 (Rate-limit) 和分布式追踪 (Tracing)。它的模块化设计意味着业务逻辑不需要处理这些杂音。' }, 'sqlx': { title: 'SQLx (The Hero)', desc: '核心组件。不同于 ORM,它直接使用 SQL。关键在于 <strong>Async Prepared Statements</strong>:它在编译期检查 SQL 有效性,在运行时缓存执行计划。这避免了每次请求都重新解析 SQL,从而极大降低了数据库 CPU 负荷。' }, 'postgres': { title: 'Postgres + JSONB', desc: '数据持久层。Stripe 广泛使用 JSONB 来存储灵活的 metadata,配合 Generated Columns 提取关键字段建立索引。这种组合允许 Schema 随业务快速演进,而无需频繁进行锁表级别的 Migrations。' } }; function showDetail(key) { const panel = document.getElementById('arch-detail'); const title = document.getElementById('detail-title'); const desc = document.getElementById('detail-desc'); // Simple fade effect panel.style.opacity = '0.5'; setTimeout(() => { title.innerHTML = archDetails[key].title; desc.innerHTML = archDetails[key].desc; panel.style.opacity = '1'; }, 150); } // Chart.js Data and Config const perfCtx = document.getElementById('performanceChart').getContext('2d'); const connCtx = document.getElementById('connectionChart').getContext('2d'); // Data Sets for Bar Chart const chartData = { throughput: { label: 'Requests Per Second (RPS)', data: [1800000, 620000, 380000], backgroundColor: ['#4f46e5', '#94a3b8', '#cbd5e1'], // Highlight Axum yLabel: 'RPS' }, latency: { label: 'P99 Latency (ms) - Lower is Better', data: [0.6, 1.9, 3.1], backgroundColor: ['#4f46e5', '#94a3b8', '#cbd5e1'], yLabel: 'Time (ms)' }, memory: { label: 'Memory Usage (GB) - Lower is Better', data: [1.6, 4.2, 5.8], backgroundColor: ['#4f46e5', '#94a3b8', '#cbd5e1'], yLabel: 'GB' } }; let currentChartInstance = null; function initMainChart(type) { if (currentChartInstance) { currentChartInstance.destroy(); } const config = chartData[type]; currentChartInstance = new Chart(perfCtx, { type: 'bar', data: { labels: ['Axum + SQLx (Rust)', 'Fiber + sqlc (Go)', 'NestJS (Node)'], datasets: [{ label: config.label, data: config.data, backgroundColor: config.backgroundColor, borderRadius: 6, barPercentage: 0.6 }] }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { display: false }, tooltip: { callbacks: { label: function(context) { return `${context.raw} ${config.yLabel}`; } } } }, scales: { y: { beginAtZero: true, title: { display: true, text: config.yLabel }, grid: { color: '#f1f5f9' } }, x: { grid: { display: false } } } } }); // Update Button Styles ['throughput', 'latency', 'memory'].forEach(key => { const btn = document.getElementById(`btn-${key}`); if (key === type) { btn.className = "px-4 py-2 text-sm font-medium rounded-md bg-white text-indigo-600 shadow-sm transition-all border border-indigo-100"; } else { btn.className = "px-4 py-2 text-sm font-medium rounded-md text-slate-600 hover:text-indigo-600 transition-all"; } }); } function updateChart(type) { initMainChart(type); } // Initialize Connection Stability Chart (Line) function initConnectionChart() { // Simulated data over time const timePoints = Array.from({length: 20}, (_, i) => i); // Rust: Stable connections const rustData = timePoints.map(() => 4200 + Math.random() * 100); // Go: Thrashing (spikes and drops) const goData = timePoints.map(i => { if (i > 5 && i < 15) return 2100 + Math.random() * 2500; // Thrashing phase return 2100 + Math.random() * 200; }); new Chart(connCtx, { type: 'line', data: { labels: timePoints.map(t => `t+${t}s`), datasets: [ { label: 'Axum + SQLx (Connections)', data: rustData, borderColor: '#4f46e5', backgroundColor: 'rgba(79, 70, 229, 0.1)', borderWidth: 2, tension: 0.4, fill: true }, { label: 'Fiber + sqlc (Connections)', data: goData, borderColor: '#ef4444', // Red for danger borderWidth: 2, borderDash: [5, 5], tension: 0.1, fill: false } ] }, options: { responsive: true, maintainAspectRatio: false, plugins: { tooltip: { mode: 'index', intersect: false, } }, scales: { y: { beginAtZero: true, title: { display: true, text: 'Active Connections' }, grid: { color: '#f1f5f9' } }, x: { display: false } } } }); } // Initialize on Load document.addEventListener('DOMContentLoaded', () => { initMainChart('throughput'); initConnectionChart(); }); </script> </body> </html>

讨论回复

0 条回复

还没有人回复,快来发表你的看法吧!