|
|
|
NIO based udp сервер - потеря данных при больших нагрузках
|
|||
|---|---|---|---|
|
#18+
Всем доброго дня! Нужно было написать сервер, способный принимать до 10000 соединений в секунду. Вычитал в интернете, что вместо классического многопоточного сервака лучше написать сервак с помощью java NIO. Почитал о MINA, Netty, но это показалось мне overkill-ом, так как мой сервак ничего не пишет/не отправляет, работает только как приемник. Ну и самое главное, захотелось для опыта пощупать технологию руками. Ниже отрывки из кода, который сейчас при малых нагрузках работает. А еще ниже вопросы к этому коду, на которые хотелось бы получить ответ. Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 1) В винде размер буфера для приема UDP пакетов по умолчанию равен всего 8 кб - увеличивал программно до 100Мб! - все равно пакеты теряются. Увеличивал так - serverChannel.setOption(StandardSocketOptions.SO_RCVBUF, 1024*1024*10); Вопрос - действительно ли буфер увеличивается и как это проверить? Может быть, как то через настройки винды можно увеличить - я не нашел. Кажется, что проблема потери пакетов именно в том, что буфер мал - когда сообщений так много, что не успеваем и обрабатывать и в буфер не помещается - сообщения теряются. 2) когда селектор отдает нам новую порцию каналов - у них у всех один DatagramChannel? Когда раньше думал, что у каждого приходящего пакета свой канал, делал так - DatagramChannel channel = (DatagramChannel)key.channel(), где key - часть новой порции - работало. Потом перестал выдергивать канал таким образом - а обращался к однаждый созданному в инициализации полю класса - serverChannel.receive(bb); Тоже работает. Но как? Неужели все пакеты с разных компов приходят по одному DatagramChannel? 3) DatagramChannel.recieve() - а чем он лучше DatagramChannel.read()? В инете пишут, что для read(), канал должен быть соединен, то есть надо сделать DatagramChannel.connect(), чтобы вызвать read(). Тогда возникает вопрос - а что, эти каналы, которые выдергивается из очередного SelectionKey, они разве не подсоединенные? Как же тогда пакет пришел? Зачем еще делать connect()? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.03.2013, 20:19:34 |
|
||
|
NIO based udp сервер - потеря данных при больших нагрузках
|
|||
|---|---|---|---|
|
#18+
так UDP вам и не гарантирует. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.03.2013, 20:29:59 |
|
||
|
NIO based udp сервер - потеря данных при больших нагрузках
|
|||
|---|---|---|---|
|
#18+
Connects the socket to a remote address for this socket. When a socket is connected to a remote address, packets may only be sent to or received from that address. By default a datagram socket is not connected. connect привязывает channel к определенному адресу, если вы не вызвали коннект на serverChannel, он будет получать пакеты от всех. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.03.2013, 20:38:37 |
|
||
|
NIO based udp сервер - потеря данных при больших нагрузках
|
|||
|---|---|---|---|
|
#18+
Лагман, знаю, что не гарантирует, но это скорее при нестабтльном инете, у меня прикол в том, что на маленькой нагрузке 100% пакетов приходит, всегда. Увеличиваю нагрузку - теряется часть инфы. Проблема либо в буфере, либо в серваке. Суть моего вопроса - если пролема в буфере, правильно ли я его увеличиваю, потому что так как я увеличивал не помогает. А может в коде что-то не то. Может надо закрывать канал, хотя он вроде один на все соединения, поэтому нельзя. Короче, проблема не в ненадежном протоколе, а именно в моей программе. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.03.2013, 21:50:23 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=38187338&tid=2129769]: |
0ms |
get settings: |
16ms |
get forum list: |
21ms |
check forum access: |
5ms |
check topic access: |
5ms |
track hit: |
48ms |
get topic data: |
14ms |
get forum data: |
4ms |
get page messages: |
66ms |
get tp. blocked users: |
3ms |
| others: | 282ms |
| total: | 464ms |

| 0 / 0 |
