rust / go / python / php CPU,IO,MYSql压测

结论: Go综合性能最强

实现三种最常用的接口:

/cpu 模拟CPU密集型计算(递归计算斐波那契数列第35项),用于测试计算性能。

/io 模拟IO密集型操作(异步sleep 100ms),用于测试IO性能。

/mysql 实现基本的select查询

用压力测试工具ab 对这两个接口进行请求,即可查看响应时间和性能表现

测试 /cpu 接口
ab -n 100 -c 10 http://127.0.0.1:3000/cpu
测试 /io 接口
ab -n 100 -c 10 http://127.0.0.1:3000/io
  • -n 100 表示总共请求100次
  • -c 10 表示并发10个请求

 

Rust

使用axum框架,代码:

main.rs

// 引入相关依赖
use axum::{Router, routing::get, response::Html, response::IntoResponse, extract::State};
use std::net::SocketAddr;
use std::time::Instant;
use tokio::time::{sleep, Duration};
use std::sync::Arc;
use sqlx::mysql::MySqlPoolOptions;
use sqlx::MySqlPool;
use rand::Rng;
use serde::Serialize;
use md5;
use serde_json;

#[tokio::main]
async fn main() {
    // 创建 MySQL 连接池
    let db_url = "mysql://root:guestR56Y@114.66.52.123:56841/uranmac?charset=utf8mb4";
    let pool = MySqlPoolOptions::new()
        .max_connections(5)
        .connect(db_url)
        .await
        .expect("数据库连接失败");

    let app = Router::new()
        .route("/", get(hello_world))
        .route("/cpu", get(cpu_bound)) // 计算密集型接口
        .route("/io", get(io_bound))
        .route("/mysql", get(mysql_test)) // MySQL查询速度测试接口
        .with_state(Arc::new(pool));

    // 监听地址
    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
    println!("服务已启动: http://{}", addr);

    // 创建 TcpListener
    let listener = tokio::net::TcpListener::bind(addr).await.unwrap();

    // 启动服务
    axum::serve(listener, app).await.unwrap();
}

// 处理函数
async fn hello_world() -> Html<&'static str> {
    Html("<h1>Hello, Axum!</h1>")
}

// 计算密集型处理函数,模拟实际业务逻辑
async fn cpu_bound() -> impl IntoResponse {
    let start = Instant::now();

    // 1. 生成10000条模拟订单数据
    #[derive(Serialize)]
    struct Order {
        order_id: String,
        amount: f64,
        user: String,
    }
    let mut rng = rand::thread_rng();
    let mut orders = Vec::with_capacity(10_000);
    for i in 0..10_000 {
        orders.push(Order {
            order_id: format!("ORD{}", 100_000 + i),
            amount: rng.gen_range(10.0..1000.0),
            user: format!("user_{}", rng.gen_range(1..=1000)),
        });
    }

    // 2. 过滤金额大于100的订单
    let mut filtered: Vec<_> = orders.into_iter().filter(|o| o.amount > 100.0).collect();

    // 3. 按金额降序排序
    filtered.sort_by(|a, b| b.amount.partial_cmp(&a.amount).unwrap());

    // 4. 计算总金额
    let total: f64 = filtered.iter().map(|o| o.amount).sum();

    // 5. 对前10个订单号做md5哈希
    let hashes: Vec<String> = filtered.iter().take(10)
        .map(|o| format!("{:x}", md5::compute(o.order_id.as_bytes())))
        .collect();

    // 6. 序列化部分结果为JSON
    let json_preview = serde_json::to_string(&filtered.iter().take(3).collect::<Vec<_>>()).unwrap_or_default();

    let elapsed = start.elapsed();

    Html(format!(
        "<h2>CPU密集型业务逻辑测试完成</h2>\
        <p>订单总数: 10000</p>\
        <p>过滤后订单数: {}</p>\
        <p>总金额: {:.2}</p>\
        <p>前10订单号哈希: {:?}</p>\
        <p>部分订单示例: {}</p>\
        <p>耗时: {:?}</p>",
        filtered.len(), total, hashes, json_preview, elapsed
    ))
}

// IO密集型处理函数,模拟异步IO操作
async fn io_bound() -> impl IntoResponse {
    let start = Instant::now();
    // 异步sleep 100ms,模拟IO密集型任务
    sleep(Duration::from_millis(100)).await;
    let elapsed = start.elapsed();
    Html(format!(
        "<h2>IO密集型任务完成</h2><p>耗时: {:?}</p>",
        elapsed
    ))
}

// MySQL 查询速度测试接口
async fn mysql_test(State(pool): State<Arc<MySqlPool>>) -> impl IntoResponse {
    let start = Instant::now();
    let row = sqlx::query("select company_name from fa_uran_companyinfo where credit_code ='91320114MADW3NT54M'")
        .fetch_optional(&*pool)
        .await;
    let elapsed = start.elapsed();
    match row {
        Ok(Some(_)) => Html(format!("<h2>MySQL查询成功</h2><p>耗时: {:?}</p>", elapsed)),
        Ok(None) => Html(format!("<h2>未查到数据</h2><p>耗时: {:?}</p>", elapsed)),
        Err(e) => Html(format!("<h2>查询出错: {}</h2>", e)),
    }
}

Cargo.toml

[package]
name = "axum-hello"
version = "0.1.0"
edition = "2024"

[dependencies]
axum = "0.8.4"
tokio = { version = "1", features = ["full"] }
sqlx = { version = "0.7", features = ["mysql", "runtime-tokio-rustls"] }
rand = "0.9.1"
serde = { version = "1.0.219", features = ["derive"] }
serde_json = "1.0.140"
md5 = "0.7.0"

运行: cargo run

CPU压测10并发1000次: ab -n 1000 -c 10 http://127.0.0.1:3000/cpu

结果1:每次请求用时 0.12秒, 总用时2.44秒 ,每秒410次请求, 请求失败654

IO压测10并发1000次:ab -n 1000 -c 10 http://127.0.0.1:3000/io

结果2: 每次请求用时 0.104 秒, 总用时11秒 ,每秒90次请求请求失败110

 mysql压测10并发1000次: ab -n 1000 -c 10 http://127.0.0.1:3000/mysql

结果3: 每次请求用时0.13秒, 用时33秒 ,每秒30次请求 请求失败106

 

PYTHON:

from fastapi import FastAPI
from fastapi.responses import HTMLResponse
import time
import asyncio
import aiomysql
import random, json, hashlib
import logging

logging.getLogger("uvicorn.access").disabled = True

app = FastAPI()

@app.get("/", response_class=HTMLResponse)
async def hello_world():
    # 首页,返回简单的 HTML
    return "<h1>Hello, world!</h1>"

@app.get("/cpu", response_class=HTMLResponse)
async def cpu_bound():
    start = time.perf_counter()

    # 1. 生成10000条模拟订单数据
    orders = [
        {
            "order_id": f"ORD{100000 + i}",
            "amount": random.uniform(10, 1000),
            "user": f"user_{random.randint(1, 1000)}"
        }
        for i in range(10000)
    ]

    # 2. 过滤金额大于100的订单
    filtered = [o for o in orders if o["amount"] > 100]

    # 3. 按金额降序排序
    filtered.sort(key=lambda x: x["amount"], reverse=True)

    # 4. 计算总金额
    total = sum(o["amount"] for o in filtered)

    # 5. 对前10个订单号做哈希
    hashes = [hashlib.md5(o["order_id"].encode()).hexdigest() for o in filtered[:10]]

    # 6. 序列化部分结果为JSON
    json_preview = json.dumps(filtered[:3], ensure_ascii=False)

    elapsed = time.perf_counter() - start

    return (
        f"<h2>CPU密集型业务逻辑测试完成</h2>"
        f"<p>订单总数: {len(orders)}</p>"
        f"<p>过滤后订单数: {len(filtered)}</p>"
        f"<p>总金额: {total:.2f}</p>"
        f"<p>前10订单号哈希: {hashes}</p>"
        f"<p>部分订单示例: {json_preview}</p>"
        f"<p>耗时: {elapsed:.6f} 秒</p>"
    )

@app.get("/io", response_class=HTMLResponse)
async def io_bound():
    # 记录开始时间
    start = time.perf_counter()
    # 异步sleep 100ms,模拟IO密集型任务
    await asyncio.sleep(0.1)
    elapsed = time.perf_counter() - start
    # 返回耗时
    return f"<h2>IO密集型任务完成</h2><p>耗时: {elapsed:.6f} 秒</p>"

@app.get("/mysql", response_class=HTMLResponse)
async def mysql_test():
    start = time.perf_counter()
    try:
        conn = await aiomysql.connect(
            host='114.66.52.123',
            port=56841,
            user='root',
            password='guestR56Y',
            db='uranmac',
            charset='utf8mb4',
            autocommit=True
        )
        async with conn.cursor() as cur:
            await cur.execute("select company_name from fa_uran_companyinfo where credit_code ='91320114MADW3NT54M'")
            result = await cur.fetchone()
        await conn.ensure_closed()
        elapsed = time.perf_counter() - start
        if result:
            return f"<h2>MySQL查询成功</h2><p>耗时: {elapsed:.6f} 秒</p>"
        else:
            return f"<h2>未查到数据</h2><p>耗时: {elapsed:.6f} 秒</p>"
    except Exception as e:
        return f"<h2>查询出错: {e}</h2>" 

 

使用fastapi框架:

  运行: uvicorn fastpython:app --host 127.0.0.1 --port 3000

CPU压测10并发10次: ab -n 10 -c 10 http://127.0.0.1:3000/cpu

结果1:每次请求用时0.01秒, 总用时17秒, 每秒58次请求, 请求失败0

IO压测10并发1000次:ab -n 1000 -c 10 http://127.0.0.1:3000/io

结果2: 每次请求用时0.11秒, 用时11秒 ,每秒86次请求, 请求失败0

 mysql压测10并发1000次: ab -n 1000 -c 10 http://127.0.0.1:3000/mysql

结果3: 每次请求用时0.21秒, 用时18秒 ,每秒54次请求, 请求失败0

 

Go语言:

package main

import (
    "context"
    "crypto/md5"
    "database/sql"
    "encoding/json"
    "fmt"
    "sort"
    "time"

    _ "github.com/go-sql-driver/mysql"
    "github.com/gofiber/fiber/v2"
)

func main() {
    app := fiber.New()

    // 首页
    app.Get("/", func(c *fiber.Ctx) error {
        return c.SendString("<h1>Hello, Fiber!</h1>")
    })

    // 计算密集型接口
    app.Get("/cpu", func(c *fiber.Ctx) error {
        start := time.Now()

        // 1. 生成10000条模拟订单数据
        type Order struct {
            OrderID string  `json:"order_id"`
            Amount  float64 `json:"amount"`
            User    string  `json:"user"`
        }
        orders := make([]Order, 0, 10000)
        for i := 0; i < 10000; i++ {
            orders = append(orders, Order{
                OrderID: fmt.Sprintf("ORD%d", 100000+i),
                Amount:  10 + (990 * float64(i%10000) / 9999), // 10~1000均匀分布
                User:    fmt.Sprintf("user_%d", 1+i%1000),
            })
        }

        // 2. 过滤金额大于100的订单
        filtered := make([]Order, 0, len(orders))
        for _, o := range orders {
            if o.Amount > 100 {
                filtered = append(filtered, o)
            }
        }

        // 3. 按金额降序排序
        sort.Slice(filtered, func(i, j int) bool {
            return filtered[i].Amount > filtered[j].Amount
        })

        // 4. 计算总金额
        total := 0.0
        for _, o := range filtered {
            total += o.Amount
        }

        // 5. 对前10个订单号做哈希
        hashes := make([]string, 0, 10)
        for i := 0; i < 10 && i < len(filtered); i++ {
            h := md5Sum(filtered[i].OrderID)
            hashes = append(hashes, h)
        }

        // 6. 序列化部分结果为JSON
        jsonPreview, _ := json.Marshal(filtered[:min(3, len(filtered))])

        elapsed := time.Since(start)

        return c.SendString(fmt.Sprintf(
            "<h2>CPU密集型业务逻辑测试完成</h2>"+
                "<p>订单总数: %d</p>"+
                "<p>过滤后订单数: %d</p>"+
                "<p>总金额: %.2f</p>"+
                "<p>前10订单号哈希: %v</p>"+
                "<p>部分订单示例: %s</p>"+
                "<p>耗时: %v</p>",
            len(orders), len(filtered), total, hashes, string(jsonPreview), elapsed,
        ))
    })

    // IO密集型接口
    app.Get("/io", func(c *fiber.Ctx) error {
        start := time.Now()
        time.Sleep(100 * time.Millisecond)
        elapsed := time.Since(start)
        return c.SendString(fmt.Sprintf("<h2>IO密集型任务完成</h2><p>耗时: %v</p>", elapsed))
    })

    // MySQL查询速度测试接口
    app.Get("/mysql", func(c *fiber.Ctx) error {
        start := time.Now()
        // 数据库连接配置
        dsn := "root:guestR56Y@tcp(114.66.52.123:56841)/uranmac?charset=utf8mb4"
        db, err := sql.Open("mysql", dsn)
        if err != nil {
            return c.SendString(fmt.Sprintf("<h2>数据库连接失败: %v</h2>", err))
        }
        defer db.Close()

        ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
        defer cancel()

        row := db.QueryRowContext(ctx, "select company_name from fa_uran_companyinfo where credit_code ='91320114MADW3NT54M'")
        var dummy interface{}
        err = row.Scan(&dummy)
        elapsed := time.Since(start)
        if err == sql.ErrNoRows {
            return c.SendString(fmt.Sprintf("<h2>未查到数据</h2><p>耗时: %v</p>", elapsed))
        } else if err != nil {
            return c.SendString(fmt.Sprintf("<h2>查询出错: %v</h2>", err))
        }
        return c.SendString(fmt.Sprintf("<h2>MySQL查询成功</h2><p>耗时: %v</p>", elapsed))
    })

    app.Listen(":3000")
}

// 工具函数:md5哈希
func md5Sum(s string) string {
    return fmt.Sprintf("%x", md5.Sum([]byte(s)))
}

// 工具函数:取最小值
func min(a, b int) int {
    if a < b {
        return a
    }
    return b
}

 

 

 go run main.go

CPU压测10并发1000次: ab -n 1000 -c 10 http://127.0.0.1:3000/cpu

结果1:每次请求用时0.002秒, 总用时0.7秒, 每秒1497次请求, 请求失败85

IO压测10并发1000次:ab -n 1000 -c 10 http://127.0.0.1:3000/io

结果2: 每次请求用时0.10秒, 用时10秒 ,每秒98次请求, 请求失败106

 mysql压测10并发1000次: ab -n 1000 -c 10 http://127.0.0.1:3000/mysql

结果3: 每次请求用时0.21秒, 用时21秒 ,每秒47次请求, 请求失败109

 

PHP

<?php
// index.php

// 路由分发
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

if ($path === '/') {
    echo "<h1>Hello, PHP!</h1>";
} elseif ($path === '/cpu') {
    $start = microtime(true);

    // 1. 生成10000条模拟订单数据
    $orders = [];
    for ($i = 0; $i < 10000; $i++) {
        $orders[] = [
            'order_id' => 'ORD' . (100000 + $i),
            'amount' => 10 + (990 * ($i % 10000) / 9999), // 10~1000均匀分布
            'user' => 'user_' . (1 + $i % 1000),
        ];
    }

    // 2. 过滤金额大于100的订单
    $filtered = array_filter($orders, function($o) {
        return $o['amount'] > 100;
    });
    $filtered = array_values($filtered); // 重新索引

    // 3. 按金额降序排序
    usort($filtered, function($a, $b) {
        return $b['amount'] <=> $a['amount'];
    });

    // 4. 计算总金额
    $total = array_sum(array_column($filtered, 'amount'));

    // 5. 对前10个订单号做哈希
    $hashes = [];
    for ($i = 0; $i < 10 && $i < count($filtered); $i++) {
        $hashes[] = md5($filtered[$i]['order_id']);
    }

    // 6. 序列化部分结果为JSON
    $jsonPreview = json_encode(array_slice($filtered, 0, min(3, count($filtered))), JSON_UNESCAPED_UNICODE);

    $elapsed = microtime(true) - $start;

    echo "<h2>CPU密集型业务逻辑测试完成</h2>"
        . "<p>订单总数: " . count($orders) . "</p>"
        . "<p>过滤后订单数: " . count($filtered) . "</p>"
        . "<p>总金额: " . number_format($total, 2) . "</p>"
        . "<p>前10订单号哈希: [" . implode(", ", $hashes) . "]</p>"
        . "<p>部分订单示例: $jsonPreview</p>"
        . "<p>耗时: {$elapsed} 秒</p>";
} elseif ($path === '/io') {
    $start = microtime(true);
    usleep(100000); // 100ms
    $elapsed = microtime(true) - $start;
    echo "<h2>IO密集型任务完成</h2><p>耗时: {$elapsed}s</p>";
} elseif ($path === '/mysql') {
    $start = microtime(true);
    $mysqli = new mysqli("114.66.52.123", "root", "guestR56Y", "uranmac", 56841);
    if ($mysqli->connect_errno) {
        echo "<h2>数据库连接失败: {$mysqli->connect_error}</h2>";
        exit;
    }
    $sql = "select credit_code from fa_uran_companyinfo where credit_code ='91320114MADW3NT54M'";
    $result = $mysqli->query($sql);
    $elapsed = microtime(true) - $start;
    if ($result && $result->num_rows > 0) {
        echo "<h2>MySQL查询成功</h2><p>耗时: {$elapsed}s</p>";
    } elseif ($result) {
        echo "<h2>未查到数据</h2><p>耗时: {$elapsed}s</p>";
    } else {
        echo "<h2>查询出错: {$mysqli->error}</h2>";
    }
    $mysqli->close();
} else {
    http_response_code(404);
    echo "Not Found";
}

// 递归斐波那契
function fibonacci($n)
{
    if ($n === 0)
        return 0;
    if ($n === 1)
        return 1;
    return fibonacci($n - 1) + fibonacci($n - 2);
}

 

 php -S 0.0.0.0:3000

CPU压测10并发10次: ab -n 10 -c 10 http://127.0.0.1:3000/cpu

结果1:每次请求用时0.009秒, 总用时10秒, 每秒100次请求, 请求失败798

IO压测10并发100次:ab -n 1000 -c 10 http://127.0.0.1:3000/io

结果2: 每次请求用时0.10秒, 用时10秒 ,每秒9次请求, 请求失败10

 mysql压测10并发100次: ab -n 1000 -c 10 http://127.0.0.1:3000/mysql

结果3: 每次请求用时0.16秒, 用时13秒 ,每秒7次请求, 请求失败8

 

 

posted @ 2025-05-21 10:18  meetrice  阅读(37)  评论(0)    收藏  举报