当前位置:编程学习 > C#/ASP.NET >>

.Net Remoting Singleton and Singlecall in concurrent enviroment

from: http://tingsaode.spaces.live.com/ 

本来我老人家打算说说这一阵子看的片子, 而不是写这种无聊的技术贴, 写了几句发现写的巨无聊, 既然同样是无聊, 那写技术贴有可能会给那些和我碰到同样问题的人提供一点帮助, 所以我决定写技术贴.
 
     对于.Net技术我一直以来都非常的缺乏热情, 大概写过c语言的人都容易不适应什么东西都不在自己掌控之下的情况. 没有热情也要用, 这个是工作, 但是因为缺乏兴趣导致的结果就是没有去主动了解相关的知识, 进一步的结果就是当碰到问题的唯一的反映就是麻爪.     

    先说说我碰到的问题, 简而言之, 当被并发调用的.Net Remoting Service的Remote Object有某个接口(Method)中有一个慢速操作的时候, 我们应该使用.Net Remoting 调用方式中的Singleton还是Singlecall, 以及原因. 
    自问自答, 应该使用Singlecall, 原因, 在并易做图况下, 用Singleton访问Remote Object的接口(Method), .Net Remoting会自动给所调用的接口(Method)加锁作同步机制, 就是说所有的并发调用会被串行化, 假如一个接口(Method) Foo() 需要执行2秒钟, 有100个.Net Remoting Client访问这个Foo() Method, 点被(运气差)点那个Client要在200秒之后才能得到结果, 而对Singlecall, 如果忽略cpu线程切换的时间(至少比秒低2个数量级), 只要2秒, 100个线程一起在2秒内干完了活, 明了吧. 当然如果你本身在.Net Remoting Service中需要同步机制, 或者你需要保持状态(如果需要保持状态, 你最好用Client Activiation)就另当别论了. 微软这个锁可能有他的设计意图, 比如为了保证Singleton是线程安全的, 但是为啥不把这个设计意图明白的写在msdn里啊, 把俺们累的, 俺们都以为server object activiation都是无状态的, 不会锁捏. 
 
     接着来说说碰到这个问题的前世今生, 以及未来我们应该进一步了解的东西. 万恶之源是一句慢速执行的sql语句, 最初, 这句慢速sql语句虽然慢速, 但是我的.net web application还能正常工作, 有一天, 我们决定把数据库的机器弄牛b点, 所以就有了数据库迁移, server更换, 用sparc替换xeon, 这种8核sparc号称很nb, 模拟成32个cpu, 并发负载能力超强, 迁移完成后, 我的.net web application运行就出现了问题, 奇慢无比. 一个nb的dba很快在数据库的监控端发现了俺们这条万恶的sql语句, 这个语句的where里用了个带index的field, 可惜的是又在这个field(char 类型的)前加了个转换成小写的函数(让我回忆起早年一位数据库牛人给俺们培训讲数据库设计n条军规, 其中一条就是禁用各种数据库函数, stored procedure, trigger等等), 导致这个sql在对一张有数十万条记录的表进行没有index的查询. 发现这个问题之后, 研究了一番, 没有什么办法, 后来为这个变成小写的函数重新对表建立index, 应用运行就转为正常了, 但是考虑到之前我们这条万恶的sql语句就已经存在(数据库迁移并未改动程序)为什么原来能正常运行的程序不行了捏? 所以有了一番调查, 以及调查结果(上面的自问自答), 这个问题的出现还证明了intel的core 2 xeon是非常nb的, 对没有index的查询都能那么快, 让俺们的问题没有暴露. 犯这个错误还有一个原因, 3年前我和当时一个同事gyc合作过一个.Net项目, 也是我的第一个.Net项目, 因为当初我对.Net的不熟悉以及无兴趣, 当时我给gyc起了个外号, 叫俺们那个项目的总设计师, 简称"总设(she)", 当时我的.Net知识基本都来自于他, 他跟我说.Net Remoting最高效率的调用方法是Singleton, md, 被丫害了, 当然也怪我自己不学习, 这次才不加考虑的使用了Singleton. 反过来如果不出问题, 我们永远也不会了解Singleton和Singlecall的差别.
 
    为了分析这个问题, 我们在内部开发环境模拟这个慢速的sql语句, 就是在method里直接sleep 2秒. 分别尝试用Singleton和Singlecall调用这个慢速的method, 用Load Runner模拟并发压力, 发现Singleton会导致整个应用缓慢无比, 而Singlecall不会出现这种问题, 原因未知, 疯狂的google各种资料 我搜索了关键字 singleton singlcall 并发 concurrent等等, 看了一些搜索结果, 发现都不能解释这个原因, 这个时候真希望能有个微软的大牛给我一个解答, 要是俺们有技术支持就好了, md. 素手无策之际, 一篇帖子给了我一点启示, 这篇帖子妄图发现.Net Remoting通信的奥秘, 所以用sockmon对他的测试环境进行了抓包, http://www.cnblogs.com/kriss/archive/2005/12/02/288900.html 就这么一篇blog, 这位同仁犯了个低级的错误, 碰到了问题, 所以进行了抓包, 不过最终他没能解决他自己的问题, 问题在于用了个相当于全局变量的东西, 没有加锁保护, 所以在不同线程切换的情况下, 出现了不同的结果, 令他郁闷无比. 但是这种抓包行为提醒了我, 我们还可以抓包来研究singleton和singlecall的区别. 最后我们得出了以上自问自答(I love wireshark).
 
    所有对于这个问题的研究和测试, 思路构成, 都是我和我的同事共同完成的, 其实我老人家出的力最少, 不过我记录一下, 也算个功劳吧, hoho. 
 
    展望, 如果我们能完全的了解.Net Remoting的线程和io模型, 那我们用起来就得心应手了, 目前看, .Net Remoting是用最sb的一连接, 一线程的方式(到了几百个线程以后, 调度本身的开销就大起来了), 为什么不用微软牛b的iocp捏(或者因为.Net本身就不是用于那种对性能最敏感的应用, 所以不需要在这方面提高了)? 是否可以把.Net Remoting 配置成用iocp捏? 另外我的同事后来发现 IIS (我们的.Net Remoting Client的host)有个在machine.config里的配置项, 叫processModel, 里面一对element叫miniothreads和maxiothreads, 这两个参数会直接影响IIS会启动多少个线程为.Net Remoting Client建立和.Net Remoting Service的连接数, 默认情况下这个max值是20每cpu(core), 不是25, 我一直跟我的同事说, 我相信msdn, 其他网上的文章我不信. 我的.Net Remoting是用于解决COM+通信问题的, 对COM+本身还有很多未解决的问题, object pooling和.Net Remoting的remote object关系怎么样? 分布式事务配置和性能到底怎么样? 我的领导也对COM+本身提出疑义, 为什么出现问题的时候我们一点trouble shooting的手段都没有, 只能靠重现以及debug, 他是tuxedo senior user, 而tuxedo提供很好的queue监控及相关性能分析工具, 我们是不是也能通过一些手段或者工具分析COM+或者.Net Remoting应用过程中出现的问题捏? 如果COM+这么弱智, 我们是不是考虑用个bt的方法, 在ASP.net里调用tuxedo? 
 
     如果你不认识我, 搜索到我这个帖子, 并且这个帖子对你有帮助, 我老人家就很有成就感了, 我想遇到和我类似的问题搜索的关键字本文中应该都包括了. 
--------------------编程问答-------------------- 有点难度哦 --------------------编程问答-------------------- 讲的太乱
补充:.NET技术 ,  其他语言
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,