2013-06-21 39 views
2

我在我的基於Java Spring的網站上有一個搜索輸入字段,用戶可以在其中搜索網站的內容。我想將用戶輸入的查詢異步保存到MySQL數據庫中以實現自動完成功能。我知道我可以使用@Async註釋在Spring中指定一個帶游泳池大小的以下內容:Spring @Async保存搜索

<task:annotation-driven executor="executor" /> 
<task:executor id="executor" pool-size="100"/> 

問:

  • 這是一個高流量的網站擁有超過10,000很好的解決方案每分鐘搜索?考慮可能導致游泳池耗盡異常?
  • 有沒有更好的解決方案?
+0

保存一個搜索查詢和獲取自動完成對我來說似乎不是一個沉重的任務(只要你得到你的索引權)。我不認爲使用執行器是必要的,我只是使用簡單的DAO連接到控制器 – gerrytan

+0

是的,我使用SOLR索引。我在我的Controller中調用QueryService.save,然後調用QueryService.query來查詢SOLR。我只是認爲QueryService.save可能會影響性能。所以我錯了? – hajime

+0

我認爲你可以有一個無限的隊列,你可以將文本添加到每個請求中(而不是在後臺),並且有一些後臺線程在有可用文本時從隊列中使用。 –

回答

1

看看ThreadPoolTaskExecutor。當池中的所有線程都處於忙碌狀態時,您的作業只會排隊等待一個線程可用。最大隊列容量和線程數可通過queueCapacity/maxPoolSize屬性(queueCapacity,默認爲INTEGER.MAX_VALUE)進行調整。

你必須關心的一件事是內存耗盡。如果您將隊列容量設置得太高而且作業運行時間過長,則所有作業都會堆積在隊列中,從而消耗內存。

也考慮拒絕服務。黑客可以通過填滿所有隊列來執行攻擊(因此拒絕正常用戶的工作)

所以我會說是的這是一個很好的方法,您的控制器不必等到工作完成但是考慮每個排隊作業需要多少內存,你有多少內存空間,運行多長時間等等。

好的方法就是最好地猜測某些值,並設置好線程池/隊列監視/統計數據並隨時調整。

+0

我基本上只是試圖保存用戶輸入的搜索查詢。保存所有搜索並不重要。所以,如果我將池大小設置爲100,並且如果池中出現問題,我應該重新啓動池。也許以某種方式保存列表中的所有現有線程,並在出現問題時關閉它們。這會是一個很好的解決方案嗎? – hajime