- 论坛徽章:
- 0
|
针对‘消息队列繁忙排队连续超时该如何处理’的解决方案
我想对楼主提出的解决方案发表一下看法,如果有不妥当的地方,还请楼主及各位同仁多提宝贵意见。
1。连接池和请求消息处理线程
这实际上模拟了一个unix域的tcp套接字实现,如果事务处理方式是“请求-应答”方式的话,完全可以省去。
如果要实现的话工作量是比较大的。既然要做到能接受连接,当然要做到能结束连接。如果按照tcp实现的话,就要6次通讯(结束连接时,ack1和fin2合在一起发出,否则是7个),如果程序风格好的话,就要处理4次异常。另外,检测“连接非协议性关闭”问题就要实现保活定时器,这时的客户端就要具有处理服务器端发来的检测报文的能力,也就是说,要具有当服务器的能力,也加大了客户端编写的复杂性。如果用消息队列实现这一功能的话,那么编程者的水平必须较高才行。
当然,如果用tcp套接字来实现这些问题的话就比较容易,但是利用tcp的功能再构造一个tcp,让人觉得有点画蛇添足的感觉。
2。通讯中的超时处理
首先要说的是,读消息队列的操作是原子性的,不用加以互斥。Richard Stevens的《unix网络编程》中提到的“惊群”问题,经过我的测试,在aix 4.3上并不存在,我想到的解释是:各大unix供应商的开发人员在1997年看了Stevens的书后,大吃一惊,赶紧查看自己编写的程序是不是也有这个问题,并改正过来了,当然,也许有的公司的程序员光顾着在chinaunix上灌水了,就没改,到底谁改了,谁没改,大家测测看。
服务器根据超时时间采用不同的处理策略,看起来是很智能的,但是:
服务器认为在客户要求的时间内,可能处理完也可能处理不完,向客户端发一个“重试”包。如果服务器处理得快,在客户要求的时间内处理完了,这个包就浪费了。如果客户要求的时间内处理不完,那么客户收到这个包后,也不需要重发,只要多等一会就行了。如果客户重发的话,我感觉情形就像服务器罚客户一样:
服务器:"What can I do for you?"
客户:"Ok,let me see..."
服务器:"How can you say that to a server! Let's try again,What can I do for you?"
如果我是客户,我会说"No,sir!"
如果服务器发“再等T1时间"的话,我感觉就像我们在餐馆吃菜,催服务员:“我们那个菜怎么还没上啊?”服务员总会说:“已经在做了,马上就好,请再等一会吧。”这种情况叫做客户的超时时间没有得到服务器的尊重,更严重的是,如果碰巧这个客户比较智能化,认为自己的超时时间设得太短了,下次发请求的时候主动加大了一些,那服务质量可能越来越低(响应时间是服务质量的一个重要部分)。
无论服务器的预测多么准确,都存在服务器处理完了客户的请求后,在将应答发给客户前,客户超时停止接收的情况,这时不但要将应答包丢弃,还要进行事务回滚之类的操作。
就写这么多,大家一起研究研究问题,开开玩笑,请别见怪 |
|