1

在我的 Catalyst 应用程序中,我使用带有 WSDL 的 SOAP 与远程服务器建立了非常重要的连接。

一切正常,但是当远程服务器由于某种原因关闭时,我的所有应用程序都会等待超时到期。一切。所有的控制器和进程,所有的客户端!!

如果我为 SOAP LITE 传输错误设置了 15 秒的超时,那么一切都会等待 15 秒。在超时等待期间,无法显示来自任何用户或连接的任何页面。

我将 Fast CGI 和 Ngnix 用于 Catalyst 应用程序。如果我在一个等待时使用多个 fcgi 进程,其他人会处理连接,但如果他们都尝试访问有故障的 SOAP 服务......他们都会等待并等待答案,直到达到超时。当他们都在等待时,不允许更多的连接。

寻找我在某处读到 SOAP::LITE 是“单线程”的答案。

这是真的吗?这是否意味着我的所有应用程序以及所有访问者都只能使用一个SOAP 连接?很难相信。

这是我的通话代码:

sub check_result {
    my ($self, $code, $IP, $PORT) = @_;

    my $soap = SOAP::Lite->new( proxy => "http://$IP:$PORT/REMOTE_SOAP
+");

    $soap->autotype(0);
    $soap->default_ns('http://REMOTENAMESPACE/namespace/default');
    $soap->transport->timeout(15);

     $soap-> on_fault(sub { my($soap, $res) = @_; 
        eval { die ref $res ? $res->faultstring : $soap->transport->st
+atus };
          return ref $res ? $res : new SOAP::SOM;
       });

     my $som = $soap->call("remote_function",
         SOAP::Data->name( 'Entry1' )->value( $code ),
     );

    return $som->paramsout;
}

我还尝试了 perlmonks 建议的这种略有不同的方法,但没有什么比这更好的了

拜托,有人能指出我正确的方向吗?

米格

4

1 回答 1

0

这不是 SOAP::Lite 或 Catalyst 本身的问题。您查询的几乎所有资源很可能会等待返回(即:磁盘上的文件读取、数据库访问)。如果资源阻塞了很长时间,那么在等待此返回时,您可能会“饿死”其他请求。

这个问题没有一个简单的答案,但是您可以创建一个单独的进程执行的“作业队列”,然后您可以将条目添加到队列中并获取令牌,而不是调用其他服务。请求完成后,队列存储与该令牌关联的结果,然后您的应用程序在单独的请求中检查您想要的令牌是否已经有结果。

有专门的“作业队列”框架,例如 RabbitMQ、ApacheMQ,甚至还有一些基于 Redis 的解决方案。如果您的 Web 应用程序使用丰富的 Javascript,您甚至可以使用例如 WebSockets 将“作业队列”通知发送到 javascript 客户端,否则,只需每秒轮询一次以查看是否有响应。

于 2014-08-07T10:53:46.513 回答