Веб-сервер Delphi может принимать множественные вызовы? - PullRequest
1 голос
/ 13 октября 2019

У меня есть веб-сервер, созданный в Delphi, который отвечает за выборку данных с сервера MySQL и получение в формате JSON. Вот простой пример того, как он выбирает список loteamentos из DB.

type
  TWM = class(TWebModule)
    ...
    procedure WMactLoteamentosAction(Sender: TObject; Request: TWebRequest;
      Response: TWebResponse; var Handled: Boolean);

    ...

procedure TWM.WMactLoteamentosAction(Sender: TObject; Request: TWebRequest;
  Response: TWebResponse; var Handled: Boolean);
var
  qryLoteamentos: TFDQuery;
  JsonArray: TJSONArray;
  JsonObject: TJSONObject;
begin
  Response.ContentType := APPLICATION_JSON + '; ' + CHARSET_UTF8;

  // Search for loteamentos
  qryLoteamentos := TFDQuery.Create(nil);
  with qryLoteamentos do
  begin
    Connection := FDConnection;
    Active := False;
    SQL.Clear;

    Open('SELECT * FROM ' + T_LOTEAMENTO);

    if qryLoteamentos.RecordCount > 0 then
    begin
      JsonArray := TJSONArray.Create;
      try
        First;
        while not Eof do
        begin
          JsonObject := TJSONObject.Create;
          CapturarCamposLoteamento(JsonObject, qryLoteamentos);
          JsonArray.AddElement(JsonObject);
          Next;
        end;
      finally
        Response.Content := JsonArray.ToString;
        JsonArray.DisposeOf;
      end;
    end
    else
      handleEmptyResponse(Response);
  end;
end;

Логика метода не имеет большого значения, просто важно, что он выбирает таблицуиз базы данных и извлеките ее в JSON.

Приложение будет работать на компьютере, MySQL будет с локального хоста этой машины, и пользователь будет обращаться к веб-серверу по внешнему IP-адресу и порту.

Следовательно, если сервер работает на порту 9070 на машине, внешний IP-адрес которой, например, 45.65.89.187

Метод будет вызываться следующим образом:

GET -> http://45.65.89.187/loteamentos

Он найдет для меня что-то вроде этого:

[{"id":1,"nome":"RESIDENCIAL ...","metros":"348516,57"},

{"id":2,"nome":"RESIDENCIAL ...","metros":"215465,65"}]

Вопросы

  1. Мой вопрос, предположим,100 человек используют мой API на своем телефоне. Представьте, что 100 человек звонят на одну и ту же конечную точку /loteamentos несколько раз. Разве это не сломало бы сервер?

  2. Интересно, что люди, вызывающие одну и ту же конечную точку в одно и то же время, не создают линии в одном и том же Thread и не мешают серверу? Разве я не должен заставить веб-сервер работать в режиме MultiThreading?

Что я сделал

Я тестировал вызов конечных точек с веб-сервера множественнымраза в 4 телефона. Веб-сервер начинает работать с 2 МБ, после нескольких вызовов он достигает 40 МБ за пару минут. Затем я перестаю звонить, но он остается на 40 МБ и не становится меньше.

1 Ответ

0 голосов
/ 17 октября 2019

Приложение WebBroker создаст первый экземпляр TWebModule при поступлении первого запроса от клиента. Всякий раз, когда 2-й HTTP-запрос клиента поступает в приложение WebBroker, платформа WebBroker будет искать, не был ли ранее созданный экземпляр WebModule бездействующим. (idle = это не выполнение обработчика действия запроса). Если нет свободных экземпляров WebModule, то будет создан новый TWebModule. Код для этого находится в Web.WebReq.pas, функция TWebRequestHandler.ActivateWebModules: TComponent;По умолчанию приложение WebBroker будет создавать до 32 экземпляров TWebModule при высокой нагрузке. Это число 32 определяется свойством Application.MaxConnections. Имейте в виду, что одновременные запросы уже являются многопоточными, и весь код в ваших обработчиках запросов должен быть потокобезопасным. Один экземпляр TWebModule будет обслуживать только 1 запрос за раз, любые другие одновременные запросы будут обслуживаться другими экземплярами вашего TWebModule. Поскольку несколько экземпляров TWebModule могут обслуживать запросы параллельно, запросы в одном экземпляре TWebModule должны использовать собственный выделенный экземпляр подключения к БД. При тестировании обработки нагрузки вы могли бы добавить длительный сон (10000), чтобы иметь много занятых обработчиков веб-запросов, и проверить, как ваше приложение реагирует. Тогда легко достичь предела Application.MaxConnections, что приведет к исключению.

Ваш веб-сервер может потреблять 40 МБ, поскольку среда WebBroker создала, например, 10 экземпляров TWebModule, когда загрузка была на пике (Application.InactiveConnections+ Application.ActiveConnections = 10). Если ваш TWebModule выделяет объекты в своем конструкторе или если в его DFM много компонентов, то все они будут сохраняться.

Также следует помнить, что любые специфичные для клиента данные не должны находиться в самом TWebModule, когда запросзаконченный. Клиент A может обслуживаться экземпляром 1 TWebModule во время первого запроса, а экземпляр 2 обслуживает клиента B одновременно. В следующем одновременном запросе клиент A может обслуживаться экземпляром 2, а клиент B - экземпляром 1.

...