![參考作業(yè)大ice for java開(kāi)發(fā)指南_第1頁(yè)](http://file4.renrendoc.com/view/fe37515eccca138f1db236a57721be52/fe37515eccca138f1db236a57721be521.gif)
![參考作業(yè)大ice for java開(kāi)發(fā)指南_第2頁(yè)](http://file4.renrendoc.com/view/fe37515eccca138f1db236a57721be52/fe37515eccca138f1db236a57721be522.gif)
![參考作業(yè)大ice for java開(kāi)發(fā)指南_第3頁(yè)](http://file4.renrendoc.com/view/fe37515eccca138f1db236a57721be52/fe37515eccca138f1db236a57721be523.gif)
![參考作業(yè)大ice for java開(kāi)發(fā)指南_第4頁(yè)](http://file4.renrendoc.com/view/fe37515eccca138f1db236a57721be52/fe37515eccca138f1db236a57721be524.gif)
![參考作業(yè)大ice for java開(kāi)發(fā)指南_第5頁(yè)](http://file4.renrendoc.com/view/fe37515eccca138f1db236a57721be52/fe37515eccca138f1db236a57721be525.gif)
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、ICE For Java 開(kāi)發(fā)指南Leader 精品充電系列/,淘寶官網(wǎng):有大量高質(zhì)量學(xué)習(xí)代碼可供,技術(shù)交流前言ICE 版本為 3.5.1,開(kāi)發(fā)環(huán)境為 Java 7+Eclipse,開(kāi)發(fā)環(huán)境準(zhǔn)備如下:安裝 JDK 7+Ecliplse安裝 ICE Windows 版本: ht/download/Ice/3.5/Ice-3.5.1-2.msi安裝 ICE for Eclipse 插件:ht/eclipse.html ,注意Home 路徑,eclipse-windows-Preference 里 Slice2Java:Zero ICE的o world 程序?yàn)榱丝焖僬莆?ICE 的編程特性,讓從最基
2、礎(chǔ)的o World 程序開(kāi)始,定義一個(gè)服務(wù),取名為訂票 OnlineBook,該服務(wù)提供一個(gè)方法 bookTick,實(shí)現(xiàn)訂票功能,此方法需要一個(gè)參數(shù),包括所訂票的名稱(name) ,如變形5、票的類型(type) ,如票、價(jià)格(price)、客戶 定制要求(content) 、若票源暫時(shí)緊張也預(yù)訂成功(valid=true )等,為此封裝為 Java Bean ,名稱為 Message ,如下定義:public class Messagepublic String name;publicpublictype;valid;public double price;public String con
3、tent;若你細(xì)心點(diǎn),會(huì)發(fā)現(xiàn)這個(gè)結(jié)構(gòu)包括了大多數(shù)常用的數(shù)據(jù)類型:字符串、整型、布爾值、小數(shù),這樣做的原因很簡(jiǎn)單,為了驗(yàn)證多語(yǔ)言情況下的接口兼容問(wèn)題。定義的訂票服務(wù)的接口如下:publicerface OnlineBooK Message bookTick(Message msg)該服務(wù)返回一個(gè) Message 對(duì)象,這么做的原因是因?yàn)榻^大多數(shù)方法調(diào)用都會(huì)有返回值,對(duì)于 RPC 調(diào)用來(lái)說(shuō),有返回值的調(diào)用代表著 RPC 方法調(diào)用是否成功,而沒(méi)有返回值的調(diào)用,則無(wú)法確定是否成功,因?yàn)橄l(fā)出去也可能在服務(wù)端無(wú)法處理,另外,只有對(duì)有返回值的 RPC 方法進(jìn)行性能測(cè)試,才是有代表性的結(jié)果。上面這個(gè)簡(jiǎn)單的
4、的程序設(shè)計(jì),正好體現(xiàn)了編程中的經(jīng)驗(yàn)和思考的重要性。ow World理解了上述訂票服務(wù)的接口、數(shù)據(jù)結(jié)構(gòu),接下來(lái)看看怎樣用 ICE 將它變成神奇的RPC 調(diào)用,為了解決跨語(yǔ)言問(wèn)題,ICE 中采用了業(yè)界通常的標(biāo)準(zhǔn)做法,即用一個(gè)“中立”的語(yǔ)法定義文件來(lái)定義 RPC 方法接口,并提供工具編譯為各種第立語(yǔ)法就是ICE 設(shè)計(jì)的 slice 語(yǔ)言,后綴名為 ice,用 slice 語(yǔ)言定義成了如下的方式:語(yǔ)言的接口,這個(gè)中的訂票服務(wù),就變modu.hp.iceookstruct Message string name;type; bool valid; double price;string content;
5、erface OnlineBookMessage bookTick(Message msg);第一行,是特定含義的注釋,告訴 Java 的slice 轉(zhuǎn)換器,轉(zhuǎn)化為 Java 代碼的時(shí)候,上述接口是在 com.hp.ice 下產(chǎn)生代碼。module 關(guān)鍵字定義了本接口的模塊名字 module,這個(gè)module 在Java 中就是 package 的一部分,在其他語(yǔ)言中也有對(duì)于的概念。 struct 關(guān)鍵字定義了一個(gè)結(jié)構(gòu)體,來(lái)自 C 的概念,注意是 struct 不能嵌套 struct。 erface關(guān)鍵字則定義了 RPC 服務(wù)和相關(guān)接口。從上面的定義來(lái)看,slice 語(yǔ)言還是很簡(jiǎn)單清晰,基本上
6、你只要花費(fèi)半天時(shí)間,就能覆蓋 90%以上的工作需求。ICE 提供了從 slice 到大多數(shù)主流語(yǔ)言的轉(zhuǎn)化工具,命名為 slice2,比如slice2java、slice2cplus、slice2py、slice2、slice2rb、在 ICE 的安裝目錄的 bin下,你可以看到上述這些命令??梢酝ㄟ^(guò)命令行執(zhí)行 slice 接口到其他語(yǔ)言的轉(zhuǎn)化,生成相應(yīng)的代碼:slice2java.ice現(xiàn)在讓開(kāi)始正式編程吧,打開(kāi) Eclilpse,建立一個(gè)普通的 Java 工程:點(diǎn)擊工程的右鍵菜單,選擇 slice2java 子菜單,執(zhí)行”add slice2java builder”,添加 slice2ja
7、vabuilder 之后,項(xiàng)目自動(dòng)產(chǎn)生了兩個(gè)文件夾,slice 目錄存放 slice 文件、generated 目錄存放生成的 java 源文件,同時(shí)項(xiàng)目也添加了 ICE 依賴庫(kù)(IceLibrary),ICE 依賴庫(kù)只有一個(gè):ICE.jar,沒(méi)有復(fù)雜的第ICE 的一個(gè)優(yōu)點(diǎn)。包,容易集成項(xiàng)目,這也是接下來(lái)只要在 slice 文件夾中創(chuàng)建一個(gè)后綴為 ice 的slice 文件,保存以后,slice2java 插件就自動(dòng)生成對(duì)應(yīng)的 java 源文件了,保存在 generated 目錄下。service.ice有沒(méi)有slice 的maven 插件呢?很不幸,沒(méi)有,但 ICE給出一個(gè)利用 ant 來(lái)在
8、可以試試,畢竟大項(xiàng)目中基本都用 maven 來(lái)完成構(gòu)中執(zhí)行上述過(guò)程的實(shí)現(xiàn)參考,有建過(guò)程了。4.0.0/mVer/grouject.grouject.artifactId0.0.1-SNAPSHOT/usr/share/Ice-3.4.2/slice/Icecom.zerocice3.5.1maven-antrun-plugin1.7generate-sourame=Slice2JavaTaskfileset dir=src/main/resour includes=fileSystem.iale.ice /runcom.zeroce3.5.1.codehaus.mojobuild-helper
9、-maven-plugin1.7add-sourcegenerate-souradd-sourcesoursourrc/generated/javaSlice2java 生成的Java 類如下:下面用 UML 工具(eclipse green uml 插件)看看 ICE 編譯后的類之間的關(guān)系,Slice 中的接口對(duì)象 OnlineBook 會(huì)產(chǎn)生三個(gè)相關(guān)的 Java 接口類:OnlineBookOperation、OnlineBookOperations、以及繼承了這兩個(gè)接口和 ICE.Object根接口的 OnlineBook 接口,OnlineBookOperations 與OnlineB
10、ookOperation為姊妹接口,了OnlineBook 服務(wù)中的方法,不同的是 OnlineBookOperations 在方法簽名中增加了ICE 的對(duì)象 Ice.Current,這個(gè) Current 對(duì)象包括了當(dāng)前調(diào)用的網(wǎng)絡(luò)連接等信息,ICE.Object 對(duì)象則代表了一個(gè)對(duì)象,對(duì)象的 ID、以及驗(yàn)證對(duì)象是否存活的方法,都在此接口中定義,一個(gè)實(shí)現(xiàn)了本接口的對(duì)象在 ICE 中被稱之為服務(wù)實(shí)例 servant。OnlineBookDisp 則是實(shí)現(xiàn)了 OnlineBook 接口的抽象類,完成了基本的 RPC 過(guò) 程,其中 Disp 代表著 Dispatch,即調(diào)用分發(fā),從下面的 Online
11、BookDisp 的下面方法即可看出ICE RPC 的基本實(shí)現(xiàn)原理:public sic Ice.DispatchS inS, Ice.Currentcurrent)us bookTick(OnlineBook obj,ingcheckMode(Ice.OperationMode.Normal,current.mode);/從Ice.Request 中RPC 請(qǐng)求所關(guān)聯(lián)的網(wǎng)絡(luò)通道中RCP 方法的參數(shù)Iceernal.BasicStreamis =inS.startRearams();Message msg;msg = new Message();/反序列化,填充 Message 對(duì)象msg.
12、read( is);inS.endRearams();/調(diào)用用戶實(shí)現(xiàn)的 OnlineBook 的具體業(yè)務(wù)接口Messageret =obj.bookTick(msg, current);/將結(jié)果寫回到RCP 請(qǐng)求的網(wǎng)絡(luò)應(yīng)當(dāng)包中Iceernal.BasicStreamos =inS. startWriteParams(Ice.FormatType.DefaultFormat); ret. write( os);inS. endWriteParams(true);/完成調(diào)用return Ice.DispatchSus.DispatchOK;以下是Message 參數(shù)對(duì)象的序列化與反序列化方法的具體
13、實(shí)現(xiàn):public voidwrite(Iceernal.BasicStreamos)os.writeString(name);os.write(type);os.writeBool(valid); os.writeDouble(price);os.writeString(content);public voidread(Iceernal.BasicStreamis)name = type = valid =price =is.readString();is.read();is.readBool();is.readDouble();content =is.readString();如果熟悉 J
14、ava 的ObjectStream 類,則發(fā)現(xiàn)上述代碼看起來(lái)很相似,這是 Java 里最基本的對(duì)象到字節(jié)流的轉(zhuǎn)換邏輯,做過(guò) java 網(wǎng)絡(luò)編程的很多人都寫過(guò)類似代碼。通過(guò)上述分析過(guò)程, 發(fā)現(xiàn)一個(gè)有趣的現(xiàn)象,即 RPC 調(diào)用過(guò)程中的請(qǐng)求參數(shù)與應(yīng)答結(jié)果,在ICE 中都抽象為“參數(shù)”,將RPC 參數(shù)與返回 RCP 應(yīng)答結(jié)果的實(shí)現(xiàn)邏輯巧妙的起來(lái),代碼簡(jiǎn)單明了。細(xì)節(jié)決定成敗,ICE 號(hào)稱是業(yè)界最快的 RPC 框架,其設(shè)計(jì)和代碼質(zhì)量處處顯示功力。這里順便說(shuō)下關(guān)于多字節(jié)類型的數(shù)據(jù)在網(wǎng)絡(luò)上傳輸?shù)淖止?jié)順序問(wèn)題,這是網(wǎng)絡(luò)編程中的一個(gè)技術(shù)細(xì)節(jié),稱之為“網(wǎng)絡(luò)字節(jié)順序”,通常有“Little endian (將低序字節(jié)
15、在起始地址)”與“Big endian :將高序字節(jié)在起始地址”兩種,JAVA 采用BIG- Big endian方式,而Zero ICE 的則采取了 Little endian 模式,其文檔上這么說(shuō)的:“Data is always encoded using little-endian byte order for numeric types. (Most machines use a little-endianbyte order, so the Ice data encoding is right more oftenn not.)”,另外,還補(bǔ)充了一點(diǎn):“Ice requires c
16、nts and serverst run on big-endian machines to incur the extracost of byte swapdatao little-endian layout, butt cost is insignificant comparedto the overall cost of sending or receiving a request.”,那么 ICE 提到的“Most machines”是那些呢?猜猜就知道了,即 X86 體系的機(jī)器,它們采用 Little endian 的主機(jī)字節(jié)順序,而 RISE 等Unix 系列的機(jī)器則普遍采用 BI
17、G- Big endian 方式。這里若使用 ICE For Java,就遺留一個(gè)懸念了,它這個(gè) Java 版本的,是否是通過(guò)編程改變了 Java 默認(rèn)的“Big endian”方式呢?,因?yàn)?Java ByteBuffer 類是可以指定編碼方式的,方式如下: ByteBuffer.order(ByteOrder.LITTLE_ENDIAN),這個(gè)問(wèn)題就留給聰明的你去探索吧。從上述的 UML 類圖中的Ice.Object 對(duì)象,還看到 ICE 中很重要的一個(gè)概念:對(duì)象標(biāo)識(shí)(Identity),從其代碼來(lái)看,一個(gè) Ice.Object 可以綁定多個(gè) ID,但其中有一個(gè)是它最確切的真正的ID,ID
18、 用來(lái)查找和定位 RPC 的面代碼就很清晰的說(shuō)明了上述這些問(wèn)題:對(duì)象,_OnlineBookDisp 中的下public sic final Stringids =:Ice:Object,所有的 Ice Object 都有此 ID:book:OnlineBook這是 OnlineBook 這個(gè)Object 的真正 ID;publicice_isA(String s) 用來(lái)查找是否是某個(gè)對(duì)象return java.util.Arrays.binarySearch( ids, s) = 0;public String ice_ids()return ids;public String ice_id
19、()return ids1;如果你熟悉 J2EE 技術(shù),應(yīng)該對(duì)“Naming”這個(gè)詞不陌生, Naming Service 是J2EE 體系的最重要基礎(chǔ)組建之一,它的原理就通過(guò)某個(gè)指定的 ID 來(lái)查找綁定的對(duì)應(yīng) EBJ對(duì)象,ICE 里也有這個(gè)組件,它稱之為 Locator。既然是調(diào)用框架,那么須要將某個(gè)對(duì)象“綁定”到某個(gè)網(wǎng)絡(luò)通道,才能完成調(diào)用,ICE 用Ice.ObjectAdapter 這個(gè)對(duì)象來(lái)完成具體的相關(guān)工作,讓我看看 ObjectAdapter 接口中的幾個(gè)重要方法:void activate()激活此 Adapter 上綁定的 ICE 服務(wù)實(shí)例,類似 J2EE 容器的加載和鈍化EJ
20、B 實(shí)例的,用于實(shí)現(xiàn)服務(wù)器資源的合理利用,按需啟動(dòng)或停止。Ice.ObjectPrx add(Ice.Object servant, Identity id)將某個(gè)服務(wù)實(shí)例以某個(gè)名字綁定到本Adapter 上。Ice.ObjectPrx createProxy(Identity id)創(chuàng)建指定服務(wù)實(shí)例的 Proxy 對(duì)象。要了解的一個(gè)概念是“Endpo”,Endpo最后通常可以理解為一個(gè)地須給址,在 WebService 中也有這個(gè)詞:“當(dāng)Host 一個(gè) Web Service 的時(shí)候,他定義一個(gè)或多個(gè) Endpo,然后service 通過(guò)這個(gè)定義的 Endpo進(jìn)行來(lái)自Cnt端的請(qǐng)求。”,在
21、ICE 中,Endpiont 有兩種:UDP 或TCP,但基本上很少用 UDP,因?yàn)楝F(xiàn)在的高速網(wǎng)絡(luò)帶寬采用 TCP 長(zhǎng)連接情況下,UDP 基本沒(méi)優(yōu)勢(shì)了。怎么創(chuàng)建一個(gè)Endpo并綁定的ICE 服務(wù)?就是Communicator 對(duì)象,它是 ICE對(duì)象,溝通Cnt 與Server 端,它的關(guān)鍵方法如下:Ice.ObjectPrx stringToProxy(String str)將一個(gè)對(duì)象標(biāo)識(shí)轉(zhuǎn)換對(duì)應(yīng)的服務(wù)對(duì)象,用于客戶端調(diào)用ObjectAdapter createObjectAdapterWithEndpos(String name, Stringendpos)創(chuàng)建 ObjectAdapter
22、并把ObjectAdapter 綁定到指定的Endpos 上LocatorPrx getDefaultLocator()獲取默認(rèn)的服務(wù) Locator 對(duì)象,Locator來(lái)定位具體的ICE 服務(wù)實(shí)例。對(duì)象用于服務(wù)o World 所需的 ICE 對(duì)象都介紹完畢,接下來(lái)就可以寫具體的實(shí)現(xiàn)至此,代碼了,先寫服務(wù)端,在寫之前,你可以停下來(lái)想想下面幾個(gè)問(wèn)題:的服務(wù)代碼繼承哪個(gè)類?通常的網(wǎng)絡(luò)編程中,服務(wù)端的實(shí)現(xiàn)是哪幾個(gè)過(guò)程?。努力思考中??肌V?。下頁(yè)揭曉,敬請(qǐng)期待?。悍?wù)實(shí)現(xiàn)Disp 抽象如下:第一個(gè)問(wèn)題的第二個(gè)問(wèn)題的創(chuàng)建 SocketServer 在一個(gè) EndPo上,如 Localhost TCP
23、9999啟動(dòng)此SocketServer,在綁定的端口上進(jìn)行寫消息接收和處理的無(wú)限循環(huán)邏輯,直到停止服務(wù)Ok,先來(lái)寫服務(wù)實(shí)現(xiàn)類(servant),按照 ICE 的建議,servant 類的后綴名為I(Implement 縮寫),為了將 Slice 生成的java 代碼與的實(shí)現(xiàn)類分開(kāi),建議定義另外的報(bào)名來(lái)存放的實(shí)現(xiàn)類,服務(wù)的代碼為了簡(jiǎn)化,直接返回訂單請(qǐng)求:import Ice.Current;import com.hp.ice.book.Message;import com.hp.ice.book._OnlineBookDisp; public class OnlineBookI extends
24、_OnlineBookDispprivate sOverrideic final long serialVerUID = 1L;public Message bookTick(Message s, Currentcurrent) return s;接下來(lái)實(shí)現(xiàn) Sever 端代碼:public class Server public sic void main(String args) sus = 0;municator ic = null;try / 初始化 Communicator 對(duì)象,args 可以傳一些初始化參數(shù),如連接超時(shí),初始化客戶端連接池的數(shù)量等ic = Ice.Util.ini
25、tialize(args);/ 創(chuàng)建名為 OnlineBookAdapter 的適配器,并要求適配器使用缺省的協(xié)議(TCP/IP 端口為 10000 的請(qǐng)求)Ice.ObjectAdapter adapter = ic.createObjectAdapterWithEndpos(OnlineBookAdapter, default -p 10000);/ 實(shí)例化一個(gè) OnlineBook 服務(wù)對(duì)象OnlineBookI object = new OnlineBookI();/ 將服務(wù)單元增加到適配器中,并給服務(wù)對(duì)象指定 ID 為OnlineBook,該名稱用于唯一確定一個(gè)服務(wù)單元adapter
26、.add(object, Ice.Util.stringToIdentity(OnlineBook);/ 激活適配器 adapter.activate();/ 讓服務(wù)在退出之前,一直持續(xù)對(duì)請(qǐng)求的System.out.pr(server started );ic.waitForShutdown(); catch (Exception e) e.prStackTrace();sus = 1; finally if (ic != null) ic.destroy();System.exit(sus);Ierver 的代碼就這么簡(jiǎn)單,甚至比大多數(shù) NIO Socket 框架用起來(lái)都簡(jiǎn)單,下面再看看客戶
27、端相關(guān)的 UML 圖:Ice.ObjectPrx 代表一個(gè)對(duì)象的,實(shí)現(xiàn)了基礎(chǔ)的通信和方法調(diào)用框架,Del 接口定義了調(diào)用(DelD)和接口,對(duì)于每個(gè) ICE 服務(wù),ICE 默認(rèn)生成了兩個(gè)實(shí)現(xiàn)類:本地調(diào)用(DelM),前者用在服務(wù)直接調(diào)用的優(yōu)化過(guò)程中,即若多個(gè)ICE 服務(wù)部署在一個(gè) JVM 中并有相用關(guān)系的情況下,ICE 是能做優(yōu)化的;后者則是通過(guò)網(wǎng)絡(luò)進(jìn)行調(diào)用,ICE 的這個(gè)設(shè)計(jì)與 J2EE EJB 的本地接口有接口很相似,只不過(guò)它這邊把這個(gè)過(guò)程給自動(dòng)化和隱蔽了,抽象類 ObjectPrxHelperBase 里創(chuàng)建的這段代碼揭示了 ICE 服務(wù)調(diào)用優(yōu)化的_ObjectDel createDel
28、egate(:async)if(_reference.getCollocationOptimized()若具備優(yōu)化條件,則創(chuàng)建本地直對(duì)象DelDObjectAdapter adapter =接調(diào)用_reference.getInstance().objectAdapterFactory().findObjectAdapter(this); if(adapter != null)_ObjectDelD d =createDelegateD(); d.setup(_reference, adapter);return d;_ObjectDelM d =createDelegateM();d.set
29、up(_reference, this, async); return d;在這里,繼承了 ObjectPrxHelperBase 的OnlineBookPrxHelper 實(shí)現(xiàn)了OnlineBookPrx 接口,具體的調(diào)用邏輯工作則交給 _OnlineBookDelD 或者或_OnlineBookDelM 來(lái)完成,前者是本地調(diào)用,不涉及到網(wǎng)絡(luò)通信,后者的代碼如下:public Message bookTick(Message msg, java.util.Mapctx,Ice.Instrumenion.InvocationObserver observer)throws Iceernal.L
30、ocalExceptionWrapper/得到網(wǎng)絡(luò)通信的輸出通道Iceernal.Outgoingog =handler.getOutgoing(bookTick,Ice.OperationMode.Normal,ctx,observer);trytry/寫RCP 調(diào)用的參數(shù),Message 對(duì)象序列化到輸出流中Iceernal.BasicStreamos =og.startWriteParams(Ice.FormatType.DefaultFormat); msg. write( os);og.endWriteParams();catch(Ice.LocalExceptionex)og.ab
31、ort( ex);/發(fā)送數(shù)據(jù)并檢查是否成功ok =og.invoke();tryif(! ok)tryog.throwUserException();catch(Ice.UserException ex)throw new Ice.UnknownUserException( ex.ice_name(),/等待服務(wù)端的響應(yīng)結(jié)果消息,并反序列化為 Message 應(yīng)答對(duì)象ex);Iceernal.BasicStreamis =og.startRearams();Messageret;ret = new Message(); ret. read( is); og.endRearams();retur
32、nret;catch(Ice.LocalExceptionex)throw new Iceernal.LocalExceptionWrapper( ex, false);finally/此次調(diào)用handler.reclaimOutgoing( og);經(jīng)過(guò)上述分析,基本能夠理解 ICE 客戶端的調(diào)用實(shí)現(xiàn)原理了,接下來(lái)就來(lái)實(shí)現(xiàn)Cnt 代碼:public class Cnt public sic void main(String args) sus = 0;municator ic = null;try / 初始化通信器ic = Ice.Util.initialize(args);/ 傳入服務(wù)單元
33、的名稱、網(wǎng)絡(luò)協(xié)議、IP 以及端口,獲取OnlineBook 的,這里使用 stringToProxy 方式Ice.ObjectPrx base = ic.stringToProxy(OnlineBook:default -p 10000);/ 通過(guò) checkedCast 向下,獲取OnlineBook 接口的,并同時(shí)檢測(cè)根據(jù)傳入的名稱獲取服務(wù)單元是否 OnlineBook 的null 對(duì)象OnlineBookPrx onlinBook = OnlineBookPrxHelper.checkedCast(base);if (onlinBook = null) throw new Error(I
34、nvalid proxy);/ 調(diào)用服務(wù)方法Message msg = new Message(); = Mr Wang; msg.type = 3;msg.price = 99.99; msg.valid = true;msg.content = abcdef;接口,如果不是則返回long start=System.currentTimeMillis();count=100000;for(i=0;icount;i+)onlinBook.bookTick(msg);long used=System.currentTimeMillis()-start; System.out.pr(tps +co
35、unt*1000.0/used); catch (Exception e) e.prStackTrace();sus = 1; finally if (ic != null) ic.destroy();System.exit(sus);代碼中 OnlineBookPrx onlinBook = OnlineBookPrxHelper.checkedCast(base);這一段實(shí)際上是從只包括基礎(chǔ)的對(duì)象 ID、EndPo等相關(guān)信息的基礎(chǔ) ObjectPrx 類拷貝信息,并構(gòu)造一個(gè)具體的 ObjectPrx 實(shí)現(xiàn)類 OnlineBookPrxHelper,其源碼如下:public sic Onli
36、neBookPrx checkedCast(Ice.ObjectPrxobj)OnlineBookPrx d = null; if( obj != null)if( obj instanceof OnlineBookPrx)d = (OnlineBookPrx) obj;elseif( obj.ice_isA(ice_sicId()OnlineBookPrxHelperh = new OnlineBookPrxHelper();/構(gòu)造具體的 Proxy 類h. copyFrom( obj);/從基礎(chǔ) Proxy 中拷貝必要信息,包括連接等d =h;對(duì)象return d;啟動(dòng)Server,然后啟
37、動(dòng) Cnt,測(cè)試一下,看看你本機(jī)調(diào)用結(jié)果如何,我本機(jī)上達(dá)到 2.5 萬(wàn)每秒的性能,這個(gè)性能差不多是 HTTP 通道的 10 倍左右,也驗(yàn)證了 ICE 的高性能。下圖是ICE 客戶端與服務(wù)器端的通信原理圖,代碼,就分別存在于客戶端與服務(wù)器端:之前分析的哪些由ICE 生成的ICE 跨的實(shí)現(xiàn)原理,是通過(guò) Slice 定義的接口文件,分別編譯成不同語(yǔ)言的實(shí)現(xiàn)類,RPC 方法和參數(shù)采用特定的編碼方式,使得各個(gè)語(yǔ)言都能,從而實(shí)現(xiàn)跨語(yǔ)言的調(diào)用,這類似 Cobra 的做法,下圖是一個(gè) C 開(kāi)發(fā)的 ICE 服務(wù)被 Java 客戶端調(diào)用的原理示意圖:本節(jié)最后留幾個(gè)小問(wèn)題:Endpo中的default 是什么含義若
38、客戶端在另外的機(jī)器上,客戶端在構(gòu)造 ObjectPrx 的時(shí)候,怎么指定服務(wù)端的 IP地址?(提示:若熟悉若服務(wù)在多個(gè)機(jī)器上命令行的連接,估計(jì)立即想到,客戶端怎么調(diào)用?)好用的 Icebox面的o World 一章中,初步了解了ICE 的原理,掌握了其重要概念:ICE 服務(wù)(servant)、服務(wù)的 ID、servant 綁定到ObjectAdaptory 上、服務(wù)的 Endpo等,通過(guò)編寫簡(jiǎn)單的o World 程序,也掌握了其基本用法。接下來(lái),開(kāi)始學(xué)習(xí)ICE 的服務(wù)框架Icebox,這個(gè)類似一個(gè) J2EE 中間件,可以大大的簡(jiǎn)化服務(wù)端的開(kāi)發(fā),讓“只開(kāi)發(fā)服務(wù)本身”而不是“開(kāi)發(fā)完整系統(tǒng)”。簡(jiǎn)單的
39、說(shuō),Icebox 就好象是一個(gè) Tomcat 中間件,只要寫N 個(gè)ICE 服務(wù)的代碼,然后用一個(gè)裝配文件定義需要加載的服務(wù)列表、服務(wù)的啟動(dòng)參數(shù)、啟動(dòng)次序等必要信息,然后啟動(dòng)IceBox,的應(yīng)用系統(tǒng)就能夠正常運(yùn)行了。與現(xiàn)在流行的 XML 文件配置不同,Icebox 采用的是Unix 上通用的方式屬性文件的方式,可能的一個(gè)原因是省去復(fù)雜的 XML和相關(guān) lib 吧。另外,一個(gè) IceBox創(chuàng)建一個(gè) service manager 的對(duì)象(Ice.Admin),這個(gè)對(duì)象專門負(fù)責(zé) loading 和initializing 那些配置好了的服務(wù),你可以選擇性地將這個(gè)對(duì)象給的客戶端,譬如 IceBox 或
40、者IceGrid 的administrative utilities,這樣 IceBox 和IceGrid就可以執(zhí)行某些管理任務(wù),Ice.Admin 默認(rèn)是關(guān)閉的,而在 IceGrid 中部署的 IceBox,則會(huì)被自動(dòng)地激活。要將一個(gè) ICE 服務(wù)納入到 Icebox 中,需要引入 IceBox.jar 這個(gè)庫(kù),另外只需讓這個(gè)服務(wù)的實(shí)現(xiàn)類實(shí)現(xiàn) Ice 的Service 接口,此接口定義如下:void start(String name,municator communicator, String args) 服務(wù)可以在start 操作中初始化自身;這通常包括創(chuàng)建對(duì)象適配器和 和args 參數(shù)
41、提供了來(lái)自服務(wù)的配置的信息,而 communicator 參數(shù)是服務(wù)管理器municator 對(duì)象。取決于服務(wù)的配置,這個(gè)通信器為供服務(wù)使用而創(chuàng)建的實(shí)例可能會(huì)由同一個(gè) IceBox 服務(wù)器中的其他服務(wù)共享,因此,你需要注意確保像對(duì)象適配器(ObjectAdapter)這樣的對(duì)象的名字是唯一的。void stop()stop 方法中回收所有被 service 使用的資源,一般在 stop 中 service 會(huì)使一個(gè) object adapter 對(duì)象無(wú)效(deactivates),不過(guò)也有可能對(duì) object adapter 執(zhí)行一個(gè) wartForDeactivate 的方法來(lái)確保所有未完成
42、的請(qǐng)求在資源前得到處理,默認(rèn)會(huì)將它的 object adapter 作為communicator 銷毀的一部分連同communicator 對(duì)象一起 destory 掉,但某些情況下不能做到,如 IceBox 中servi使用共享的 communicator 對(duì)象時(shí),此時(shí)你需要明確指明銷毀它的 objectadapter 對(duì)象。繼續(xù)之前的例子,把 OnlineBook 服務(wù)變成 IceBox 托管的服務(wù),只要再增加一個(gè)類,實(shí)現(xiàn)上述接口,并在 start 里完成服務(wù)綁定即可,代碼如下:public class BoxOnlineBookI implements Service private I
43、ce.ObjectAdapter _adapter;private sic final long serialVerUID = 1L;priva/用來(lái)ogger getLogger() 服務(wù)的日志信息 returnmunicator().getLogger();Overridepublic void start(String name, Communicator communicator, String args) / 創(chuàng)建 objectAdapter,這里和service 同名_adapter = communicator.createObjectAdapter(name);/ 創(chuàng)建 ser
44、vant 并激活I(lǐng)ce.Object object = new OnlineBookI();_adapter.add(object, communicator.stringToIdentity(name);_adapter.activate(); getLogger().trace(name,servitarted ,with param size + args.length + ,detail:+ Arrays.toString(args);Overridepublic void stop() _adapter.destroy();接下來(lái)看看 Icebox 的配置文件,其配置文件分為兩部分,
45、一部分是共性,一部分是具體服務(wù)定義相關(guān)的配置:共性部分如下:#本Icebox 的實(shí)例名稱IceBox.InstanceName=MyAppIceBox 1#在所有服務(wù)的初始化完成之后,服務(wù)管理器將打印token ready。如果有 #要等待所有服務(wù)準(zhǔn)備就緒,這項(xiàng)特性很有用,下面例子就會(huì)輸出日志:#“ MyAppIceBox1 ready”想IceBox.PrServiReady= MyAppIceBox 1#定義服務(wù)的啟動(dòng)順序,解決服務(wù)啟動(dòng)過(guò)程中的先后順序問(wèn)題IceBox.LoadOrder=serv1,serv2,serv3#優(yōu)化本地服務(wù)之間調(diào)用的重要參數(shù),municator,若o 與Pre
46、r 兩個(gè)服務(wù)存在調(diào)用關(guān)系,又部署在一個(gè) Icebox 實(shí)例中,則可以定義兩者使用同一個(gè) Communicator 對(duì)象,實(shí)現(xiàn)服務(wù)本地調(diào)用的優(yōu)化。IImunicator.o=1municator.Prer=1#Ice 一些常用參數(shù)屬性Ice.MessageSizeMax = 2048 Ice.Trace.Network=1Ice.Trace.Threool=1Ice.Trace.Locator=1#定義 IceBox 服務(wù)管理器接口的端點(diǎn),以激活 IceBox 管理服務(wù)使之能夠被制,默認(rèn)是關(guān)閉的,在內(nèi)網(wǎng)中可以打開(kāi),并綁定私有地址??豂ceBox.ServiceManager.Endpos=tcp
47、 -p 9999 -h localhost下面是定義具體服務(wù)的時(shí)候參數(shù)格式,每個(gè)服務(wù)的參數(shù)格式如下:IceBox.S=entry_po-key=value argsname 這個(gè)屬性定義了 service 的名字,作為 start 方法的 name 參數(shù),必須唯一。entry_po到)。是上面的 service 的完整類名,必須可以在 classpath 中可以找-key=value 將會(huì)被作為property 屬性用于構(gòu)造該服務(wù)的communicator,用來(lái)更加精確的控制每個(gè) Ice 服務(wù)的性能調(diào)優(yōu),這里也可以用-Ice.Config=.cfg 的方式從具體服務(wù)的配置文件中加載參數(shù),具體是
48、一個(gè)大而全的配置文件,還是 N 個(gè)獨(dú)立的小配置文件,這是一個(gè)仁者見(jiàn)仁了,另外也可以用 IceBox.InheritProperties=1 這個(gè)屬性,讓所有的Ice 服務(wù)實(shí)例都使用 IceBox 的配置屬性。args部分則作為參數(shù)傳入到 start 方法的參數(shù) String args 中,作為服務(wù)的啟動(dòng)初始化參數(shù)。繼續(xù)上面的例子,的最終配置文件perties的內(nèi)容如下:#servropertiesIceBox.InstanceName=MyAppIceBox 1IceBox.InheritProperties=1IceBox.PrServiReady= MyAppIceBox 1IceBox.
49、ServiceManager.Endpo#performance propertiess=tcp -p 9999 -h localhostIce.Thre Ice.Thre Ice.ThreIce.Threool.Server.Size=4 ool.Server.SizeMax=100 ool.Server.SizeWarn=40ool.Cnt.Size=4Ice.ThreIce.Threool.Cnt.SizeMax=100ool.Cnt.SizeWarn=40#for system stronger Ice.ACM.Cnt=300Ice.ACM.Server=300 # log and t
50、race#表明日志存放在日志文件中,否則會(huì)在控制臺(tái)輸出日志#Ice.LogFile=ierv.logIce.PrStackTra=1Ice.Trace.Retry=2Ice.Trace.Network=2Ice.Trace.Threool=1Ice.Trace.Locator=2Ice.Warn.Connections=1 Ice.Warn.Dispatch=1Ice.Warn.Endpos=1#service define beginIceBox.Serv prop2=2 prop3=3.hp.serviceimp.BoxOnlineBook prop1=1OnlineBook.Endpos
51、=tcp -p 10000 -h localhost #service define end#service load orderIceBox.LoadOrder=OnlineBook#serviIhare communicatormunicator.OnlineBook=1上述文件若在 Java classpath 里(如跟java 類放在一起),則啟動(dòng) Icebox令如下,否則 Ice.Config 用絕對(duì)路徑即可:-Ice.Config=C:projectTestIceperties。java -cp .;C:ZeroCIce-3.5.1lib* IceBox.Server -Ice.C
52、onfig= perties啟動(dòng)成功以后,日志文件的輸出如下:從日志中看到,一共啟動(dòng)兩個(gè)端口:9999 為管理端口,10000 為的業(yè)務(wù)端口,線程池的數(shù)量大小也安裝的要求進(jìn)行了配置。提示:eclipse 中也可以啟動(dòng)和調(diào)試 Icebox,界面如下:下面增加另外一個(gè)服務(wù),SMSService,來(lái)測(cè)試服務(wù)之間調(diào)用定義如下(smsservice.ice):,其 slice 文件.hp.icemodule messageerfaMSServicevoid sendSMs(string msg);為了省去 Icebox 的服務(wù)包裝類,面是SMSService 的實(shí)現(xiàn)類:包裝類和業(yè)務(wù)實(shí)現(xiàn)類在一個(gè)對(duì)象里面實(shí)
53、現(xiàn),下public class SMSServiceI extends _SMSServiceDisp implements Service privaogger log;private ObjectAdapter _adapter;private sic final long serialVerUID =7L;Overridepublic void sendSMs(String msg, Currentcurrent) /log.trace(service, send sms message + msg);Overridepublic void start(String name, Comm
54、unicator communicator, String args) this.log = communicatetLogger().clithPrefix(name);/ 創(chuàng)建 objectAdapter,這里和service 同名_adapter = communicator.createObjectAdapter(name);/ 創(chuàng)建 servant 并激活I(lǐng)ce.Object object = this;_adapter.add(object, communicator.stringToIdentity(name);_adapter.activate(); log.trace(con
55、trol, started );Overridepublic void stop() log.trace(control, stoped );_adapter.destroy();這里將服務(wù)的日志通過(guò)克隆方法變成了另外的日志:communicatetLogger().clithPrefix(name),目的是日志輸出更加符合規(guī)范,log.trace 的第一個(gè)參數(shù)并非日志級(jí)別, 而是屬于分類這樣的概念,perties,增加下面的定義:修改IceBox.ServSMSService.Endpo.hp.serviceimp.SMSServiceIs=tcp -p 10001 -h localhost
56、IceBox.LoadOrder=OnlineBook,SMSService啟動(dòng)以后,觀察到日志里面 SMSService 與OnlineBook 的輸出有所不同:另外, 有一個(gè)有趣,是否可以將多個(gè)不同的服務(wù)綁定到同一個(gè)Endpo上去?用之前的 BoxOnlineBookI 這種單獨(dú)的類,在 Start 方法里面通過(guò)調(diào)用_adapter.add(object, communicator.stringToIdentity(name),增加多個(gè) IceObject 的方式是可以做到的,但此時(shí)這個(gè)類已經(jīng)不是 IceBox 的原本定義的“服務(wù)”概念了,其不建議多個(gè)服務(wù)綁定到同一個(gè) EndPo上,并解釋
57、如下:“It would besible for two IceBox servito share an endpo, but only if theservicooperated with one another to share a single object adapter instance (sinceobject adapters ownpos). This would certainly not be a typical use case for were configured to share a single communicator, eachIceBox. Even if
58、several serviservice would normally create its own object adapter and therefore get its own endpo.”至于是否多個(gè)Service 綁定到一個(gè)Endpo下日志:,這里還有另外一個(gè)重要原因需要考慮,看每一個(gè)服務(wù)都有自己的的線程池,這樣會(huì)避免一個(gè)服務(wù)導(dǎo)致另外的服務(wù)不可用,因此,Icebox 從端口上和線程池上分離不同的服務(wù),對(duì)于系統(tǒng)的穩(wěn)定可靠運(yùn)行,是有很大好處的。與此相關(guān)的服務(wù)之間本地調(diào)用的參數(shù):Imunicator 設(shè)置以后,共用同一個(gè) communicator 的服務(wù)會(huì)共用同一個(gè)線程池,后端日志上也能
59、發(fā)現(xiàn)這個(gè)現(xiàn)象。,先修改 SMSServiceI 服務(wù)代碼如下:接下來(lái)來(lái)看看服務(wù)之間怎么調(diào)用public void sendSMs(String msg, Currentcurrent) / log.trace(service, send sms message + msg); if (msg.startsWith(book) Ice.ObjectPrx base;try bamunicator().stringToProxy(OnlineBook);OnlineBookPrx onlinBook =OnlineBookPrxHelper.checkedCast(base);/ log.trac
60、e(service, find proxy +onlinBook); Message bookMsg = new Message(); bookM = Mr Wang;bookMsg.type = 3;bookMsg.price = 99.99; bookMsg.valid = true; bookMsg.content = abcdef; onlinBook.bookTick(bookMsg); catch (Exception e) throw new RuntimeException(e);客戶端調(diào)用代碼如下:public class SMSCnt public sic void mai
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年江蘇公務(wù)員考試行測(cè)試題(B卷)
- 2024-2025學(xué)年第13課清朝前中期的鼎盛與危機(jī)-勤徑學(xué)升高中歷史必修上同步練測(cè)(統(tǒng)編版2019)
- 2025年共同發(fā)展協(xié)議書細(xì)目
- 2025年全球化學(xué)品物流協(xié)議
- 2025年倉(cāng)儲(chǔ)物流租賃合同文件
- 2025年四人股東策劃經(jīng)營(yíng)合作協(xié)議書
- 2025年特種自行車項(xiàng)目立項(xiàng)申請(qǐng)報(bào)告模板
- 2025年公共服務(wù)設(shè)施建設(shè)策劃管理協(xié)議書
- 2025年肥料級(jí)磷酸氫鈣項(xiàng)目規(guī)劃申請(qǐng)報(bào)告模板
- 2025年公共環(huán)衛(wèi)設(shè)施:環(huán)衛(wèi)垃圾桶項(xiàng)目立項(xiàng)申請(qǐng)報(bào)告模板
- 光伏十林業(yè)可行性報(bào)告
- 小學(xué)綜合實(shí)踐《我做環(huán)保宣傳員 保護(hù)環(huán)境人人有責(zé)》
- 鋼煤斗內(nèi)襯不銹鋼板施工工法
- 公司人事招聘面試技巧培訓(xùn)完整版課件兩篇
- 出國(guó)勞務(wù)派遣合同(專業(yè)版)電子版正規(guī)范本(通用版)
- 公路工程安全風(fēng)險(xiǎn)辨識(shí)與防控手冊(cè)
- 供應(yīng)商評(píng)估報(bào)告范本
- 職業(yè)生涯規(guī)劃-自我認(rèn)知-價(jià)值觀
- 建筑集團(tuán)公司商務(wù)管理手冊(cè)(投標(biāo)、合同、采購(gòu))分冊(cè)
- 威海劉公島PPT介紹課件
- 2022年廣西高考英語(yǔ)真題及答案(全國(guó)甲卷)
評(píng)論
0/150
提交評(píng)論