惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Hugging Face - Blog
Hugging Face - Blog
云风的 BLOG
云风的 BLOG
大猫的无限游戏
大猫的无限游戏
M
MIT News - Artificial intelligence
L
LangChain Blog
阮一峰的网络日志
阮一峰的网络日志
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Recent Announcements
Recent Announcements
IT之家
IT之家
Google DeepMind News
Google DeepMind News
罗磊的独立博客
爱范儿
爱范儿
Last Week in AI
Last Week in AI
人人都是产品经理
人人都是产品经理
U
Unit 42
MongoDB | Blog
MongoDB | Blog
S
SegmentFault 最新的问题
B
Blog
博客园 - 叶小钗
月光博客
月光博客
Stack Overflow Blog
Stack Overflow Blog
V
Visual Studio Blog
C
Check Point Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知

希仁之拥

领克900半年使用体验 | 希仁之拥的博客 Ubuntu 26.04 Desktop使用体验 | 希仁之拥的博客 【转载】谈谈不受欢迎的博客技术特征 | 希仁之拥的博客 【转载】ClaudeCode 你想知道的所有秘密,源码深度研究报告 | 希仁之拥的博客 2025年年终总结 | 希仁之拥的博客 集成和使用Openclaw后的思考 | 希仁之拥的博客 我买了领克900 | 希仁之拥的博客 服务器性能优化之io拷贝 | 希仁之拥的博客 Go-Sail导航站上线啦 | 希仁之拥的博客 今年国庆的一些感受 [2025] | 希仁之拥的博客 在Deepin 25上配置forticlient | 希仁之拥的博客 分享一些酷酷的站点 [20250908] | 希仁之拥的博客 Go-Sail发布v3.0.6版本了 | 希仁之拥的博客 我对V2EX发布$V2EX讨论的一些感受 | 希仁之拥的博客 如何让Stripe支持支付宝和微信支付 | 希仁之拥的博客 2025上半年里程碑 | 希仁之拥的博客 GitLab+Drone使用体验 | 希仁之拥的博客 四姑娘山之旅 | 希仁之拥的博客 近来帮同事做性能优化的过程回顾 | 希仁之拥的博客 聊聊接口的返回数据结构 | 希仁之拥的博客 由GORM的Updates语法糖 我把 Go-Sail 的文档站更新了 | 希仁之拥的博客 这就是我为什么讨厌拼多多 | 希仁之拥的博客 元旦快乐~ | 希仁之拥的博客 致敬还在写博客的我们 | 希仁之拥的博客 逐步的把图片资源迁移到星光图床上 | 希仁之拥的博客 帮弟弟配了一台mini主机 | 希仁之拥的博客 国庆的一些碎碎念 | 希仁之拥的博客 就这一刻而言,我觉得科技冷冰冰的。 | 希仁之拥的博客 如何使用acme.sh自动续签证书 | 希仁之拥的博客
php使用mysqlnd扩展进行mysql异步并行查询 | 希仁之拥的博客
希仁之拥 · 2018-06-27 · via 希仁之拥

吃水不忘挖井人,thanks to Eric Don

示例代码如下:

class AnsycQuery
{
    public $connection_timout = 3;

    public function __construct($worlds)
    {
        $this->_batch_connections = ['logdb'=>collect()];
        //初始化连接实例
        foreach ($worlds as $world) {
            if (!$world->status)
            {
                //未启用的world不允许实时查询
                continue;
            }
            $logdb_connection = $world->getLogDBConnection()->getDB();
            $logdb_config = [
                'host' => $logdb_connection->getConfig('host'),
                'port' => $logdb_connection->getConfig('port'),
                'user' => $logdb_connection->getConfig('username'),
                'password' => $logdb_connection->getConfig('password'),
                'dbname' => $logdb_connection->getConfig('database')
            ];
            $retry=0;
            while(++$retry)
            {
                try {
                    $logdb = mysqli_init();
                    $logdb->options(MYSQLI_OPT_CONNECT_TIMEOUT, $this->connection_timout);
                    $logdb->real_connect($logdb_config['host'], $logdb_config['user'], $logdb_config['password'], $logdb_config['dbname'], $logdb_config['port']);
                    $logdb->query("set names utf8");
                    $this->_batch_connections['logdb']->put($world->id,$logdb);
                    break;
                }catch (\Exception $e)
                {
                    if($retry>5)
                    {
                        \App::abort(500,"服务器:".$world->id."的logdb数据库连接超时({$this->connection_timout}秒*5次尝试)");
                    }
                }
            }

        }
        return $this->_batch_connections;
    }

    public function query($from="gamedb", $sql)
    {
        switch ($from)
        {
            case "logdb":
                $connections = $this->_batch_connections['logdb'];
                break;
            default:
                return false;
                break;
        }

        foreach ($connections as $world_id=>$connection)
        {
            $replaced_sql = str_replace('{world_id}', $world_id, $sql);
            //文档地址:http://php.net/manual/zh/mysqli.query.php
            $connection->query($replaced_sql, MYSQLI_ASYNC);
        }

        $processed = 0;
        $ret = collect();
        //开始执行并行查询
        do {
            $links = $errors = $reject = array();
            foreach ($connections as $link) {
                $links[] = $errors[] = $reject[] = $link;
            }
            if (!mysqli_poll($links, $errors, $reject, 1)) {
                continue;
            }
            foreach ($links as $link) {
                if($result = $link->reap_async_query()) {
                    if(is_object($result)){
                        while($row = $result->fetch_object())
                        {
                            $ret->push($row);
                        }
                        mysqli_free_result($result);
                    }else if (false !== $result) {
                        //据文档说,insert, delete之类的,会在这里返回
                        $ret->push($result);
                    } else {
                        throw new \mysqli_sql_exception(mysqli_error($link));
                    }
                }
                $processed++;
            }
        } while ($processed < $connections->count());
        return $ret;
    }
}

注意:并行批量查询,需要服务器的php安装mysqlnd扩展,ubuntu下执行apt-get install php5-mysqlnd,然后执行php5enmod mysqlnd,mysqli也是需要开启的

由于是并行查询,每次返回结果顺序可能都会有差异。