风景
我有一个乌班图18.04DigitalOcean 中的服务器具有以下规格:1 vCPUs, 1GB and 25GB磁盘.
在这个服务器(我们称之为 API SERVER)中,我使用 PHP 和 NodeJS(在由 apache 管理的代理中运行)。
我使用以下规格设置我的虚拟主机(000-默认.conf,我没有使用域名):
DocumentRoot /var/www/html/api
#Allow Htacess Files
<Directory "/var/www/html">
AllowOverride All
</Directory>
#Nodejs (API) Directory Redirection
ProxyRequests Off
ProxyPreserveHost On
ProxyVia Full
KeepAlive On
<Proxy *>
Require all granted
</Proxy>
<Location /node_api>
ProxyPass http://127.0.0.1:3569 retry=0
ProxyPassReverse http://127.0.0.1:3569
</Location>
In /var/www/html
我有两个文件夹:
-
api
包含 php 制作的 api 的文件夹(只需输入服务器 IP 即可访问);
-
node_api
包含节点中制作的 api 的文件夹(要访问,您需要输入服务器 ip 并添加/node_api
在网址中);
我使用 PM2 来管理我的节点服务器 (server.js)。
我的 API 是做什么的
另一台服务器向该服务器(实际上是一个 API)发出请求,更具体地说是针对 PHP 中创建的文件。
PHP文件执行一些内部分析,最后它向使用node创建的api发送一些请求,等待响应并保存在本地文件中(这些请求通过CURL
).
$chNodePrintDesktop = curl_init('http://MY_PUBLIC_IP_SERVER/node_api/requestScreenShootForDesktop/');
curl_setopt($chNodePrintDesktop, CURLOPT_HEADER, 0);
curl_setopt($chNodePrintDesktop, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($chNodePrintDesktop, CURLOPT_CONNECTTIMEOUT, 0);
curl_setopt($chNodePrintDesktop, CURLOPT_TIMEOUT, 0);
curl_setopt($chNodePrintDesktop, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
curl_setopt($chNodePrintDesktop, CURLOPT_POSTFIELDS, "urlsite=http://".$argv[2]);
$dataNodePrintDesktop = curl_exec($chNodePrintDesktop);
curl_close($chNodePrintDesktop);
在我的例子中,我向节点 api 发送 5 个请求,每个请求都调用不同的路由(正如我们在上面的代码中看到的,我正在调用该路由)'requestScreenShootForDesktop'
).
我的节点 api 中存在所有 5 条路由,请使用名为的库'puppeteer
'。在这种情况下,当我调用其中一个路由时,节点会获取 CURL 发送的 url 并返回数据,例如来自路由的数据/requestScreenShootForMobile/
:
app.post('/requestScreenShootForMobile/', async function(req, res){
const pathUpload = '/var/www/html/node_api/uploads/' + Math.floor(Date.now() / 1000) + '.png';
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(req.body.urlsite);
await await page.emulate(devices['iPhone 6']);
await page.screenshot({path: pathUpload});
await browser.close();
var img = await fs.readFileSync(pathUpload);
await res.writeHead(200, {'Content-Type': 'image/png' });
await res.end(img, 'binary');
await fs.unlinkSync(pathUpload);
});
正如您在上面看到的,每次调用路线时我都会打开和关闭 chrome。
问题
在向服务器发出的单个请求中,php 执行以下过程:
- 执行一些内部分析。
- 对 NODE api 的不同路由执行 5 个 CURL(请求桌面的屏幕截图,另一个移动设备的屏幕截图,抓取所有链接等等......所有这些都使用 puppeteer,每次调用路由时打开和关闭 chrome)。
- 将所有数据保存在 .txt 文件中。
在一些分析过程中,我注意到 Node 所做的一些结果最终返回了错误503 service unavailable
:
由于以下原因,服务器暂时无法满足您的请求
维护停机或容量问题。请稍后再试
Apache/2.4.29 (Ubuntu) 服务器位于 MY_PUBLIC_IP_SERVER 端口 80
第一次分析时,结果通常会正确显示,但随着执行多个分析(通常是同时执行),CURL 通常会更频繁地返回错误 503。
我尝试升级我的服务器的规格(2 个专用 vCPU, 4GB and 25GB磁盘), use retry=0
in ProxyPass
,但这些都不起作用。
有趣的一点是,虽然 Node 返回错误 503,但 php 始终生成 .txt 文件。
可能发生什么情况以及如何解决这个问题?