您好!
在2007-10-12来自yaya...@gmail.com的邮件[[TopLanguage] 有个跨平台c++系统7*24小时不间断运行。怎么样实现动态跟新代码?给个意见]中写到:
> 如题,这是个电信关键业务系统稳定性和性能是性命攸关的。现在遇到的问题是电信现在要求系统99.9999%以上的可靠性,也就是说这个系统不能够停止
> 运行大于1分钟。这就给系统升级带来了很大的困难和压力。想做个如osgi一样的动态跟新服务的系统,用c++能实现吗?或者用其他技术?反正现在我是
> 没想到很好的解决办法。各位大大给个意见吧:)
>
> >
祝:
工作顺利!
万事如意!
徐梓鼎
2007-10-12
除非你的项目也能这样做, 才可以学习 OSGI; 如果可以这样, 只要你的程序启动
时间不超过一分钟, 那么直接杀掉老进程, 启动新进程就什么都解决了, 如果这么
简单的话, 我想你不会来问这个问题.
---------------
首先, 你的系统是运行在支撑系统里面的设备/服务器中? 还是 ip 通信中设备/服
务器 ?
---------------
如果是 tcp, udp 通信, 并且可以在user space 写程序, 那么
1. 如果当前通信的session 可以在一分钟内 save/restore, 那么让老process
save old session, quit, 新process 启动, load, 就可以了.
为了防止 process 退出造成 tcp reset, 或者 udp 丢包之类的, 和外界的网络通
信, 要写一个通信服务器, 所有和外界通信都通过它进行, 这个程序和业务无关,
一旦写好调试好, 以后不用升级.
2. 如果一分钟是无法完成 save/restore 的, 那么就设计成新老程序可以同时服
务, 新程序启动之后
A. 通信服务器将所有的新 session 给新程序, 老程序服务到现有 session 完毕
之后就退出
B. 老程序每次 save 一部分 session, 给新程序 restore, 转换完毕退出.
A 的方法更简单, 但是如果业务要求, 可能需要用 B 方法.
---------------
如果不是ip层的东西, 或者不是 user space 编程, 有没有类似的方法可以用, 就
要看具体情况了.
进一步, 如果你的程序不是跑 OS, 而是直接在 CPU 上面编程(例如用 np 做的设
备), 这个问题你在这边问, 估计没有人可以回答你, 和具体情况太相关了.
---------------
同一个进程内用 dynamic load library 处理这个问题也不方便:
1. 新老 library 用的数据结构不同的带来的问题
2. 可能还有 thread 在执行老的 library, 除非新老 library 可以同时工作, 否
则等待老library 所有 session 完工, 将其 unload, 未必是一分钟可以搞定的事情.
即使你可以费老大的劲搞定这两点, 这两点也将成为你以后痛苦的来源.
ACE 里面有service 描述, 也支持动态加载模块(跨平台), 但是上面两点的麻烦还
是存在. 而且, ACE 太复杂了 (我说过 ACE 的好话, 其实是对 ACE_OS 里面的 OS
portable 封装而言的, ACE 的整体设计过于复杂了.)
我是不喜欢用太复杂的方法解决复杂的问题的, 使用太复杂的方法, 就像用一把锤
子敲打铁板, 想拼成劳斯莱斯车厢一样, 肯定有很多结合不密的破绽, 为了挡住破
绽, 又敲一些专门贴破绽的铁板, 最后得到一个外表光鲜, 但很不牢靠的东东
---- 我不是批评现在的劳斯莱斯啊, 我的意思是如果我亲自来敲辆车 ;)
---------------
这样的系统还是不好做的 ;) 可靠性要求很高, 甚至 runtime library 的heap 碎
片太多, 都可能造成问题, 用 C++ 这种频繁动态内存分配的语言, 你要检查
runtime 需要持续分配, 释放内存的各种大小, 先后次序, 会不会造成你的程序跑
5个月之后, 由于碎片问题, 无法再分配到大的内存块了 ---- 以前就有人的程序
碰到这样的问题, 如果有这个危险, 那么要加入自己的定制内存管理程序.
C 模式开发的程序, 这种问题一般还少一些.
ACE 里面有多种内存管理程序可以参考, apr 里面也有多次申请, 一次释放的pool
可用, boost 里面也有一点.
而且, 要跨平台? 奇怪, 跨什么平台 ? 电信的可靠服务器应该不会用 windows
啊, 跨 bsd/solaris/linux ?
>这是个电信关键业务系统稳定性和性能是性命攸关的。
你的性命危险了 :)
嗯, 我的建议有用就好 :)呵呵 redsea 受教了。
我记得电信的人说起过, 他们的 radius 系统似乎只能支持到一秒钟几千个查询, 如果只是这个性能级别, 似乎也不是很难弄吧 ? erlang 说不定都能够支持.这个系统其实就是radius系统,做宽带计费认证用的,运行在用户空间。这是个老系 统,不断演进的的。最开始adsl还不是很流行当时压力小就做在了pc上了,后来当用户逐渐增多的时候就开始向unix平台移植。现在 这个系统的应用环境比较复杂有像四川这样的大省在用。也有一些大的企业在使用,定制情况很复杂。有pc平台也有solaris、aix、hpux平台上跑 的。你说的A方法我想可以解决实时性问题,在这先感谢了:)之所以考虑osgi这种庞大的东西,是因为定制情况太多。现在的系统,中国人都知道:) 2000年左右做的系统又过了这么多人的手。。代码的混乱可以想想。现在公司业务扩展得很迅速,要同时支持几十个不同的部署点,而且这些服务器服务于不同 的行业用户。现在的想法是能够比较轻松的为我们的客户进行升级服务又不会中断他们的的业务。
如果能够定义出相对稳定的数据结构来, 那么用动态库的方法支持模块化应该还是可以用的. 这样的话, 将数据都用 POD描述(不带 virtual 的struct), 如果要用 OO, 那么再给POD 套一层封装好了. 这样, 数据就一份, 只需要考虑加载不同的执行代码, 事情就容易很多.考虑类似于osgi这种方式还有一些商业上的考虑,不光是技术上的问题。不知这样的系统有没有好的模块化方式?
ps:做这个系统已经死过几会了:)要不也不会想要重构它。1分钟不到的暂停10000号就给打爆了。。。。。- -!
李扬 写道:嗯, 我的建议有用就好 :)呵呵 redsea 受教了。
迟一些我可能需要做 radius 接口模块, 到时候有问题, 我会来请教你这个 radius 专家 :)
这个系统其实就是radius系统,做宽带计费认证用的,运行在用户空间。这是个老系统,不断演进的的。最开始adsl还不是很流行当时压力小就做在了pc上了,后来当用户逐渐增多的时候就开始向unix平台移植。现在这个系统的应用环境比较复杂有像四川这样的大省在用。也有一些大的企业在使用,定制情况很复杂。有pc平台也有solaris、aix、hpux平台上跑的。你说的A方法我想可以解决实时性问题,在这先感谢了:)之所以考虑osgi这种庞大的东西,是因为定制情况太多。现在的系统,中国人都知道:) 2000年左右做的系统又过了这么多人的手。。代码的混乱可以想想。现在公司业务扩展得很迅速,要同时支持几十个不同的部署点,而且这些服务器服务于不同的行业用户。现在的想法是能够比较轻松的为我们的客户进行升级服务又不会中断他们的的业务。