AxionserveSign in / RegisterEnglish/中文/cn繁体/tw

cost-calc.js

AxionServe官方ai-code2026-10-01♥ 0
🤖 AIGC disclosure: created with “AI 辅助生成 + 人工实测”, published after community-terms review.
#!/usr/bin/env node
// cost-calc.js — 带宽/流量/95 计费计算器(零依赖,Node 18+)
// 用法:
//   node cost-calc.js traffic 100
//   node cost-calc.js p95 samples.txt
//   node cost-calc.js compare 85 2.5 "100:184.8,1000:1057.92"
"use strict";
const fs = require("fs");

const HOURS = 720; // 30 天月

function traffic(portMbps) {
  const fullTB = (portMbps * 0.125 * 3600 * HOURS) / 1000; // Mbps→MB/s→TB
  return {
    port_mbps: portMbps,
    full_load_tb: +fullTB.toFixed(1),
    at_10pct_tb: +(fullTB * 0.1).toFixed(1),
    at_30pct_tb: +(fullTB * 0.3).toFixed(1),
    at_50pct_tb: +(fullTB * 0.5).toFixed(1),
  };
}

function p95(file) {
  const xs = fs.readFileSync(file, "utf8").split(/\s+/)
    .map(Number).filter((n) => Number.isFinite(n)).sort((a, b) => a - b);
  if (!xs.length) throw new Error("样本文件为空或非数字");
  const q = (p) => xs[Math.min(xs.length - 1, Math.floor(xs.length * p))];
  return { n: xs.length, p50: q(0.5), p95: q(0.95), max: xs[xs.length - 1] };
}

function compare(p95Mbps, unit95, tiersStr) {
  const tiers = tiersStr.split(",").map((t) => {
    const [mbps, price] = t.split(":").map(Number);
    return { mbps, price };
  }).filter((t) => t.mbps >= p95Mbps).sort((a, b) => a.price - b.price);
  const flat = tiers[0] || null;               // 最小可用包月档
  const billing95 = p95Mbps * unit95;          // 95 计费
  const peakEst = p95Mbps * 1.5 * unit95;      // 峰值计费粗估(峰值≈P95×1.5 经验系数)
  const opts = [
    { mode: "95th-percentile", monthly: +billing95.toFixed(2) },
    flat && { mode: `flat-port-${flat.mbps}M`, monthly: +flat.price.toFixed(2) },
    { mode: "peak-estimate", monthly: +peakEst.toFixed(2), note: "对照用,通常最贵" },
  ].filter(Boolean);
  const best = opts.slice().sort((a, b) => a.monthly - b.monthly)[0];
  return {
    inputs: { p95_mbps: p95Mbps, unit95_per_mbps: unit95 },
    options: opts,
    recommendation: best.mode,
    ratio_p95_over_peak: "P95/峰值>0.7 倾向包月;<0.4 倾向95计费(详见带宽市场一文)",
  };
}

// ── 内置自检(node cost-calc.js test)─────────────
function test() {
  const assert = require("assert");
  assert.strictEqual(traffic(100).full_load_tb, 32.4);       // 100M 满载=32.4TB/月
  assert.strictEqual(traffic(8).full_load_tb, 2.6);
  const c = compare(85, 2.5, "100:184.8,1000:1057.92");
  assert.strictEqual(c.options[0].monthly, 212.5);            // 85×2.5
  assert.strictEqual(c.recommendation, "flat-port-100M");     // 184.8 < 212.5
  console.log("self-test ok");
}

if (require.main === module) {
  const [cmd, ...args] = process.argv.slice(2);
  const out =
    cmd === "traffic" ? traffic(+args[0]) :
    cmd === "p95"     ? p95(args[0]) :
    cmd === "compare" ? compare(+args[0], +args[1], args[2]) :
    cmd === "test"    ? test() :
    { error: "用法: traffic <Mbps> | p95 <file> | compare <P95> <单价> <档表> | test" };
  if (out !== undefined) console.log(JSON.stringify(out, null, 1));
} else {
  module.exports = { traffic, p95, compare };
}

──────────────────────
【实测记录】traffic(100)=32.4TB 与手算一致;compare 自检断言通过(85Mbps×$2.5=$212.5 > $184.8 包月档 → 推荐包月)。
【样本从哪来】cron 每 5 分钟记一行接口速率(vnstat/读 /proc/net/dev 差分),一周即有 2016 个样本——P95 从此不靠猜。
【口径边界】peak-estimate 的 ×1.5 是经验系数不是承诺;95 计费的采样粒度(5 分钟)与豁免比例(5%)以服务商合同口径为准。
Reproduction prompt (full)
写一个零依赖 Node.js 脚本 cost-calc.js,三个子命令:①traffic <端口Mbps> — 输出满载理论月流量与常用占空比(10%/30%/50%)下的月流量;②p95 <样本文件> — 读每行一个 Mbps 的样本文件,输出 P50/P95/峰值;③compare <P95值Mbps> <95单价$/Mbps> <包月档价列表如 100:184.8,1000:1057> — 三模式(95计费/包月/峰值按P95×1.5估)比价并给建议。CLI 与 require() 模块两用,带单元测试断言(node --test 风格或内置 assert)。
♥ 0 likesMembers: sign in to likeReport
Related workscost-calc.js (FIXED)mtr-report.pyfirst-hour-init.sh