hyperf / hyperf

🚀 A coroutine framework that focuses on hyperspeed and flexibility. Building microservice or middleware with ease.

Home Page:https://www.hyperf.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

数据库连接数过多

crytjy opened this issue · comments

开启5个数据库, 每个库 min_connections => 10, max_connections => 100
使用http服务时,没有问题,
但是使用nats监听时, 过一会就会出现 Too many connections

<?php

declare(strict_types=1);

namespace App\Nats\Consumer;

use App\Controller\RpcController;
use Hyperf\Nats\AbstractConsumer;
use Hyperf\Nats\Annotation\Consumer;
use Hyperf\Nats\Message;
use Psr\Container\ContainerInterface;

/**
 * @Consumer(queue="WsREQ", name="MsgConsumer", nums=2)
 */
class MsgConsumer extends AbstractConsumer
{

    public function __construct(ContainerInterface $container)
    {
        parent::__construct($container);

        $this->setSubject('WsREQ-'  . env('NATS_FLAG'));
    }

    public function consume(Message $payload)
    {
        go(function () use ($payload) {
            di()->get(RpcController::class)->dispatch($payload->getBody());
        });

        return true;
    }
}

Hyperf的不同的Worker是用的不同的链接池。你的实际链接池上限是你的[节点数Worker配置数max_connections],确认一下你得出来的是多少。其次看你的数据库连接池使用方法,又没有做release操作。最后看你的mysql设置,idle_timeout时间是多少。

我认为是因为开启了子协程 并且没有限制并发的原因导致的。

go(function () use ($payload) {
    di()->get(RpcController::class)->dispatch($payload->getBody());
});

有两个思路

  1. MsgConsumer 开多点num 比如10个,同时消费逻辑不开子协程
  2. 利用 Hyperf\Coroutine\Concurrent 控制每个消费者最大并行数量

Hyperf的不同的Worker是用的不同的链接池。你的实际链接池上限是你的[节点数_Worker配置数_max_connections],确认一下你得出来的是多少。其次看你的数据库连接池使用方法,又没有做release操作。最后看你的mysql设置,idle_timeout时间是多少。

节点数Worker配置数max_connections = 10000, 数据库链接用的是官方提供的组件,还需要自己操作release?

我认为是因为开启了子协程 并且没有限制并发的原因导致的。

go(function () use ($payload) {
    di()->get(RpcController::class)->dispatch($payload->getBody());
});

有两个思路

  1. MsgConsumer 开多点num 比如10个,同时消费逻辑不开子协程
  2. 利用 Hyperf\Coroutine\Concurrent 控制每个消费者最大并行数量

开启10个我试过, 但并没有关闭子协程, 有写代码是有好几个子协程的.

Hyperf的不同的Worker是用的不同的链接池。你的实际链接池上限是你的[节点数_Worker配置数_max_connections],确认一下你得出来的是多少。其次看你的数据库连接池使用方法,又没有做release操作。最后看你的mysql设置,idle_timeout时间是多少。

节点数Worker配置数max_connections = 10000, 数据库链接用的是官方提供的组件,还需要自己操作release?

不是自己操作,意思就是你看着自己接管链接池的get与release,目前3.1版本都是直到当前Coroutine结束才release。你是实际应用最大连接数是 Node ✖️ Workders ✖️ config.database.max_connections 如果大于你数据库设置就会出现 to many connections。

Hyperf的不同的Worker是用的不同的链接池。你的实际链接池上限是你的[节点数_Worker配置数_max_connections],确认一下你得出来的是多少。其次看你的数据库连接池使用方法,又没有做release操作。最后看你的mysql设置,idle_timeout时间是多少。

节点数Worker配置数max_connections = 10000, 数据库链接用的是官方提供的组件,还需要自己操作release?

不是自己操作,意思就是你看着自己接管链接池的get与release,目前3.1版本都是直到当前Coroutine结束才release。你是实际应用最大连接数是 Node ✖️ Workders ✖️ config.database.max_connections 如果大于你数据库设置就会出现 to many connections。

我每个数据可查询都有用上 wait , 根据这个https://chat.swoole.com/#/chat?uuid=04b5aca5-9a55-45a1-8463-999836c49d55 意思是会释放的