面向对象的 PHP 中的非阻塞 HTTP 请求?
我有一个与 RESTful 服务器交互的 PHP 客户端应用程序。客户端上的每个 PHP Goat 实例都需要根据服务器上 /goat 请求中的信息(例如 /goat/35、/goat/36 等)来初始化自身。它通过 cURL 向其相应的 URL 发送 HTTP 请求来实现此目的。每页加载 30 多个山羊对象相当于 30 多个 HTTP 请求,每个请求需要 0.25 秒 - 正如我的山羊所说,这真是太糟糕了。在内存中延迟加载和缓存响应会有所帮助,但还不够。
foreach ($goats as $goat) {
$goat->getName() // goat needs to hit the REST API
}
这种技术的优点是我的山羊都很聪明,而且封装得很好。缺点是性能很糟糕。山羊不知道如何对它们的 HTTP 请求进行排队,一只山羊不知道是否有其他山羊需要发起请求,等等。我想一种替代方案是在外部构建山羊:
$urls = array('http://', 'http://', ...); // array of goat URLs
$result = fancy_pipelined_http_request_queue($urls);
foreach ($result as $xml) {
$goat->buildSelfFromXML($xml);
}
我确信这一点是一个众所周知的 OO/REST 困境,有更高级的解决方法,我只是不知道在哪里寻找。有什么想法吗?
I have a PHP client application that is interfacing with a RESTful server. Each PHP Goat instance on the client needs to initialize itself based on information in a /goat request on the server (e.g. /goat/35, /goat/36, etc.). It does this by sending an HTTP request to its corresponding URL via cURL. Working with 30+ goat objects per page load equates to 30+ HTTP requests, and each one takes 0.25 second - that's baaaad, as my goats would say. Lazy-loading and caching the responses in memory helps, but not enough.
foreach ($goats as $goat) {
$goat->getName() // goat needs to hit the REST API
}
The advantage of this technique is that my goats are all smart and encapsulated. The disadvantage is that the performance is horrible. The goats don't know how to queue their HTTP requests, one goat doesn't know if there are other goats that need to initiate a request, etc. I guess one alternative would be to build the goats externally:
$urls = array('http://', 'http://', ...); // array of goat URLs
$result = fancy_pipelined_http_request_queue($urls);
foreach ($result as $xml) {
$goat->buildSelfFromXML($xml);
}
I'm sure this is a well-known OO/REST dilemma that there are more advanced ways of solving, I just don't know where to look. Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您愿意,可以使用非阻塞套接字。这需要一些编码来切换到它们,因为您需要将curl踢到一边。但这可能会提高性能,因为您确实能够同时执行请求。
请参阅 socket_set_blocking / stream_set_blocking 函数。
You can use non-blocking sockets if you like. This involves a bit of coding to switch to them as you will need to kick curl aside. But this may improve performance because you will really be able to perform requests simultaneously.
See socket_set_blocking / stream_set_blocking functions.