锁定老帖子 主题:内部系统间调用效率的讨论
精华帖 (0) :: 良好帖 (2) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2012-08-23
最后修改:2012-08-23
java_user 写道
allwefantasy 写道
我觉得想复杂了。能不能就简单通过http呢。不需要考虑队列,每个请求无状态。如果是内网,我并不认为http调用会很慢。
系统相互之间直接调用,连接就太多了 比如10个应用都要调用对方,结果需要100种连接,网络也不好保证啊
才100个连接,别说server,就算是你的笔记本眼睛都不会眨巴下。如果真到了你不能接受的数量级再说,还有解决方案。 |
|
返回顶楼 | |
发表时间:2012-08-23
楼上大牛们的讨论要小弟学习了真多,收藏下
|
|
返回顶楼 | |
发表时间:2012-08-23
vlinux 写道 java_user 写道
allwefantasy 写道
我觉得想复杂了。能不能就简单通过http呢。不需要考虑队列,每个请求无状态。如果是内网,我并不认为http调用会很慢。
系统相互之间直接调用,连接就太多了 比如10个应用都要调用对方,结果需要100种连接,网络也不好保证啊
才100个连接,别说server,就算是你的笔记本眼睛都不会眨巴下。如果真到了你不能接受的数量级再说,还有解决方案。 说的好,避免过渡设计,JMS or 简单的socket队列,做好热备和failtolerance就好 |
|
返回顶楼 | |
发表时间:2012-08-23
最后修改:2012-08-23
youarestupid 写道 方世玉 写道 瞬间是:某人一按按钮,另外一个地方的警报器就马上响起来,绝对不能漏接,绝对不能等待。
纳秒?毫秒?有指标吗。 要求没那么精确,反应在五秒以内就是正常。 反应不是最关键的,我怕java端宕掉,但是C++端得不到结果不知道该怎么处理后续步骤; 更担心Java端的Socket Server出现大规模线程等待,导致C++新请求进不来。 在做个程序,实时监测java服务是否当了,如果当了,重启java服务器。如果你害怕连接堵塞,在搞个程序事实监测请求不在5秒内返回数据包,直接重启java服务器,办法有好多,如果你说机器上只能跑两个程序,那就没办法了。 还有个笨方法,监听同一文件夹,没个请求生成一个xml,请求处理完,删除一个xml。 |
|
返回顶楼 | |
发表时间:2012-08-23
youarestupid 写道
方世玉 写道
youarestupid 写道
方世玉 写道
youarestupid 写道
java_user 写道
vlinux 写道
偶不是大牛,不过跳出来吐槽下
统一调用平台,实际上你要做的是业务总线咯。用JMS的方式不是说不ok,但从执行效率来说绝对不是高效的。因为你的业务总线(也就是你的统一调用平台啦)是一个绝对的单点,这就意味着你的这个平台必须保证至少一组热备。另外由于是所有业务都接入,每个业务自身都有优先级,所以你的前置接口机必须根据业务优先级进行物理隔离,防止低级业务挤占高级业务的线程池。物理隔离还必须延伸到JMS,防止不同优先级的业务事件相互挤占。此外基于JMS的QoS你还很不好做。
还有JMS消息的重复投递、无序投递,服务的幂等被迫做得很细,如果业务上无法做幂等,你还得在技术上判重。 当JMS的Producer全部下线(server端故障)时,做为Consumer无法及时感知,无法立即返回业务方失败,只能活生生的等待超时。
非个人研究,不敢做实验,呵呵 JMS可以做集群,响应的服务器也可以做集群,感觉问题应该不大,至于等待超时这个确实没办法只能在客户端做文章。之前也是有过相关的经验,才会想到这个的。
使用Socket在Java <==> C++通信,自己约定一些通信协议规则,是目前采取的措施,但是有时候Java应用和C++应用就在同一台服务器上,这样也用Socket通信,有点走弯路的感觉。
如果使用JNI,则Java 和 C++之间必须耦合成一个应用,这样就不能做到C++应用的替换了。
大家有没有一种比较好的办法,实现Java 与 C++之间高效率、及时性地通信?
Java和C++之间的调用可以选用Facebook开源的Thrift或者Google开源的Protocolbuf作为远程通讯协议。 至于JMS的使用,我觉得vlinux说的很好,去中心化是必须要考虑的。如果是Java之间通讯,楼主可以考虑一下阿里的Dubbo。
我的面临的核心问题是: 两个应用部署在同一台服务器上,一个Java应用,一个C++应用,两个应用之间独立,不能互相成为彼此的嵌入模块,但是两个应用之间又需要高实时性地通信。 也就是: 外部电流信号进入硬件==>硬件检测电压变化,将感应传输给硬件驱动 ==>硬件驱动告诉C++应用 ==>> C++应用调用Java应用 ==>Java引用处理一些逻辑,将结果返回C++应用 ==>C++应用告诉硬件驱动 ==>硬件驱动命令硬件做出反应。
这是一个完整的回路流程,要求在瞬间完成,不能阻塞。
因为Java应用和C++应用部署在同一台服务器上,我就想,有没有办法让着两个应用间建立一种非常快速的通信机制,类似Java通过JNI调用动态链接库,但是又不能使用JNI,因为C++应用不能成为Java应用的一部分。
如果使用Socket通信,当并发数量很多的时候,Java的Socket Server会出现线程排队的现象,这样整个流程就不是一个实时性的东西了。
在你的场景下,“瞬间”是什么样的响应时间,指标是多少?如果真的是实时系统,用java就不合适了,因为还要考虑GC导致的停顿。 另外部署在一台服务器上可以考虑用操作系统的消息机制,不过按照你说的方案,c++一定要同步的调用java获取返回值,那就又不合适了,因为消息机制是异步的。
目前来看,Java与C++之间唯一可行的通信方式,就是Socket,但是我的担心是: 1、如果Java服务宕掉怎么办,C++端都不知道它宕掉了; 2、如果Java端的Socket Server有线程一直执行不完,C++端再发来请求,出现了线程等待怎么办? 3、我想如果Java端出现什么情况,我在C++端都能立刻知道,就像所有的流程都在C++中一样,不要出现C++端不知道java端发生了什么事情的问题。 从描述看C++端为客户端,建议采用socket长连接的形式。长连接一般的实现方法都是在客户端,客户端打开socket通道后不去关闭连接,客户端开启两个线程,一个只做发送一个只做接受。然后客户端发送心跳测试信号,来确定服务端是否存活并检查通道是否联通,如果没有联通就重新连接。 服务端针对阻塞可以采用收到一个命令后,就启用一个新的线程来运行,这样服务端不会有阻塞。当服务端完成后,可以返回给客户端,因为客户端是异步接受命令的,所以即使该客户端的命令执行较长时间,也不会影响其他的客户端执行命令。
当然以上为正常的执行情况,该结构最麻烦的地方就是对于性能的调整,包括发送池管理,线程自身情况管理等等。 |
|
返回顶楼 | |
发表时间:2012-08-23
小弟拙见:我觉得定义好C++那边程序的接口,直接用JNI就ok了呀。这也是一种接口方式嘛,只要接口稳定,那C++那边重写或替换都没问题啊。反正你都是在一台机器上。
只是我只做过Java单纯调用C++,你的需求是要C++主动发起请求,没试过呢。呵呵。 不过也可以用类似轮询的方式来变相弄下的。 |
|
返回顶楼 | |
发表时间:2012-08-23
并发是多少呀,如果不大,用什么其实都没什么问题。
响应时间5s,已经很长了,基本可以忽略实时这个问题。 关于担心宕机问题: 1. 可以通过心跳指令的方式,C向java发消息“服务器你还活着么” 2. 守护进程,自己监控,宕机重启服务或应用 还有,为什么不能用jni呢 |
|
返回顶楼 | |
发表时间:2012-08-23
rmi hessian nio
|
|
返回顶楼 | |
发表时间:2012-08-23
最后修改:2012-08-23
xxwinnie 写道 小弟拙见:我觉得定义好C++那边程序的接口,直接用JNI就ok了呀。这也是一种接口方式嘛,只要接口稳定,那C++那边重写或替换都没问题啊。反正你都是在一台机器上。
只是我只做过Java单纯调用C++,你的需求是要C++主动发起请求,没试过呢。呵呵。 不过也可以用类似轮询的方式来变相弄下的。 kelvem 写道 并发是多少呀,如果不大,用什么其实都没什么问题。 响应时间5s,已经很长了,基本可以忽略实时这个问题。 关于担心宕机问题: 1. 可以通过心跳指令的方式,C向java发消息“服务器你还活着么” 2. 守护进程,自己监控,宕机重启服务或应用 还有,为什么不能用jni呢 在一开始我就说了,不能用JNI,因为用JNI,c++应用就成为Java应用的一部分,但是我的项目不能这样,Java和C++两个应用需要彼此独立为两个应用,而且C++应用要可替换,因为硬件有不同厂家,不同厂家提供的驱动不一样,所以要写不一样的c++应用去调度驱动程序。 Java应用和C++应用是彼此独立的两个应用,不能相互成为一部分,所以JNI被排除。 ======================================================================== 我现在采取的方法是Socket,但是我总有一个疑问:同一台机器上的程序间,还要通过Socket来通信,这样是不是浪费了在同一台电脑上? 我想有没有内存共享的方法,实现同一台机器上的异构应用间通信? Socket当然可以实现,我现在也是用Socket来用的,但是我想探求一种更省资源,更稳定的方案,毕竟两个应用在同一台机器上,用网络通信去传递消息,太浪费了。 |
|
返回顶楼 | |
发表时间:2012-08-23
最后修改:2012-08-23
youarestupid 写道
xxwinnie 写道
小弟拙见:我觉得定义好C++那边程序的接口,直接用JNI就ok了呀。这也是一种接口方式嘛,只要接口稳定,那C++那边重写或替换都没问题啊。反正你都是在一台机器上。
只是我只做过Java单纯调用C++,你的需求是要C++主动发起请求,没试过呢。呵呵。 不过也可以用类似轮询的方式来变相弄下的。 kelvem 写道
并发是多少呀,如果不大,用什么其实都没什么问题。 响应时间5s,已经很长了,基本可以忽略实时这个问题。 关于担心宕机问题: 1. 可以通过心跳指令的方式,C向java发消息“服务器你还活着么” 2. 守护进程,自己监控,宕机重启服务或应用 还有,为什么不能用jni呢 在一开始我就说了,不能用JNI,因为用JNI,c++应用就成为Java应用的一部分,但是我的项目不能这样,Java和C++两个应用需要彼此独立为两个应用,而且C++应用要可替换,因为硬件有不同厂家,不同厂家提供的驱动不一样,所以要写不一样的c++应用去调度驱动程序。 Java应用和C++应用是彼此独立的两个应用,不能相互成为一部分,所以JNI被排除。 ======================================================================== 我现在采取的方法是Socket,但是我总有一个疑问:同一台机器上的程序间,还要通过Socket来通信,这样是不是浪费了在同一台电脑上? 我想有没有内存共享的方法,实现同一台机器上的异构应用间通信? Socket当然可以实现,我现在也是用Socket来用的,但是我想探求一种更省资源,更稳定的方案,毕竟两个应用在同一台机器上,用网络通信去传递消息,太浪费了。
你太过于纠结这个浪费就是过渡设计呢,能用就是好的。这种方案,就算有,量上来了你肯定也不会用。 |
|
返回顶楼 | |