收藏 分享(赏)

ICE for Java开发指南.pdf

上传人:jintaihu 文档编号:5713198 上传时间:2022-06-16 格式:PDF 页数:43 大小:702.60KB
下载 相关 举报
ICE for Java开发指南.pdf_第1页
第1页 / 共43页
ICE for Java开发指南.pdf_第2页
第2页 / 共43页
亲,该文档总共43页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

1、ICE For Java 开发指南 Leader 精品充电系列丛书,淘宝官网:http:/ 有大量高质量学习代码可供下载,技术交流 QQ:719867650 前言 ICE 版本为 3.5.1,开发环境为 Java 7+Eclipse,开发环境准备如下: 安装 JDK 7+Ecliplse 安装 ICE Windows 版本: http:/ 3.5.1-2.msi 安装 ICE for Eclipse 插件:http:/ ,注意 Zero ICE 的Home 路径,eclipse-windows-Preference 里 Slice2Java: Hello world 程序 为了快速掌握 ICE

2、 的编程特性,让我们从最基础的 Hello World 程序开始,我们定义一个服务,取名为在线订票 OnlineBook,该服务提供一个方法 bookTick,实现订票功能,此方法需要一个参数,包括所订票的名称(name),如变形金刚 5、票的类型(type),如电影票、价格(price)、客户定制要求(content)、若票源暂时紧张也预订成功(valid=true)等,为此我们封装为 Java Bean,名称为 Message,如下定义: public class Message public String name; public int type; public boolean val

3、id; public double price; public String content; 若你细心点,会发现这个结构包括了大多数我们常用的数据类型:字符串、整型、布尔值、小数,这样做的原因很简单,为了验证多语言情况下的接口兼容问题。 我们定义的订票服务的接口如下: public interface OnlineBooK Message bookTick(Message msg) 该服务返回一个 Message 对象,这么做的原因是因为绝大多数方法调用都会有返回值,对于 RPC 调用来说,有返回值的调用代表着 RPC 方法调用是否成功,而没有返回值的调用,则无法确定是否成功,因为消息发出去

4、也可能在服务端无法处理,另外,只有对有返回值的 RPC 方法进行性能测试,才是有代表性的结果。上面这个简单的 Hellow World的程序设计,正好体现了编程中的经验和思考的重要性。 理解了上述订票服务的接口、数据结构,我们接下来看看怎样用 ICE 将它变成神奇的 RPC 调用,为了解决跨语言问题,ICE 中采用了业界通常的标准做法,即用一个“中立”的语法定义文件来定义 RPC 方法接口,并提供工具编译为各种第三方语言的接口,这个中立语法就是 ICE 设计的 slice 语言,后缀名为 ice,用 slice 语言定义我们的订票服务,就变成了如下的方式: java:package:com.h

5、p.tel.ice module book struct Message string name; int type; bool valid; double price; string content; ; interface OnlineBook Message bookTick(Message msg); ; ; 第一行,是特定含义的注释,告诉 Java 的 slice 转换器,转化为 Java 代码的时候,上述接口是在 com.hp.tel.ice 下产生代码。module 关键字定义了本接口的模块名字module,这个 module 在 Java 中就是 package 的一部分,在其

6、他语言中也有对于的概念。struct 关键字定义了一个结构体,来自 C 的概念,注意是 struct 不能嵌套 struct。Interface关键字则定义了 RPC 服务和相关接口。从上面的定义来看,slice 语言还是很简单清晰,基本上你只要花费半天时间,就能覆盖 90%以上的工作需求。 ICE 提供了从 slice 到大多数主流语言的转化工具,命名为 slice2XXX,比如slice2java、slice2cplus、slice2py、slice2php、slice2rb、在 ICE 的安装目录的 bin下,你可以看到上述这些命令。可以通过命令行执行 slice 接口到其他语言的转化,

7、生成相应的代码: slice2java xxx.ice 现在让我们开始正式编程吧,打开 Eclilpse,建立一个普通的 Java 工程: 点击工程的右键菜单,选择 slice2java 子菜单,执行”add slice2java builder”, 添加 slice2javabuilder 之后,项目自动产生了两个文件夹,slice 目录存放 slice 文件、generated 目录存放生成的 java 源文件,同时项目也添加了 ICE 依赖库(Ice Library),ICE 依赖库只有一个:ICE.jar,没有复杂的第三方包,容易集成项目,这也是ICE 的一个优点。 接下来我们只要在

8、slice 文件夹中创建一个后缀为 ice 的 slice 文件,保存以后,slice2java 插件就自动生成对应的 java 源文件了,保存在 generated 目录下。 service.ice 有没有 slice 的 maven 插件呢?很不幸,没有,但 ICE 官方给出一个利用 ant 来在中执行上述过程的实现参考,有兴趣可以试试,毕竟大项目中基本都用 maven 来完成构建过程了。 4.0.0 my.project.groupId my.project.artifactId 0.0.1- SNAPSHOT my.project.name /usr/share/Ice- 3.4.2/

9、slice/Ice com.zeroc ice 3.5.1 maven- antrun- plugin 1.7 generate- sources run com.zeroc ant- ice 3.5.1 org.codehaus.mojo build- helper- maven- plugin 1.7 add- source generate- sources add- source src/generated/java Slice2java 生成的 Java 类如下: 下面我们用 UML 工具(eclipse green uml 插件)看看 ICE 编译后的类之间的关系, Slice 中

10、的接口对象 OnlineBook 会产生三个相关的 Java 接口类:OnlineBookOperationsNC、OnlineBookOperations、以及继承了这两个接口和 ICE.Object根接口的 OnlineBook 接口,OnlineBookOperations 与 OnlineBookOperationsNC 为姊妹接口,声明了 OnlineBook 服务中的方法,不同的是 OnlineBookOperations 在方法签名中增加了 ICE 的内部对象 Ice.Current,这个 Current 对象包括了当前调用的网络连接等信息,ICE.Object 对象则代表了一个

11、远程对象,远程对象的 ID、以及验证远程对象是否存活的Ping 方法,都在此接口中定义,一个实现了本接口的对象在 ICE 中被称之为服务实例servant。OnlineBookDisp 则是实现了 OnlineBook 接口的抽象类,完成了基本的 RPC 过程,其中 Disp 代表着 Dispatch,即调用分发,从下面的 OnlineBookDisp 的下面方法即可看出 ICE RPC 的基本实现原理: public static Ice.DispatchStatus _bookTick(OnlineBook _obj, IceInternal.Incoming _inS, Ice.Curr

12、ent _current) _checkMode(Ice.OperationMode.Normal, _current.mode); /从 Ice.Request 中读取 RPC 请求所关联的网络通道中读取 RCP 方法的参数 IceInternal.BasicStream _is = _inS.startReadParams(); Message msg; msg = new Message(); /反序列化,填充 Message 对象 msg._read(_is); _inS.endReadParams(); /调用用户实现的 OnlineBook 的具体业务接口 Message _ret

13、 = _obj.bookTick(msg, _current); /将结果写回到 RCP 请求的网络应当包中 IceInternal.BasicStream _os = _inS._startWriteParams(Ice.FormatType.DefaultFormat); _ret._write(_os); _inS._endWriteParams(true); /完成调用 return Ice.DispatchStatus.DispatchOK; 以下是 Message 参数对象的序列化与反序列化方法的具体实现: public void _write(IceInternal.BasicS

14、tream _os) _os.writeString(name); _os.writeInt(type); _os.writeBool(valid); _os.writeDouble(price); _os.writeString(content); public void _read(IceInternal.BasicStream _is) name = _is.readString(); type = _is.readInt(); valid = _is.readBool(); price = _is.readDouble(); content = _is.readString(); 如果

15、熟悉 Java 的 ObjectStream 类,则发现上述代码看起来很相似,这是 Java 里最基本的对象到字节流的转换逻辑,做过 java 网络编程的很多人都写过类似代码。通过上述分析过程,我们发现一个有趣的现象,即 RPC 调用过程中的请求参数与应答结果,在 ICE 中都统一抽象为“参数”,将读取 RPC 参数与返回 RCP 应答结果的实现逻辑巧妙的统一起来,代码简单明了。细节决定成败,ICE 号称是业界最快的 RPC 框架,其设计和代码质量处处显示功力。 这里顺便说下关于多字节类型的数据在网络上传输的字节顺序问题,这是网络编程中的一个技术细节,称之为“网络字节顺序”,通常有“Littl

16、e endian (将低序字节存储在起始地址)”与“Big endian :将高序字节存储在起始地址”两种,JAVA 采用 BIG- Big endian方式,而 Zero ICE 的则采取了 Little endian 模式,其文档上这么说的:“Data is always encoded using little- endian byte order for numeric types. (Most machines use a little- endian byte order, so the Ice data encoding is right more often than not.

17、)”,另外,还补充了一点:“Ice requires clients and servers that run on big- endian machines to incur the extra cost of byte swapping data into little- endian layout, but that cost is insignificant compared to the overall cost of sending or receiving a request.”,那么 ICE 提到的“Most machines”是那些呢?猜猜就知道了,即 X86 体系的机器,它

18、们采用 Little endian 的主机字节顺序,而RISE 等 Unix 系列的机器则普遍采用 BIG- Big endian 方式。这里若使用 ICE For Java,就遗留一个悬念了,它这个 Java 版本的,是否是通过编程改变了 Java 默认的“Big endian”方式呢?,因为 Java ByteBuffer 类是可以指定编码方式的,方式如下:ByteBuffer.order(ByteOrder.LITTLE_ENDIAN),这个问题就留给聪明的你去探索吧。 从上述的 UML 类图中的 Ice.Object 对象,我们还看到 ICE 中很重要的一个概念:对象标识(Identi

19、ty),从其代码来看,一个 Ice.Object 可以绑定多个 ID,但其中有一个是它最确切的真正的 ID,ID 用来查找和定位 RPC 的远程对象,_OnlineBookDisp 中的下面代码就很清晰的说明了上述这些问题: public static final String _ids = :Ice:Object,所有的 Ice Object 都有此 ID :book:OnlineBook这是 OnlineBook 这个 Object 的真正 ID ; public boolean ice_isA(String s) 用来查找是否是某个远程对象 return java.util.Arrays

20、.binarySearch(_ids, s) = 0; public String ice_ids() return _ids; public String ice_id() return _ids1; 如果你熟悉 J2EE 技术,应该对“Naming”这个词不陌生, Naming Service 是J2EE 体系的最重要基础组建之一,它的原理就通过某个指定的 ID 来查找绑定的对应 EBJ对象,ICE 里也有这个组件,它称之为 Locator。既然是远程调用框架,那么我们必须要将某个远程对象“绑定”到某个网络通道,才能完成远程调用,ICE 用 Ice.ObjectAdapter 这个对象来完

21、成具体的相关工作,让我看看 ObjectAdapter 接口中的几个重要方法: void activate()激活此 Adapter 上绑定的 ICE 服务实例,类似 J2EE 容器的加载和钝化 EJB 实例的,用于实现服务器资源的合理利用,按需启动或停止。 Ice.ObjectPrx add(Ice.Object servant, Identity id)将某个服务实例以某个名字绑定到本 Adapter 上。 Ice.ObjectPrx createProxy(Identity id)创建指定服务实例的 Proxy 对象。 最后我们要了解的一个概念是“Endpoint”,Endpoint 通

22、常可以理解为一个访问地址,在 WebService 中也有这个词:“当我们 Host 一个 Web Service 的时候,我们必须给他定义一个或多个 Endpoint,然后 service 通过这个定义的 Endpoint 进行监听来自 Client端的请求。”,在 ICE 中,Endpiont 有两种:UDP 或 TCP,但基本上很少用 UDP,因为现在的高速网络带宽采用 TCP 长连接情况下,UDP 基本没有什么优势了。怎么创建一个Endpoint 并绑定我们的 ICE 服务?答案就是 Communicator 对象,它是 ICE 核心对象,沟通 Client 与 Server 端,它的

23、关键方法如下: Ice.ObjectPrx stringToProxy(String str)将一个对象标识转换对应的服务代理对象,用于客户端调用 ObjectAdapter createObjectAdapterWithEndpoints(String name, String endpoints)创建 ObjectAdapter 并把 ObjectAdapter 绑定到指定的Endpoints 上 LocatorPrx getDefaultLocator()获取默认的服务 Locator 对象,Locator对象用于服务代理来定位具体的远程 ICE 服务实例。 至此,我们 Hello Wo

24、rld 所需的 ICE 对象都介绍完毕,接下来就可以写具体的实现代码了,先写服务端,在写之前,你可以停下来想想下面几个问题: 我们的服务代码继承哪个类? 通常的网络编程中,服务端的实现是哪几个过程? 。努力思考中。考。中。 答案下页揭晓,敬请期待! 第一个问题的答案:服务实现 XXXDisp 抽象 第二个问题的答案如下: 创建 SocketServer 在一个 EndPoint 上,如 Localhost TCP 9999 启动此 SocketServer,在绑定的端口上进行监听 写消息接收和处理的无限循环逻辑,直到停止服务 Ok,我们先来写服务实现类(servant),按照 ICE 的建议,

25、servant 类的后缀名为I(Implement 缩写),为了将 Slice 生成的 java 代码与我们的实现类分开,我们建议定义另外的报名来存放我们的实现类,服务的代码为了简化,直接返回订单请求: import Ice.Current; import com.hp.tel.ice.book.Message; import com.hp.tel.ice.book._OnlineBookDisp; public class OnlineBookI extends _OnlineBookDisp private static final long serialVersionUID = 1L;

26、Override public Message bookTick(Message s, Current _current) return s; 接下来实现 Sever 端代码: public class Server public static void main(String args) int status = 0; Ice.Communicator ic = null; try / 初始化 Communicator 对象,args 可以传一些初始化参数,如连接超时,初始化客户端连接池的数量等 ic = Ice.Util.initialize(args); / 创建名为 OnlineBoo

27、kAdapter 的适配器,并要求适配器使用缺省的协议(TCP/IP 端口为 10000 的请求) Ice.ObjectAdapter adapter = ic.createObjectAdapterWithEndpoints( OnlineBookAdapter, default - p 10000); / 实例化一个 OnlineBook 服务对象 OnlineBookI object = new OnlineBookI(); / 将服务单元增加到适配器中,并给服务对象指定 ID 为OnlineBook,该名称用于唯一确定一个服务单元 adapter.add(object, Ice.Uti

28、l.stringToIdentity(OnlineBook); / 激活适配器 adapter.activate(); / 让服务在退出之前,一直持续对请求的监听 System.out.print(server started ); ic.waitForShutdown(); catch (Exception e) e.printStackTrace(); status = 1; finally if (ic != null) ic.destroy(); System.exit(status); ICE Server 的代码就这么简单,甚至比大多数 NIO Socket 框架用起来都简单,下面

29、我们再看看客户端相关的 UML 图: Ice.ObjectPrx 代表一个远程对象的代理,实现了基础的通信和方法调用框架, XXXDel 接口定义了远程访问接口,对于每个 ICE 服务,ICE 默认生成了两个实现类:本地调用(XXXDelD)和远程调用(XXXDelM),前者用在服务直接调用的优化过程中,即若多个 ICE 服务部署在一个 JVM 中并有相互调用关系的情况下,ICE 是能做优化的;后者则是通过网络进行远程调用,ICE 的这个设计与 J2EE EJB 的本地接口有远程接口很相似,只不过它这边把这个过程给自动化和隐蔽了,抽象类 ObjectPrxHelperBase 里创建代理的这段

30、代码揭示了 ICE 服务调用优化的秘密: _ObjectDel createDelegate(boolean async) if(_reference.getCollocationOptimized()若具备优化条件,则创建本地直接调用代理对象 XXXDelD ObjectAdapter adapter = _reference.getInstance().objectAdapterFactory().findObjectAdapter(this); if(adapter != null) _ObjectDelD d = _createDelegateD(); d.setup(_referen

31、ce, adapter); return d; _ObjectDelM d = _createDelegateM(); d.setup(_reference, this, async); return d; 在这里,继承了 ObjectPrxHelperBase 的 OnlineBookPrxHelper 实现了OnlineBookPrx 接口,具体的远程调用逻辑工作则交给 _OnlineBookDelD 或者或_OnlineBookDelM 来完成,前者是本地调用,不涉及到网络通信,后者的代码如下: public Message bookTick(Message msg, java.util

32、.Map _ctx, Ice.Instrumentation.InvocationObserver _observer) throws IceInternal.LocalExceptionWrapper /得到网络通信的输出通道 IceInternal.Outgoing _og = _handler.getOutgoing(bookTick, Ice.OperationMode.Normal, _ctx, _observer); try try /写 RCP 调用的参数,Message 对象序列化到输出流中 IceInternal.BasicStream _os = _og.startWrit

33、eParams(Ice.FormatType.DefaultFormat); msg._write(_os); _og.endWriteParams(); catch(Ice.LocalException _ex) _og.abort(_ex); /发送数据并检查是否成功 boolean _ok = _og.invoke(); try if(!_ok) try _og.throwUserException(); catch(Ice.UserException _ex) throw new Ice.UnknownUserException(_ex.ice_name(), _ex); /等待服务端

34、的响应结果消息,并反序列化为 Message 应答对象 IceInternal.BasicStream _is = _og.startReadParams(); Message _ret; _ret = new Message(); _ret._read(_is); _og.endReadParams(); return _ret; catch(Ice.LocalException _ex) throw new IceInternal.LocalExceptionWrapper(_ex, false); finally /清理此次调用 _handler.reclaimOutgoing(_og)

35、; 经过上述分析,我们基本能够理解 ICE 客户端的调用实现原理了,接下来就来实现Client 代码: public class Client public static void main(String args) int status = 0; Ice.Communicator ic = null; try / 初始化通信器 ic = Ice.Util.initialize(args); / 传入远程服务单元的名称、网络协议、IP 以及端口,获取OnlineBook 的远程代理,这里使用 stringToProxy 方式 Ice.ObjectPrx base = ic .stringToP

36、roxy(OnlineBook:default - p 10000); / 通过 checkedCast 向下转型,获取 OnlineBook 接口的远程,并同时检测根据传入的名称获取服务单元是否 OnlineBook 的代理接口,如果不是则返回null 对象 OnlineBookPrx onlinBook = OnlineBookPrxHelper.checkedCast(base); if (onlinBook = null) throw new Error(Invalid proxy); / 调用服务方法 Message msg = new Message(); msg.name = M

37、r Wang; msg.type = 3; msg.price = 99.99; msg.valid = true; msg.content = abcdef; long start=System.currentTimeMillis(); int count=100000; for(int i=0;icount;i+) onlinBook.bookTick(msg); long used=System.currentTimeMillis()- start; System.out.print(tps +count*1000.0/used); catch (Exception e) e.print

38、StackTrace(); status = 1; finally if (ic != null) ic.destroy(); System.exit(status); 代码中 OnlineBookPrx onlinBook = OnlineBookPrxHelper.checkedCast(base);这一段实际上是从只包括基础的对象 ID、EndPoint 等相关信息的基础 ObjectPrx 类拷贝信息,并构造一个具体的 ObjectPrx 实现类 OnlineBookPrxHelper,其源码如下: public static OnlineBookPrx checkedCast(Ice

39、.ObjectPrx _obj) OnlineBookPrx _d = null; if(_obj != null) if(_obj instanceof OnlineBookPrx) _d = (OnlineBookPrx)_obj; else if(_obj.ice_isA(ice_staticId() OnlineBookPrxHelper _h = new OnlineBookPrxHelper();/构造具体的 Proxy 类 _h._copyFrom(_obj);/从基础 Proxy 中拷贝必要信息,包括连接等内部对象 _d = _h; return _d; 启动 Server,然

40、后启动 Client,测试一下,看看你本机调用结果如何,我本机上达到 2.5 万每秒的性能,这个性能差不多是 HTTP 通道的 10 倍左右,也验证了 ICE 的高性能。 下图是 ICE 客户端与服务器端的通信原理图,我们之前分析的哪些由 ICE 生成的代码,就分别存在于客户端与服务器端: ICE 跨平台的实现原理,是通过 Slice 定义的接口文件,分别编译成不同语言的实现类,RPC 方法和参数采用特定的编码方式,使得各个语言都能解析,从而实现跨语言的调用,这类似 Cobra 的做法,下图是一个 C 开发的 ICE 服务被 Java 客户端调用的原理示意图: 本节最后留几个小问题: Endp

41、oint 中的 default 是什么含义 若客户端在另外的机器上,客户端在构造 ObjectPrx 的时候,怎么指定服务端的 IP地址?(提示:若熟悉 MySQL 命令行的连接,估计立即想到答案) 若服务在多个机器上注册,客户端怎么调用? 好用的 Icebox 在前面的 Hello World 一章中,我们初步了解了 ICE 的原理,掌握了其重要概念:ICE 服务(servant)、服务的 ID、servant 绑定到 ObjectAdaptory 上、服务的 Endpoint等,通过编写简单的 Hello World 程序,我们也掌握了其基本用法。接下来,我们开始学习 ICE 的服务框架I

42、cebox,这个类似一个 J2EE 中间件,可以大大的简化服务端的开发,让我们“只开发服务本身”而不是“开发完整系统”。 简单的说,Icebox 就好象是一个 Tomcat 中间件,我们只要写 N 个 ICE 服务的代码,然后用一个装配文件定义需要加载的服务列表、服务的启动参数、启动次序等必要信息,然后启动 IceBox,我们的应用系统就能够正常运行了。与现在流行的 XML 文件配置不同,Icebox 采用的是 Unix 上通用的方式属性文件的方式,可能的一个原因是省去复杂的 XML 解析和相关 lib 吧。 另外,一个 IceBox 内部创建一个 service manager 的对象(Ic

43、e.Admin),这个对象专门负责 loading 和 initializing 那些配置好了的服务,你可以选择性地将这个对象暴露给远程的客户端,譬如 IceBox 或者 IceGrid 的 administrative utilities,这样 IceBox 和 IceGrid就可以执行某些远程管理任务,Ice.Admin 默认是关闭的,而在 IceGrid 中部署的 IceBox, 则会被自动地激活。 要将一个 ICE 服务纳入到 Icebox 中,我们需要引入 IceBox.jar 这个库,另外只需让这个服务的实现类实现 Ice 的 Service 接口,此接口定义如下: void st

44、art(String name, Ice.Communicator communicator, String args) 服务可以在 start 操作中初始化自身;这通常包括创建对象适配器和 servant。name和 args 参数提供了来自服务的配置的信息,而 communicator 参数是服务管理器为供服务使用而创建的 Ice.Communicator 对象。取决于服务的配置,这个通信器实例可能会由同一个 IceBox 服务器中的其他服务共享,因此,你需要注意确保像对象适配器(ObjectAdapter)这样的对象的名字是唯一的。 void stop()stop 方法中回收所有被 se

45、rvice 使用的资源,一般在 stop 中service 会使一个 object adapter 对象无效(deactivates),不过也有可能对 object adapter 执行一个 wartForDeactivate 的方法来确保所有未完成的请求在资源清理前得到处理,默认会将它的 object adapter 作为 communicator 销毁的一部分连同communicator 对象一起 destory 掉,但某些情况下不能做到,如 IceBox 中services 使用共享的 communicator 对象时,此时你需要明确指明销毁它的 object adapter 对象。 继

46、续之前的例子,我们把 OnlineBook 服务变成 IceBox 托管的服务,只要再增加一个类,实现上述接口,并在 start 里完成服务绑定即可,代码如下: public class BoxOnlineBookI implements Service private Ice.ObjectAdapter _adapter; private static final long serialVersionUID = 1L; private Logger getLogger() /用来记录服务的日志信息 return _adapter.getCommunicator().getLogger();

47、Override public void start(String name, Communicator communicator, String args) / 创建 objectAdapter,这里和 service 同名 _adapter = communicator.createObjectAdapter(name); / 创建 servant 并激活 Ice.Object object = new OnlineBookI(); _adapter.add(object, communicator.stringToIdentity(name); _adapter.activate();

48、getLogger().trace( name, service started ,with param size + args.length + ,detail: + Arrays.toString(args); Override public void stop() _adapter.destroy(); 接下来我们看看 Icebox 的配置文件,其配置文件分为两部分,一部分是共性,一部分是具体服务定义相关的配置: 共性部分如下: #本 Icebox 的实例名称 IceBox.InstanceName=MyAppIceBox 1 #在所有服务的初始化完成之后,服务管理器将打印token r

49、eady。如果有脚本想#要等待所有服务准备就绪,这项特性很有用,下面例子就会输出日志: #“ MyAppIceBox1 ready” IceBox.PrintServicesReady= MyAppIceBox 1 #定义服务的启动顺序,解决服务启动过程中的先后顺序问题 IceBox.LoadOrder=serv1,serv2,serv3 #优化本地服务之间调用的重要参数,UseSharedCommunicator,若 Hello 与Printer 两个服务存在调用关系,又部署在一个 Icebox 实例中,则可以定义两者使用同一个 Communicator 对象,实现服务本地调用的优化。 Ic

50、eBox.UseSharedCommunicator.Hello=1 IceBox.UseSharedCommunicator.Printer=1 #Ice 一些常用参数属性 Ice.MessageSizeMax = 2048 Ice.Trace.Network=1 Ice.Trace.ThreadPool=1 Ice.Trace.Locator=1 #定义 IceBox 服务管理器接口的端点,以激活 IceBox 管理服务使之能够被远程控制,默认是关闭的,在内网中可以打开,并绑定私有地址。 IceBox.ServiceManager.Endpoints=tcp - p 9999 - h lo

展开阅读全文
相关资源
相关搜索
资源标签

当前位置:首页 > 技术资料 > 技术方案

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:文库网官方知乎号:文库网

经营许可证编号: 粤ICP备2021046453号世界地图

文库网官网©版权所有2025营业执照举报