簡體   English   中英

實例之間的Google App Engine對象交換

[英]Google App Engine object exchange between instances

我正在運行GAE Java應用程序,並使用后端實例進行一些計算。 經過計算,后端實例創建一個映射,供http請求使用時前端應使用該映射。

最初,我創建了靜態地圖,並使用在后端實例上運行的cron作業更新了地圖值。 但是當我嘗試通過發送http請求來檢索值時,我仍然得到舊值。 這是我的代碼

public class ServerServlet extends HttpServlet {

public static Map<String,String> highQualityMap;

protected void doGet( HttpServletRequest request,
        HttpServletResponse response)
                throws ServletException, IOException {
    try{
        String uri = request.getRequestURI();
        PrintWriter out = response.getWriter();

        if(uri.equalsIgnoreCase("/getstatus")){
            String id = request.getParameter("id");
            out.write(highQualityMap.get(id));
        }
        else if(uri.equalsIgnoreCase("/recacheAll")){
            System.out.println("recache all");
            buildData();
        }
        if(out!=null)
            out.close();
    }
    catch(Exception e){
        e.printStackTrace();
    }
}

private void buildData(){
    // here after some processing, data is populated in highQualityMap
}

}

這是我的cron.xml

<?xml version="1.0" encoding="UTF-8"?>
<cronentries>
  <cron>
    <url>/recacheAll</url>
    <description>Repopulate the cache every 3 hours</description>
    <schedule>every 3 hours</schedule>
    <target>backend</target>
  </cron>
</cronentries>

這是我的backends.xml

<?xml version="1.0" encoding="UTF-8"?>
<backends>
    <backend name="backend">
        <class>B1</class>
        <options>
            <dynamic>true</dynamic>
            <public>false</public>
        </options>
    </backend>
</backends>

我相信前端和后端實例都是單獨運行的,並且不會共享對象。 當我在前端運行cron作業時,它將獲取正確的數據。 因此,我正在尋找一種方法,以便可以在前端通過后端實例使用相同的計算圖。

Update1:​​在后端計算了哈希表之后,我嘗試將其保存在數據存儲區中,但是出現錯誤,指出“ java.util.HashMap不是受支持的屬性類型”。 因此,我沒有創建地圖,而是創建列表並嘗試將其存儲在數據存儲區中。 但是由於對實體大小的限制(1mb),我無法將arraylist也存儲在數據存儲中。

Update2:我將地圖轉換為列表,將其拆分為多個較小的列表,並將其存儲到數據存儲區的不同實體中。 存儲后,我啟動了一個應該在前端執行的任務。 此任務從數據存儲中讀取較小的列表,從中創建一個大列表,最后創建一個我保存在內存中的映射。

您至少有五個選擇:

  1. POST(我不確定App Engine的限制是多少,但我想最多10MB應該可以)。
  2. 數據存儲(無限制)。
  3. Google雲端存儲(無限制)。
  4. 專用的內存緩存(最大1MB)。
  5. 由數據存儲支持的常規內存緩存(最大1MB)。

假設您的對象適合Memcache,則最后一個選項可能是最具成本效益的。 您的后端實例會創建一個地圖,將其放入數據存儲區,然后將其放入Memcache。 您的前端實例嘗試從Memcache加載它。 如果那里不可用,它將從數據存儲加載它,並將其放入Memcache中,以備再次需要時使用。

更新:

當您的地圖很大時,您仍然可以選擇最后一個最有效的選擇。 在后端:

ArrayList<Entity> batch = new ArrayList<Entity>(500);

for (String key : map.keySet()) {

    memcache.put(key, map.get(key));

    Entity entity = new Entity("Entry", key);
    entity.setUnindexedProperty("value", map.getKey());
    /* or, if a value can be longer than 500 characters
     * entity.setUnindexedProperty("value", new Text(map.getKey()));
     */

    batch.add(entity);
    if (batch.size() == 500) {
         datastore.put(batch);
         batch.clear();
    }
}
datastore.put(batch);

如果您不需要知道前端的所有鍵,這將起作用。 如果這樣做,則檢查keySet()是否小於1MB,以便可以將其作為對象放入Memcache。 如果更大,則跳過內存緩存部分,僅使用數據存儲區即可:

Query q = new Query("Entry");
// etc.

暫無
暫無

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

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