解释一下 Workerman 中使用 global 问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
cs5117155
V2EX    PHP

解释一下 Workerman 中使用 global 问题

  •  
  •   cs5117155 2024-05-23 10:04:15 +08:00 2089 次点击
    这是一个创建于 572 天前的主题,其中的信息可能已经有所发展或是发生改变。
    <?php use Workerman\Worker; use Workerman\Connection\TcpConnection; use Workerman\Protocols\Http\Request; require_once __DIR__ . '/vendor/autoload.php'; // 创建一个 Wrker 监听 2345 端口,使用 http 协议通讯 $http_worker = new Worker("http://0.0.0.0:2345"); // 启动 1 个进程对外提供服务 $http_worker->count = 1; $http_worker->OnWorkerStart= function ($worker) { // 将 db 实例存储在全局变量中(也可以存储在某类的静态成员中) global $a; $a=0; }; // 接收到浏览器发送的数据时回复 hello world 给浏览器 $http_worker->OnMessage= function(TcpConnection $connection, Request $request) { global $a; $a++; // 向浏览器发送 hello world $connection->send("hello world---$a"); }; // 运行 worker Worker::runAll(); 

    为何浏览器每次运行不是递增,而是 1,3,5,7,9....这样的

    能否从计算机原理基础解释一下吗,我看 workman 文档说进程间的共享数据,可以用全局变量,或者管道,或者 redis 这样的存储工具,我声明了一个 global,该进程也是只有 1 个,读取$a 的时候,只会从$a 地址读取值,但是值每次都不是递增,实在想不通

    15 条回复    2024-05-23 19:03:39 +08:00
    b821025551b
        1
    b821025551b  
       2024-05-23 10:09:08 +08:00
    $a++ 后面打 log 进文件,看具体怎么执行的。
    sun2920989
        2
    sun2920989  
       2024-05-23 10:10:49 +08:00
    看看浏览器是不是自动多请求了一次图标文件.
    sun2920989
        3
    sun2920989  
       2024-05-23 10:11:12 +08:00
    或者换命令行或 postman 之类的工具再试试.
    cs5117155
        4
    cs5117155  
    OP
       2024-05-23 10:22:23 +08:00
    @sun2920989 如果开了一个进程,确实多请求图标导致。但是如果我开了 4 个进程
    hello world---4 curl http://127.0.0.1:2345
    hello world---1 curl http://127.0.0.1:2345
    hello world---1 curl http://127.0.0.1:2345
    hello world---1 curl http://127.0.0.1:2345
    hello world---1 curl http://127.0.0.1:2345
    hello world---2 curl http://127.0.0.1:2345
    hello world---2 curl http://127.0.0.1:2345
    hello world---2 curl http://127.0.0.1:2345
    hello world---3 curl http://127.0.0.1:2345
    hello world---3 curl http://127.0.0.1:2345
    hello world---2 curl http://127.0.0.1:2345
    hello world---4 curl http://127.0.0.1:2345
    hello world---5 curl http://127.0.0.1:2345
    为何它$a 请求不一样,是因为我请求的时候是无状态,每次请求会从 4 个进程中随机选取一个,然后再进行$a++,所以每次请求的$a ,不一定是上一次请求的进程?
    sundev
        5
    sundev  
       2024-05-23 10:42:09 +08:00   1
    一看就是浏览器多请求的。还有如果多进程,workerman 是没有会话级别负载均衡的,就是从空闲的进程分配一个来处理的。
    sundev
        6
    sundev  
       2024-05-23 10:44:42 +08:00
    你如果的确需要真全局变量的,你可以使用 https://github.com/walkor/GlobalData 来实现,或者用个缓存组件来做。
    javalaw2010
        7
    javalaw2010  
       2024-05-23 10:46:37 +08:00
    @cs5117155 workerman 是多进程的,你用 global 声明,其实只在当前的进程内有效,Worker::runAll()之后,进程就 fork 了,此时你的 global 变量在每个进程里都是独立的。
    cs5117155
        8
    cs5117155  
    OP
       2024-05-23 10:52:36 +08:00
    @javalaw2010 谢谢,这样说,我就明了很多了,有时看文档说,进程间数据不互通,都是独立,需要编程者自已实现互通,总感觉就停留在似懂非懂的状态
    sun2920989
        9
    sun2920989  
       2024-05-23 11:04:39 +08:00
    @cs5117155 进程间的 global 不是互通的.
    cs5117155
        10
    cs5117155  
    OP
       2024-05-23 11:09:17 +08:00
    @sun2920989 那我还想问一个问题,我在 workman 里面使用 Mysql 获取数据,workman 开启 4 个进程,每一个 tcp 请求进来,通过数据库查询 A 用户金额,那么 4 个进程中获取 A 用户金额肯定是不变的吧,数据的变动只依赖数据库有无改动
    sun2920989
        11
    sun2920989  
       2024-05-23 14:15:24 +08:00
    @cs5117155 如果您数据库的值没有变 那么四个进程去查询的结果当然是一样的. 另外请注意四个进程每个要使用一个独立的数据库连接.不要共享数据库连接.
    cs5117155
        12
    cs5117155  
    OP
       2024-05-23 16:46:20 +08:00
    @sun2920989 在 workman 文档 https://www.workerman.net/doc/workerman/components/workerman-mysql.html 。看到在 onWorkerStart 回调中初始化数据库连接,并设置 global $db ,$worker->onMessage 使用$db 的连接查询,Worker::runAll()之后,进程就开始 4 个 fork 了,有 4 个进程,那么这时 global $db 都是 4 个相互独立的数据库连接吧,并没有发生共享数据库连接的情况?
    ivanshaoaz
        13
    ivanshaoaz  
       2024-05-23 18:03:11 +08:00   1
    @cs5117155 #12 我的理解:onWorkerStart 回调函数会在每个 worker 进程启动时执行,这个回调中初始化的任何变量都是这个进程独有的,初始化的 $db 变量对于每个 worker 进程是独立的,不会发生共享。
    cs5117155
        14
    cs5117155  
    OP
       2024-05-23 18:41:28 +08:00
    @ivanshaoaz 感谢。我也是这样认为
    sun2920989
        15
    sun2920989  
       2024-05-23 19:03:39 +08:00
    @cs5117155 是的 您和 13 楼说的完全正确.
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1445 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 16:46 PVG 00:46 LAX 08:46 JFK 11:46
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86