疑问:webman是基于workerman的框架,mysql既然是阻塞的,如何做到高并发呢?

RayInHeart

webman是基于workerman的框架,mysql既然是阻塞的,如何做到高并发呢?

根据官方手册,workerman是多进程架构,各个工作进程处理请求,而mysql是阻塞操作,也就是说要遇到耗时的数据库操作是要等待的。那么我不能理解的是,既然这里出现阻塞,岂不是拖累了框架的性能嘛。workerman每个进程都是使用epoll的非阻塞运行方式,那我理解应该是对http请求用这个方式处理,也就是事件机制,那mysql在这里到底会不会拖累这个结果呢,比如一个http请求需要等mysql的数据结果,那个这个是不是等结果出来再响应,等待的时间继续下一个请求?这么理解对吗?那么问题来了,如果出现一个超长时间阻塞的case(在真实的公网环境下一定有概率发生,DNS查询卡住、网络请求超时等),那么这个进程岂不是被阻塞了嘛,那是不是就要靠其他进程来处理更多请求,那不是要开好多进程。换言之,单个 IO 等待过长是否影响当前一个请求所在的进程,其他请求是可以在该进程继续向下执行还是由其他进程执行?遇到这种短时间多个复杂mysql查询的请求,这种情况webman是如何优化的?

谢谢!

2650 9 5
9个回答

liziyu

那么问题来了,如果出现一个超长时间阻塞的case(在真实的公网环境下一定有概率发生,DNS查询卡住、网络请求超时等),那么这个进程岂不是被阻塞了嘛。

大佬tw**e吗?^_^

  • nitron 2022-12-20

    哈哈哈,要素察觉

  • RayInHeart 2022-12-21

    我不是tw**e。这句话是我和同事聊天的时候他发给我的,我觉得描述的比较精炼,直接copy了~看来这句话是有出处的...

  • 张若初 2022-12-22

    等PHP8的协程吧

nitron

等待mysql结果时当前进程无法处理下一个请求,每个进程只能同时处理一个

单个 IO 等待过长是否影响当前一个请求所在的进程,其他请求是可以在该进程继续向下执行还是由其他进程执行

由其他进程执行或者在当前进程排队

遇到这种短时间多个复杂mysql查询的请求,这种情况webman是如何优化的?

优化sql

  • zgh419566 2022-12-21

    方法1:将请求发给其他专门的程序去处理;
    方法2:使用workerman+swoole协程方式实现

  • RayInHeart 2022-12-21

    workerman也可以和swoole并存吗,厉害的

  • RayInHeart 2022-12-21

    我有点不解的是,每个工作进程都是epoll非阻塞模型,为什么遇到mysql查询就退化成阻塞了呢,如果是这样,岂不是比FPM的运行模式的优势不就就只多了一个常驻内存嘛?(当然workerman还可以用于网络编程,应用领域更广)

  • zgh419566 2022-12-26

    可以的 ,你试一下
    <?php
    //*****//
    Worker::$eventLoopClass = 'Workerman\Events\Swoole';
    Co::set(['hook_flags' => SWOOLE_HOOK_SLEEP]);
    Swoole\Coroutine::set(['enable_deadlock_check' => false]);

  • 王巨根 2023-09-10

    对啊,有没有大佬来回答一下,webman和php-fpm的区别到底是啥啊?如果webman都是阻塞的了,那不就只比php-fpm多了个常驻内存吗?上面的兄弟也提到了这点

  • happy321 2023-09-11

    https://www.techempower.com/benchmarks/#section=data-r21&hw=ph&test=query
    PHP排名第一的框架,比gin还强,把swoole远远甩在后面,看似只有常驻内存,其实是常驻内存的一系列适配~
    php的原生协程已经发布了,也渐渐集成进来了

    现在PHP已经很完美了 只是缺一个好用的源码加密 大家可以多交流下 推荐下 https://www.workerman.net/a/1561

  • heguangyu5 2023-09-11

    感谢 happy321 推荐

    BPC确实可以100%保护源码,经过两层转译(PHP->Scheme->C),在C源码层面上想看代码逻辑都是很困难的,更别提二进制逆向回汇编那一层了.

    另外编译后项目的目录和文件名全都md5了,项目结构也能保护.

    再有就是强有力的license机制,通过随机插入足够多的license检查,让授权破解费时费力.

    但是目前BPC还没怎么做编译优化,所以性能远不如PHP8,我们自己的项目测试来看基本能和PHP7.2持平.

    BPC目前已经成功编译了workerman 4.1 和 GatewayWorker 3.x,并在生产环境正式使用,完全没问题,大家也可以在 https://bpc.dev 上尝试在线编译 workerman 和 GatewayWorker 的项目.

    但鉴于我们自己没有webman相关的项目,所以还没有尝试编译webman.

    如果有网友愿意拿出点时间编译一下webman,可以联系我,我可以提供协助.编译主要分两部分:

    一是调整webman代码以适应编译的语义(比如通过scandir来获取php文件列表显然需要调整,因为编译后都在二进制里,没有dir的概念).
    二是测试编译后的webman各项功能运行正确无误.

MarkGo

个人见解:
1、mysql是阻塞操作,也就是说要遇到耗时的数据库操作是要等待的。
就算使用协程方式,其实也是堵塞,mysql只要发生堵塞,后续基本越来越塞,特别是加锁的情况下,必须等待上一个解锁后才能开始下一个。这场景是否协程意义不大。
单纯慢查询不涉及锁的情况下,协程的优点会提现出来,但最终还要看数据库IO,比方一个3S的慢查,可能触发了全表查询,此时如果数据库IO已经100%了,后续再多查询都快不了去哪里,针对这种情况webman的方法是多开进程。

2、如果出现一个超长时间阻塞的case(在真实的公网环境下一定有概率发生,DNS查询卡住、网络请求超时等)
其实同上,协程并不能减少以上case发生频率,只是能加大吞吐。
如果通过协程方式,开一个进程,可能就能解决了单进程阻塞问题;
而webman的话只能通过多进程方式,具体多到多少就要看平均请求量,一般这种涉及网络查询的,最好加个超时。

  • 暂无评论
happy321

https://revolt.run/ php的协程库已经发正式版了,等老大集成进去了就可以用了

什么是Revolt?
Revolt是一个用于并发的PHP应用程序的坚硬的事件循环。通常的PHP应用程序的大部分时间是在等待I/O。虽然PHP是单线程的,但合作多任务可以通过利用等待时间做不同的事情来实现并发。

PHP的传统同步执行流程很容易理解。一次做一件事。如果你查询一个数据库,你发送查询并等待数据库服务器的响应。一旦得到响应,你就可以开始做下一件事。

Amp、ReactPHP和其他库在PHP中提供合作式多任务已经有很长一段时间了。然而,它们的事件驱动性质与许多现有的接口不兼容,需要一个不同的思维模型。PHP 8.1内置了Fibers,它提供了合作多线程。调用可以是异步的,没有承诺或回调,同时仍然允许非阻塞的I/O。

每个使用合作多线程的应用程序都需要一个单一的调度器(也叫事件循环),这个包提供了这个调度器。Revolt是结合Amp和ReactPHP的事件循环实现的多年经验的结果。然而,它并不是一个完整的编写并发PHP应用程序的框架,而只是提供了作为一个共同基础的必要条件。不同的(强烈)意见的库可以建立在它上面,Amp和ReactPHP都将继续共存。

  • 暂无评论
深林孤鹰

workerman差个协程就无敌了~
至于数据库瓶颈,只能优化sql语句、加各种cache、读写分离、分布式数据库来缓解。

  • 暂无评论
tanhongbin

你这种情况,啥玩意啥语言都是白费的,mysql出现这个问题意味着cpu飙升,并发几十个就会100%,后续的处理基本都瘫痪

  • 暂无评论
zgh419566
  • 暂无评论
luohonen

mysql在哪都是阻塞的,mysql性能的问题谁也不能决定它,webman做的只是发挥它最大的作用而已

  • 暂无评论
liudada

webman 解决了 fpm 并发数量不高问题 不是mysql 问题呀,你mysql 卡死 cpu 也就百分百 啥语言也解决不了呀!

  • 暂无评论
年代过于久远,无法发表回答
🔝