2013年7月2日 星期二

GAE 的 urlfetch 超時問題

自從使用 GAE 以來, 一直認為其 urlfetch 功能只能執行 5 秒左右, 實際測試就是如此. 例如我們用 Python 去抓取證交所網站之每日收盤行情 :

url="http://www.twse.com.tw/ch/trading/exchange/MI_INDEX/genpage/" + \
      "Report201111/A11220111125ALLBUT0999_1.php?select2=" + \
      "ALLBUT0999&chk_date=100/11/25"
result=urlfetch.fetch(url)

保證在 5 秒後就會看到如下 DeadlineExceededError 錯誤回應 :

"DeadlineExceededError: Deadline exceeded while waiting for HTTP response from URL: http://www.twse.com.tw/ch/trading/exchange/MI_INDEX/genpage/Report201111/A11220111125ALLBUT0999_1.php?select2=ALLBUT0999&chk_date=100/11/25"

這會導致後面的資料分析工作停擺, 所以一直以來我都只用 GAE 的 cron 當 hearbeat 去驅動 PHP 應用程式作網頁擷取與分析的動作. 其實這是我學習 Python 時囫圇吞棗造成的誤解, urlfetch 有一個 deadline 參數可以設定最長的擷取等待時間 (GAE 最長可設為 60 秒, cron 可達 10 分鐘), 如果沒有指定, 那麼在 GAE 預設是大約 5 秒左右, 超過五秒沒有收到回應就會導致 DeadlineExceededError 錯誤. 詳見下列資訊 :

  1. The fetch Function
  2. If Google App Engine cron jobs have a 10 minute limit, then why do I get a DeadlineExceededError after the normal 30 seconds?

所以上面的 Python 程式只要加入 deadline=60 參數就可以避免 5 秒就超時的問題了 :

result=urlfetch.fetch(url, deadline=60)

這樣一來, GAE 的 Cron Jobs 本來顯示 "on time failed" 的 :

every day 15:00 (Asia/Taipei) 
2013/07/02 15:00:00 on time Failed

也變正常了 :

every day 15:00 (Asia/Taipei) 
2013/07/02 15:00:00 on time Success

沒有留言 :