Реализация асинхронной очереди сообщений в Java - PullRequest
1 голос
/ 02 декабря 2010

У меня есть сервер Java, который обрабатывает входы от нескольких клиентов. Сервер создает поток для каждого слушателя сокета tcp / ip. Доступ к базе данных обрабатывается другим потоком, который создает сервер.

В настоящее время число клиентов, которых я подключаю к серверу, довольно мало (<100), поэтому у меня нет особых проблем с производительностью, но я разрабатываю, как мне следует обрабатывать больше клиентов в будущем. Меня беспокоит то, что из-за большого количества клиентов потоки моего сервера и базы данных будут зависать от постоянных вызовов их методов из потоков клиента. </p>

В частности, в отношении базы данных: в данный момент каждый клиентский поток обращается к общему потоку базы данных на своем родительском сервере и выполняет метод доступа к данным. То, что я думаю, я должен сделать, это иметь какую-то очередь сообщений, в которую клиентский поток может поместить свой запрос данных, и поток базы данных сделает это, когда получит ответ. Если есть данные, которые должны быть возвращены из вызова доступа к данным, то он может поместить их в очередь для потока клиента, чтобы забрать. Все это не затронет основной код сервера или другие потоки клиента.

Поэтому я считаю, что хочу реализовать асинхронную очередь сообщений, в которую клиентские потоки могут помещать сообщения, и поток базы данных будет получать их. Это правильный подход? Буду признателен за любые мысли и ссылки где-либо, что я могу прочитать о реализации.

Ответы [ 3 ]

5 голосов
/ 02 декабря 2010

Я бы не рекомендовал такой подход.

JMS был рожден для такого рода вещей. Это будет лучше, чем любая реализация, которую вы напишите с нуля. Я бы порекомендовал использовать сервер приложений Java EE со встроенным JMS или что-то вроде ActiveMQ или RabbitMQ, которое вы можете добавить к сервлету, например Tomcat.

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

1 голос
/ 02 декабря 2010

То, что вы описываете, звучит как ExecutorCompletionService .По сути, это асинхронный брокер задач, который принимает запросы ( Runnable s или Callable s) из одного потока, возвращая «дескриптор» для ожидаемого результата в виде будущее .Затем запрос выполняется в пуле потоков (который может быть однопоточным пулом потоков ), и результат запроса затем доставляется обратно в вызывающий поток через Future.

В промежутке между отправкой запроса и предоставлением ответа ваш клиентский поток просто будет ожидать в будущем (с необязательным таймаутом).

Однако я бы посоветовал, что есливы ожидаете значительного увеличения числа клиентов (и, следовательно, клиентских потоков), вам следует оценить некоторые из инфраструктур Java NIO Server.Это позволит вам избежать выделения одного потока на клиента, тем более что вы ожидаете, что все эти потоки будут тратить некоторое время на ожидание запросов БД.Если это так, я бы посоветовал посмотреть MINA или Netty .

Cheers.

// Nicholas

0 голосов
/ 02 декабря 2010

Звучит так, будто вы хотите ограничить количество одновременных запросов к базе данных, которую вы хотите разрешить. (Чтобы он не был перегружен)

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

private final BlockingQueue<Connection> connections = new ArrayBlockingQueue<Connection>(40); {
   // create connections
}

// to perform a query.
Connection conn = connections.get();
try {
    // do something
} finally {
    connections.add(conn);
}

Таким образом, вы можете сохранить свой дизайн потока таким же, как он есть, и ограничить количество одновременных запросов к базе данных. С некоторыми изменениями вы можете создавать соединения по мере необходимости и предоставлять тайм-аут, если соединение с базой данных не может быть установлено быстро.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...