簡體   English   中英

使用並發,線程,靜態變量實現GAE / Java計數器

[英]Implementing A GAE/Java Counter using Concurrency, Threads, Static variables

我已經閱讀了很多關於計數器的GAE文章和GAE中令人討厭的寫入限制。 我已經看到了帶有分片,cron任務,內存緩存等的解決方案。然后我學到了足夠多的java線程能夠提出問題:

問:我們可以使用並發/ servlet靜態varibales在servlet線程中實現計數器嗎?

這將帶來額外的好處,即減少對數據存儲區和內存緩存的寫入(花費相同的$),並刪除cron要求,因為一系列快速計數器命中中的最后一個servlet將更新數據存儲區。

我不太了解並發編程以提出解決方案,但我想象一下靜態servlet變量,可能是“atomic-integers”和last-update標志,以便檢查這個servlet是否是最后一個更新servlet的servlet static var,在最后200ms內,從而觸發對數據存儲區的保存。

// Servlet gets a hit
// static var counter++
// Checks last datastore save time of the static var, if longer than 200ms
// save to datastore & save "last update time"
// If shorter than 200 ms ago, let the next servlet call update the datastore

可以這樣做嗎? 有什么建議? Mucho贊賞你的想法。

只是詳細說明我的評論:

您可能已經意識到,App Engine會在達到某個流量閾值時啟動應用程序的新實例。 鑒於新實例可以在完全不同的服務器上運行,您的靜態計數器將變為無效。

現在只是為了澄清,在App Engine中實現計數器的正確方法是使用Sharding並將其拆分為多個entite。

現在假設您希望最小化數據存儲區調用,您可以使用memcache存儲計數器數據並以指定的頻率將其寫入數據存儲區(例如通過cron)。 您的memcache數據將在您應用的所有實例中保持一致。

在memcache發生故障的情況下,你當然會冒失去 memcache計數器的風險,但這就是把它寫到數據存儲區的工作。 同樣,這不是一個100%萬無一失的解決方案,分片是; 但這是最小化數據存儲區調用的一種方法。

Guido van Rossum在他博客上的一篇文章中談到了這一點。 據我了解,你處於競爭狀態問題。 我對Java一無所知。 但是guido鏈接到了一個用於Java的Memcache服務的API 也許這可以幫助您找到解決方案。

如果您正在計算“關鍵任務”的內容,請不要假設同一個實例將處理下一個請求或任何后續請求。 App Engine能夠快速擴展以處理需求高峰的另一面是,當尖峰通過時,實例會消失。 實例也可能因其他原因而消失。 當計數到右時,分片計數器是要走的路。

將memcache視為可以具有任意縮短的生命周期的緩存以外的其他任何東西通常也是錯誤的。

如果大概數量可以做,那么你有幾個選擇。 你可以做一些事情,比如在memcache中累積計數,每隔N次點擊一次將數據清除到數據存儲區,或者你可以使用受鎖保護的全局變量做同樣的事情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM