Salesforce/PHP - 批量出站消息 (SOAP),超时问题 - 请参阅更新 #2

发布于 2024-08-26 09:52:21 字数 2253 浏览 2 评论 0 原文

Salesforce 最多可以在 1 条 SOAP 消息中发送 100 个请求。在发送此类批量出站消息请求时,我的 PHP 脚本完成执行,但 SF 无法接受用于清除 Salesforce 端消息队列的 ACK。查看出站消息日志(监视),我看到所有消息均处于挂起状态,且传递失败原因为“java.net.SocketTimeoutException:读取超时”。如果我的脚本已完成执行,为什么会出现此错误?

我尝试了这些方法来增加服务器上的执行时间,因为我无法访问 Salesforce 端:

  • set_time_limit(0); // 在脚本中
  • max_execution_time = 360 ;每个脚本的最大执行时间,以秒为
  • 单位 max_input_time = 360 ;每个脚本解析请求数据可能花费的最大时间
  • memory_limit = 32M ;脚本可能消耗的最大内存量

我使用高设置只是为了测试。

您是否想过为什么无法将 ACK 传送回 Salesforce?

这是一些代码: 这就是我接受和发送即将到来的 SOAP 请求的 ACK 文件的方式。

$data = 'php://input';
$content = file_get_contents($data);

if($content) {
    respond('true');
} else {
    respond('false');
}

响应函数

function respond($tf) {
    $ACK = <<<ACK
<?xml version = "1.0" encoding = "utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
        <notifications xmlns="http://soap.sforce.com/2005/09/outbound">
            <Ack>$tf</Ack>
        </notifications>
    </soapenv:Body>
</soapenv:Envelope>
ACK;

    print trim($ACK); 
}

这些位于通用脚本中,我将其包含到使用特定工作流程的数据的脚本中。我可以处理大约 25 个请求(在 1 个 SOAP 响应中),但一旦处理完毕,我就会在 Salesforce 队列中收到超时错误。 50 个请求通常需要我的 PHP 脚本 86.77 秒。

会是阿帕奇吗? PHP?

我还测试了仅接受 100 个请求 SOAP 响应以及仅接受和发送队列清除的 ACK,所以我知道这是我这边的事情。

我在 apache 日志中没有显示任何错误,脚本运行良好。

我确实在 Salesforce 网站上找到了一些信息,但仍然没有找到。这是链接

我还使用 PHP Toolkit 11(来自 Salesforce)。

其他论坛有好的SF帮助

感谢您对此的任何见解, --Phill

更新:

如果我收到传入消息并打印响应,是否应该首先发生这种情况,无论我之后是否执行其他操作?或者它会等待我的进程完成然后打印响应?

更新#2:

好吧,我想我有问题: PHP 使用单线程处理方法,在线程完成处理之前不会发回 ACK 文件。有没有办法使它成为多线程进程? 线程 #1 - 接受传入的 SOAP 请求并发回 ACK 线程 #2 - 处理 SOAP 请求

我知道我可以将其分解为数据库表或平面文件,但是有没有办法在不这样做的情况下完成此任务?

我将尝试在提交 ACK 后关闭套接字并继续处理,祈祷它能工作。

Salesforce can send up to 100 requests inside 1 SOAP message. While sending this type of Bulk Ooutbound message request my PHP script finishes executing but SF fails to accept the ACK used to clear the message queue on the Salesforce side of things. Looking at the Outbound message log (monitoring) I see all the messages in a pending state with the Delivery Failure Reason "java.net.SocketTimeoutException: Read timed out". If my script has finished execution, why do I get this error?

I have tried these methods to increase the execution time on my server as I have no access on the Salesforce side:

  • set_time_limit(0); // in the script
  • max_execution_time = 360 ; Maximum execution time of each script, in seconds
  • max_input_time = 360 ; Maximum amount of time each script may spend parsing request data
  • memory_limit = 32M ; Maximum amount of memory a script may consume

I used the high settings just for testing.

Any thoughts as to why this is failing the ACK delivery back to Salesforce?

Here is some of the code:
This is how I accept and send the ACK file for the imcoming SOAP request

$data = 'php://input';
$content = file_get_contents($data);

if($content) {
    respond('true');
} else {
    respond('false');
}

The respond function

function respond($tf) {
    $ACK = <<<ACK
<?xml version = "1.0" encoding = "utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
        <notifications xmlns="http://soap.sforce.com/2005/09/outbound">
            <Ack>$tf</Ack>
        </notifications>
    </soapenv:Body>
</soapenv:Envelope>
ACK;

    print trim($ACK); 
}

These are in a generic script that I include into the script that uses the data for a specific workflow. I can process about 25 requests (That are in 1 SOAP response) but once I go over that I get the timeout error in the Salesforce queue. for 50 requests is usually takes my PHP script 86.77 seconds.

Could it be Apache? PHP?

I have also tested just accepting the 100 request SOAP response and just accepting and sending the ACK the queue clears out, so I know it's on my side of things.

I show no errors in the apache log, the script runs fine.

I did find some info on the Salesforce site but still no luck. Here is the link.

Also I'm using the PHP Toolkit 11 (From Salesforce).

Other forum with good SF help

Thanks for any insight into this,
--Phill

UPDATE:

If I receive the incoming message and print the response, should this happen first regardless if I do anything else after? Or does it wait for my process to finish and then print the response?

UPDATE #2:

okay I think I have the problem:
PHP uses the single thread processing approach and will not send back the ACK file until the thread has completed it's processing. Is there a way to make this a mutli thread process?
Thread #1 - accept the incoming SOAP request and send back the ACK
Thread #2 - Process the SOAP request

I know I could break it up into like a DB table or flat file, but is there a way to accomplish this without doing that?

I'm going to try to close the socket after the ACK submission and continue the processing, cross my fingers it will work.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

深海不蓝 2024-09-02 09:52:21

听起来出站消息已超时。其他用户报告的超时时间低至 10 秒(请参阅下面的论坛链接)。根据我的测试,我使用的沙箱实例 (cs1) 在大约 1 分钟后超时。超时可能是 Salesforce 控制的组织或实例级别设置。

您可以尝试以下两件事:

  1. 通过以下方式打开支持票证
    Salesforce 看看他们是否可以
    增加超时值
    出站消息。来自我的
    经验,有很多
    他们可以修改的设置
    组织级别 - 这可能是
    其中之一。

  2. 卸载数据处理,因此
    立即发送 ACK
    回到 Salesforce。那么实际的
    处理您的数据将需要
    异步放置。 IE。信息
    队列、单独线程等。

其他一些可能有用的资源:

相关 Salesforce 论坛讨论

出站消息传递文档

Sounds like the outbound message is hitting the timeout. Other users have reported timeouts as low as 10 seconds (see forum link below). The sandbox instance that I use (cs1) is timing out after about 1 minute, from my testing. It's possible that the timeout is an organization or instance level setting that Salesforce controls.

Two things you could try:

  1. Open a support ticket with
    Salesforce to see if they can
    increase the timeout value for
    outbound messages. From my
    experience, there are lot of
    settings that they can modify on the
    organization level - this might be
    one of them.

  2. Offload processing of your data, so
    that the ACK is sent immediately
    back to Salesforce. Then the actual
    processing of your data will take
    place asynchronously. ie. Message
    queue, separate thread, etc.

Some other resources that might be helpful:

related Salesforce forum discussion

Outbound messaging documentation

时光清浅 2024-09-02 09:52:21

我认为他们在等待你的脚本结束时超时了。

有一种方法你可以尝试解决这个问题。

在开头输出带有 ack 消息的信封,然后刷新该内容,以便他们的服务器在您结束处理之前获取它。没有线程,只是重新思考简单的优先级:)

阅读此内容以获取有关刷新的最佳信息内容

I think they timeout the thing waiting for Your script to end.

There is a way You could try to fix this.

Output the envelope with ack message at the beginning and then flush the thing so that their server gets it before You end processing. No threading, just plain priorities rethinking :)

read this for best info on flushing content

一曲爱恨情仇 2024-09-02 09:52:21

您是否 100% 确定 Salesforce 会等待您的脚本运行所需的时间? 80秒对我来说也显得很长。

如果所有请求都失败,我猜测 Salesforce 希望您适当地设置 Content-Type 标头,但情况似乎并非如此。

Are you 100% sure that Salesforce will wait the amount of time your scripts need too run? 80 seconds seem like a loong time too me.

If all requests failed I would guess that Salesforce expects you to set the Content-Type header appropriately, but this does not seem to be the case.

皇甫轩 2024-09-02 09:52:21

我不了解 Salesforce,但如果您想使用 PHP 进行一些多线程处理,您应该看看 此代码示例,更准确地说是 pcntl_fork()

注意:默认情况下,pcntl 启用,并且无法在 Windows 平台上运行。

I don't know about Salesforce, but if you want to make some multithreading with PHP you should take a look at this code example and more precisely to pcntl_fork().

N.B: pcntl is not enabled by default and won't work on Windows platforms.

梅窗月明清似水 2024-09-02 09:52:21

所以我所做的是:

  1. 接受所有传入的 OBM,将它们解析为数据库
  2. 完成后,启动在后台运行的进程(实际上我将其发送到后台,以便脚本可以结束)
  3. 发回 ACK

文件只需接受原始数据、解析字段并将其插入数据库就相当快了。然后我发出一个 Linux 命令行命令,该命令还发送处理脚本以在后台运行。然后我将 ACK 文件发送到 SF,脚本在指定的时间内结束。将脚本过程分成两个单独的阶段很麻烦,但它确实有效。

So what I've done is:

  1. Accept all incoming OBM's, parse them into a DB
  2. When this is done kick of a process that runs in the background (Actually I send it to the background so the script can end)
  3. Send ACK file back

By just accepting the raw data, parsing into fields and inserting it into a DB is fairly quick. Then I issue a Linux Command Line command that also send the processing script to run in the background. Then I send the ACK file to SF and the script ends within the allotted time. It is cumbersome to split the script process into two separate stages but it works.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文