架构:TSocketConnection -> scktsrvr.exe -> RemoteDataModule
 
现状:大量客户端(如200个)同时发起连接请求,中间层或scktsrvr明明无法处理这么多的连接,却又不推辞,最终导致客户端、中间层和scktsrvr都死掉。
 
期望:让scktsrvr限制Socket的数量,超过限度(如20个)之后的客户端可以向scktsrvr发出连接请求,但scktsrvr不分配给Socket,拒绝连接;客户端超时之后,弹出对话框提示用户。
 
条件:
1、在客户端,必须由应用程序自己来捕获“无法连接”这个错误,不能让操作系统擅自弹出对话框;
2、在客户端,必须由应用程序自己指定尝试连接的超时时间,不能无限地等下去。
3、在服务器端,scktsrvr拒绝“超限客户端”的连接请求之后,仍然正常监听;当现有客户端释放连接,导致连接总数低于限制值时,scktsrvr又可继续接纳客户端的连接请求。
4、在服务器端,scktsrvr拒绝一个“超限客户端”的连接请求时,必须干净地关闭或拒绝创建Socket,干净地结束或拒绝创建Thread,不能在内存里积攒越来越多的“死Socket”“死Thread”。
5、可少量改写scktsrvr,但不能大量改写或全部重写,不能换架构,不能用第三方构件。
 
  

解决方案 »

  1.   

    不如加一个 负载均衡 的入口,由它取得每个scktsrvr的连接数,引导新的客户端连到最空闲的scktsrvr
      

  2.   

      软件的话,需要改动程序架构;硬件的话,需要甲方掏钱。都不容易实现。
        现在只希望在scktsrvr及其引用的库(单元)上做文章。
      

  3.   


    这个 负载均衡 的入口,其实只是一个特殊的scktsrvr,它仅仅负责接收其它真正的scktsrvr的负荷,把连接进来的客户端转到负荷最小的真正的scktsrvr
      

  4.   

      思路很简单,关键是在哪个地方写、如何写呢?
      我曾尝试在OnGetSocket、DoConnect等处写,写CloseSocket、Socket.Close、Disconnect,都没有成功。
      
      

  5.   

      查询负荷,必然要调用服务器端方法,这样服务器已经死掉了。
      我希望在请求连接的环节由服务器断掉。
      并且不希望使用负载均衡。我只用一台服务器,只用一个中间层程序,只用一个scktsrvr.exe
      

  6.   

    用datasnap,在客户端连接时,判断在线连接的是否达到200,TRUE就主动断开,不让连上
      

  7.   

      做个类比:开办银行。由于条件所限,只能开设一个业务大厅,大厅里只能开10个业务窗口。但是,储户非常多,比如说有上万人。
      
      现在的midas程序的状况是:允许所有储户同时进入大厅,但窗口营业员只能为10个储户办业务,于是储户们就在窗口争抢,搅成一锅粥,最后谁也办不成业务。
      
      “负载均衡”的解决方案是:开4个大厅,每个大厅仍是10个窗口。银行门口站一个迎宾,根据四个大厅的业务繁忙程度来引导新储户到最闲的大厅。
      
      我的要求是:仍然只是1个大厅、10个窗口,但只允许10个储户同时进大厅。大厅里有10个储户时,第11个储户会在门口处被迎宾拒绝进入。储户可以等几分钟再来,也可以等几小时再来,也可以不再来。
      

  8.   


    使用 datasnap 吧。你的这个要求很容易实现的。给你一篇文章参考。http://blog.csdn.net/aroc_lo/archive/2010/02/28/5333773.aspx看过之后,你才发觉 Midas/Socket/Scktsrvr 可以扔了。拥抱 datasnap 吧。
      

  9.   

      您指的是哪种负载均衡机制呢?应该不是指TSimpleObjectBroker吧?