ZeroC ICE之旅

Ice 是 Internet Communications Engine 的简称,出自ZeroC名门之下。 
Ice 是一种面向对象的中间件平台。从根本上说,这意味着Ice 为构建面向对象的客户-服务器应用提供了工具、API 和库支持。Ice 应用适合于异构平台环境中使用:客户和服务器能够采用不一样的编程语言,能够运行在不一样的操做系统和机器架构上,而且可使用多种网络技术进行通讯。不管部署环境如何,这些应用的源码都是可移植的。 

其采用C/S 模式结构,支持同步调用方式和异步调用方式,异步派发调用方式。支持跨语言的对象调用。多种语言之间采用共同的Slice(Specification Language for Ice)进行沟通。支持ice到C,JAVA,C#,VB,Python,Ruby,PHP等多种语言的映射。

工欲善其事,必先利其器,咱们首先从www.zero.com,下载最新安装包; 
btw: 

目前最新的v3.3 
http://www.zeroc.com/download_beta.html 
最新稳定版本: 
http://www.zeroc.com/download.html 


因为我本身的平台是CentOS release 4.4 (Final),java version "1.6.0_01" 
因此下载的是: 
http://www.zeroc.com/download/Ice/3.3/Ice-3.3b-rhel4-i386-rpm.tar.gz 

解开以后: 
-rw-r--r--  1 506 users 1130231  4月  1 10:39 db46-4.6.21-2ice.rhel4.i386.rpm 
-rw-r--r--  1 506 users   51459  4月  1 10:39 db46-devel-4.6.21-2ice.rhel4.i386.rpm 
-rw-r--r--  1 506 users  810562  4月  1 10:40 db46-java-4.6.21-2ice.rhel4.i386.rpm 
-rw-r--r--  1 506 users   72125  4月  1 10:40 db46-utils-4.6.21-2ice.rhel4.i386.rpm 
-rw-r--r--  1 506 users   84281  4月  1 10:15 ice-3.3b-1.rhel4.noarch.rpm 
-rw-r--r--  1 506 users  450359  4月  1 10:15 ice-c++-devel-3.3b-1.rhel4.i386.rpm 
-rw-r--r--  1 506 users 2823701  4月  1 10:16 ice-java-3.3b-1.rhel4.noarch.rpm 
-rw-r--r--  1 506 users  263085  4月  1 10:16 ice-java-devel-3.3b-1.rhel4.i386.rpm 
-rw-r--r--  1 506 users 3439061  4月  1 10:17 ice-libs-3.3b-1.rhel4.i386.rpm 
-rw-r--r--  1 506 users  162092  4月  1 10:19 ice-php-3.3b-1.rhel4.i386.rpm 
-rw-r--r--  1 506 users  739055  4月  1 10:19 ice-python-3.3b-1.rhel4.i386.rpm 
-rw-r--r--  1 506 users   32913  4月  1 10:19 ice-python-devel-3.3b-1.rhel4.i386.rpm 
-rw-r--r--  1 506 users  223577  4月  1 10:19 ice-ruby-3.3b-1.rhel4.i386.rpm 
-rw-r--r--  1 506 users   21406  4月  1 10:19 ice-ruby-devel-3.3b-1.rhel4.i386.rpm 
-rw-r--r--  1 506 users 3657167  4月  1 10:20 ice-servers-3.3b-1.rhel4.i386.rpm 
-rw-r--r--  1 506 users 4350193  4月  1 10:24 ice-utils-3.3b-1.rhel4.i386.rpm 
-rw-r--r--  1 506 users   74856  4月  1 10:40 mcpp-devel-2.6.4-1ice.rhel4.i386.rpm 
因为须要c和java的包: 
因此咱们仅安装: 
rmp -ivh ice-3.3b-1.rhel4.noarch.rpm 
rmp -ivh ice-3.3b-1.rhel4.noarch.rpm 
rpm -ivh ice-3.3b-1.rhel4.noarch.rpm 
rpm -ivh ice-libs-3.3b-1.rhel4.i386.rpm 
rpm -ivh ice-utils-3.3b-1.rhel4.i386.rpm 
rpm -ivh mcpp-devel-2.6.4-1ice.rhel4.i386.rpm 
rpm -ivh ice-servers-3.3b-1.rhel4.i386.rpm 
rpm -ivh ice-libs-3.3b-1.rhel4.i386.rpm 
rpm -ivh ice-c++-devel-3.3b-1.rhel4.i386.rpm 
rpm -ivh ice-java-3.3b-1.rhel4.noarch.rpm 
rpm -ivh ice-java-devel-3.3b-1.rhel4.i386.rpm 

安装以后的Ice相关路径: 
slice2cpp,slice2java在/usr/bin/下 
Ice.jar 存储于 /usr/share/java/下 
相关的Ice的库存储于/usr/lib下. 

一切就绪,咱们开始Ice之旅的Slice地带: 
首先,咱们创建一个demo.ice的文件: 

Java代码  
  1. module Demo{  
  2. interface test{  
  3.  string   execute(string mth,string cmd);  
  4. };  
  5. };  


注意,后两个"}"必定要包含";",不然slice2java就会过不去,赫赫 
执行: 
slice2java demo.ice 

会在当前目录产生一个Demo目录,目录下自动生成: 
-rw-r--r--  1 root root 2316  4月 15 17:01 _testDelD.java 
-rw-r--r--  1 root root  560  4月 15 17:01 _testDel.java 
-rw-r--r--  1 root root 1929  4月 15 17:01 _testDelM.java 
-rw-r--r--  1 root root 4177  4月 15 17:01 _testDisp.java 
-rw-r--r--  1 root root 1070  4月 15 17:01 testHolder.java 
-rw-r--r--  1 root root  488  4月 15 17:01 test.java 
-rw-r--r--  1 root root  481  4月 15 17:01 _testOperations.java 
-rw-r--r--  1 root root  460  4月 15 17:01 _testOperationsNC.java 
-rw-r--r--  1 root root 5418  4月 15 17:01 testPrxHelper.java 
-rw-r--r--  1 root root  569  4月 15 17:01 testPrxHolder.java 
-rw-r--r--  1 root root  567  4月 15 17:01 testPrx.java 
到目前为止,demo.ice因此Ice接口部分的定义以及相关依赖都已经自动生成. 

咱们要实现本身的execute方法,覆盖testPrx.java的同名方法: 
Java代码  
  1. //TestImp.java  
  2. package Demo;  
  3.   
  4. import Ice.Current;  
  5.   
  6.   
  7. public class TestImp extends _testDisp{  
  8.   
  9.     public String execute(String mth, String cmd, Current __current) {  
  10.         // TODO Auto-generated method stub  
  11.         return mth+cmd;  
  12.     }  
  13.   
  14.   
  15.   
  16. }  
看到了,就是这么简单,仅仅覆盖_testDisp里面的抽象方法,实现把咱们本身的实现代码填充到里面就好了. 
以后,咱们创建一个Server服务在10000端口进行侦听。 
Java代码  
  1. //Server.java  
  2. package Demo;  
  3.   
  4. public class Server {  
  5.     public static void main(String[] args) {  
  6.         int status = 0;  
  7.         Ice.Communicator ic = null;  
  8.         try {  
  9.             ic = Ice.Util.initialize(args);  
  10.             Ice.ObjectAdapter adapter = ic.createObjectAdapterWithEndpoints(  
  11.                     "TestAdapter""default -p 10000");  
  12.             Ice.Object object = new TestImp();  
  13.             adapter.add(object, ic.stringToIdentity("TestAdapter"));  
  14.             adapter.activate();  
  15.             ic.waitForShutdown();  
  16.         } catch (Ice.LocalException e) {  
  17.             e.printStackTrace();  
  18.             status = 1;  
  19.         } catch (Exception e) {  
  20.             System.err.println(e.getMessage());  
  21.             status = 1;  
  22.         }  
  23.         if (ic != null) {  
  24.             // Clean up  
  25.             //  
  26.             try {  
  27.                 ic.destroy();  
  28.             } catch (Exception e) {  
  29.                 System.err.println(e.getMessage());  
  30.                 status = 1;  
  31.             }  
  32.         }  
  33.         System.exit(status);  
  34.     }  
  35. }  

貌似很复杂,其实里面的不少内容都是固定格式,有些部分须要固定和约定。其中上述红色部分是修改部分。 

到目前为止,咱们已经完成了大部分工做,咱们还须要建一个客户端来对服务端的方法进行调用。 
Java代码  
  1. package Demo;  
  2.   
  3. public class Client {  
  4.     public static void main(String[] args) {  
  5.         int status = 0;  
  6.         Ice.Communicator ic = null;  
  7.         try {  
  8.             ic = Ice.Util.initialize(args);  
  9. //          Ice.ObjectPrx base = ic  
  10. //                  .stringToProxy("SimplePrinter:tcp -h 172.17.12.101 -p 10000");  
  11.             Ice.ObjectPrx base = ic  
  12.             .stringToProxy("TestAdapter:default -p 10000");  
  13.   
  14.             testPrx test = testPrxHelper.checkedCast(base);  
  15.             if (test == null)  
  16.                 throw new Error("Invalid proxy");  
  17.             System.out.println(test.execute("My first Ice ""demo"));  
  18.             //System.out.println("ok");  
  19.         } catch (Ice.LocalException e) {  
  20.             e.printStackTrace();  
  21.             status = 1;  
  22.         } catch (Exception e) {  
  23.             System.err.println(e.getMessage());  
  24.             status = 1;  
  25.         }  
  26.         if (ic != null) {  
  27.             // Clean up  
  28.             //  
  29.             try {  
  30.                 ic.destroy();  
  31.             } catch (Exception e) {  
  32.                 System.err.println(e.getMessage());  
  33.                 status = 1;  
  34.             }  
  35.         }  
  36.         System.exit(status);  
  37.     }  
  38. }  


也貌似很复杂吧,其实否则,也很简单,一样包含不少固定格式。其中 

Java代码  
  1. System.out.println(test.execute("my first Ice ""demo"));  


是咱们本身调用的逻辑。 

赫赫,大功告成了,如今咱们开始运行Server,再运行Client看到了么? 
"My first Ice demo" 

获得这样的结果,基本Ice之旅的Java部分简单实例咱们基本完成。 

Ice的性能和稳定性远超于咱们的想象,skype知道么?其部分通信架构就是采用的Ice. 

ZeroC ICE之旅------Slice

 Slice是在ICE所特有的特殊语言,ICE 提供基于Ice语言的多语言映射工具。Slice主要针对程序所涉及到的接口和类型进行定义。不涉及到具体实现和具体语言的特征。 
   既然ICE支持跨语言的调用,那么是否是Slice支持每种的特有数据类型呢? 
   固然不是,ICE只是保留各类具体语言数据类型的最小交集。 
提供: 
Java代码  
  1. 1.bool (false or true,>=1bit)  
  2. 2.byte (-128-127@,>=8bits)  
  3. 3.short (-2^15 to 2^15-1,>=16bits)  
  4. 4.int (-2^31 to 2^31-1,>=32bits)  
  5. 5.long (-2^63 to 2^63-1,>=64bits)  
  6. 6.float (IEEE single-precision,>=32bits)  
  7. 7.double (IEEE double-precision,>=64bits)  
  8. 8.string (All Unicode characters, excluding ,the character with all bits zero.)  


string 采用Unicode编码,具备很好的国际化语言支持。 

下面主要在介绍一下Slice的特性和约束: 
1. Slice文件必须以.ice结尾,其余结尾方案的文件会被编译器拒绝。 
2. Slice 文件格式实际就是text文本描述,因为Slice形式自由,能够用任何文本编辑器进行编辑。 
3. Slice 支持#ifndef,#define,#endif,#include 
例如: 
Java代码  
  1. // File Clock.ice  
  2. #ifndef _CLOCK_ICE  
  3. #define _CLOCK_ICE  
  4. // #include directives here...  
  5. // Definitions here...  
  6. #endif _CLOCK_ICE  

在include 要避免使用双引号"",以及"",而要使用"/" 
例如: 
#include "Clock.ice" // 不推荐采用; 
#include <SliceDefs/Clock.ice> // 正确 
#include <SliceDefs\Clock.ice> // 非法 
4.Slice 中文件的结构,模块,接口,类型出现的顺序,,能够按照你的喜爱而自由定义。 
5.Slice 的词法规则不少来源于C++和Java,只有少许的差别。 
6.能够采用c++的注释规则。// 或  
7.Slice 的关键词须要区分大小写: 
关键词: 
Java代码  
  1. bool        enum        implements      module      struct  
  2. byte        exception   int         Object      throws  
  3. class       extends     interface       out     true  
  4. const       false       local           sequence    void  
  5. dictionary  float       LocalObject     short  
  6. double      idempotent  long            string  
8.在接口定义的时候也避免使用非Slice关键字,可是C++ 或 Java关键字的标识符。 

例如:switch 

9.Ice保留了全部以"ice"做为开始标识符。保留以"Helper","Holder","Prx","Ptr"结尾的标识符。因此你们定义的时候最好避免一些没必要要的麻烦。 

10.Ice能够经过module嵌套的方式,相似于c++的namespace和java的包的概念。 


11.除了刚才提到的Slice支持的基础类型外,还支持用户自定义类型:enumerations, structures, sequences, and dictionaries. 

enumerations:枚举就不要介绍了,采用C++的语法形式 
enum Fruit { Apple, Pear, Orange }; 

Structures:结构,也是采用C++的语法形式,避免,结构中定义结构 
Java代码  
  1. 合法:  
  2. struct TimeOfDay {  
  3. short hour; // 0 - 23  
  4. short minute; // 0 - 59  
  5. short second; // 0 - 59  
  6. };  
  7. 无效:  
  8. struct TwoPoints {  
  9. struct Point { // Illegal!  
  10. short x;  
  11. short y;  
  12. };  
  13. Point coord1;  
  14. Point coord2;  
  15. };  

sequence:序列号类型,映射到java采用的数组方式实现,而不是所谓的集合容器类型对象存储。映射到C++中则采用STL容器存储。 
sequence<int> values; 
dictionary:字典类型,映射到java采用Map 进行存储,映射到C++采用map进行存储. 
dictionary<int,string> myValues; 
12.常量定义能够直接使用,但常量的定义必须是基本类型或枚举类型.定义形式也是采用C++定义方式. 
13.方法的定义,形式类型java的方法定义,方法返回可使void或对象类型. 
14.Slice支持方法异常的定义,以及异常的继承.关于异常机制,我想java开发者可能更加熟悉, 
例如: 
Java代码  
  1. exception Error {}; // Empty exceptions are legal  
  2. exception RangeError {  
  3. TimeOfDay errorTime;  
  4. TimeOfDay minTime;  
  5. TimeOfDay maxTime;  
  6. };  
  7. interface Clock {  
  8. idempotent TimeOfDay getTime();  
  9. idempotent void setTime(TimeOfDay time)  
  10. throws RangeError, Error;  
  11. };  

Ice的错误机制也是异常强大,吸收了不少Java关于异常机制的特色. 


Slice还包括不少良好的特性,在这里就不一一列举,对于支持自定义类型,基本类型,异常支持,对于通常的网络通信应用已经足够了,更多Slice语言的介绍参阅其帮助. 

Ice为咱们提供了强大而又丰富的Slice,能够利用Slice,结合咱们应用的特色,定义间接的Slice描述。 

btw: 

    虽然Slice提供给咱们丰富的功能和特性,在此我仍是建议你们尽可能采用基本类型和非异常机制.这样会对系统性能会带有必定的帮助。 
    另外接口的定义我想你们可以保持KISS(Keep it It Simple)设计原则,会使咱们的应用看起来更美丽。 
    不要过分的使用Slice,不然会给咱们带来无尽的烦恼。 

ZeroC ICE之旅------多语言互通互联

ce的服务端能够采用C++/Java/Python/C#等实现,客户端能够采用C++/Java/Python/C#/VB/PHP/Ruby来实现,就是说个人一个服务端采用C++实现,客户端能够采用java/php/vb/c# 等其余语言实现。 

这个特性也是Ice的很重要的优点之一. 

Ice的多语言之间如何确保对象的正确传输,每种语言都有各自的特色,数据类型,Ice是如何达到各类语言之间的互通互联的呢? 
那么就必定提到Slice语言.Slice是保证各类语言的互通互联的关键,它是独立于其它任何语言,Ice能够经过把Slice代码片段转化为各自的 

语言描述. 

Java代码  
  1. -rwxr-xr-x  1 system users 447888 2007-03-09  slice2java  
  2. -rwxr-xr-x  1 system users  67753 2007-03-09  slice2py  
  3. -rwxr-xr-x  1 system users  38679 2007-03-09  slice2rb  
  4. -rwxr-xr-x  1 system users 505441 2007-03-09  slice2vb  
  5. -rwxr-xr-x  1 system users 507119 2007-03-09  slice2cpp  
  6. -rwxr-xr-x  1 system users 454347 2007-03-09  slice2cs  


赫赫够多! 

Slice的全称:Specification Language for Ice,是Ice本身的特殊语言,一种用于使对象接口与其实现相分离的基础性抽象机制。Slice 创建在客户与服务器之间的合约,用以描述应用所使用的类型和对象接口。Slice描述独立于实现语言,因此客户实现语言是否与编写服务器所用的语言相同没有任何关系。 

slice语言片断能够被编译为任何所支持语言的实现。目前Ice Slice能够支持映射到到C++, Java, C#, Python,Ruby, and PHP。 
由于Slice主要对接口和类型的定义和描述,没有实现部分。 

到底如何实现不一样语言的互通互联的呢?咱们已Java,C++做为Ice例子原形,实际上咱们仅仅作少许修改,就能够实现 

C++的服务端,Java的客户端。Server和Client仍是保持在同一台机器上运行。注意咱们基于同一个demo.ice的事例。 

首先运行./Server,再运行Client,看到结果了么?赫赫,是否是出现了正常结果。 

到目前没有咱们全部实例都是基于同一台机器的,实际状况Server,Client会分布在不一样机器上。这种状况下,咱们须要如何处理呢? 


这个很简单,在Server少许修改 
Java代码  
  1. Ice::ObjectAdapterPtr adapter  =   ic->createObjectAdapterWithEndpoints ("TestAdapter",                                "default -p 10000");  


"default -p 10000" 采用 "tcp -h server1 -p port" 替代 

Server所在主机IP:172.17.12.101 ,端口:10000 

因此就修改成:tcp -h 172.17.12.101 -p 10000,再从新编译Server 

Java代码  
  1. #include <Ice/Ice.h>  
  2. #include <demo.h>  
  3. using namespace std;  
  4. using namespace Demo;  
  5. class Server:public test  
  6. {  
  7. public:  
  8.   ::std::string execute (const string & mth, const string & str,  
  9.                          const Ice::Current &);  
  10. public:  
  11.     Server ();  
  12. };  
  13. Server::Server ()  
  14. {  
  15.    
  16. };  
  17. std::string Server::execute (const string & mth, const string & str,  
  18.                              const Ice::Current &)  
  19. {  
  20.   cout << mth + str << endl;  
  21.   return mth + str;  
  22. }  
  23.    
  24. int  
  25. main (int argc, char *argv[])  
  26. {  
  27.   int  
  28.     status = 0;  
  29.   Ice::CommunicatorPtr ic;  
  30.   try  
  31.   {  
  32.     ic = Ice::initialize (argc, argv);  
  33.     Ice::ObjectAdapterPtr adapter  
  34.       =  
  35.       ic->createObjectAdapterWithEndpoints ("TestAdapter",  
  36.                                             "tcp -h 172.17.12.101 -p 10000");  
  37.     Ice::ObjectPtr object = new Server;  
  38.     adapter->add (object, ic->stringToIdentity ("TestAdapter"));  
  39.     adapter->activate ();  
  40.     ic->waitForShutdown ();  
  41.   } catch (const Ice::Exception & e)  
  42.   {  
  43.     cerr << e << endl;  
  44.     status = 1;  
  45.   } catch (const char *msg)  
  46.   {  
  47.     cerr << msg << endl;  
  48.     status = 1;  
  49.   }  
  50.   if (ic)  
  51.     {  
  52.       try  
  53.       {  
  54.         ic->destroy ();  
  55.       }  
  56.       catch (const Ice::Exception & e)  
  57.       {  
  58.         cerr << e << endl;  
  59.         status = 1;  
  60.       }  
  61.     }  
  62.   return status;  
  63. }  

编译方式参见: 
http://masterkey.iteye.com/blog/183307 

下面咱们须要对Client链接部分进行修改,同理: 
Java代码  
  1. Ice.ObjectPrx base = ic.stringToProxy("TestAdapter:tcp -h 172.17.12.101 -p 10000");  


Java代码  
  1. package Demo;  
  2.   
  3. public class Client {  
  4.     public static void main(String[] args) {  
  5.         int status = 0;  
  6.         Ice.Communicator ic = null;  
  7.         try {  
  8.             ic = Ice.Util.initialize(args);  
  9. //          Ice.ObjectPrx base = ic  
  10. //                  .stringToProxy("SimplePrinter:tcp -h 172.17.12.101 -p 10000");  
  11.             Ice.ObjectPrx base = ic  
  12.             .stringToProxy("TestAdapter:tcp -h 172.17.12.101 -p 10000");  
  13.   
  14.             testPrx test = testPrxHelper.checkedCast(base);  
  15.             if (test == null)  
  16.                 throw new Error("Invalid proxy");  
  17.             System.out.println(test.execute("My first Ice ""事例"));  
  18.             //System.out.println("ok");  
  19.         } catch (Ice.LocalException e) {  
  20.             e.printStackTrace();  
  21.             status = 1;  
  22.         } catch (Exception e) {  
  23.             System.err.println(e.getMessage());  
  24.             status = 1;  
  25.         }  
  26.         if (ic != null) {  
  27.             // Clean up  
  28.             //  
  29.             try {  
  30.                 ic.destroy();  
  31.             } catch (Exception e) {  
  32.                 System.err.println(e.getMessage());  
  33.                 status = 1;  
  34.             }  
  35.         }  
  36.         System.exit(status);  
  37.     }  
  38. }  

看到了么,就是这么简单,其余部分不用修改。 

好了,咱们进行验证,首先启动./Server,再执行Client ,看到了 

"My first Ice 事例" 看到了么,祝贺你,跨语言的分布式调用例子你已经实现了。 


其实Ice的通信机制极其强大,支持集群和容错技术。关于集群的事例会在往后的文章中介绍。 

BTW: 

注意,Server运行以后监听于10000端口,须要修改iptables,容许其余机器能够链接。 
编辑 iptables 
vi /etc/sysconfig/iptables 
追加: 
Java代码  
  1. -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 10000 -j ACCEPT  


Zero ICE咱们已经掌握其基本运行原理。下面咱们主要介绍一下ICe的多端口邦定的问题。  ICE使用TCP/IP 和UDP协议,以及基于TCP/IP之上的SSL协议。SSL协议能够充分保障Server/Client数据传输的加密安全性问题。  在这里,Server如何在同一台主机监听多个端口。  关于TCP/IP仍是UDP仍是SSL协议的选择,仍是要看具备应用的要求,一般状况下TCP/IP协议的ICE应用已经足够了。  在同一个主机主机上,ICE服务支持多端口的监听。  服务端注册: tcp -h host -p port1:tcp -h host -p port2形式,  例如:  IP:172.17.12.101,须要在10001和10000同时监听。  就能够写成:  tcp -h 172.17.12.101 -p 10000:tcp -h 172.17.12.101 -p 10001  赫赫是否是很简单,运行以后,服务就监听于10000和10001端口,请注意:避免其余应用相冲突。  客户端链接能够采用以下3种形式:  1. tcp -h 172.17.12.101 -p 10000  2. tcp -h 172.17.12.101 -p 10001  3. tcp -h 172.17.12.101 -p 10000:tcp -h 172.17.12.101 -p 100001  是否是很爽。  不管Server监听在多个端口,仍是只有惟一的一个Server在工做,  对于Client较多的应用或负载要求很高的状况下,咱们能够把Server程序运行于多台主机之上。经过集群方式合理有效的化解来自Client的压力。  例如:  ServerA 172.17.12.101 tcp -h 172.17.12.101 -p 10000  ServerB 172.17.12.102 tcp -h 172.17.12.102 -p 10000  ServerC 172.17.12.103 tcp -h 172.17.12.103 -p 10000  Client能够以下的链接方式:  tcp -h 172.17.12.101 -p 10000:tcp -h 172.17.12.102 -p 10000:tcp -h 172.17.12.103 -p 10000  或是  tcp -h 172.17.12.101 -p 10000:tcp -h 172.17.12.102 -p 10000  等多种状况,能够根据应用的具体要求合理有效的构造所需链接主机的字符串。  这种链接方式是否是很cool。  其实这种链接方式能够有效地利用ICE提供的load balancing功能,把Client的每一个请求合理的分配到每一个Server。从而有效地避免了Client大量请求对同一台Server的巨大压力。  ICE的load balancing主要采用round-robin算法,round-robin是一种很是有效的负载均衡算法.  你们会问了,若是某个Server若是宕机,那么这个Client还能正常工做么?      这个问题问得好,其实ICE自身提供一种极其强大容错技术功能。      具体体如今若是当某个Server(假设是ServerA)宕机以后,来自Client的请求分配到ServerA服务器上,Client会自动记录ServerA失效状态,会把请求再分配给可正常工做的Server(ServerB,ServerC),对于用户的每次请求都能分配到正常的服务主机上(除非A,B,C都同时宕机).当ServerA回复正常以后,Client会自动感知ServerA工做状态.Client的请求又能够有效地分配到上述A,B,C主机上.这一切对于开发者都是透明的.  ICE所提供的集群功能和容错功能是极其强大的.     Client状态感知的变化和更新彻底不须要Client从新启动。
相关文章
相关标签/搜索