我在我的应用程序中使用Bigcommerce PHP SDK。此SDK记录在此处:
https://github.com/bigcommerce/bigcommerce-api-php
我有一个脚本迭代大量的对象(1000个对象)。在每次迭代期间,使用此SDK对Bigcommerce进行了许多调用。例如,在脚本中的一个文件中,这里可能是一个获取产品skus的调用:
Bigcommerce::configure(array(
'client_id' => BC_CLIENT_ID,
'auth_token' => BC_AUTH_TOKEN,
'store_hash' => BC_STORE_HASH,
));
Bigcommerce::getCollection('product/123/skus', 'Sku');
然后在脚本中使用的另一个文件中,有一个调用来检索另一个资源,比如产品的图像:
Bigcommerce::configure(array(
'client_id' => BC_CLIENT_ID,
'auth_token' => BC_AUTH_TOKEN,
'store_hash' => BC_STORE_HASH,
));
Bigcommerce::getCollection('product/123/images', 'Sku');
我遇到的问题是,在此脚本运行一段时间后,我收到一条错误消息,指出打开的文件太多。这是实际错误:
PHP Fatal error: Uncaught exception 'ErrorException' with message 'include(/var/www/html/app/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Response.php): failed to open stream: Too many open files' in /var/www/html/app/vendor/composer/ClassLoader.php:386
Stack trace:
#0 /var/www/html/app/vendor/composer/ClassLoader.php(386): Illuminate\Exception\Handler->handleError(2, 'include(/var/ww...', '/var/www/html/a...', 386, Array)
#1 /var/www/html/app/vendor/composer/ClassLoader.php(386): Composer\Autoload\includeFile()
#2 /var/www/html/app/vendor/composer/ClassLoader.php(278): Composer\Autoload\includeFile('/var/www/html/a...')
#3 [internal function]: Composer\Autoload\ClassLoader->loadClass('Symfony\Compone...')
#4 /var/www/html/app/vendor/laravel/framework/src/Illuminate/Exception/WhoopsDisplayer.php(49): spl_autoload_call('Symfony\Compone...')
#5 /var/www/html/app/ve in /var/www/html/app/vendor/composer/ClassLoader.php on line 386
PHP Fatal error: Uncaught exception 'ErrorException' with message 'include(/var/www/html/app/vendor/symfony/debug/Symfony/Component/Debug/Exception/FatalErrorException.php): failed to open stream: Too many open files' in /var/www/html/app/vendor/composer/ClassLoader.php:386
Stack trace:
#0 /var/www/html/app/vendor/composer/ClassLoader.php(386): Illuminate\Exception\Handler->handleError(2, 'include(/var/ww...', '/var/www/html/a...', 386, Array)
#1 /var/www/html/app/vendor/composer/ClassLoader.php(386): Composer\Autoload\includeFile()
#2 /var/www/html/app/vendor/composer/ClassLoader.php(278): Composer\Autoload\includeFile('/var/www/html/a...')
#3 [internal function]: Composer\Autoload\ClassLoader->loadClass('Symfony\Compone...')
#4 /var/www/html/app/vendor/laravel/framework/src/Illuminate/Exception/Handler.php(191): spl_autoload_call('Symfony\Compone...')
#5 [internal function]: Illuminate\Exception\Hand in /var/www/html/app/vendor/composer/ClassLoader.php on line 386
我已经能够确定在脚本运行时,与Bigcommerce建立的每个连接似乎都算作另一个"文件"那是开放的。我通过运行以下命令来看到这一点:
lsof -uroot | grep 104.236.XX.XXX | wc -l
此命令输出的数字不断增加。如果我实际查看打开的文件,我可以看到状态为CLOSE_WAIT
的很长的文件列表,例如:
php 14005 root 5u IPv4 1792827 0t0 TCP 104.236.XX.XXX:58077->192.200.169.163:https (CLOSE_WAIT)
php 14005 root 7u IPv4 1793002 0t0 TCP 104.236.XX.XXX:58078->192.200.169.163:https (CLOSE_WAIT)
php 14005 root 8u IPv4 1793003 0t0 TCP 104.236.XX.XXX:58079->192.200.169.163:https (CLOSE_WAIT)
php 14005 root 9u IPv4 1793004 0t0 TCP 104.236.XX.XXX:58080->192.200.169.163:https (CLOSE_WAIT)
php 14005 root 10u IPv4 1793005 0t0 TCP 104.236.XX.XXX:58081->192.200.169.163:https (CLOSE_WAIT)
php 14005 root 11u IPv4 1793006 0t0 TCP 104.236.XX.XXX:58082->192.200.169.163:https (CLOSE_WAIT)
php 14005 root 12u IPv4 1793007 0t0 TCP 104.236.XX.XXX:58083->192.200.169.163:https (CLOSE_WAIT)
php 14005 root 13u IPv4 1793008 0t0 TCP 104.236.XX.XXX:58084->192.200.169.163:https (CLOSE_WAIT)
php 14005 root 14u IPv4 1793093 0t0 TCP 104.236.XX.XXX:58085->192.200.169.163:https (CLOSE_WAIT)
php 14005 root 15u IPv4 1793094 0t0 TCP 104.236.XX.XXX:58086->192.200.169.163:https (CLOSE_WAIT)
php 14005 root 16u IPv4 1793095 0t0 TCP 104.236.XX.XXX:58087->192.200.169.163:https (CLOSE_WAIT)
php 14005 root 17u IPv4 1793170 0t0 TCP 104.236.XX.XXX:58088->192.200.169.163:https (CLOSE_WAIT)
php 14005 root 18u IPv4 1793234 0t0 TCP 104.236.XX.XXX:58089->192.200.169.163:https (CLOSE_WAIT)
php 14005 root 19u IPv4 1793242 0t0 TCP 104.236.XX.XXX:58090->192.200.169.163:https (CLOSE_WAIT)
php 14005 root 20u IPv4 1793315 0t0 TCP 104.236.XX.XXX:58091->192.200.169.163:https (CLOSE_WAIT)
php 14005 root 21u IPv4 1793328 0t0 TCP 104.236.XX.XXX:58092->192.200.169.163:https (CLOSE_WAIT)
php 14005 root 22u IPv4 1793389 0t0 TCP 104.236.XX.XXX:58093->192.200.169.163:https (ESTABLISHED)
php 14005 root 23u IPv4 1793390 0t0 TCP 104.236.XX.XXX:58094->192.200.169.163:https (ESTABLISHED)
php 14005 root 24u IPv4 1793458 0t0 TCP 104.236.XX.XXX:58095->192.200.169.163:https (ESTABLISHED)
php 14005 root 25u IPv4 1793464 0t0 TCP 104.236.XX.XXX:58096->192.200.169.163:https (ESTABLISHED)
php 14005 root 26u IPv4 1793465 0t0 TCP 104.236.XX.XXX:58097->192.200.169.163:https (ESTABLISHED)
此列表会继续变得越来越长,直到脚本出现错误并且打开太多文件"我在上面显示的错误。
我的假设是这些CLOSE_WAIT
文件导致我达到可以打开的文件数量的限制。有什么办法可以摆脱这些文件吗?为什么他们被考虑"开放"文件如果与Bigcommerce的连接已经完成?
也许我错误地使用了SDK?换句话说,是否有办法让所有调用都来自单个Bigcommerce
类而不是每次都创建一个新连接?
答案 0 :(得分:0)
我能够通过改变configure
方法来解决这个问题,以便在每次调用时都不创建新连接。新方法可以在github上的fork中找到: