ServerSocketChannel против ServerSocket Java

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

Проект разработан с использованием Java NIO ServerSocketChannel.

Теперь в этом сценарии я мог получать от клиента около 70-80 записей в секунду. В то время как, если я использую простой Java ServerSocket (только для целей тестирования), результат увеличивается примерно до 800 повторений.

Почему в обоих случаях такая большая разница? И как я могу изменить ServerSocketChannel для имитации ServerSocket?

Вот моя основная часть обработки,

SocketChannel client = (SocketChannel) key.channel();
                        if (!key.isReadable()) {
                            key.cancel();
                            client.close();
                            continue;
                        }

                        int[] k = (int[]) key.attachment();

                        if (k[2] == 0) {
                                ByteBuffer lengthBuffer = ByteBuffer.allocate(2);

                                int bytesRead = -1;
                                if (!client.socket().isClosed() && key.isValid()) {
                                    bytesRead = client.read(lengthBuffer);
                                }

                                if (bytesRead == -1) {
                                    key.cancel();
                                    client.close();
                                    continue;
                                }
                                lengthBuffer.flip();
                                byte[] bytes = new byte[2];
                                lengthBuffer.get(bytes, 0, 2);
                                short length = DRMSDecoder.getShort(bytes);


                                k[0]++;
                                k[1] = length;
                                k[2] = 1;
                                key.attach(k);
                                lengthBuffer.clear();
                            } 
                            else {
                                try {

                                    int length = k[1];
                                    ByteBuffer dataBuffer = ByteBuffer.allocate(length);
                                    dataBuffer.clear();
                                    System.gc();

                                    int bytesRead = -1;
                                    if (!client.socket().isClosed() && key.isValid()) {
                                        bytesRead = client.read(dataBuffer);
                                    }

                                    if (bytesRead == -1) {
                                        key.cancel();
                                        client.close();
                                        continue;
                                    }

                                    dataBuffer.flip();

                                    Hashtable<String, Object> request = decoder.decode(dataBuffer);
                                    short call_type = (Short) request.get("Call Type");

                                    if (request.get("Call Type") != null && (((Short) request.get("Call Type")) == 78 || ((Short) request.get("Call Type")) == 80)) {


                                    } else if (request.get("Call Type") != null && (((Short) request.get("Call Type")) == 79)) {
                                        key.cancel();
                                        client.close();

                                    } 
                                        String message = (String) request.get("Buffer");

                                        handleMessage(message);

                                    }
                                    k[0]++;
                                    k[2] = 0;
                                    key.attach(k);
                                    lastMessageProcessed++;

                                    dataBuffer.clear();

                                } catch (Exception e) {
//                                    System.out.println(e);
                                }
                            }

Я написал статью о самом быстром и самом медленном способах, которые я могу придумать, для использования IO и NIO в Java. Самое медленное, что я мог придумать, - это создание нового соединения каждый раз, но это все равно было 3500 сообщений / с с одним клиентом. vanilla-java.github.io/2018/08/28/Reducing-network-latency.h‌ tml Я подозреваю, что ваши основные задержки не на сетевом уровне. Вы можете многое сделать, чтобы сделать этот код более эффективным, но я сомневаюсь, что это объясняет наблюдаемую вами медлительность. Вы пробовали профилировать свое приложение с помощью JMC?

Peter Lawrey 17.09.2018 10:04

Я бы начал с удаления всего, что создает новый объект. :П

Peter Lawrey 17.09.2018 10:07

Кстати, в моей статье есть ссылки на код, который я использовал. Я не использовал селекторы, хотя они не должны сильно замедлять код. ;)

Peter Lawrey 17.09.2018 10:09

Питер Лоури Спасибо, попробую ваше решение

Jay Vyas 17.09.2018 10:34
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
4
2 933
1

Ответы 1

Разница в блокирующий ввод / вывод против неблокирующего ввода / вывода.

Ссылка: https://medium.com/coderscorner/tale-of-client-server-and-socket-a6ef54a74763

но я уже делаю это server.configureBlocking (false); client.configureBlocking (ложь);

Jay Vyas 17.09.2018 09:50

Оба примера блокируют. Неблокирование NIO обычно немного быстрее, но в этом случае NIO работает медленнее. -1

Peter Lawrey 17.09.2018 10:01

@JayVyas NIO по умолчанию блокируется.

Peter Lawrey 17.09.2018 10:01

Другие вопросы по теме