JSRB设计思想-无状态的,粗粒度的SERVICE
出于提高性能和负载均衡实现的考虑,JSRB 采取了无状态的,粗粒度的SERVICE请求和响应机制。
该思想与有状态的ORB(如CORBA或EJB Container)的设计思想截然相反.本文将详述原因.
JSRB定位与想要解决的问题
JSRB定位于传统的SERVICE REQUEST BROKER地位,就是原始意义上的中间件的位置: 负责将大量客户端(N千或N万)的请求,排队到几十或几百个的请求处理进程(线程)中,最优化的使用系统资源,从而达到吞吐量最大化的目的.
从这个角度来看, EJB Container和CORBA ORB是标准的中间件. Java Web Container由于内建了线程池,也算是中间件(前端协议HTTP,后端协议是JDBC).
无状态vs有状态,远程调用的选择.
有状态要求服务器在远程调用之间保存对应客户端的Session数据,这种设计思想会简化程序代码,有助于将分布式的程序写得更
像非分布式程序.
但是在某些情况下,这种设计会带来严重的性能问题.在金融的在线交易系统中,业务系统需要处理十万至千万级别的用户信息(例如网银系统),而中间件服务器较为合适的session池数量不过万.要在中间件服务器的JVM内存中处理如此巨量的数据,肯定会将系统撑爆; 而如果存储大部分数据到硬盘(钝化技术)来应对,则就会面临IO性能还不如 RDBMS 的窘境. RDBMS 在目前阶段始终是最快速的数据存储方案.
当业务系统面临大数据量的问题时,需要采用应用相关的解决方案(数据分区,存储过程等等)解决.将问题推给应用服务器固然方便,但是却会带来系统的性能和可扩展性的问题.远程调用的代价本来就很大,不必要让ORB再承担session数据的重担了.与之相反,无状态的远程调用在可扩展性和负载均衡方面的实现要简单得多,也没有session迁移的问题.
SERVICE的粒度问题
SERVICE远程调用的粒度需要粗一点,在保证SERVICE可重用的前提下,应该尽量减少SERVICE的调用次数, 因为SERVICE的调用开销非常大(一般的远程调用都是以毫秒记,而普通方法的执行时间是以微秒或纳秒为单位的).
有状态SERVICE的一个副作用就是容易出现过细粒度的设计(同时由于Stub/Skeleton的生成很方便,这种设计就更加容易出现了),导致交互次数过多,会严重降低业务系统的性能.
这方面一个鲜明的对比是大型机的智能终端和telnet协议.智能终端只有等到用户填充完一个表单并确认发送后,才会将请求数据发送到主机,并且自行解释和显示主机返回的数据(非常像Broswer/HTTP), 而telnet协议则将每个按键事件发送到主机,主机处理保存有所有的session数据. 主机可以毫不费劲的处理N万个并发的客户端,而UNIX主机在连接了几千个telnet客户端后,自身的正常运行都会出问题了.
顺便说一句, 类似的, 从个人项目经历来看, 由于 Hibernate 隐藏JDBC调用很成功,查询或更新数据库非常方便, 程序员就很容易滥用; 有可能导致程序从逻辑上来看毫无问题, 但是运行起来却出现性能低下, 并且这种性能问题还很难改正(性能低下是由于数据库查询过多引起的,要调整的代码遍布整个项目).
其它
- 本文的一些思想来源于MidWay(midway.sourceforge.net)和个人的项目经验,仅为一家之言.
- 大型项目(企业级)和小项目(部门级)的区别主要就在于,大项目在各个阶段都要将非功能性的要求(性能,容错,恢复,分布式,响应时间,事务等等)放在设计/实现/测试首要考虑的位置,而小项目则几乎无需考虑这样的问题.
- 本文和JSRB主要集中在真正的中间层( Service/Object Request Broker/EJB Container).