摘 要:獲取組合服務執(zhí)行的拓撲結(jié)構(gòu)有很多重要的意義,比如說可以讓程序員更清楚的知道組合服務的調(diào)用關系,可以通過每個原子構(gòu)建的參數(shù)來通過拓撲結(jié)構(gòu)構(gòu)建組合服務的相應參數(shù),可以更直觀的分析具體實例的執(zhí)行。為了上述目的,我們要采取一定的工作來獲取SOA組合服務的拓撲結(jié)構(gòu)。
關鍵詞:SOA組合服務 獲取
中圖分類號:P208 文獻標識碼:A 文章編號:1672-3791(2012)10(a)-0015-02
SOA就是面向服務的體系結(jié)構(gòu),SOA中一個重要的概念就是服務組合,完成組合服務的各個原子服務分布在網(wǎng)絡上各個不同網(wǎng)絡位置。為此我們出于分析組合服務參數(shù)等目的,要獲取組合服務的拓撲結(jié)構(gòu)。和一般的程序或者軟件一樣,我們在設計階段很容易的知道一個組合服務或者說一個軟件的整體拓撲結(jié)構(gòu),這個整體拓撲結(jié)構(gòu)是整個軟件或者說程序的體系結(jié)構(gòu),是在程序或者軟件設計時期就已經(jīng)根據(jù)程序需求或者軟件需求就已經(jīng)知道的。然而在程序或者軟件的執(zhí)行過程中,并不是所有在整體拓撲結(jié)構(gòu)中出現(xiàn)的構(gòu)建都會被執(zhí)行,也可以說并不是這個整體拓撲圖都會被執(zhí)行,在實際執(zhí)行過程中,往往只執(zhí)行了整體拓撲結(jié)構(gòu)中的一部分,這執(zhí)行的一小部分顯而易見的是整體拓撲結(jié)構(gòu)的一個子圖,這篇論文的目的就是要獲取這樣一個多個原子服務組合而成的實際執(zhí)行了的組合服務的執(zhí)行拓撲結(jié)構(gòu)。那么如何來獲取這樣一個拓撲結(jié)構(gòu)還有一定的工作要做。
1 獲取SOA組合服務拓撲結(jié)構(gòu)的抽象方法
我們采用的方法是采用一串字符來表示組合服務調(diào)用的拓撲結(jié)構(gòu)。在每個原子服務執(zhí)行的開始和結(jié)尾做上標記(在本篇文章中,我們做標記的方法是在服務A執(zhí)行的開始輸出標記AO和結(jié)尾輸出標記A1),此標記要求與服務一一對應,這樣,組合服務執(zhí)行完畢后會得到一串標記。而此時得到的標記與組合服務的執(zhí)行拓撲結(jié)構(gòu)是一一對應的。
舉個例子來說,一個簡單的A,B兩個原子服務,如果發(fā)生A調(diào)用B的組合服務,則會得到AOBOB1A1的這樣一串標記。較為復雜的組合服務也一樣,會得到一個與執(zhí)行拓撲結(jié)構(gòu)相一致的一串標記。
如圖1的組合服務。
則會得到這樣一串標記:SOAOCOC1 A1BODOFOF1GOG1D1EOE1B1S1。這樣一串標記可以還原為拓撲樹。因此,我們可以獲得表示拓撲結(jié)構(gòu)的字符串,可以通過獲得這樣的字符串來間接還原為拓撲結(jié)構(gòu)。這樣在開發(fā)程序或者軟件模塊的時候,可以在程序或者軟件組件執(zhí)行的開始和結(jié)尾中加入標記,當然對于不用或者沒必要監(jiān)控的模塊,我們不必這樣做,這樣可以屏蔽一些不需要關注的細節(jié)模塊,可以通過這樣簡化拓撲結(jié)構(gòu)的復雜度,關注我們關注的重點。以上是獲取拓撲結(jié)構(gòu)的抽象方法,另外還涉及到具體實施的問題。
2 獲取拓撲結(jié)構(gòu)方法的具體實現(xiàn)
在具體實施的過程中,我們還遇到了一類具體問題。在上述方法中,我們要求輸出標志,這需要在程序或者軟件組件的開始和結(jié)尾中編寫輸出標志的代碼,這就要求軟件或者程序要求在開發(fā)階段就在代碼中植入,是對程序開發(fā)有設計要求的,但是由于SOA服務的特殊性,SOA服務是一個廣泛的范圍,它在網(wǎng)絡上分布于不同的節(jié)點,也由不同的開發(fā)者開發(fā),對這樣一個開放的環(huán)境中所有的開發(fā)者做出設計要求是不現(xiàn)實的,因為不可能所有的開發(fā)者都會事先知道我們對于拓撲結(jié)構(gòu)的需求,從而不會按我們所預計的那樣事先編入所要的輸出拓撲結(jié)果標志的代碼。這顯然成為了一個需要解決的問題:如何在服務程序或者軟件中插入輸出標志代碼?
對此我們采用的方式是在知道服務程序源代碼的情況下使用面向方面(或者說面向切面,Aspect Oriented Programming簡稱AOP)的方法來執(zhí)行代碼的植入功能。面向方面的方法有很多應用的地方,在這篇論文中,我們所應用到的僅僅是達到我們目的的面向方面方法中的一小部分,也就是進行輸出標志代碼的植入,這也使得AOP對于這個應用也容易實現(xiàn),程序員不需要太多的培訓就可以達到這個目的。我們舉個簡單的例子來說明AOP如何在已有程序或者組件中植入輸出標志。我們采用AOP的方法,可使用AspectJ軟件來對原程序進行編寫含有插入代碼方面(或者說切面),并在適當?shù)臅r機把輸出標志代碼植入原程序,從而成為帶有拓撲字符輸出的不影響原程序功能的程序。
下面是主程序的代碼,在下面的程序中主程序調(diào)用了一個子方法sayHello();我們通過把下列程序通過面向方面的方法來改造成能夠輸出拓撲字符的程序來說明改造的簡單方法,在下面的程序中,我們將會通過改造來捕獲sayHello()方法的使用,程序一旦調(diào)用了sayHello()方法,或者說sayHello()這個模塊,那么改造后的程序就會給出相應的字符說明,通過這個字符我們能說明在何時何處調(diào)用了這個方法。
public class Hello
{
public static void sayHello()
{
System.out.print(\"Hello\");
}
public static void main(String[] args)
{
sayHello();
}
}
要完成對程序的改造,就要為原程序添加和編寫所謂的方面,方面包括了兩方面的內(nèi)容:一類是要匹配插入代碼的方法名(或者說是模塊名字,組件名字了,示具體情況而定);第二類是要在匹配的方法或者組件、模塊的開始之前和結(jié)束之后輸出拓撲字符。下面定義方面的代碼中的注釋很好的解釋了代碼的作用。
public aspect World
{
pointcut greeting():execution(* Hello.sayHello(..));//指定要注入代碼的切入點greeting()為sayHello()方法
before():greeting()//在切入點greeting()執(zhí)行之前執(zhí)行下面中括號中的代碼,即輸出
{
System.out.print(\"sayHello方法執(zhí)行開始\");
}
after() returning():greeting()
{
System.out.print(\"sayHello方法執(zhí)行結(jié)束\");
}
}
在把上面的方面類與原程序進行編織后可以得到捕獲調(diào)用sayHello()方法,在調(diào)用它之前程序會輸出“sayHello方法執(zhí)行開始”,調(diào)用結(jié)束后會輸出“sayHello方法執(zhí)行結(jié)束”。這樣我們就能夠知道這個方法在何時被調(diào)用,對于更復雜的多個方法、組件、模塊的捕獲與上述方法類似,為了簡便我們可以用類似于AoA1這樣的輸出,上述例子為了更清楚的說明沒有用這類字符而用“sayHello方法執(zhí)行開始”,“sayHello方法執(zhí)行結(jié)束”這樣讓我們對例子更清楚。通過這個簡單的例子可以告訴我們怎么去解決實施獲取拓撲結(jié)構(gòu)字符的問題。
3 結(jié)語
隨著SOA的發(fā)展,對于分析SOA服務性能的需求越來越迫切,而本文對SOA組合服務拓撲結(jié)構(gòu)的獲取方法作了一定的分析,并有力的為分析SOA組合服務性能做了一定的支撐和鋪墊。
參考文獻
[1] 劉中兵.開發(fā)者突擊:精通AOP[m].電子工業(yè)出版社,2008,10.