关于Channel Server 做队列后,内存一直增长的问题

zgh419566

问题描述

以前我的业务逻辑一直写在基于workerman的tcp服务端程序里面,如果需要修改业务逻辑,就会导致整个程序需要重启,会导致成百上千的机器TCP需要重连。

自从看了gateway的源码以后,深受里将gateway和business服务分开的启发

因此我也想将tcp服务和业务逻辑分开,于是想到了使用channel做跳转(类似于gateway的注册中心register)

之前我使用了Channel做进程间通信,一直用的事件机制(publish模式),对方使用on进行挂钩回调
但这会带来一个问题:为避免消息复杂,只能给channel的event名称使用进程名字分开,不然所有后端进程都会收到同样的事件通知。

于是想到了使用channel的消息队列模式,即:前端的tcp服务用来做报文解析和加密解密,通过channel将指令传给后端的多台服务器去做业务逻辑处理。

这样的好处是:
1、不同的业务逻辑可以发给不同的后端服务器群处理,用queue名称进行区分;
2、当某台后端挂掉时可以做到不影响业务逻辑,对用户无感;
3、可以实现多台服务器共同监听某个队列,做任务的负载分担。

初期,所有的前端事件,都通过同一个队列往后端扔,后端多个进程也共同监听同一队列,但遇到一个问题:
channel服务器的内存不再像之前那一直保持4M的使用,而是一直在增加

至今没有找到原因,麻烦各位帮解答一下。
此外:我只用channel来做通讯和任务轮询,丢一些数据可以接受。
我确认生产者发的内容均已被消费者消费掉。

----------------------------------------------GLOBAL STATUS----------------------------------------------------
Workerman version:4.0.30 PHP version:7.4.28
start time:2023-04-03 08:45:32 run 0 days 5 hours
load average: 0.16, 0.12, 0.13 event-loop:\Workerman\Events\Event
1 workers 1 processes
worker_name exit_status exit_count
ChannelServer 0 0
----------------------------------------------PROCESS STATUS---------------------------------------------------
pid memory listening worker_name connections send_fail timers total_request qps status
141714 52M frame://0.0.0.0:12206 ChannelServer 98 0 0 11357962 0 [idle]
----------------------------------------------PROCESS STATUS---------------------------------------------------
Summary 52M - - 98 0 0 11357962 0 [Summary]

程序代码或配置

<?php
生产者:
Channel\Client::enqueue($event_name , $report_json_data);

消费者:
Channel\Client::watch($event_name, function($event_str)use(){
        $event_data = json_decode($event_str , true);
});

重现问题的步骤

操作系统环境及workerman/webman等具体版本

CentOS7.9
Workerman version:4.0.30
PHP version:7.4.28

438 1 0
1个回答

zgh419566

再补充问两个问题:
1、否因为有一些数据在内存中,没有被消费,所以导致内存增长?
2、能否将channel设置为没有匹配到消费者自动丢弃?

  • walkor 2023-04-03

    1、如果数据没消费,就会一直占用内存,如果没消费的数据越来越多,占用内存就越来越大
    2、channel生产和消费是其它开发者提交的功能,不确认是否有这个功能

    另外PHP在运行过程中申请的内存不一定会及时交还给系统,而是会留着复用提升性能。例如当处理一个大请求或者从存储中读取大数据后内存会有明显增长,并不一定是内存泄漏

  • zgh419566 2023-04-04

    收到,感谢

    我在channel 1.1.0的基础上对 publish方法增加了参数,在channel Server.php中增加了publishLoop指令类型,这个问题已经解决。

    支持从众多订阅进程中顺序选择一个发送数据,实现类似于rabbitmq那样的轮询投递机制。

    Channel\Client::publish($event_name, $data_arr , true);

年代过于久远,无法发表回答
🔝