Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

数据库连接数过多 #6732

Closed
crytjy opened this issue May 7, 2024 · 6 comments
Closed

数据库连接数过多 #6732

crytjy opened this issue May 7, 2024 · 6 comments
Labels
question Further information is requested

Comments

@crytjy
Copy link

crytjy commented May 7, 2024

开启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;
    }
}

@crytjy crytjy added the question Further information is requested label May 7, 2024
@lazychanger
Copy link
Contributor

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

@xuanyanwow
Copy link
Member

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

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

有两个思路

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

@crytjy
Copy link
Author

crytjy commented May 16, 2024

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

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

@crytjy
Copy link
Author

crytjy commented May 16, 2024

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

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

有两个思路

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

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

@lazychanger
Copy link
Contributor

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。

@crytjy
Copy link
Author

crytjy commented May 17, 2024

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 意思是会释放的

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants