2013-04-21 46 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記錄您的詳細資料。根本不需要額外的時間成本。

相關問題