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

Deno 1.40+版本WebWorker执行MySQL查询性能骤降问题排查

问题描述

我正在开发一个需并行执行大量MySQL查询的Web应用,为提升速度与用户体验,采用WebWorker处理查询:主Deno线程将SQL发送至WebWorker,执行后返回结果。在Deno 1.39.4版本前,应用性能极佳,部分查询耗时从数秒降至0.xx秒。但升级至Deno 1.40+(已测试至1.46.x全版本)后,查询速度变得极慢,且在另一台电脑测试也出现相同情况。

主线程代码

connect(): Promise<this> {
    return new Promise(resolve => {
        this.worker = new Worker(import.meta.resolve("./MySQLWorker.ts"), { type: "module" });
        this.worker.addEventListener("message", e => resolve(this), { once: true });
        this.worker.postMessage({ msg: "connect", data: this.settings });
    });
}

query(sql:string, values?:any[]):Promise<any>{
    return new Promise(resolve => {
        const requestId = crypto.randomUUID();
        const listener = (e:any) => {
            const message = e.data;

            if (message.requestId != requestId) return;
            this.worker?.removeEventListener("message", listener);

            resolve(message.data);
        }

        this.worker?.addEventListener("message", listener);
        this.worker?.postMessage({ requestId, msg: "query", data: { sql, values }})
    });
}

WebWorker代码

import { Client } from "https://deno.land/x/mysql@v2.12.1/mod.ts";

const client = new Client();

let iid = 0;

addEventListener("message", async e => {

    const message = e.data;
    switch(message.msg){
        case "connect": {
            await client.connect(message.data);
            postMessage("connected");

            iid = setInterval(() => query("SELECT id FROM users WHERE id = 0"), 60000); // keep connection alive

            break;
        }

        case "disconnect": {
            clearInterval(iid);
            client.close();
            break;
        }

        case "query": {
            const requestId = message.requestId;

            setTimeout(async () => {
                /* Sometimes in production / test under customer infrastructure
                 * the connection is forcibly closed by the remote host. (os error 10054)
                 * That causes the application to crash. So we try to catch this error
                 * and exceute the query again for a maxAttempts number of times before failing
                 * but keeping the application alive anyways
                 */

                const sql = message.data.sql;
                const values = message.data.values;
                let maxAttempts = 5;
                let data = undefined;

                while (data == undefined && maxAttempts-- > 0){
                    data = await query(sql, values);
                    if (data == undefined && maxAttempts > 0) {
                        console.log("DB Connection problem, trying again in 500ms");
                        await pause(500);
                    }
                }
                    
                data = data || [];
                
                postMessage({ requestId, data });
            }, 1)
            break;
        }
    }
});

function pause(millis:number):Promise<void>{
    return new Promise(resolve => setTimeout(resolve, millis));
}

// deno-lint-ignore no-explicit-any
async function query(sql: string, values?:any):Promise<any>{
    try {
        return await client.query(sql, values);
    } catch (err){
        return err.code == "ECONNRESET" ? undefined : []
    }
}
可能的原因分析
  • Worker消息传递机制变更:Deno 1.40+对Worker的结构化克隆算法或消息通道实现做了调整,导致主线程与Worker间的消息序列化/反序列化开销大幅增加。你的架构依赖频繁的postMessage传递SQL和结果,序列化逻辑变慢会直接拖慢查询响应速度。
  • MySQL客户端库兼容性问题:你使用的mysql@v2.12.1未针对Deno 1.40+的新API或运行时变化适配。比如新版本对网络IO调度逻辑做了调整,旧版客户端的连接池、查询执行逻辑无法高效利用新调度机制,引发查询阻塞或延迟升高。
  • 异步任务调度瓶颈:Worker处理query消息时用了setTimeout(async () => {}, 1),Deno旧版本中这只是微任务调度,但新版本事件循环优先级调整后,1ms延迟被放大,大量并行查询下任务排队等待时间累积,整体响应变慢。
  • 单Worker串行处理瓶颈:当前实现是单Worker串行处理所有查询,每个查询的重试逻辑(最多5次、每次间隔500ms)会阻塞后续查询执行。旧版本事件循环调度更高效时问题不明显,新版本调度逻辑变化后,串行处理的瓶颈被放大。
  • 线程模型变化:Deno 1.40+对Worker的线程管理做了调整,比如线程启动开销增加、线程间上下文切换成本变高,Worker与主线程的通信链路效率下降,影响整体性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 16:12:08