2013-04-21 53 views
1

我们使用REST进行日志记录 - 我们需要比简单的文本日志所能提供的更多的信息。所以我们实现了一个REST服务,它接受关于事件的一些基本信息,然后异步地从事件的源网站获取更多细节。所以它实际上是一个平台,只有很少的附加信息。记录仪机器比验证API密钥,连接到数据库,并写入基本信息以及指向更多详细信息的指针。如何提出真正快速的请求,而不是等待答案?

我们有一个问题,即记录可能会使应用程序变慢,因为连接和等待答案需要相当长的一段时间(速度很快,但是当您在一个请求中记录10个以上的事件时,这是一个问题)。

的问题是:

是否有纯PHP(5.3)的方式做任何回答的URL请求,并观望,或者等待HTTP 200头,以确保?

我想我可以让日志服务器发送HTTP 200头,只要它得到请求。但它需要做更多的工作,然后;)

+0

这是在这里解决: http://stackoverflow.com/questions/124462/asynchronous-php-calls – 2013-04-21 23:54:39

回答

2

你想要什么被称为异步请求。

一个解决方案看起来是这样的(引用):

function curl_post_async($url, $params) 
{ 
    foreach ($params as $key => &$val) { 
     if (is_array($val)) $val = implode(',', $val); 
     $post_params[] = $key.'='.urlencode($val); 
    } 
    $post_string = implode('&', $post_params); 

    $parts=parse_url($url); 

    $fp = fsockopen($parts['host'], 
     isset($parts['port'])?$parts['port']:80, 
     $errno, $errstr, 30); 

    $out = "POST ".$parts['path']." HTTP/1.1\r\n"; 
    $out.= "Host: ".$parts['host']."\r\n"; 
    $out.= "Content-Type: application/x-www-form-urlencoded\r\n"; 
    $out.= "Content-Length: ".strlen($post_string)."\r\n"; 
    $out.= "Connection: Close\r\n\r\n"; 
    if (isset($post_string)) $out.= $post_string; 

    fwrite($fp, $out); 
    fclose($fp); 
} 

如果你需要更多信息以看一看:

http://petewarden.typepad.com/searchbrowser/2008/06/how-to-post-an.html

1

这里有两个技巧也许有帮助。

I.在http连接关闭后继续执行。这意味着您可以在完成主要功能时立即关闭连接,然后继续进行日志处理。

<?php 
ignore_user_abort(true);//avoid apache to kill the php running 
ob_start();//start buffer output 
echo "show something to user";//do something you need -- your main function 
session_write_close();//close session file on server side if needed 
header("Content-Encoding: none");//send header to avoid the browser side to take content as gzip format 
header("Content-Length: ".ob_get_length());//send length header 
header("Connection: close");//or redirect to some url 
ob_end_flush();flush();//really send content, can't change the order:1.ob buffer to normal buffer, 2.normal buffer to output 
//continue do something on server side 
ob_start(); 
sleep(5);//the user won't wait for the 5 seconds 
echo 'for log';//user can't see this 
file_put_contents('/tmp/process.log', ob_get_contents()); 
// or call remote server like http://your.log.server/log.php?xxx=yyy&aaa=bbb 
ob_end_clean(); 
?> 

II。使用函数apache_note来写日志是比插入数据库更轻量的选择。因为Apache将在Apache运行期间打开日志文件并保留该句柄。它稳定而且非常快速。

Apache配置:

<VirtualHost *:80> 
DocumentRoot /path/to/your/web 
ServerName your.domain.com 
ErrorLog /path/to/your/log/error_log 
    <Directory /path/to/your/web> 
     AllowOverride All 
     Order allow,deny 
     Allow from all 
    </Directory> 
    SetEnvIf Request_URI "/log\.php" mylog 
    LogFormat "%{mylog}n" log1 
    CustomLog "|/usr/sbin/cronolog /path/to/logs/mylog/%Y%m%d/mysite.%Y%m%d%H.log" log1 env=mylog 
</VirtualHost> 

PHP代码:

<?php 
apache_note('mylog', session_id()); //you can log any data you need, see http://www.php.net/manual/en/function.apache-note.php 

然后你可以使用我的技巧I和II,之后主网页连接关闭呼叫URL http://your.log.server/log.php?xxx=yyy&aaa=bbb记录您的详细资料。根本不需要额外的时间成本。

相关问题