ICE中介軟體研究筆記

taozi343805436發表於2013-12-11

1      <wbr><wbr><wbr><wbr><wbr><wbr> ICE中介軟體簡介

2      <wbr><wbr><wbr><wbr><wbr><wbr> 平臺核心功能

2.1       <wbr><wbr><wbr><wbr><wbr><wbr><wbr> 介面描述語言(Slice

2.2       <wbr><wbr><wbr><wbr><wbr><wbr><wbr> ICE執行時

2.2.1        <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> 通訊

2.2.2        <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> 物件介面卡

2.2.3        <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> 位置透明性

2.3       <wbr><wbr><wbr><wbr><wbr><wbr><wbr> 非同步程式設計模型

2.3.1        <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> 非同步方法呼叫

2.3.2        <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> 非同步方法分派

2.4       <wbr><wbr><wbr><wbr><wbr><wbr><wbr> 訂閱/釋出程式設計模型

2.5       <wbr><wbr><wbr><wbr><wbr><wbr><wbr> 動態服務管理(IceBox

2.6       <wbr><wbr><wbr><wbr><wbr><wbr><wbr> ICE網格計算

2.6.1        <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> 分散式部署

2.6.2        <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> 負載均衡

2.6.3        <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> 註冊中心叢集

2.7       <wbr><wbr><wbr><wbr><wbr><wbr><wbr> IceSSL應用

2.8       <wbr><wbr><wbr><wbr><wbr><wbr><wbr> 持久化儲存(IceFreeze

3      <wbr><wbr><wbr><wbr><wbr><wbr> ICE平臺功能研究小結

 <wbr>


 <wbr>

1      <wbr><wbr><wbr><wbr><wbr><wbr> ICE中介軟體簡介

Ice  Internet Communications Engine 的簡稱,是一種物件導向的中介軟體平臺,支援物件導向的RPC程式設計,其最初的目的是為了提供類似CORBA技術的強大功能,又能消除CORBA技術的複雜性。該平臺為構建物件導向的客戶-伺服器應用提供了工具、API 和庫支援。

   <wbr><wbr><wbr> ICE平臺開發的應用支援跨平臺部署,多語言程式設計,其中服務端支援C++JAVAC#Python等幾種程式語言,客戶端還支援RubyPHPICE支援同步/非同步、訂閱/釋出的程式設計模式,支援分散式部署,網格計算,內建負載均衡功能,支援SSL安全加密。

   <wbr><wbr><wbr> ICE 既可以把TCP/IP、也可以把UDP 用作底層傳輸機制, 還允許你把SSL 用作傳輸機制,讓客戶與伺服器間的所有通訊都進行加密。 <wbr>

ICE平臺還提供一序列的程式設計庫,包括執行緒模型庫、定時器、訊號處理器,這些程式設計庫的API全部支援執行緒安全。

ICE目前的最新版本為ICE3.4.1,20106月份釋出的,ICE3.1.1200610月份釋出)及以前的版本支援WindowsLINUXAIXHP-UXSolaris作業系統,但是ICE3.2.0(包含)以後的版本官方不再保證對AIX的完全支援,而3.3.1(包含)以後版本連HP-UX都不保證完全支援,雖然原始碼中仍然提供了這兩個作業系統下的原始碼編譯檔案Make.rules.AIX Make.rules.HP-UX,根據官方的論壇說明是因為他們基本上沒有這兩個系統的商業客戶,所以不再對這兩個平臺進行程式碼測試,如果有需要的需要和他們聯絡。

2      <wbr><wbr><wbr><wbr><wbr><wbr> 平臺核心功能

2.1    <wbr><wbr><wbr><wbr> 介面描述語言(Slice

Slice Specification Language for Ice)是一種用於使物件介面與其實現相分離的基礎性抽象機制。Slice 在客戶與伺服器之間建立合約,描述應用所使用的各種型別及物件介面。這種描述與實現語言無關,所以編寫客戶所用的語言是否與編寫伺服器所用的語言相同,這沒有什麼關係。

Slice 定義由編譯器編譯到特定的實現語言。編譯器把與語言無關的定義翻譯成針對特定語言的型別定義和API。開發者使用這些型別和API 來提供應用功能,並與Ice 互動。目前ICE支援SliceC++JAVAC#PythonRubyPHP的語言對映。

Slice示例:

module Family //對應C++的名字空間

{

interface Child;

sequence<Child*> Children; // OK 可以利用C++Vector

interface Parent //對應C++的類

{

Children getChildren(); // OK

};

interface Child

{

Parent* getMother();

Parent* getFather();

};

};

利用Slice 定義介面/類方法時和其他程式語言很相似,需要一個返回值和若干個引數,但是需要注意的是Slice不支援引用方式的引數傳遞,引數要麼為輸入引數,要麼為輸出引數,不同時為inout.作為out引數的時候,不管客戶端對out引數的初始賦值是什麼,在服務端都取不到該,但是服務端可以對該引數進行賦值,再傳遞給客戶端。例如:

interface Hello

{

   <wbr><wbr><wbr> string sayHello(int num,out string strMsg);

};

   <wbr><wbr><wbr> 還要注意的是out引數一定是放在所有輸入引數後面,不允許交叉

2.2    <wbr><wbr><wbr><wbr> ICE執行時

2.2.1 <wbr> 通訊器

Ice run time 的主進入點由本地介面Ice::Communicator 表示,通常一個應用伺服器只使用一個通訊器,一個通訊器例項管理著執行時資源,主要的執行時資源包括:

² <wbr> 執行緒池:負責接收客戶端連線和請求。

² <wbr> 配置屬性:Ice run time 的各個方面可以通過屬性進行配置。每個通訊器都有自己的配置屬性

² <wbr> 外掛管理器:外掛是用於給通訊器增加特性的物件。例如, IceSSL (參見第23章)被實現成外掛。每個通訊器都有一個外掛管理器,這個管理器實現Ice::PluginManager 介面,通過它,你可以訪問通訊器的外掛集。

² <wbr> 物件工廠:為了例項化從已知基類派生的類,通訊器維護有一組物件工廠,能夠替Ice run time 對類進行例項化。使用者定義的每一個介面/類都隱式地繼承同一個基類Ice:Object.

² <wbr> 預設定位器:定位器用於把客戶請求的物件標識解析為代理物件。

² <wbr> 物件介面卡:物件介面卡用於分派接收到的請求,把每個請求轉發到正確的Servant。每個物件介面卡可以繫結多個ICE物件,不同通訊器的物件介面卡和物件完全是相互獨立的。

2.2.2 <wbr> 物件介面卡

一個通訊器含有一個或更多物件介面卡。物件介面卡處在Ice run time和伺服器之間的界線上,負有這樣一些責任:

² <wbr> 它把Ice物件對映到到來請求的servant,並把請求分派給每個servant中的應用程式碼(也就是說,物件介面卡實現了一個向上呼叫介面,把Icerun time 與伺服器中的應用程式碼連線在一起)。

² <wbr> 它協助進行生命週期操作,使得Ice物件和servant在建立和銷燬時不會出現競爭狀況。

² <wbr> 它提供一個或更多傳輸端點。客戶通過這些端點訪問介面卡所提供的Ice物件。每個物件介面卡都有一個或更多servant,對Ice 物件進行體現;同時還有一個或更多傳輸端點。如果物件介面卡擁有的傳輸端點不止一個,所有向該介面卡作了註冊的servant 可以在任何一個端點上響應到來的請求。換句話說,如果物件介面卡有多個傳輸端點,這些端點代表的是通往同一組物件的不同通訊路徑(例如,通過不同的傳輸機制)。

² <wbr> 每個物件介面卡都只屬於一個通訊器(但一個通訊器可以有多個物件介面卡)。

2.2.3 <wbr> 位置透明性

Ice run time 的一個有用的特性是位置透明性:客戶無需知道Ice 物件的實現的位置;對某個物件的呼叫會被自動引導到正確的目標,不管這個物件的實現是在本地地址空間中,在同一臺機器上的另一個地址空間中,還是在一臺遠地機器上的另一個地址空間中。位置透明性十分重要,因為有了它,我們能夠改變物件實現的位置,而不會破壞客戶程式,同時,通過使用IceGrid,像域名和埠號這樣的資訊可以放在應用的外部,不用出現在串化代理中。

2.3    <wbr><wbr><wbr><wbr> 非同步程式設計模型

ICE平臺支援客戶端非同步呼叫(AMI)和服務端非同步分派程式設計(AMD)。

2.3.1 <wbr> 非同步方法呼叫

非同步方法呼叫(AMI) 這個術語描述的是客戶端的非同步程式設計模型支援。如果你使用AMI 發出遠地呼叫,在Ice run time 等待答覆的同時,發出呼叫的執行緒不會阻塞。相反,發出呼叫的執行緒可以繼續進行各種活動,當答覆最終到達時, Ice run time 會通知應用。通知是通過回撥發給應用提供的程式語言物件的。

要使用非同步方法呼叫,只需要給對應的類或者方法前面加上後設資料[“ami”],示例如下:

interface Hello

{

   <wbr><wbr><wbr>     <wbr><wbr><wbr><wbr> [ami] string sayHello(int num);

};

通過Slice編譯器生成標頭檔案時,會生成對應的方法同步呼叫方法和非同步呼叫方法,使用者在客戶端可以自行選擇使用同步呼叫還是非同步呼叫,非常方便。編譯後對於每一個非同步方法都會生成相應的非同步回撥類和非同步呼叫代理方法,類的命名方式AMI_類名_方法名,上述的slice經編譯後生成的類為 AMI_Hello_sayHello同時這個類提供了兩個方法:

void ice_response(<params>);

表明操作已成功完成。各個引數代表的是操作的返回值及out 引數。如果操作的有一個非void 返回型別, ice_response 方法的第一個引數就是操作的返回值。操作的所有out 引數都按照宣告時的次序,跟在返回值的後面。

void ice_exception(const Ice::Exception &);

表明丟擲了本地或使用者異常。

客戶端只需要從AMI_Hello_sayHello 類繼續並實現上述兩個方法就可以了。示例程式碼如下:

class AMI_Hello_sayHelloI : public AMI_Hello_sayHello

{

    <wbr><wbr><wbr><wbr> void ice_response(const ::std::string& strMsg)

    <wbr><wbr><wbr><wbr> {

        <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> printf("%s\n",strMsg.c_str());

    <wbr><wbr><wbr><wbr> }

    <wbr><wbr><wbr><wbr> void ice_exception(const Ice::Exception& exception)

    <wbr><wbr><wbr><wbr> {

        <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> printf("error\n");

    <wbr><wbr><wbr><wbr> }

};

生成的非同步呼叫代理方法命名為方法名_async,上述示例生成的方法為 sayHello_async.然後客戶端的程式非同步呼叫如下:

hello->sayHello_async(AMI_Hello_sayHelloPtr,<params>);

然後只需在ice_response 方法處理返回結果。

也可以呼叫同步方法:

hello->sayHello(<params>);

2.3.2 <wbr> 非同步方法分派

非同步方法分派(AMD) AMI 的伺服器端等價物,在使用AMD 時,伺服器可以接收一個請求,然後掛起其處理,以儘快釋放分派執行緒。當處理恢復、結果已得出時,伺服器要使用Ice runtime 提供的回撥物件,顯式地傳送響應。

用實際的術語說, AMD 操作通常會把請求資料(也就是,回撥物件和操作引數)放入佇列 ,供應用的某個執行緒(或執行緒池)隨後處理用。這樣,伺服器就使分派執行緒的使用率降到了最低限度,能夠高效地支援大量併發客戶。

要使用非同步方法呼叫,只需要給對應的類或者方法前面加上後設資料[“amd”],示例如下:

interface Hello

{

   <wbr><wbr><wbr>     <wbr><wbr><wbr><wbr> [amd] string sayHello(int num);

};

和非同步方法呼叫不同的是,非同步分派是服務端的,在服務端會生成相應的非同步分派類和非同步分派方法。服務端的分派器在接收到客戶請求時把請求分派給sayHello_async(const Demo::AMD_Hello_sayHelloPtr&, int, const Ice::Current&).然後使用者可以在該方法內把任務引數資訊放入佇列,在佇列中迴圈檢查任務並處理,處理完成後呼叫 AMD_Hello_sayHelloPtr 類的 ice_response 方法返回給客戶端。

 <wbr>

2.4    <wbr><wbr><wbr><wbr> 訂閱/釋出程式設計模型

IceStorm是一個高效的用於ICE應用的釋出/訂閱服務,IceStorm有幾個比較重要的概念:

² <wbr> 訊息:IceStorm的訊息和普通的訊息佇列中介軟體中描述的訊息有點區別,IceStorm 的訊息是強型別的,由對某個Slice 操作的呼叫代表:操作名標識訊息的型別,操作引數定義訊息內容。要釋出訊息,可以按普通的方式呼叫某個IceStorm 代理上的操作。與此類似,訂閱者會像收到常規的向上呼叫(upcall)一樣收到訊息。所以IceStorm 的訊息遞送使用的是“推”模式

² <wbr> 主題:應用要通過訂閱某個主題(topic)來表明自己有興趣接收某些訊息。IceStorm 伺服器能夠支援任意數量的主題,這些主題是動態建立的,通過唯一的名字來區分。每個主題都可以有多個釋出者和訂閱者。   <wbr><wbr><wbr>

² <wbr> 持久模式:IceStorm 擁有一個資料庫,裡面維護的是關於其主題和連結的資訊。但是,通過IceStorm傳送的訊息不會被持久地儲存,而是會在遞送給主題目前的訂閱者集之後,馬上被丟棄。如果在把訊息遞送給某個訂閱者的過程中發生錯誤, IceStorm 不會為該訂閱者進行訊息排隊。

² <wbr> 訂閱者出錯:因為IceStorm 訊息是採用單向語義遞送的, IceStorm 只能檢測到連線或超時錯誤。如果在把訊息遞送給訂閱者的過程中, IceStorm 遇到這樣的錯誤,該訂閱者就會立刻被解除與該訊息對應的主題的訂閱。當然使用者在使用過程中也可以通過設定QOS引數來改善這個問題,比如重試次數(retryCount),但是對於ObjectNotExistException 或者 NotRegisteredException之類的硬錯誤,Ice執行時不會重試,而是仍然直接解除訂閱關係。

 <wbr>

IceStorm支援兩個主要的QOS引數reliability  retryCountreliability的取值分別為ordered 和空值,取ordered時,釋出者釋出的訊息會保證按順序遞送給訂閱者。

IceStorm提供的功能來看,對於不需要進行訊息持久儲存轉發的應用來說很適合,但是由於在訂閱者出錯後立即解除訂閱關係,不是由訂閱者主動解除,這個在應用中需要特別注意是否符合實際應用。

IceStorm被實現為IceBox服務,所以在部署IceStorm應用時需要啟動IceBox服務。

 <wbr>

2.5    <wbr><wbr><wbr><wbr> 動態服務管理(IceBox

IceBox 用於動態載入使用者服務並對他們進行集中管理,可以通過iceboxadmin管理工具對IceBox中的服務進行遠端管理,通過IceBox使用者服務可以被開發成可以動態載入的動態庫元件.

使用IceBox的服務元件需要繼承IceBox::Service類,並實現start()、stop()方法,並在實現類中提供服務進入點函式,一般為create()函式,在這函式中建立服務實現類的物件並返回。例如:

extern "C"

{

ICE_DECLSPEC_EXPORT IceBox::Service*

create(Ice::CommunicatorPtr communicator)

{

   <wbr><wbr><wbr> return new HelloServiceI;

}

}

   <wbr><wbr><wbr> 對於Ice3.3.0以上版本,iceboxadmin提供了啟動、停止服務及停止IceBox 伺服器的命令管理工具和應用程式介面,管理工具命令如下:

iceboxadmin [options] [command...]

commands:

start SERVICE Start a service.

stop SERVICE Stop a service.

shutdown Shutdown the server.

 

 

 

ICE中介軟體研究筆記2

 

2.6    <wbr><wbr><wbr><wbr> ICE網格計算

IceGrid用於支援分散式網路服務應用,一個IceGrid域由一個登錄檔(Registry)和任何數目的節點(Node)構成。登錄檔(Registry)和節點(Node)一起合作管理一些資訊以及包含一些應用(Application)的服務程式。每項應用(Application)被指定在特定節點上的服務。這個登錄檔(Registry)持久記錄了這些資訊,而節點(Node)負責啟動和監測其指定的伺服器程式。對於一個典型的配置,一個節點(Node)執行在一臺計算機(稱之為Ice伺服器主機)。登錄檔(Registry)並不消耗很多處理器時間,所以它常常是和一個節點(Node)執行在同一臺計算機上的,登錄檔(Registry)還可以和一個節點(Node)可以執行在同一程式中.如果需要容錯,登錄檔(Registry)還可以用主從式的設計支援複製(Replication)。

登錄檔(Registry)的主要責任,是解決作為Ice定位服務的間接代理問題,當客戶端第一次嘗試使用一種間接代理,客戶端Ice run time首先連線登錄檔(registry),登錄檔將間接代理的符號資訊轉化為直接代理的endpoint,然後客戶端和直接代理建立一個連線。通過介面卡複製,同名介面卡可以分佈在多個節點上,間接代理可以對映到多個節點上的直接代理,在執行時由登錄檔服務根據負載均衡自動選擇一個直接代理給客戶端。

使用間接代理時,客戶端可以用以下方式直接獲取服務物件代理:

MyProxy=theObject@theAdapter  <wbr><wbr> // <wbr> 物件@介面卡

更簡單一點的話可以用以下方式

MyProxy=theObject  <wbr><wbr> // <wbr> 物件

2.6.1 <wbr> 分散式部署

在部署IceGrid分散式服務時,需要啟動登錄檔服務(icegridregistry),並配置登錄檔服務地址埠、通訊協議和註冊資訊儲存的目錄地址(ICE的註冊資訊儲存為BerkeleyDB的資料庫檔案):

IceGrid.Registry.Client.Endpoints=tcp -p 4061

IceGrid.Registry.Data=/opt/ripper/registry

 <wbr>

在伺服器節點中和客戶端都需要配置登錄檔服務的地址埠和通訊協議:

Ice.Default.Locator=IceGrid/Locator:tcp -h 172.0.0.1 -p 4061

然後分別啟動登錄檔服務(icegridregistry)和節點服務(icegridnode).

ICE提供了部署工具icegridadmin, 這個icegridadmin工具也需要定義Ice.Default.Locator屬性.

接下需要編寫應用部署檔案,應用部署檔案以XML方式儲存。以下為支援介面卡複製的應用配置檔案,使用了服務模板:

<icegrid>

<application name="Ripper">

<replica-group id="EncoderAdapters"> //定義介面卡複製組

<object identity="EncoderFactory"   <wbr><wbr><wbr> //identity將在客戶端中使用。

type="::Ripper::MP3EncoderFactory"/>

</replica-group>

<server-template id="EncoderServerTemplate"> //定義伺服器模板

<parameter name="index"/>

<parameter name="exepath"

default="/opt/ripper/bin/server"/>

<server id="EncoderServer${index}"

exe="${exepath}"

activation="on-demand">

<adapter name="EncoderAdapter"

replica-group="EncoderAdapters"

endpoints="tcp"/>

</server>

</server-template>

<node name="Node1">

<server-instance template="EncoderServerTemplate"

index="1"/>

</node>

<node name="Node2">

<server-instance template="EncoderServerTemplate"

index="2"/>

</node>

</application>

</icegrid>

然後在客戶端可以用以下方式獲取物件代理:

Ice::ObjectPrx obj = communicator->stringToProxy("EncoderFactory");

2.6.2 <wbr> 負載均衡

ICE平臺內嵌負載均衡功能,對於分佈大多個節點上的應用服務提供多種負載均衡方案,只需要通過XML配置檔案即可完成負載均衡配置。配置項包括Type (負載均衡型別)Sampling interval(負載資訊收集間隙)、Number of replicas(返回給客戶端的介面卡個數)。

負載均衡型別有以下4種方式:

² <wbr> Random (隨機方式):註冊中心隨機選擇一個介面卡給客戶端,不檢查介面卡的負載。

² <wbr> Adaptive(適配方式):註冊中心從所有介面卡中選擇一個負載最輕的介面卡給客戶端,Sampling interval引數只有在該型別的負載均衡中有效,這個引數指定節點定期向註冊中心報告本地系統負載資訊(system load information;

² <wbr> Round Robin(最近最少使用):註冊中心從對應的介面卡組中選擇一個最近最少使用的介面卡給客戶。

² <wbr> Ordered(順序方式):註冊中心根據介面卡的優先順序,從高到低順序選擇一個介面卡給客戶端。

配置示例:

        <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> <replica-group id="EncoderAdapters">

<load-balancing type="adaptive"/>  <wbr><wbr> //配置為適配方式

<object identity="EncoderFactory"

type="::Ripper::MP3EncoderFactory"/>

</replica-group>

2.6.3 <wbr> 註冊中心叢集

前兩節中描述的是屬於使用者應用的分佈部署,分散式部署一個很重要的支撐是ICE的註冊中心,所有客戶端都向註冊中心查詢服務代理的真實端點,從而建立通訊連線,在這裡註冊中心又成了一個單點服務,為了避免註冊中心成為應用的瓶頸,提高系統的可靠性,ICE3.3.0以上版本提供了註冊中心叢集功能

ICE註冊中心叢集通過主從式的註冊中心複製來實現,一個叢集中有一個主註冊中心,若干個副註冊中心,主從的區別通過IceGrid.Registry.ReplicaName屬性配置來實現,主註冊中心的名稱為 Master,其他的名字可以任意取。啟動時先啟動主註冊中心,再啟動其他註冊中心,通過主註冊中心更新的資訊都將同步給副註冊中心,各副註冊中心之間不通訊。如果主註冊中心失效,需要從其他副註冊中心提撥一個成為主註冊中心,但是從3.3版本的說明文件中來看,如果需要把某個副註冊中心提撥成為主註冊中心需要重新啟動相應程式並修改IceGrid.Registry.ReplicaName 屬性值為Master,或者刪除該屬性,預設情況下該屬性值為Master.

使用叢集方式時,在客戶端配置時把所有的主從註冊中心地址埠全部填到Ice.Default.Locator,例如:

Ice.Default.Locator=IceGrid/Locator:default -p 12000:default -p 12001

在應用節點也把所有的註冊中心地址埠繫結,這樣應用的更新會同時通知所有的註冊中心。

2.7    <wbr><wbr><wbr><wbr> IceSSL應用

ICE平臺可以通過簡單的配置來支援SSL應用,配置過程如下:

² <wbr> 首先需要通過修改配置檔案來啟用SSL外掛,C++服務端的配置方法為:Ice.Plugin.IceSSL=IceSSL:createIceSSL

只需要把IceSSL動態庫放到LD_LIBRARY_PATH包含的路徑下即可。

² <wbr> 然後修改介面卡的監聽選項:

MyAdapter.Endpoints=tcp -p 8000:ssl -p 8001:udp -p 8000 //表示該介面卡在三種協議埠上同時監聽。

ICE還提供了多種配置屬性來滿足實際應用,例如下例所示:

Ice.Plugin.IceSSL=IceSSL:createIceSSL

IceSSL.DefaultDir=/opt/certs <wbr> //預設證照目錄

IceSSL.CertFile=pubkey.pem <wbr> //證照檔案

IceSSL.KeyFile=privkey.pem <wbr> //私鑰檔案

IceSSL.CertAuthFile=ca.pem <wbr> //信任的根證照檔案

IceSSL.Password=password   <wbr><wbr><wbr> //私鑰檔案檢視密碼

2.8    <wbr><wbr><wbr><wbr> 持久化儲存(IceFreeze

ICE提供的持久化方案可以支援普通使用者資料(鍵/值對)的持久化儲存和服務物件例項的持久化管理,普通使用者資料的持久化儲存使用比較簡單,服務物件例項的管理相對複雜一點,暫時不關注。

ICE的持久儲存介質為BerkeleyDB,對普通資料的持久化在C++實現中採用Map的方式進行操作,使用者需要用Slice定義需要儲存的資料,並用slice2freeze 生成相應的Map操作類,然後對資料的操作就可以使用Map容器函式來進行。示例如下:

首先生成需要儲存的資料型別:

slice2freeze --dict StringIntMap,string,int StringIntMap

程式碼使用:

Ice::CommunicatorPtr communicator =

Ice::initialize(argc, argv);

// Create a Freeze database connection.

Freeze::ConnectionPtr connection = Freeze::createConnection(communicator, "db"); //連線到資料庫檔案。

// Instantiate the map.

StringIntMap map(connection, "simple");//建立表。

// Clear the map.

map.clear();

Ice::Int i;

StringIntMap::iterator p;

// Populate the map.

for (i = 0; i < 26; i++)

{

std::string key(1, 'a' + i);

map.insert(make_pair(key, i));

}

// Iterate over the map and change the values.

for (p = map.begin(); p != map.end(); ++p)

p.set(p->second + 1);

// Find and erase the last element.

p = map.find("z");

assert(p != map.end());

map.erase(p);

// Clean up.

connection->close();

communicator->destroy();

IceFreeze還允許使用結構體和類物件作為值進行儲存,但是隻有public的成員變數會被儲存,其他成員變數不會被儲存。

對於較高版本的ICE,還允許對值建立索引,如果值為結構體或者類物件,那麼還允許以結構體/物件變數作為索引,通過slice2freeze編譯後會生成對應的索引查詢函式。例如定義瞭如下需要儲存的資料結構:

module Demo

{

struct Struct1

{

   <wbr><wbr><wbr> long l;

};

class Class1

{

   <wbr><wbr><wbr> string s;

};

};

然後執行以下命令生成對映表,同時生成索引,以class1的成員變數s為索引。

Slice2freeze

--dict Demo::IndexedStruct1Class1Map,Demo::Struct1,Demo::Class1         <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>--dict-index Demo::IndexedStruct1Class1Map,s,case-sensitive         <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>BenchTypes Test.ice

編譯後程式碼中會自動生成findByS(string &),在程式中可以按以下方式直接呼叫:

IndexedStruct1Struct2Map& m=...;<wbr>

IndexedStruct1Struct2Map::iterator p = m.findByS(os.str());<wbr>

3      <wbr><wbr><wbr><wbr><wbr><wbr> ICE平臺功能研究小結

ICE平臺提供的功能比較多,除了文件中羅列的部分,還支援程式包分發(IcePath2)、防火牆穿透(Glacier),鑑於目前的專案應用暫時不對這兩部分作介紹。

ICE官方提供的Demo和自己編寫的測試程式在Iinux(opensuse)執行良好,對於適用於AIX3.1.1版本在AIX上執行非同步程式設計的測試也很順利,但是目前還未對ICE平臺的應用做效能測試。

從文件的介紹,ICE平臺支援同步/非同步、訂閱/釋出、分散式部署、內部持久化儲存,支援介面描述語言到各種物件導向開發語言的對映,可以滿足ESB系統開發的技術需求,但是也有一定的風險,ICE3.1以後的版本對AIXHP-UX作業系統不保證完全支援,對3.1以後各個升級版本需要進行編譯並執行測試。


相關文章