2016-05-11 63 views
3

點燃了一個夢幻般的「零部署」的功能和它的工作流程如下:如何點燃零部署工作

  1. 點燃會檢查是否類是可用的本地類路徑(即如果 它在系統加載啓動),如果是,則返回 。在這個 的情況下,沒有來自對等節點的類加載會發生。
  2. 如果類不是本地可用的,那麼請求將被髮送到起始節點 以提供類定義。發起節點 將發送類字節碼定義,並且該類將被加載到工作者節點的 上。這種情況只發生在每個班級 - 一旦 定義加載到一個節點上,就不會再次加載 。

而且我寫的示例代碼:

Collection<Long> broadcastResult = compute.broadcast(new IgniteCallable<Long>() { 
       @Override 
       public Long call() throws Exception { 
        long result = 0; 
        Long total = getTotal(10); 
        for (int i = 0; i < total; i++) { 
         LOGGER.info("adding {}, result {}", i, (result = result + i)); 
        } 
        return result; 
       } 
      }); 
... 
    public static Long getTotal(long total) { 
      LOGGER.info("Total:{}", total); 
      return total; 
     } 

,它工作正常,遠程節點印刷add xxx數十倍。但我真的很想知道如何?

  1. 如何點燃知道My IgniteCallable Instance需求 getTotal(long total)方法?
  2. 點燃如何轉移My IgniteCallable Instance's Byte Code到 遠程節點,當我只給他My IgniteCallable Instance's Reference而不是一個類文件?

請幫我一下,謝謝!

回答

0

回答你的問題。

  1. 最初您的IgniteCallable被序列化並通過電線發送。當JVM開始執行它時,當需要getTotal時,它將查找具有此方法的類定義,並且如果JVM未在本地找到它,它也會從源節點預加載它。

  2. 一切都很簡單。基本上我們只需要Class你的實例使用像igniteCalllable.getClass()這樣的調用序列化它並通過線路發送。如果你看看Class對象源代碼,你會看到它的Serializable

+0

小修正。 'getTotal'方法是靜態的,因此封裝類的實例不是序列化的(甚至可能不存在)。但是當這個類需要它時,這個類的字節碼將被服務器節點的類加載器加載。 –

+0

感謝您的回答。我想出了一些觀點,但並不完全清楚。當一個節點發送IgniteCallable實例到遠程節點執行時,它會以一般方式序列化。關鍵點是遠程節點有一個特殊的類加載器。在反序列化過程中。類加載器的resolve()方法將被調用,並且所有相關的類將被傳遞給類加載器,並且類加載器將嘗試從本地加載類,如果local有,或者廣播'Class Fetch'請求並從其他節點獲取。但我並不確定或清楚。 – BilboDai

+0

你的理解幾乎完全正確。我唯一的補充是,只有當JVM在需要依賴類時到達執行點時,纔會加載一個依賴類,在IgniteCallable的源代碼中使用某些方法或實例。 – dmagda