Netty — последовательная логика приложения и как избежать переключения контекста?

Я пишу систему обмена сообщениями, используя Netty. Я не могу отправить последующее сообщение до того, как первое сообщение будет успешно отправлено (и иногда жду ответа на отправку от одноранговой конечной точки). Я вижу рекомендации не ждать, пока будущее будет завершено в ChannelHandlerAdapter, так как это поглощает циклы ЦП в EventLoop.

Тогда возникает вопрос: как реализовать эту последовательную логику, не дожидаясь завершения первой отправки в EventLoop ChannelHandlerAdapter, или избежать переключения контекста потока между потоком приложения и потоком цикла событий?

а) Если я подожду, пока ChannelFuture завершится в ChannelHandlerAdapter, он съест циклы процессора. Если я отправлю последующие сообщения в прослушивателе, зарегистрированном в каналеFuture записи, имея логику приложения в прослушивателе, зарегистрированном в ChanelFuture этого канала, это также приведет к пережевыванию циклов процессора в EventLoop.

or,

б) Если я использую канал в потоке приложения и пишу в этот канал, происходит переключение контекста потока с потока приложения на поток канала. Есть ли способ избежать этого переключения контекста потока в этом случае использования?

Есть ли способ лучше?


person Sunny    schedule 11.04.2015    source источник


Ответы (1)


В идеале вы можете делать все, вообще не выходя из потока ввода-вывода, если ваше приложение полностью асинхронно.

Обычно для этого требуется:

  • вы знакомы с работой с фьючерсами. Асинхронная операция обычно возвращает будущее или требует обратного вызова в качестве параметра. Вам нужно будет добавить прослушиватель в будущее или указать правильную реализацию обратного вызова, чтобы действие, которое вы хотите выполнить, выполнялось после завершения запрошенной асинхронной операции. При правильном кодировании вам никогда не придется вызывать future.await() или подобные блокирующие вызовы в будущем.
  • библиотеки, которые вы используете, являются асинхронными.
person trustin    schedule 12.04.2015
comment
В системе обмена сообщениями при отправке сообщений отправитель не может отправлять последующие сообщения, если он не уверен, что сообщение попало в удаленную очередь сообщений. И если это так, то он может отправить последующее сообщение только в будущем обратном вызове. По сути, это означает, что я должен заблокировать, чтобы первое сообщение было успешно отправлено на удаленную конечную точку. Это противоречит цели регистрации слушателя. Мне не нужно регистрировать будущего слушателя. Вместо этого я просто блокирую будущее, чтобы оно было завершено. - person Sunny; 12.04.2015
comment
И если рекомендация не блокировать в цикле событий, то это можно сделать в потоке приложения. Но это будет означать дополнительное переключение контекста. Это дополнительное переключение контекста может быть неприемлемо для приложений, чувствительных к задержке. - person Sunny; 12.04.2015
comment
Приведенный выше сценарий, который я упомянул, предназначен для клиентов. На стороне сервера мы используем прослушиватели фьючерсов для любого блокирующего ввода-вывода, поскольку сервер обслуживает множество клиентов, и мы не хотим удерживать поток в заложниках (даже потоки без цикла событий). Клиенты по-прежнему заблокированы при отправке ожидающего сообщения до тех пор, пока будущие прослушиватели на серверах не ответят и не разблокируют клиентов. - person Sunny; 12.04.2015
comment
Вы можете отправить последующее сообщение в свой будущий слушатель. - person trustin; 14.04.2015
comment
Это то, что я делаю в настоящее время. Но тот факт, что я должен ждать, пока первое сообщение будет успешно отправлено на клиенте, почему бы просто не отправить его в самом цикле событий на клиенте. Этот цикл событий обслуживает только одного производителя/поток на клиенте, и приложение не может позволить себе переключение контекста на клиенте из-за характера приложения для торговли акциями, которое обслуживает эта система, и очень чувствительно к задержке. - person Sunny; 16.04.2015