2014-07-03 94 views
6

我有一個原型風暴應用程序,它讀取STOMP流並將輸出存儲在HBase上。它可以工作,但不是很靈活,我試圖讓它與其他應用程序以更一致的方式建立,但沒有太多的運氣來弄清楚目前與Storm合作的方式。我們使用spring-jms類,但不是以標準Spring方式使用它們,而是在運行時創建它們,並手動設置依賴關係。Storm和Spring 4集成

這個項目:https://github.com/granthenke/storm-spring看起來很有希望,但是它已經有兩年沒有被觸及過,並且由於風暴罐被帶入了阿帕奇孵化器並被重新包裝,所以沒有正確地建造。

有沒有我失蹤的東西,還是不值得我一陣子把這些東西整合起來?

+2

你的意思是你想配置一個基於Spring的噴嘴/螺栓和屬性配置Storm?確切地說,是 – zenbeni

+0

。我們在那裏使用spring-jms和其他一些東西,風暴使用的IOC模式和IOC模式彈簧使用的構建器模式有點不一致。如果能夠讓我們的代碼庫與我們其他的Java項目保持一致,那麼額外的XML將會引入這個命中,我很好。 – liam

回答

5

事實上,風暴春天似乎是你在找什麼,但它不更新,並有限制(無法定義的,例如螺栓/嘴等任務)。也許你應該推出自己的整合?

不要忘記你的目標:有很多工人的集羣。當您將一個工作人員的風暴api(例如重新平衡)部署到您的拓撲時,Spring如何運作?這是否意味着在Storm部署目標螺栓/噴口並定義執行器之前,它必須在啓動時在工作器JVM上實例化新的Spring上下文?恕我直言,如果你只在Spring配置中定義了Storm組件,它應該可以工作(拓撲的啓動配置,然後風暴只管理對象),但是如果你依靠Spring來管理其他組件(Spring-jms似乎是這樣) ,那麼它可能會在拓撲重新平衡(例如每個worker/jvm?或整個拓撲?)上變得混亂。

這是由你來決定是否值得麻煩,我對Spring配置的擔心是你很容易忘記風暴拓撲結構(它似乎是一個JVM,但可以更多)。就個人而言,我爲每個類加載器定義了自己的單例(例如static final或者如果我需要延遲實例,則使用雙重檢查鎖定),因爲它不會隱藏(中高)複雜度。

+0

好點。我接受了這個,我將重新評估我們如何將應用程序放在一起。 – liam

+0

@zenbeni我有一些服務層類需要注入風暴拓撲。我無法正常創建它們,因爲它們依次具有將在春季自動裝配的依賴關係。現在,我能做什麼? – user12458

1

我意識到這是事後,但你認爲使用Apache駱駝的JMS連接處理?駱駝不是IOC或DI,但它確實模擬了企業集成模式。也許這就是你正在尋找的東西?

Nick。

6

@zenbeni已經回答了這個問題,但我想告訴你我的執行情況,很難將噴嘴/螺栓作爲彈簧豆。但是要在你的噴嘴/螺栓內使用其他彈簧,你可以在執行方法中聲明一個全局變量&檢查變量是否爲空。如果它爲空,則必須從應用程序上下文獲取bean。創建一個包含初始化bean的方法的類,如果它尚未初始化。查看ApplicationContextAware接口以獲取更多信息(Spring bean重用)。

示例代碼:

螺栓類:

public class Class1 implements IRichBolt{ 
    Class2 class2Object; 

    public void prepare() { 
     if (class2Object== null) {   
      class2Object= (Class2) Util 
       .initializeContext("class2"); 
     } 
    } 
} 

的Util類初始化豆如果尚未初始化:

public class Util{ 
    public static Object initializeContext(String beanName) { 
     Object bean = null; 
     try { 
      synchronized (Util.class) { 
       if (ApplicationContextUtil.getAppContext() == null) { 
        ApplicationContext appContext = new ClassPathXmlApplicationContext("beans.xml"); 
        bean = ApplicationContextUtil.getAppContext().getBean(
         beanName); 
       } else { 
        bean = ApplicationContextUtil.getAppContext().getBean(
         beanName); 
       } 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     return bean; 
    } 
} 

監聽器應用環境的變化:

@Component 
public class ApplicationContextUtil implements ApplicationContextAware { 

    private static ApplicationContext appContext; 

    public void setApplicationContext(ApplicationContext applicationContext) 
     throws BeansException { 
     appContext = applicationContext; 
    } 

    public static ApplicationContext getAppContext() { 
     return appContext; 
    } 
} 

注意:每個Worker都會初始化Spring上下文,因爲它運行在不同的JVM中。

UPDATE

如果你想使用中,你必須事先指定嘗試一些這方面的價值彈簧bean類,

注:傳遞當前類博爾特的構造

類(拓撲創建類),它已包含值:

public class StormTopologyClass implements ITopologyBuilder, Serializable { 
    public Map<String, String> attributes = new HashMap<String, String>(); 

    TopologyBuilder builder=new TopologyBuilder(); 
    builder.setBolt("Class1",new Class1(this)); 
    builder.createTopology(); 
} 

螺栓由我們荷蘭國際集團單參數的構造函數:

public class Class1 implements IRichBolt{ 
    StormTopologyClass topology; 

    public Class1 (StormTopologyClass topology) { 
     this.topology = topology; 
    } 
} 

現在你可以使用屬性變量&它在螺栓類值。

+0

偉大的評論。這就是我們現在正在經歷的。 – markthegrea

+0

@markthegrea你可以在prepare方法中進行初始化,因爲每次有新元組進入時,execute方法都會運行。 – Ajeesh

+0

是的,這就是我們發現的,但是我們得出的結論是Spring只是Bolts的不正確範例。這些螺栓可以移動到許多jvms,而Spring的美麗就是單身。那麼,爲什麼在創建對象的20個副本時使用Spring?另外,你必須在每一個例子中開始涌現,這需要時間。 – markthegrea