问题描述
通过Page.RegisterAsyncTask(asynctask);实现了消息的推送,但是当用户达到7、80的时候,服务器网络通讯就会变得很卡,有没有遇到这种情况的,怎么解决?//请求页面代码//没有消息则开始监听this.AsyncTimeout=newTimeSpan(0,0,Global.thread_sleep);//启动监听PageAsyncTaskasynctask=newPageAsyncTask(OnBegin,OnEnd,OnTimeout,null);//Registertheasynchronoustask.Page.RegisterAsyncTask(asynctask);//Executetheregisterasynchronoustask.Page.ExecuteRegisteredAsyncTasks();
publicclassListeningResult:IAsyncResult{bool_IsCompleted=false;publicHttpContextcontext;privateAsyncCallbackCallBack;privateobjectextraData;publicThreadItemit_current;publicListeningResult(HttpContextcontext,AsyncCallbackcb,objectextraData){this.context=context;this.CallBack=cb;this.extraData=extraData;}publicvoidSend(stringas_ResponseID){//SendThreadList.AsyncSend(context.Response,as_ResponseID);//Beginif(CallBack!=null){CallBack(this);}_IsCompleted=true;}//超时结束线程2014-1-16目前的方式不会走这里了,留着备用publicvoidEnd(){context.Response.Write("null");//nullit_current.Thread=null;//Beginif(CallBack!=null){CallBack(this);}_IsCompleted=true;;}#regionIAsyncResult成员publicobjectAsyncState{get{returnnull;}}publicWaitHandleAsyncWaitHandle{get{returnnull;}}publicboolCompletedSynchronously{get{returnfalse;}}publicboolIsCompleted{get{return_IsCompleted;}}#endregion}
解决方案
解决方案二:
Chrome+F12看看Network是不是死循环了?
解决方案三:
滥用轮询是任何高并发程序设计的万恶之源,而许多人则是没有这个基本的概念。只有在特定的情况下才轮询——几乎没有并发的情况下。只要是你说“我启动线程去监听啦”,这一下子就暴露出问题来了。真正的监听,使用事件驱动方式来设计,当没有请求发来时不会占用任何线程,哪里是什么“死循环、阻塞”式的?!
解决方案四:
线程(的执行部分)只运行几十毫秒就结束了(或者说就把线程归还给系统线程池了)。弄81个线程去死循环的思路,这跟实际应该具有的设计思路实在是天壤之别的。在高性能的系统中,往往要求并发处理几千甚至几万个并发客户端连接,如果都搞你这种思路,那么用128G内存、32核心安腾服务器,也可能撑不住。而用正常的异步并发处理思路,普通的个人电脑配置就够了。从编程上说,你的代码一定是非常复杂、冗余、纠结的,甚至可能会有Thread.Sleep(...)这种垃圾语句(在正常的服务中出现这种语句本身就是很荒唐的,说明开发人员实在是“没有办法”了)。正常的高并发系统异步处理的逻辑,很精简。只不过是因为需要从“画流程图上”就真正体现出回调或者事件的机制,要比那种“顺序同步、阻塞式”的逻辑稍微要多动脑筋而已。
解决方案五:
要跟网页端进行双向通讯,应该使用websocket机制(不论是windowsservice还是asp.net应用架构都支持服务器端)。基本上最近2年的浏览器都支持websocket(对ie用户来说,考虑10以上的用户吧)不要把你的服务器折腾坏了。你的服务器可以腾出大量资源去做各种“后台”统计运算,例如给成百上千类型的用户的爱好的产品排个序啥的,甚至你可以用轻量级的widnowsservice机制来服务于web客户端请求(而不需要安装IIS和启动asp.net),而不要为了尝试一些10年前的什么垃圾的“网页长连接机制”而浪费掉。
解决方案六:
引用2楼sp1234的回复:
滥用轮询是任何高并发程序设计的万恶之源,而许多人则是没有这个基本的概念。只有在特定的情况下才轮询——几乎没有并发的情况下。只要是你说“我启动线程去监听啦”,这一下子就暴露出问题来了。真正的监听,使用事件驱动方式来设计,当没有请求发来时不会占用任何线程,哪里是什么“死循环、阻塞”式的?!
这样是不是就完全否定了comet的负载能力?80个长连接就承受不了了?
解决方案七:
引用5楼PLAYROME的回复:
Quote: 引用2楼sp1234的回复:
滥用轮询是任何高并发程序设计的万恶之源,而许多人则是没有这个基本的概念。只有在特定的情况下才轮询——几乎没有并发的情况下。只要是你说“我启动线程去监听啦”,这一下子就暴露出问题来了。真正的监听,使用事件驱动方式来设计,当没有请求发来时不会占用任何线程,哪里是什么“死循环、阻塞”式的?!这样是不是就完全否定了comet的负载能力?80个长连接就承受不了了?
comet模式即使在高频通讯的情况下也不会比websocket差多少,在低频通讯的情况下可能会更好,所以问题的根源不会出在comet。比如也是采用comet模式,比赛的时候长连接数量超过500的时候CPU利用率也就1-2%之间(当然CPU是16核心的),而且长连接涉及的业务逻辑计算量相对于其它业务逻辑算是重量级的。我举这个例子,只是想说明comet模式不存在严重的性能问题,真正的性能问题在于你的业务逻辑,与采用某种连接模式没有多少关系。我上面提到的死循环,意思是说客户端是不是在不断(即使没有数据更新的时候)的请求服务器,导致每个客户端每秒的请求数量几十或者上百。如果客户端请求数量正常,那就应该是业务逻辑本身的问题了,比如是否依赖于数据库而没有充分使用数据缓存,而且数据库压力达到了瓶颈。
解决方案八:
没有做过测试,大家好像都说得很有道理,顶贴~