Skip to content

Conversation

jingjingxyk
Copy link
Contributor

@jingjingxyk jingjingxyk commented Dec 24, 2023

完善 swoole 扩展静态编译

@crazywhalecc crazywhalecc added wip Work In Process kind/extension Issues related to extensions labels Dec 24, 2023
@jingjingxyk
Copy link
Contributor Author

jingjingxyk commented Dec 27, 2023

@jingjingxyk jingjingxyk reopened this Dec 27, 2023
@crazywhalecc
Copy link
Owner

crazywhalecc commented Dec 27, 2023

目前我的决策还是不把 swoole 当作一个框架,继续作为扩展,因为 static-php-cli 是用于编译 PHP 的,而不是构建框架的。如果要实现框架一样的比较高耦合的项目的话,我更建议将 static-php-cli 作为依赖,然后将所需要的所有东西编译进去,就像 FrankenPHP 和 Laravel Herd。

另外有关协程的问题,我了解过但不参与讨论。我也写过框架,最后发现一切还是要大道至简。

@jingjingxyk
Copy link
Contributor Author

目前我的决策还是不把 swoole 当作一个框架,继续作为扩展,因为 static-php-cli 是用于编译 PHP 的,而不是构建框架的。如果要实现框架一样的比较高耦合的项目的话,我更建议将 static-php-cli 作为依赖,然后将所需要的所有东西编译进去,就像 FrankenPHP 和 Laravel Herd。

另外有关协程的问题,我了解过但不参与讨论。我也写过框架,最后发现一切还是要大道至简。

按你说的办

@crazywhalecc
Copy link
Owner

我搞清楚了,上面的 pdo 是因为你在测试过程中发现缺少头文件导致的,因为必须启用 pdo 扩展才能包含 pdo/pdo.h,才能 Hook pdo_。然后不能启用 pdo_ 的原因是 swoole 的 pdo_driver 和原有的 pdo_driver 不能链接到一起。所以应该是一个依赖 provide 的关系,Swoole 提供了 pdo_* 的扩展内容,启用这些特性时不能启用原来的 pdo_*。

@crazywhalecc
Copy link
Owner

crazywhalecc commented Dec 27, 2023

目前测试了下,如果使用不启用 pdo_pgsql 扩展、启用 Swoole 的 pgsql hook,是没办法正常使用 new PDO('pgsql:host=127.0.0.1;port=5432;dbname=postgres'),执行到这句代码会卡住,而使用 pdo_pgsql 扩展才是正常的(在 macOS 下)。Linux 下是正常的,不知道是哪里出了问题。

  • 使用 Swoole 的 pgsql 支持时,编译的扩展有:zlib, openssl, curl, pgsql, pdo, swoole
  • 使用 pdo_pgsql 时,编译的扩展有:pdo, pgsql, pdo_pgsql

感觉可能是 Swoole 自身或者 postgresql 的老问题,因为我在 macOS 连接的 postgres 数据库是 14,Linux 上是 15,Swoole 都使用的稳定版(5.1.1)。

@jingjingxyk
Copy link
Contributor Author

jingjingxyk commented Dec 28, 2023

似乎主要是 DSN 的写法不同

协程的写法,应该运行在协程运行时中。

启动 pgsql 数据库例子:

version: "3"
services:
    postgresql-server:
        image: postgres:15-alpine
        hostname: "postgresql"
        ports:
            - "5432:5432"
        environment:
            - "POSTGRES_PASSWORD=example"
        
        # 容器内数据目录 /var/lib/postgresql/data
        # auth_user: postgres
        # auth_password: example

swoole 以协程的方式连接 PGSQL 例子

文档: https://wiki.swoole.com/#/coroutine_client/postgresql

<?php

declare(strict_types=1);

use Swoole\Coroutine\PostgreSQL;

use function Swoole\Coroutine\run;

run(function () {
    $pg = new PostgreSQL();
    //pdo_pgsql DSN 写法:  'pgsql:host=127.0.0.1;port=5432;dbname=postgres'
    $conn = $pg->connect('host=127.0.0.1 port=5432 dbname=postgres user=postgres password=example');
    if (!$conn) {
        var_dump($pg->error);
        return;
    }
    // $stmt = $pg->query('select * from pg_tables;');
    $stmt = $pg->query('SELECT version();');
    $stmt = $pg->query('SHOW search_path;');
    $stmt = $pg->query('select now();');
    $stmt = $pg->query('select * from information_schema.columns ');
    $stmt = $pg->query('SELECT * from  pg_stat_activity;');
    // $stmt = $pg->query('SELECT * FROM test;');
    $arr = $stmt->fetchAll();
    var_dump($arr);
});

@jingjingxyk
Copy link
Contributor Author

jingjingxyk commented Dec 28, 2023

@jingjingxyk
Copy link
Contributor Author

jingjingxyk commented Dec 28, 2023

对于macos 下载构建好的包,这里下载的构建软件包 https://github.com/jingjingxyk/static-php-cli/actions/runs/7344504695

# Mac安装应用“提示文件已损坏”或“来自身份不明开发者”解决方法
sudo xattr -d com.apple.quarantine ./php

# 查看链接的系统库信息
otool -L ./php

image
image

用构建好的包测试了一遍,没有你说的这个问题哈。

最大的区别就是构建参数不太一样。
构建配置:(分支feature-swoole-my) https://raw.githubusercontent.com/jingjingxyk/static-php-cli/feature-swoole-my/src/globals/test-extensions.php

@jingjingxyk
Copy link
Contributor Author

jingjingxyk commented Dec 28, 2023

目前测试了下,如果使用不启用 pdo_pgsql 扩展、启用 Swoole 的 pgsql hook,是没办法正常使用 new PDO('pgsql:host=127.0.0.1;port=5432;dbname=postgres'),执行到这句代码会卡住,而使用 pdo_pgsql 扩展才是正常的(在 macOS 下)。Linux 下是正常的,不知道是哪里出了问题。

* 使用 Swoole 的 pgsql 支持时,编译的扩展有:`zlib, openssl, curl, pgsql, pdo, swoole`。

* 使用 pdo_pgsql 时,编译的扩展有:`pdo, pgsql, pdo_pgsql`。

感觉可能是 Swoole 自身或者 postgresql 的老问题,因为我在 macOS 连接的 postgres 数据库是 14,Linux 上是 15,Swoole 都使用的稳定版(5.1.1)。

需要检查编译链接时,是否链接到了系统提供的 libpq 库 ,你再用上面的例子试一试

@jingjingxyk
Copy link
Contributor Author

jingjingxyk commented Dec 28, 2023

我搞清楚了,上面的 pdo 是因为你在测试过程中发现缺少头文件导致的,因为必须启用 pdo 扩展才能包含 pdo/pdo.h,才能 Hook pdo__。然后不能启用 pdo__ 的原因是 swoole 的 pdo_driver 和原有的 pdo_driver 不能链接到一起。所以应该是一个依赖 provide 的关系,Swoole 提供了 pdo_* 的扩展内容,启用这些特性时不能启用原来的 pdo_*。

对,是这么回事。

swoole 提供数据库协程实现原理: 是在 pdo_* 基础上,添加了协程调度。 详情见这里: https://github.com/swoole/swoole-src/tree/master/thirdparty/php81

出现扩展互斥这个问题,其实是因为原生就没有提供协程调度、事件循环、协程调度 等功能,目前也没有统一的标准。
也就是这个讨论很激烈的问题: https://zhuanlan.zhihu.com/p/356942841

@crazywhalecc
Copy link
Owner

crazywhalecc commented Dec 28, 2023

需要检查编译链接时,是否链接到了系统提供的 libpq 库 ,你再用上面的例子试一试

这些我肯定会确认好的,否则不会轻易得出无法连接的结论。另外,macOS 平台我也只尝试了 arm64 架构,x86_64 架构不排除会有不一样的结论。

更新:x86_64 也确定会卡住。

启动 pgsql 数据库例子:

我主要是测试 pdo_pgsql 能否正常使用,与 Swoole 自身的客户端和 pgsql 扩展无关,这两个可以正常使用。

@crazywhalecc
Copy link
Owner

应该就是静态 php 和 swoole 的 hook 导致的问题,我刚才也尝试了 macOS 的 swoole-cli 也是存在这个问题的。

@jingjingxyk
Copy link
Contributor Author

jingjingxyk commented Dec 28, 2023

应该就是静态 php 和 swoole 的 hook 导致的问题,我刚才也尝试了 macOS 的 swoole-cli 也是存在这个问题的。

<?php

declare(strict_types=1);

try {
    $dbh = new PDO('pgsql:dbname=postgres host=127.0.0.1 port=5432 ', 'postgres', 'example');

    $stmt = $dbh->prepare('SELECT version()');
    $stmt->execute();
    $result = $stmt->fetch(PDO::FETCH_ASSOC);
    var_dump($result);

    $stmt = $dbh->prepare('SELECT * from  pg_stat_activity');
    $stmt->execute();
    $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
    var_dump($result);
    $dbh = null;
} catch (PDOException $e) {
    exit('Database connection failed: ' . $e->getMessage());
}

上面是测试脚本

你的编译配置是啥?

1 、编译时 启用 swoole 扩展 ,不启用 pdo_pgsql 扩展 ,同时 swoole扩展启用coroutine_pgsql 特性
2、 编译时 启用 swoole 扩展 ,启用 pdo_pgsql 扩展, 不启用 swoole扩展的coroutine_pgsql 特性
3、 编译时 启用 swoole 扩展 ,不启用 pdo_pgsql 扩展, 不启用swoole扩展的coroutine_pgsql 特性
4、 编译时 不启用 swoole 扩展 ,启用 pdo_pgsql 扩展
5、 编译时 启用 swoole 扩展 ,启用 pdo_pgsql 扩展 ,同时 swoole扩展启用coroutine_pgsql 特性。这个是无法编译通过的 (详情: https://github.com/jingjingxyk/static-php-cli/actions/runs/7346590267)

swoole-cli 默认并不包括 pdo_pgsql 这个扩展,使用上述代码测试(new PDO('pgsql:dbname=postgres host=127.0.0.1 port=5432 ', 'postgres', 'example');),应该出现报错, 而不是卡住 。报错信息 (Database connection failed: could not find driver)

image

@crazywhalecc
Copy link
Owner

crazywhalecc commented Dec 28, 2023

就是卡住了,执行到 new PDO 这句,就不动了。

image

而 pecl install swoole 安装的没有问题。

image

编译配置使用的是 1 、编译时 启用 swoole 扩展 ,不启用 pdo_pgsql 扩展 ,同时 swoole扩展启用coroutine_pgsql 特性

使用编译配置 2、 编译时 启用 swoole 扩展 ,启用 pdo_pgsql 扩展, 不启用 swoole扩展的coroutine_pgsql 特性 时,也可以正常执行。

我先本地 lldb 调试一下,看看能不能找到卡住的位置。

@jingjingxyk
Copy link
Contributor Author

就是卡住了,执行到 new PDO 这句,就不动了。
image

而 pecl install swoole 安装的没有问题。
image

编译配置使用的是 1 、编译时 启用 swoole 扩展 ,不启用 pdo_pgsql 扩展 ,同时 swoole扩展启用coroutine_pgsql 特性

使用编译配置 2、 编译时 启用 swoole 扩展 ,启用 pdo_pgsql 扩展, 不启用 swoole扩展的coroutine_pgsql 特性 时,也可以正常执行。

就是卡住了,执行到 new PDO 这句,就不动了。
image

而 pecl install swoole 安装的没有问题。
image

编译配置使用的是 1 、编译时 启用 swoole 扩展 ,不启用 pdo_pgsql 扩展 ,同时 swoole扩展启用coroutine_pgsql 特性

使用编译配置 2、 编译时 启用 swoole 扩展 ,启用 pdo_pgsql 扩展, 不启用 swoole扩展的coroutine_pgsql 特性 时,也可以正常执行。

我先本地 lldb 调试一下,看看能不能找到卡住的位置。

使用 1 、编译时 启用 swoole 扩展 ,不启用 pdo_pgsql 扩展 ,同时 swoole扩展启用coroutine_pgsql 特性。 连接的时候,应该是报错,报错信息提示应该是是 could not find driver ,出现卡着,很奇怪呀。 调试工具 https://wiki.swoole.com/#/other/tools?id=gdb

@crazywhalecc
Copy link
Owner

crazywhalecc commented Dec 28, 2023

使用 1 、编译时 启用 swoole 扩展 ,不启用 pdo_pgsql 扩展 ,同时 swoole扩展启用coroutine_pgsql 特性。 连接的时候,应该是报错,报错信息提示应该是是 could not find driver

不,在 Linux 下是正常的。macOS 下使用 brew install php 和 pecl install swoole 安装后也是正常的。

出现卡着,很奇怪呀。

确实奇怪。我刚才调试了发现它卡到 libpq 中了,栈里也调用到 swoole 了,但还是不知道为什么卡住。

@jingjingxyk
Copy link
Contributor Author

jingjingxyk commented Dec 28, 2023

使用 1 、编译时 启用 swoole 扩展 ,不启用 pdo_pgsql 扩展 ,同时 swoole扩展启用coroutine_pgsql 特性。 连接的时候,应该是报错,报错信息提示应该是是 could not find driver

不,在 Linux 下是正常的。macOS 下使用 brew install php 和 pecl install swoole 安装后也是正常的。

出现卡着,很奇怪呀。

确实奇怪。我刚才调试了发现它卡到 libpq 中了,栈里也调用到 swoole 了,但还是不知道为什么卡住。

我又看了看文档,看到了这个: Swoole5.0 之前是使用协程客户端进行对 PostgreSQL 进行协程化,Swoole5.1 之后,除了使用协程客户端进行协程化,也能够使用原生的 pdo_pgsql 协程化 PostgreSQL 了

https://wiki.swoole.com/#/environment?id=-enable-swoole-pgsql

@crazywhalecc crazywhalecc merged commit 31c71f1 into crazywhalecc:main Jan 3, 2024
@jingjingxyk jingjingxyk deleted the feature-swoole branch October 9, 2024 02:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/extension Issues related to extensions need test This PR has not been tested yet, cannot merge now
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants