首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当集群退出并重新启动时,使用集群和mariaSQL 100%的CPU使用率

当集群退出并重新启动时,使用集群和mariaSQL 100%的CPU使用率
EN

Stack Overflow用户
提问于 2016-06-14 13:43:55
回答 1查看 583关注 0票数 6

在我的Node.JS应用程序上,我使用集群来使用我的多核CPU。我正在使用节点的mariasql库与我的数据库进行通信。由于node-mariasql库不支持池,所以我使用第三方- 通用池来维护连接池。

我已经注意到,当主线程中的连接在未察觉的异常导致一个子集群重新启动后关闭时,我们的CPU使用率就会上升到100%。

每当子集群重新启动时,我将销毁所有MySQL连接。

节点版本- v4.2.2

MariaDB版本- v10.0.15

node-mariasql版本- v0.2.5

可复制代码- https://github.com/bsurendrakumar/node-simplex/

代码段

建立连接池..。

代码语言:javascript
复制
var pool = poolModule.Pool({
  name: 'mariadb',
  create: function(callback) {
    var client = new mSQLClient();
    client.connect(dbConfig);
    client.on('error', function(err) {
      callback(err, null);
    });
    client.on('ready', function() {
      callback(null, client);
    });
  },
  destroy: function(client) {
    if(cluster.isMaster) {
      console.log('Destroying / ending master thread ID -', client.threadId);
    }
    if(isDraining) {
      client.destroy();
    } else {
      client.end();
    }
  },
  max: dbConfig.maxConn,
  min: dbConfig.minConn,
  idleTimeoutMillis: dbConfig.idleTimeout
});

在主线上。

代码语言:javascript
复制
console.log('------------------------------------');
console.log('Master Process ID:', process.pid);
console.log('------------------------------------\n\n');

console.log('Creating an extra DB connection on the master thread.\n\n');
getCountries();

// Create a worker for each CPU
for (var i = 0; i < cpuCount; i += 1) {
  cluster.fork();
}

// Restarting the thread if something exits...
cluster.on('exit', function () {
  cluster.fork();
});

一旦异常发生..。

代码语言:javascript
复制
// Handle uncaught exceptions...
process.on('uncaughtException', function (err) {
  try {
    console.log('\n--------------');
    console.log(err);
    // Stop the HTTP Server
    console.log('\n--------------');
    console.log('Encountered uncaught exception!');
    console.log('Stopping HTTP server ...');
    if(httpServer) {
      httpServer.close();
    }
    console.log('Stopped HTTP server, performing cleanup ...');
    // Call the cleanup function
    cleanUp(function() {
      // Exit!!
      console.log('Cleanup done!');
      restartProcess();
    });
  } catch (e) {
    console.log(e);
    restartProcess();
  }

  function restartProcess() {
    console.log('Restarting process ...');
    process.exit(1);
  }
});

清理功能..。

代码语言:javascript
复制
function cleanUp(cbMain) {
  isDraining = true;
  if(pool.hasOwnProperty('_inUseObjects')
    && Array.isArray(pool._inUseObjects)
    && pool._inUseObjects.length > 0) {
      let inUseObjs = pool._inUseObjects;
      let inUseObjsLen = pool._inUseObjects.length;
    for(let i = 0; i !== inUseObjsLen; ++i) {
      inUseObjs[0].destroy();
      pool.release(inUseObjs[0]);
    }
  }
  pool.drain(function() {
    pool.destroyAllNow(function() {
      return cbMain();
    });
  });
}

池中的最小连接数设置为5。它的所有配置都可以在这里下找到。因此,当服务器启动时,泛型池将启动到MySQL的5个连接,并将它们保存在其池中。

池中的对象的idleTimeout设置为120秒。这意味着,如果池中有超过5个对象(因为5是最小的),并且其中一个对象在过去120秒内没有被使用,那么它将被销毁。

在服务器启动时,我简单地调用我们的国家模型来获取国家列表。这段代码是这里。这将建立到数据库的新连接,因此现在池中将有一个6 SQL连接,其中一个将在120秒后被清除。

以下是一步一步的过程,我相信这个问题与我们使用mariasql图书馆有关-

  • 当服务器启动时,我将进程ID记录到控制台。获取mater进程ID,例如- 20584
  • 使用- ls -l /proc/20584/fd查看进程使用的文件描述符。记下套接字连接。它的输出将类似于- lrwx------ 1 abijeet abijeet 64 Jun 9 19:24 12 -> socket:[2469914] lrwx------ 1 abijeet abijeet 64 Jun 9 19:24 13 -> socket:[2469917] lrwx------ 1 abijeet abijeet 64 Jun 9 19:24 14 -> socket:[2468106] lrwx------ 1 abijeet abijeet 64 Jun 9 19:24 15 -> socket:[2468109] lrwx------ 1 abijeet abijeet 64 Jun 9 19:24 17 -> socket:[2467206] lrwx------ 1 abijeet abijeet 64 Jun 9 19:24 18 -> socket:[2467208] lrwx------ 1 abijeet abijeet 64 Jun 9 19:24 19 -> socket:[2467210] lrwx------ 1 abijeet abijeet 64 Jun 9 19:24 2 -> /dev/tty lrwx------ 1 abijeet abijeet 64 Jun 9 19:24 20 -> socket:[2467212] lrwx------ 1 abijeet abijeet 64 Jun 9 19:24 21 -> socket:[2467214] lrwx------ 1 abijeet abijeet 64 Jun 9 19:24 22 -> socket:[2467306]
  • 复制少量的套接字编号(例如2467212 ),然后运行lsof | grep 2467212。您会注意到,这些都是到MySQL服务器的连接。它的输出应该类似于- node 20584 abijeet 20u IPv4 2467212 0t0 TCP localhost:57092->localhost:mysql (ESTABLISHED) V8 20584 20585 abijeet 20u IPv4 2467212 0t0 TCP localhost:57092->localhost:mysql (ESTABLISHED) V8 20584 20586 abijeet 20u IPv4 2467212 0t0 TCP localhost:57092->localhost:mysql (ESTABLISHED) V8 20584 20587 abijeet 20u IPv4 2467212 0t0 TCP localhost:57092->localhost:mysql (ESTABLISHED) V8 20584 20588 abijeet 20u IPv4 2467212 0t0 TCP localhost:57092->localhost:mysql (ESTABLISHED)
  • 通过转到http://127.0.0.1:3000/api/v1/country/list使服务器崩溃。这将使一个子进程崩溃。每当出现未察觉的异常时,我都会进行一些清理和退出。然后我用另一个程序来代替刚刚被杀的那个。清理工作包括-
代码语言:javascript
复制
- Closing http server
- Closing MySQL connections in generic pool
- Closing winston logger streams.

  • 等待主线程中的MySQL连接关闭。当发生这种情况时,我正在将日志写入控制台- Destroying / ending master thread ID - 4984
  • 检查你的CPU使用情况,你会注意到其中一个CPU的使用率高达100%。
  • 下一轮,strace -o log.txt -eepoll_ctl,epoll_wait -p 20584。注意,您可能需要安装strace。此命令记录由epoll_ctl, epoll_wait进程执行的所有Node.JS系统调用,并将其放入一个名为log.txt的文件中,该文件是当前工作目录。
  • 打开log.txt文件,您将注意到类似于- epoll_wait(5, {{EPOLLIN|EPOLLHUP, {u32=16, u64=16}}}, 1024, 847) = 1 epoll_ctl(5, EPOLL_CTL_DEL, 16, 7ffe441aa850) = -1 EBADF (Bad file descriptor) epoll_wait(5, {{EPOLLIN|EPOLLHUP, {u32=16, u64=16}}}, 1024, 845) = 1 epoll_ctl(5, EPOLL_CTL_DEL, 16, 7ffe441aa850) = -1 EBADF (Bad file descriptor) epoll_wait(5, {{EPOLLIN|EPOLLHUP, {u32=16, u64=16}}}, 1024, 843) = 1 epoll_ctl(5, EPOLL_CTL_DEL, 16, 7ffe441aa850) = -1 EBADF (Bad file descriptor)的日志
  • 这里的文件描述符是16,如果您将其与早期的ls -l /proc/20584/fdlsof | grep 2467212关联起来,您就会意识到这属于刚刚关闭的MySQL连接。

这使我相信,即使在发布到MySQL的连接时,也有一个文件描述符挂在那里,该描述符仍在使用中。我在论坛上发现了很多类似问题的线索-

EN

回答 1

Stack Overflow用户

发布于 2020-01-05 23:26:40

你好,我已经想到了.我的服务器内存不足..。我的数据库里到处都是帖子。那是..。他有很多关于两种破译的信息。(MyISAM & Innodb)在同一个银行.我找到的解决方案是导出这个数据库..。这是备份..。仅通过决定单一编码(Innodb),从零开始创建数据库。并一点一点地执行导入,检查所有表和可能的错误。

我所做的另一个选择是删除旧的,并将其放在另一个数据库中。成为另一个网站的一部分。数据集成将通过两个站点之间的链接..。

发送消息!希望它能帮到你!强烈的拥抱。祝好运!

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37813847

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档