zoukankan      html  css  js  c++  java
  • [问题][已解决] 并发场景下 "mysql: too many connections" 原因

    问题出现是这样的,用node写爬虫, 之前每条数据都是await插入,并且是阻塞的,后来改成了非阻塞,可以并行插入操作,结果一直找不到原因。

    后来在日志中找到了 too many connections,分析如下:

    用nodejs写爬虫的时候,使用了类似这样的函数

    let conn = null;

    try{

      conn = await pool.getConnection();

      await conn.begin()

      let rst = await .conn.query('xxxx',params);

      // 处理rst

      ...

      await conn.commit()

    }catch(e){

      if(conn) await conn.rollback(); 

    }finally{

      if(conn) await conn.release();

    }

    乍一看没有问题,执行爬虫之后,我会调用这段代码把分析过的数据存在数据库里。

    但是由于我是使用非阻塞的形式进行抓取数据的,如下

    emitter.on('url_found', async (url)=>{

      // 请求url地址,获取返回的response body

      let res = await request(url);

      // 处理res

      ...

      // 后面调用上面的第一段代码

    })

    这里会发生一件事,就是可能同时触发了1000个这样的事件,然后一起获取链接,但是还没有释放,然后报错: too many connections

    ============================ 解决方案 ===============================

    改造获取sql连接的函数

    1. 判断当前连接数是否达到最大,如果否,则直接返回连接池内连接,连接数++

    2. 如果上述判断为true,则等待一个promise,将该promise的resolve函数推入等待队列

    3. 当某一个连接release的时候,连接数--

    4. release中调用pool的notifyFirstWaiting方法,每次取出队列第一个resolve并执行,然后该resolve出列

    5. 第二步中的promise的resolve被执行后,则会执行后续代码,此时等待的promise被唤醒,尝试重新获取连接返回

  • 相关阅读:
    nohup 命令的使用
    Linux下完全删除用户
    free命令详解
    Nginx页面不能访问排查思路
    netstat命令详解
    VMware Workstation工具给liunx创建共享磁盘
    yum命令使用小技巧
    Linux 常用命令-- top
    ssh免密访问对端服务
    Java根据IP获取地区(淘宝接口)
  • 原文地址:https://www.cnblogs.com/kazetotori/p/9333465.html
Copyright © 2011-2022 走看看