<!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"><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 条回复还没有人回复,快来发表你的看法吧!