Как и когда нужно создавать экземпляр соединения с бд в серверном приложении? Путем чтения книг, опыта и ошибок я понял, что под каждый запрос, создается поток, под каждый поток нужно создавать соединение отдельно, иначе начинается хаос…
Но это в случае, если у нас не 20 000 запросов в секунду, которые открывают соединение, в этом случае, наш сервер захлебнется, потому что не будет успевать это обрабатывать, соединения будут открываться быстрее, чем закрываться, и это будет расти как снежный ком, до того момента, пока MySQL, например, не скажет, “у вас слишком много соединений, бай бай”.
Выход из этой ситуации в том, чтобы держать в оперативной памяти некоторую структуру – буфер, под критическими секциями, которая будет с определенной интенсивностью черпать данные из базы на одном соединении, а потоки будут по очереди получать из нее данные. Такой подход я применил в одном высоконагруженном проекте и он отлично сработал.
На более конкретном примере это выглядело так. 20 000 потоков в сек. опрашивали сервер – а нет ли чего нового для меня в буфере? Дожидаясь своей очереди, они забирали информацию и изменяли буфер, удаляя унесенные данные и передавали квант следующему потоку.
Реализуем пока самый простой случай. Когда нагрузка у нас по данному запросу небольшая. А высоконагруженный вариант сделаем чуть позже. Сделаем же нашу реадизацию красиво, то есть так…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
procedure TCommandGet.ProcessUsers(ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo); var u: IRPUsers; uri: string; db : ISmartPointer<TDb>; begin db := TSmartPointer<TDb>.Create(); // << Создаем соединение uri := ARequestInfo.URI; if GetFirstURISection(uri) = 'Users' then begin u := TRPUsers.Create(ARequestInfo, AResponseInfo, db); // передаем его для работы if uri = '/Users/Add' then u.Add else if uri = '/Users/Delete' then u.Delete else if uri = '/Users/Update' then u.Update else if uri = '/Users/GetInfo' then u.GetInfo; end; end; |
Поскольку CommandGet оборачивает код в поток, то экземпляр соединения работает у нас на один поток и все должно быть корректно.