Декодирование двоичного сообщения с использованием java

Мне нужно декодировать двоичные сообщения, поступающие с высокой скоростью (> 1000 msgs/sec), и хранить их в БД (не решил, какой именно), используя JAVA. На этот сервер будет поступать несколько TCP-соединений, каждое из которых будет иметь собственный поток двоичных данных, которые необходимо обработать.

Сообщения не разделены никакими "флагами".
Начало сообщения имеет поле длиной 4 байта. За ним следует фиксированный заголовок.

Полезная нагрузка сообщения, в свою очередь, будет состоять из нескольких сообщений, каждое из которых имеет фиксированный заголовок, за которым следуют битовые маски (32 бита), определяющие наличие других полей. Каждое поле битовой маски имеет длину 32 бита, а биты 32-30 (MSB -32 / Big endian) определяют длину каждого из необязательных полей. Все остальные биты (29-1), если «ON» означает, что поле присутствует в сообщении.

Например, если биты 32-30 равны 100, а бит 1 равен «1», то поле XXX следует за полем битовой маски и имеет длину 4 байта. Если бит 2 равен «0», поле YYY отсутствует в сообщении и так далее. Будет несколько полей битовой маски (необязательно), но ограничено максимальным числом. Я новичок в java (фон c/C++), поэтому могут возникнуть вопросы...

1) Я думаю разработать приложение обычным образом, чтобы «основной» поток получал соединения и создавал «рабочий поток A» для обработки сообщений в этом сокете. Я думаю о том, чтобы позволить файлу конфигурации управлять тем, создает ли «workerThread A» threadPool для обработки каждого сообщения или делает это самостоятельно. Я реализую первое, проверю производительность и посмотрю, нужно ли ее улучшать. У меня вопрос: стоит ли рассматривать netty или Apache Mina? Поскольку это усилие POC, мне нужно быстро его запустить.

2) Я думал об использовании nio - SocketChannel и ByteBuffer. Но похоже, что я не могу прочитать указанное количество байтов из сокета? Я думаю, что было бы проще «readInt ()», чтобы получить длину, а затем прочитать «длину» количества байтов из сокета, чтобы получить полное одно сообщение, а затем проанализировать его. Лучше ли использовать DataInputStream? Будет ли какое-либо влияние на производительность при использовании oio по сравнению с nio?

3) Должен ли я искать какие-либо фреймворки для декодирования сообщения? Я немного посмотрел на буферы протокола Google, но похоже, что он не будет поддерживать поля битовой маски декодирования.


person user127091    schedule 14.06.2012    source источник


Ответы (3)


Я бы создал один рабочий поток для каждого соединения.

Я бы использовал DataInputStream, если вы не решите, что это недостаточно быстро. Существует небольшое влияние на производительность, но вряд ли это будет иметь значение при скорости 1000 мс/сек.

Я бы просто расшифровал сообщение по мере его поступления с помощью JDK. Я не нашел сторонних библиотек, чтобы упростить эту ситуацию.

person Peter Lawrey    schedule 14.06.2012
comment
Спасибо, я пошел по этому пути, но до сих пор не провел никаких тестов производительности. - person user127091; 19.07.2012

Apache MINA — очень хороший вариант для вашего случая. Мина очень хорошо управляет несколькими сеансами и очень масштабируема. Мы использовали его для очень похожего случая, и пока мы очень довольны им.

Мы разработали шлюз с использованием MINA, который получает бинарные сообщения от тысяч gsm-устройств, расшифровывает их и сохраняет в базе данных. Мы провели нагрузочное тестирование нашего шлюза с более чем 2000 одновременных сеансов непрерывной отправки данных на сервер с Core2 Duo, 4 ГБ ОЗУ.

Вы можете очень аккуратно подключить к нему декодеры и кодировщики, используя фильтры кодеков. . Документация также достаточно разумна, и вы можете быстро начать с базовые знания JAVA.

person Umer Hayat    schedule 16.06.2012

Я бы выбрал NIO и модель Selector. Вот статья (старая, но по-прежнему актуально), которые вы можете прочитать.

Если вы хотите добиться сверхнизкой задержки, вам следует рассмотреть возможность объединения объектов, которые вы можете использовать повторно, вместо создания новых. Сборщик мусора не подойдет для приложений с низкой задержкой.

И, наконец, я бы попробовал использовать Protocol Buffers от Google, так как они очень эффективны и просты в использовании на нескольких языках.

person maba    schedule 14.06.2012