zoukankan      html  css  js  c++  java
  • 服务器开发

    总结了一些经验,现贴出于大家讨论。
    1、构件的使用
       开始我一直使用Indy,但最近在开发一个100-350并发用户的服务器端时发现了Indy问题,由于用户的访问非常繁重,服务器工作两周后出现了70多的废连接。导致服务器响应变的慢。而且我观察到有时INDY能自动释放这些废连接,有时多到200多都不释放。后来我改DXSock 3.0构件,代码没有作任何改动,服务从6月1日到今天没有重启一次而且没有一个废连接,
       我花了一周看DXSock的代码,改了些错误,也学习了很多,DXSock构成思想很好。它的连接响应线程不是动态创建的,而是你设置多少就一次性创建多少。节省了创建、释放的大量时间。
       所以再开发服务器端软件我推进使用DXSOCK构件。
       2、数据库使用
          很多朋友在讨论多线程中使用数据库的问题,这在网络服务器开发中这是常常需要考虑的问题,很多朋友都采用一个线程建立一个数据库的连接,我认为这种方法在小规模、小并发应用中是可以的,但是一旦负荷上去、并发一多这样就很多问题了,比如资源消耗(数据库)、时间消耗。这种方式我用过,结果是运行一段时间后数据库再也连接不上了。
          我再这方面有两个解决办法:
          a、采用ASTA构件的方法,根据分析负荷一次性创建一个ADOCONNEC连接池,靠一个同步模块来管理,客户端请求-》构造SQL-》让同步管理模块来分配一个ADOCONNECT联机-》执行SQL,返回结果,如果这时ADOCONNECT满,此SQL等待。代码如下:
          b、对于不需要实时返回数据库信息的应用,客户端请求来-》服务器创建SQL语句和一个TAG-》SQL语句送入队列,然后一条一条的执行,TAG返回客户端,过一段时间客户端再通过这个TAG来服务端获得结果。
    ********************************************队列管理代码***********************
    Unit uitQueueManage;
    Interface
    Uses
      Windows,
      Messages,
      SysUtils,
      Variants,
      Classes,
      Contnrs;
    Type
      TSyncManage = Class(TObject)
      Protected
        FHandle: THandle;
      Public
        Property Handle: THandle Read FHandle;
        Constructor Create(Const Name: String; InitCount, MaxBuffer: Integer);
        Destructor Destroy; Override;
        Function Release: Boolean; Overload;
        Function WaitFor(TimeOut: Integer): Boolean;
      End;
    Type
      PQueueItem = ^TQueueItem;
      TQueueItem = Record
        FRequestCount: Integer;
        FCommand: Integer;
        FDataStr: String;
        FDataInt: Integer;
        FDataBool: Boolean;
      End;
      TProgressEvent = Procedure(Sender: TObject; aQueueItem: TQueueItem) Of Object;
      TQueueManage = Class(TObject)
      Private
        FQueue: TQueue;
        FSyncManage: TSyncManage;
        FOnProgress: TProgressEvent;
        FLock: TRTLCriticalSection;
      Public
        Constructor Create(aQueueName: String; aBuffer: Integer);
        Destructor Destroy; Override;
        Procedure PushQueue(aQueueItem: TQueueItem);
      Published
        Property OnProgress: TProgressEvent Read FOnProgress Write FOnProgress;
      End;
    Type
      TQueueThread = Class(TThread)
      Private
        hSyncManage: TSyncManage;
        hOwner: TQueueManage;
        hQueue: TQueue;
        Procedure DoProgress;
      Protected
        Procedure Execute; Override;
      Public
        Constructor Create(aOwner: TQueueManage; aQueue: TQueue; aSyncManage: TSyncManage); Virtual;
      End;
    Implementation
    //***********************************************************TSyncThread**************************
    Constructor TSyncManage.Create(Const Name: String; InitCount, MaxBuffer: Integer);
    Begin
      FHandle := CreateSemaphore(Nil, InitCount, MaxBuffer, Pchar(Name));
      If FHandle = 0 Then abort;
    End;
    Destructor TSyncManage.Destroy;
    Begin
      If FHandle <> 0 Then CloseHandle(FHandle);
    End;
    Function TSyncManage.WaitFor(TimeOut: Integer): Boolean;
    Begin
      Result := WaitForSingleObject(FHandle, TimeOut) = WAIT_OBJECT_0;
    End;
    Function TSyncManage.Release: Boolean;
    Begin
      Result := ReleaseSemaphore(FHandle, 1, Nil);
    End;
    //***********************************************************TQueueThread**************************
    Constructor TQueueThread.Create(aOwner: TQueueManage; aQueue: TQueue; aSyncManage: TSyncManage);
    Begin
      Inherited Create(True);
      hOwner := aOwner;
      hQueue := aQueue;
      hSyncManage := aSyncManage;
      Priority := tpHigher;
      Resume;
    End;
    Procedure TQueueThread.Execute;
    Begin
      While Not Terminated Do
      Begin
        hSyncManage.WaitFor(Integer(INFINITE)); //无限等
        If Terminated Then Exit;
        DoProgress;
      End;
    End;
    Procedure TQueueThread.DoProgress;
    Var
      mQueueItem: PQueueItem;
    Begin
      mQueueItem := hQueue.Pop;
      If Assigned(hOwner.FOnProgress) Then hOwner.FOnProgress(hOwner, mQueueItem^);
      Dispose(mQueueItem);
    End;
    //***********************************************************TQueueManage*************************
    Var
      FQueueThread: TQueueThread;
    Constructor TQueueManage.Create(aQueueName: String; aBuffer: Integer);
    Begin
      Inherited Create;
      InitializeCriticalSection(FLock);
      FQueue := TObjectQueue.Create;
      FSyncManage := TSyncManage.Create(aQueueName, 0, aBuffer); //缓冲区大小
      FQueueThread := TQueueThread.Create(Self, FQueue, FSyncManage);
    End;
    Destructor TQueueManage.Destroy;
    Begin
      EnterCriticalSection(FLock);
      Try
        FQueueThread.Terminate;
        FSyncManage.Release;
        FreeAndNil(FQueueThread);
        FreeAndNil(FSyncManage);
        FreeAndNil(FQueue);
        Inherited Destroy;
      Finally
        LeaveCriticalSection(FLock);
        DeleteCriticalSection(FLock);
      End;
    End;
    Procedure TQueueManage.PushQueue(aQueueItem: TQueueItem);
    Var
      mQueueItem: PQueueItem;
    Begin
      New(mQueueItem);
      mQueueItem^ := aQueueItem;
      EnterCriticalSection(FLock);
      FQueue.Push(mQueueItem);
      LeaveCriticalSection(FLock);
      FSyncManage.Release;
    End;
    End.
    ********************************************队列管理代码***********************
    ADO连接同步管理我稍后放上来,欢迎大家讨论。 

  • 相关阅读:
    牛客IOI周赛17-提高组 卷积 生成函数 多项式求逆 数列通项公式
    6.3 省选模拟赛 Decompose 动态dp 树链剖分 set
    AtCoder Grand Contest 044 A Pay to Win 贪心
    5.29 省选模拟赛 树的染色 dp 最优性优化
    luogu P6097 子集卷积 FST FWT
    CF724C Ray Tracing 扩展欧几里得 平面展开
    5.30 省选模拟赛 方格操作 扫描线 特殊性质
    5.29 省选模拟赛 波波老师 SAM 线段树 单调队列 并查集
    Spring main方法中怎么调用Dao层和Service层的方法
    Bug -- WebService报错(两个类具有相同的 XML 类型名称 "{http://webService.com/}getPriceResponse"。请使用 @XmlType.name 和 @XmlType.namespace 为类分配不同的名称。)
  • 原文地址:https://www.cnblogs.com/94YY/p/2199339.html
Copyright © 2011-2022 走看看