swoole⾥⾯的全局变量的误区和解决⽅案
swoole⾥⾯的关于全局变量的坑和解决⽅案
⾸先,抛出答案
⾥⾯的全局变量,⽐如:global$a,static,在同⼀个work进程⾥⾯,它是不会在请求结束后⾃动销毁和还原的,特别是你有
做⼀些累加或者修改的操作,如果你不主动销毁复原,这个work的下⼀个请求进来,这些全局变量的值依然会存在,不会初始化。
2.不同work之间的全局变量,是相互隔离的,并不会产⽣影响。
⽂章⽬录
单个work⾥⾯的全局变量
我们举个例⼦来看,为了防⽌每次请求可能分到不同的work⾥⾯,我们设置只启动1个work进程:
<?php
classUr{
static$name=[];
}
$rver=newSwooleHttpServer('127.0.0.1',9500);
$rver->t([
'worker_num'=>1,
'daemonize'=>fal,
]);
$i=1;
$rver->on('Request',function($request,$respon){
global$i;
Ur::$name[]=time();
$respon->end($i++."-------".json_encode(Ur::$name));
});
$rver->start();
服务启动:
然后,我们在终端⾥⾯请求多次看下,请求了23次,看下输出的结果:
$curl127.0.0.1:9500
1-------[1599795836]%
2-------[1599795836,1599795837]%
3-------[1599795836,1599795837,1599795838]%
4-------[1599795836,1599795837,1599795838,1599795839]%
5-------[1599795836,1599795837,1599795838,1599795839,1599795839]%
6-------[1599795836,1599795837,1599795838,1599795839,1599795839,1599795840]%
7-------[1599795836,1599795837,1599795838,1599795839,1599795839,1599795840,1599795841]%
8-------[1599795836,1599795837,1599795838,1599795839,1599795839,1599795840,1599795841,1599795841]%
9-------[1599795836,1599795837,1599795838,1599795839,1599795839,1599795840,1599795841,1599795841,1599795842]%
10-------[1599795836,1599795837,1599795838,1599795839,1599795839,1599795840,1599795841,1599795841,1599795842,1599795843]%
11-------[1599795836,1599795837,1599795838,1599795839,1599795839,1599795840,1599795841,1599795841,1599795842,1599795843,1599795843]
%
12-------[1599795836,1599795837,1599795838,1599795839,1599795839,1599795840,1599795841,1599795841,1599795842,1599795843,1599795843,
1599795844]%
13-------[1599795836,1599795837,1599795838,1599795839,1599795839,1599795840,1599795841,1599795841,1599795842,1599795843,1599795843,
1599795844,1599795845]%
14-------[1599795836,1599795837,1599795838,1599795839,1599795839,1599795840,1599795841,1599795841,1599795842,1599795843,1599795843,
1599795844,1599795845,1599795845]%
15-------[1599795836,1599795837,1599795838,1599795839,1599795839,1599795840,1599795841,1599795841,1599795842,1599795843,1599795843,
1599795844,1599795845,1599795845,1599795846]%
16-------[1599795836,1599795837,1599795838,1599795839,1599795839,1599795840,1599795841,1599795841,1599795842,1599795843,1599795843,
1599795844,1599795845,1599795845,1599795846,1599795847]%
17-------[1599795836,1599795837,1599795838,1599795839,1599795839,1599795840,1599795841,1599795841,1599795842,1599795843,1599795843,
1599795844,1599795845,1599795845,1599795846,1599795847,1599795848]%
18-------[1599795836,1599795837,1599795838,1599795839,1599795839,1599795840,1599795841,1599795841,1599795842,1599795843,1599795843,
1599795844,1599795845,1599795845,1599795846,1599795847,1599795848,1599795850]%
19-------[1599795836,1599795837,1599795838,1599795839,1599795839,1599795840,1599795841,1599795841,1599795842,1599795843,1599795843,
1599795844,1599795845,1599795845,1599795846,1599795847,1599795848,1599795850,1599795853]%
20-------[1599795836,1599795837,1599795838,1599795839,1599795839,1599795840,1599795841,1599795841,1599795842,1599795843,1599795843,
1599795844,1599795845,1599795845,1599795846,1599795847,1599795848,1599795850,1599795853,1599795875]%
21-------[1599795836,1599795837,1599795838,1599795839,1599795839,1599795840,1599795841,1599795841,1599795842,1599795843,1599795843,
1599795844,1599795845,1599795845,1599795846,1599795847,1599795848,1599795850,1599795853,1599795875,1599795876]%
22-------[1599795836,1599795837,1599795838,1599795839,1599795839,1599795840,1599795841,1599795841,1599795842,1599795843,1599795843,
1599795844,1599795845,1599795845,1599795846,1599795847,1599795848,1599795850,1599795853,1599795875,1599795876,1599795892]%
23-------[1599795836,1599795837,1599795838,1599795839,1599795839,1599795840,1599795841,1599795841,1599795842,1599795843,1599795843,
1599795844,1599795845,1599795845,1599795846,1599795847,1599795848,1599795850,1599795853,1599795875,1599795876,1599795892,1599795
893]%
明显的我们可以看出,每次请求完成后,并没有释放和销毁全局,下次请求来的时候,依然会累计使⽤。
这样其实就和传统的PHP⾥⾯的全局变量有很⼤的区别,之前的PHP请求,在⼀次请求⾥⾯,这个全局变量在这次请求的⽣命周期内是起
作⽤的,请求结束,就释放和还原了。下次PHP请求进来,⼜跟新的初始化⼀样。⽽swoole⾥⾯的不同,在同⼀个work⾥⾯,它接受的不
同的request请求,⾥⾯的全局变量不会被释放的,需要开发者⾃⾏处理这些变量和对象的销毁⼯作。
解决⽅案
如果我们代码⾥⾯,有使⽤全局变量做⼀些累加和赋值的⼯作,那就得⼩⼼了,因为swoole⾥⾯的work进程是⾼并发的,是可以同时接受
多个request请求并发⼯作的。可能刚在A请求⾥⾯改了,在B请求⾥⾯⼜被修改了,会造成⼀些莫名其妙的BUG。
解决⽅案有很多种,swoole官⽅也给了我们答案:
1.设置配置⽂件中的max_request的值,表⽰⼀个work最⼤接受的请求数,当超过后,会⾃动重启work,这样,代码⾥⾯的全局变量就
会随之销毁(这样其实解决的是⼤内存溢出的问题,并没有解决抢占变量的逻辑问题)
2.程序内在tcp相关的服务的onClo或设置定时器及时使⽤unt清理变量,回收资源。
多个work之间的全局变量
还是刚才这个例⼦,我们设置work_num=2,启动2个work进程。
<?php
classUr{
static$name=[];
}
$rver=newSwooleHttpServer('127.0.0.1',9500);
$rver->t([
'worker_num'=>2,
'daemonize'=>fal,
]);
$i=1;
$rver->on('Request',function($request,$respon){
global$i;
Ur::$name[]=time();
$respon->end($i++."-------".json_encode(Ur::$name));
});
$rver->start();
为了来试验,每次请求,分别在2个work⾥执⾏的。我们分别⽤终端curl来质询1种请求,⽤浏览器来质询另⼀种请求,这样,curl⾥执⾏
的可能是Awork,浏览器⾥执⾏的可能是Bwork。
终端⾥执⾏curl请求执⾏多次:
$curl127.0.0.1:9500
1-------[1599802937]%
2-------[1599802937,1599802938]%
3-------[1599802937,1599802938,1599802939]%
4-------[1599802937,1599802938,1599802939,1599802939]%
5-------[1599802937,1599802938,1599802939,1599802939,1599802940]%
1-------[1599802972]
3-------[1599802972,1599802972,1599802984]
我们可以看出,2个work进程⾥的全局变量是不受影响的。
我们在curl⾥执⾏⼀下,发现,数据是接着增长的。没受其他work进程的影响。
6-------[1599802937,1599802938,1599802939,1599802939,1599802940,1599803058]%
本文发布于:2022-12-06 09:48:31,感谢您对本站的认可!
本文链接:http://www.wtabcd.cn/fanwen/fan/88/52244.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |