`
zhaoningbo
  • 浏览: 610158 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Zeroc Ice中间件之通讯器资源回收

阅读更多

引言:

 

    一个类的方法非常多,且被调用较多时,就不宜采用“单方法单代理”的方式了来调用远程ICE服务了。其本质原因是,客户端每次申请新代理都会占用本机的一个端口。如果“单方法单代理”遭遇峰值,可能会直接导致本机端口原因引发异常。异常内容如下:

41:30,031:[CCX_S_FA_INVESTINCOME]002143
Exception in thread "main" Ice.SyscallException
    error = 0
	at IceInternal.Selector.<init>(Selector.java:29)
	at IceInternal.ThreadPool.<init>(ThreadPool.java:77)
	at IceInternal.Instance.finishSetup(Instance.java:786)
	at Ice.CommunicatorI.finishSetup(CommunicatorI.java:286)
	at Ice.Util.initialize(Util.java:212)
	at Ice.Util.initialize(Util.java:222)
	at com.ccx.stock.financialAnalysisNew.DerRepoDataClient.getOwnPrx(DerRepoDataClient.java:83)
	at com.ccx.stock.financialAnalysisNew.DerRepoDataClient.CCX_S_FA_INVESTINCOME(DerRepoDataClient.java:204)
	at com.ccx.stock.financialAnalysisNew.TestDerRepoDataClient.main(TestDerRepoDataClient.java:44)
Caused by: java.io.IOException: Unable to establish loopback connection
	at sun.nio.ch.PipeImpl$Initializer.run(PipeImpl.java:106)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.nio.ch.PipeImpl.<init>(PipeImpl.java:122)
	at sun.nio.ch.SelectorProviderImpl.openPipe(SelectorProviderImpl.java:27)
	at java.nio.channels.Pipe.open(Pipe.java:133)
	at sun.nio.ch.WindowsSelectorImpl.<init>(WindowsSelectorImpl.java:104)
	at sun.nio.ch.WindowsSelectorProvider.openSelector(WindowsSelectorProvider.java:26)
	at java.nio.channels.Selector.open(Selector.java:209)
	at IceInternal.Selector.<init>(Selector.java:25)
	... 8 more
Caused by: java.net.BindException: Address already in use: connect
	at sun.nio.ch.Net.connect(Native Method)
	at sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:507)
	at java.nio.channels.SocketChannel.open(SocketChannel.java:146)
	at sun.nio.ch.PipeImpl$Initializer.run(PipeImpl.java:78)
	... 16 more

 

    下文将对此问题做以简单介绍。

 

正文:

 

    (晚点续上)

 

     (续上)
 
1,首先有以下几个要点需要说明。


    A)项目中ICE通讯使用的是默认TPC/IP(socket)通讯;
    B)Java1.4后以NIO升级老版IO(以支持多路复用);
    C)请求发出后,返回之前,请求者需要被阻塞(java Object.wait()等及线程机制的需要);

2,接下来说说引言中提到的报错信息。


    第2行:Ice.SyscallException,ICE骨架支持异常。

    第13行:Unable to establish loopback connection,本机对本机的连接不能持久化。

    第24行BindException: Address already in use: connect,地址已经被占用。

 

3,详细分析。

 

    本例异常,引发的根本原因是13行与24行。

 

    24行的异常。主要是由于Java每个socket请求时,都会占用*至少*一个端口,本例测试时循环5000个socket请求,在400左右时便出现上述异常。其原因就在当前请求的socket端口已被之前的socket占有。关于此异常很常见,随便搜索一下,可以看到大量的说明,因此这里跳过。

 

    13行的异常。也是本例异常产生的重点。

 

    loopback connection,这是什么connection呢?!是形如如下的connection:

  TCP    10.0.2.128:3024        10.0.2.128:3046      ESTABLISHED
  TCP    10.0.2.128:3046        10.0.2.128:3024      ESTABLISHED

    这两行TCP连接互相监听,组成一对“loopback connection”。初看此连接觉得很费解,为什么会出现这样的TCP(socket)连接呢?回想一下正文第1节C中提到的“阻塞-唤醒”这一需要。我们假设有一个名A的socket请求发出后,很自然进入阻塞状态,随后服务者B在处理结束(正常、异常、强制),想以更效率的DI(Donot call me, I'll call U.)方式唤醒请求者A进行后续处理。

 

    这时就遇到一个问题DI的唤醒如何实现。可能的方式有三:一是B处理结束后有数据需要处理或发生异常;二是超时timeout;三是强制方式(如Executors强制限时完成等)。一看就只有第一种方式了。让自己的3024监听自己的3046,如果自己的socket请求正常调用就不说了;非正常情况下,只要把异常处理或者超时处理交给3046来处理并返回给3024,通知失败(有返回数据需要处理时可被自动唤配),随后自己即可被唤醒了。

 

    这样也就解释了为什么会有loopback connection异常发生。

 

    另外,需要说明的是ICE穿墙采用的是“双向连接”方式,每个客户端请求可能需要使用不止一两个端口。因此在客户端编写并发、单请求单通路,这类socket短时峰值较高的代码时,应该尽力避免。

 

总结:

 

    1,由于java socket连接本身存在“对端口资源的消耗性 与 端口资源的有限性”这一问题,加之ICE默认TCP双向连接的特点更加强了消耗性影响,因此在使用ICE创建通讯器请求远程代理时,尽可能加强代理“复用性”,减少“回收与重申请”。

 

    2,ICE是主要是用于企业架构的,而非通信的。如果不是为架构而来,建议可以考虑一下mina——更专业的java通信框架。

 

尾声:

 

    因为笔者是C/C++,Java双修,双“半吊子”,对socket的理解,欢迎大家批评、讨论。

 

(完)

 

 

 

1
0
分享到:
评论

相关推荐

    Zero Ice中文教程

    Zero Ice中文教程里面详细介绍了Ice的分布式设计,中文版本。

    zero ICE快速入门java版

    zero ICE快速入门文档, ice是最优秀的rpc框架。 4、开发服务端代码如下 步骤一:编写Servant类即带有Disp的存根文件也就是说继承_HelloWorldDisp 这个类,这个类是个抽象类定义如下: public abstract class _...

    基于ICE中间件实现的传文件

    基于ICE中间件实现的传文件 InstallService UpdateService dllICE

    Zero ICE 3.5.1 jar

    远程调用框架 Zero ICE 3.5.1 jar

    ICE客户端与服务端通信Demo

    平台编译环境:VS2017 ICE版本:3.7.7 ICEbuilder:5.0.9 源码中有两套程序: Server:启动服务器,等待连接 。连接后可双方通信 Client:连接服务器,与服务器通讯。 Slice: 手写几个接口即可。

    Ice zero分布式程序设计2分

    Ice zero分布式程序设计Ice zero分布式程序设计Ice zero分布式程序设计Ice zero分布式程序设计Ice zero分布式程序设计

    Zero Ice 3.6源码

    ICE是ZEROC的开源通信协议产品,它的全称是:The Internet Communications Engine,翻译为中文是互联网通信引擎,是一个面向对象的中间件,源码供大家研究使用。

    ZeroMQ 消息通讯中间件库

    该库存可以动态库 乐意直接嵌入到应用层序中,使用简洁方便,空间也很小。zero MQ提供的celue API比较丰富,完全可以满足日常需要。并发负载能力,可以深入挖掘。

    ice_3.7.0_linux版

    Zero ICE,Zeroc ICE,ice,linux,2017年最新版的Zero ICE版本3.7.0,linux版本 Zero ICE,Zeroc ICE,ice,linux,2017年最新版的Zero ICE版本3.7.0,linux版本

    ZeroC ICE 简单介绍及代码

    介绍ICE互联网通讯引擎是什么,以及其工作原理。附有简单的源代码,可以实现测试使用。

    zeroc ice教程 ice环境配置 Ice中文教程 C++ ICE java ICE ICE入门 ice基础教程 ice开发文档

    教程包括: 第一部分 Ice综述 第二部分 核心概念 第三部分 高级Ice 第四部分 Ice服务 附录ice各种配置说明

    ICE 3.6.1 异步调用 VS2013 Demo

    ICE 异步调用 按照网上已有的例子,客户端调用需要加入["ami"]元数据指定,但ICE 3.4以后的版本不支持,所以对于ICE...本资源的ICE的版本为3.6.1,所以需要提前下载好ICE3.6.1,并在工程中设置头文件的路径和库的路径。

    Ice 分布式程序设计 中文PDF版_C++_Zero_

    ICE开发资料,帮助程序使用ZERO-ICE进行C++开发

    Ice 3.4.1 在ARM上移植, 源代码补丁

    ICE 3.4.1 在移植到ARM Linux中时,double型的数据会有错误。见我在ZeroC发的帖子: http://www.zeroc.com/forums/bug-reports/5308-double-data-format-arm-linux-not-correct.html 在移植前,需要对源代码进行一些...

    Ice-3.6.4.msi

    Ice-3.6.4-msvc2015.msi zero-ice msvs2015 Ice-3.6.4-msvc2015.msi zero-ice msvs2015

    zeroc ice u3d 网络组件

    zeroc_ice u3d tcp socket c# www.zeroc.com ice的unity3d版本。 独家发布。外边绝对没有。 需要咨询。可以给我发信息。

    Go微服务精讲:Go-Zero全流程实战即时通讯(13章)

    本文将结合经典 IM 项目,带你深入微服务架构精髓,探究主流微服务框架Go-Zero框架底层运作机制和框架自研之道,让你从分布式系统架构设计、容器化部署管理、高并发性能提升、系统监控等,多维度掌握Go开发高薪技能...

    ice-3.6.1.msi

    网络通信引擎ICE(Internet Communications Engine)是Zero C公司的分布式系统开发专家实现的一种新的高性能的面向对象中间件平台,ice-3.6.1.msi 是官网的下载安装包 。

    基于ice可靠消息传输框架

    基于ICE的可靠的、顺序的消息传输框架,发送消息时,先将消息持久到本地,等消息成功发送到目标机器后,删除本地消息。开发此框架的目的是为了公司业务数据的同步。消息节点有id和group,支持id、group以及其他任意...

    zeroc_ice-3.7.6 for python Windows32

    python安装ice: pip install zeroc-ice

Global site tag (gtag.js) - Google Analytics