You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python/C异步TCP server开发需求:优化MySQL远程写入性能

解决方案:Ubuntu上的异步TCP服务器+MySQL高性能写入实现

针对你遇到的VB.NET TCP服务器配合远程MySQL写入耗时过高的问题,下面分别提供Python和C两种技术栈的异步实现方案,重点解决高并发客户端连接下的数据库写入性能瓶颈。


一、Python方案(快速开发+高并发友好)

Python的asyncio原生支持异步IO,搭配异步MySQL驱动aiomysql可以高效处理1000个客户端的并发请求,同时优化数据库写入性能。

1. 核心实现代码

import asyncio
import aiomysql
import struct

# 数据库配置
DB_CONFIG = {
    'host': 'localhost',  # 替换为你的MySQL服务器地址
    'user': 'your_db_user',
    'password': 'your_db_pwd',
    'db': 'your_target_db',
    'charset': 'utf8mb4',
    'maxsize': 20  # 连接池大小,根据并发量调整
}

# 处理单个客户端连接
async def handle_client(reader: asyncio.StreamReader, writer: asyncio.StreamWriter):
    try:
        # 确保读取完整的160字节数据,避免粘包
        data = await reader.readexactly(160)
        # 解析数据(这里根据你的业务规则自定义解析逻辑)
        # 示例:前8字节为客户端ID(无符号长整型),剩余为业务内容
        client_id = struct.unpack('Q', data[:8])[0]
        content = data[8:].decode('utf-8').strip()

        # 异步写入数据库(使用连接池复用连接)
        async with aiomysql.connect(**DB_CONFIG) as conn:
            async with conn.cursor() as cur:
                # 参数化查询避免SQL注入,同时提升执行效率
                await cur.execute(
                    "INSERT INTO your_table (client_id, content) VALUES (%s, %s)",
                    (client_id, content)
                )
                # 批量写入场景建议累积N条后再commit,减少事务提交开销
                await conn.commit()

        writer.write(b'Success')
        await writer.drain()
    except asyncio.IncompleteReadError:
        print("客户端发送数据不完整,已断开连接")
    except Exception as e:
        print(f"处理请求出错: {str(e)}")
    finally:
        writer.close()
        await writer.wait_closed()

# 启动异步TCP服务器
async def main():
    server = await asyncio.start_server(
        handle_client, '0.0.0.0', 8888  # 监听所有网卡,端口可自定义
    )
    addr = server.sockets[0].getsockname()
    print(f"异步TCP服务器启动,监听地址: {addr}")
    async with server:
        await server.serve_forever()

if __name__ == '__main__':
    asyncio.run(main())

2. 性能优化要点

  • 连接池复用:aiomysql的连接池可以避免每次请求都创建新数据库连接,这是提升写入速度的核心优化点。
  • 批量写入:如果客户端请求是批量到达的,可以缓存100-200条请求后,执行INSERT ... VALUES (...), (...), ...批量插入,大幅减少数据库IO次数。
  • MySQL配置调优:
    • 调整innodb_buffer_pool_size为服务器内存的50%-70%,提升缓存命中率
    • 关闭autocommit,手动控制事务提交时机
    • 将innodb_flush_log_at_trx_commit设为2(牺牲少量持久性换写入性能,根据业务需求选择)
    • 增大innodb_write_io_threads提升写入线程数

二、C方案(极致性能需求)

如果追求极致低延迟和高吞吐量,推荐使用C语言配合Boost.Asio(异步IO框架)和MySQL异步客户端API实现。

1. 核心实现框架(Boost.Asio + MySQL异步写入)

#include <iostream>
#include <memory>
#include <boost/asio.hpp>
#include <mysql/mysql.h>

using boost::asio::ip::tcp;

// 数据库配置
const char* DB_HOST = "localhost";
const char* DB_USER = "your_db_user";
const char* DB_PASS = "your_db_pwd";
const char* DB_NAME = "your_target_db";

// 客户端会话类
class Session : public std::enable_shared_from_this<Session> {
public:
    Session(tcp::socket socket) : socket_(std::move(socket)) {}

    void start() {
        do_read();
    }

private:
    void do_read() {
        auto self(shared_from_this());
        // 异步读取160字节数据
        boost::asio::async_read(socket_, boost::asio::buffer(data_, 160),
            [this, self](boost::system::error_code ec, std::size_t /*length*/) {
                if (!ec) {
                    // 解析数据(自定义业务逻辑)
                    uint64_t client_id = *reinterpret_cast<uint64_t*>(data_);
                    std::string content(data_ + 8, 152);

                    // 异步写入数据库(这里用异步非阻塞API实现真正的异步)
                    async_mysql_insert(client_id, content);
                    do_write();
                } else {
                    std::cerr << "读取数据错误: " << ec.message() << std::endl;
                }
            });
    }

    void async_mysql_insert(uint64_t client_id, const std::string& content) {
        // 初始化MySQL异步连接
        MYSQL* conn = mysql_init(nullptr);
        if (!mysql_real_connect_nonblocking(conn, DB_HOST, DB_USER, DB_PASS, DB_NAME, 3306, nullptr, 0)) {
            std::cerr << "数据库连接失败: " << mysql_error(conn) << std::endl;
            mysql_close(conn);
            return;
        }

        // 使用预处理语句提升性能和安全性
        MYSQL_STMT* stmt = mysql_stmt_init(conn);
        const char* query = "INSERT INTO your_table (client_id, content) VALUES (?, ?)";
        if (mysql_stmt_prepare(stmt, query, strlen(query)) != 0) {
            std::cerr << "预处理语句失败: " << mysql_stmt_error(stmt) << std::endl;
            mysql_stmt_close(stmt);
            mysql_close(conn);
            return;
        }

        MYSQL_BIND params[2];
        memset(params, 0, sizeof(params));
        params[0].buffer_type = MYSQL_TYPE_LONGLONG;
        params[0].buffer = &client_id;
        params[1].buffer_type = MYSQL_TYPE_STRING;
        params[1].buffer = const_cast<char*>(content.c_str());
        params[1].buffer_length = content.length();

        if (mysql_stmt_bind_param(stmt, params) != 0) {
            std::cerr << "绑定参数失败: " << mysql_stmt_error(stmt) << std::endl;
            mysql_stmt_close(stmt);
            mysql_close(conn);
            return;
        }

        // 异步执行插入
        if (mysql_stmt_execute_nonblocking(stmt) != 0) {
            std::cerr << "执行插入失败: " << mysql_stmt_error(stmt) << std::endl;
        }

        mysql_stmt_close(stmt);
        mysql_close(conn);
    }

    void do_write() {
        auto self(shared_from_this());
        boost::asio::async_write(socket_, boost::asio::buffer("Success", 7),
            [this, self](boost::system::error_code ec, std::size_t /*length*/) {
                if (!ec) {
                    socket_.close();
                }
            });
    }

    tcp::socket socket_;
    char data_[160];
};

// TCP服务器类
class Server {
public:
    Server(boost::asio::io_context& io_context, short port)
        : acceptor_(io_context, tcp::endpoint(tcp::v4(), port)) {
        do_accept();
    }

private:
    void do_accept() {
        acceptor_.async_accept(
            [this](boost::system::error_code ec, tcp::socket socket) {
                if (!ec) {
                    std::make_shared<Session>(std::move(socket))->start();
                }
                do_accept();
            });
    }

    tcp::acceptor acceptor_;
};

int main() {
    try {
        boost::asio::io_context io_context;
        Server server(io_context, 8888);
        io_context.run();
    } catch (std::exception& e) {
        std::cerr << "服务器异常: " << e.what() << std::endl;
    }
    return 0;
}

2. 编译与优化

  • 编译命令(需提前安装Boost和MySQL开发库):
    g++ -std=c++17 tcp_server.cpp -o tcp_server -lboost_system -lmysqlclient -pthread
    
  • 性能优化建议:
    • 实现数据库连接池:复用数据库连接,避免频繁建立连接的开销
    • 使用MySQL异步非阻塞API:确保数据库操作不会阻塞IO线程
    • 批量写入:缓存多条请求后批量插入,减少数据库交互次数
    • 操作系统调优:调整TCP参数(如net.core.somaxconn、tcp_tw_reuse)提升并发连接处理能力

通用测试建议

  • 使用wrk或tcpcopy工具模拟1000个并发客户端发送请求,测试服务器吞吐量和写入延迟
  • 开启MySQL慢查询日志,定位写入操作的性能瓶颈
  • 根据业务需求选择方案:Python适合快速迭代,C适合极致性能场景

内容的提问来源于stack exchange,提问作者davidsd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:31:36