Netty
Самый популярный фреймворк NIO, предоставляемый JBOSS, интегрирует протоколы FTP, SMTP, HTTP.
- API простой
- Стабильная зрелость
- Активное сообщество ·
- Массовая верификация (интернет, большие данные, онлайн-игры, телекоммуникации)
Elasticsearch, подпроект Hadoop, проект avro, платформа с открытым исходным кодом Alibaba Dubbo, с использованием Netty
BIO
Преимущества: простая модель, простое кодирование. Недостатки: узкое место в производительности, количество запросов и количество потоков. Высокий параллелизм N:N, потеря контекста потока при переключении процессора. Пример: до Tomcat 7 это был BIO, после 7 — NIO. Улучшение: псевдо NIO. , использовать пул потоков для обработки логики
режим ввода-вывода
Синхронная блокировка: бросить одежду -> дождаться окончания стирки в стиральной машине -> пойти сушить одежду Потерять одежду -> больше ничего не делать, после стирки одежда будет автоматически высушена, и вы будете уведомлены о том, что она сушеный
Пять моделей ввода/вывода
Пять моделей ввода-вывода: блокирующий ввод-вывод, неблокирующий ввод-вывод, мультиплексирующий ввод-вывод, управляемый сигналом ввод-вывод, асинхронный ввод-вывод, первые четыре — синхронный ввод-вывод, который блокируется, когда данные ядра копируются в пользовательское пространство.
блокировка ввода-вывода
неблокирующий ввод-вывод
мультиплексирование ввода-вывода
Ядро: может обрабатывать несколько подключений одновременно, вызывать системные функции select и recvfrom и устанавливать для каждого сокета неблокирующий режим Блокировка блокируется функцией select вместо сокета Недостатки: при небольшом количестве подключений производительность не обязательно лучше, чем многопоточность + блокировка ввода-вывода — это хорошо (вызов еще одной функции выбора)
управляемый сигналом
Асинхронный ввод-вывод
Принять механизм будущего-слушателя
Операции IO разделены на два шага:
- Инициировать запрос ввода-вывода и дождаться подготовки данных
- Фактическая операция ввода-вывода, копирование данных из ядра в процесс
Разница между блокирующим вводом-выводом и неблокирующим вводом-выводом заключается в том, заблокирован ли инициирующий запрос ввода-вывода.
Синхронный ввод-вывод и асинхронный ввод-вывод зависят от того, блокирует ли фактическое чтение и запись ввода-вывода запрашивающий процесс.
Блокировка неблокировка - это состояние потока
Синхронный и асинхронный механизмы уведомления для сообщений
Синхронизация требует активного чтения и записи данных, а асинхронная не требует активного чтения и записи данных.
Синхронный ввод-вывод и асинхронный ввод-вывод предназначены для взаимодействия пользовательского приложения и ядра.
мультиплексирование ввода-вывода
Ввод-вывод относится к сетевому вводу-выводу, мультиплексирование — к нескольким соединениям TCP, а мультиплексирование — к одному или нескольким потокам. Проще говоря: это использование одного или нескольких потоков для обработки нескольких TCP-соединений.Самое большое преимущество состоит в том, чтобы уменьшить нагрузку на систему, не создавая слишком много процессов потоков и не поддерживая эти процессы потоков.
select
Файловые дескрипторы writefds,readdfs,exceptfds 30w подключения будут заблокированы.Когда данные доступны для чтения, записи, возникает исключение, или функция выбора возвращается после тайм-аута, после нормального возврата функции выбора, можно узнать который обрабатывает события путем обхода всего массива fdset для поиска дескриптора готовности fd, а затем выполняет соответствующую операцию ввода-вывода, которая поддерживается практически на всех платформах и имеет хорошую кросс-платформенную поддержку.
- select сканирует файловые дескрипторы в режиме опроса и сканирует их все.По мере увеличения числа FD файловых дескрипторов производительность снижается.
- Каждый раз, когда вы вызываете select(), вам нужно скопировать набор fd из пользовательского состояния в состояние ядра и пройти его (передача сообщений происходит из ядра в пространство пользователя)
- Самый большой недостаток в том, что FD, открываемый одним процессом, ограничен, по умолчанию 1024.
poll
Основной процесс аналогичен выбору.Обработка нескольких дескрипторов также является опросом и обработкой их в соответствии с состоянием дескрипторов.Также необходимо скопировать набор fd из пользовательского состояния в состояние ядра и пройти его. Разница в том, что у опроса нет максимального ограничения файлового дескриптора (fd хранится в связанном списке)
epoll
Ограничений на количество дескрипторов нет. Для копирования из пользовательского режима в режим ядра требуется использовать уведомление о событии только один раз. Зарегистрируйте fd через epoll_ctl. После того, как fd готов, ядро использует механизм обратного вызова для активации соответствующих преимуществ fd:
- Ограничения fd нет, верхний предел поддерживаемого FD - это максимальное количество дескрипторов файлов операционной системы (65535), память 1G поддерживает дескрипторы около 10 Вт, а если поддерживает миллионы подключений, можно сделать память 16G
- Высокая эффективность, использующая уведомление обратного вызова вместо опроса, не снизит эффективность при увеличении количества FD.
- Через уведомление механизма обратного вызова ядро и пространство пользователя mmap реализованы в одной и той же памяти.
недостаток:
Модель программирования сложнее, чем select/poll
основные функции ядра Linux - epoll_create() Когда система запускается, она обращается к ядру Linux за файловой системой, деревом b+ и возвращает объект epoll, который также является fd.
- epoll_ctl() Управление объектом epoll, изменение, добавление и удаление соответствующей ссылки fd в этом объекте и привязка функции обратного вызова
- epoll_wait() оценивает и завершает соответствующую операцию ввода-вывода
Пример: соединения 100Вт, активен 1Вт, как ведет себя в select, poll, epoll
select : без изменения определения макроса требуется 1000 процессов для поддержки 100-ваттных подключений.
Опрос: подключение 100 Вт, обход не отвечает, копия места потребляет много ресурсов
epoll: нет необходимости проходить через fd, нет копирования пространства ядра и данных пользовательского пространства.
Если активны соединения 95W из 100W, poll и epoll примерно одинаковы
Java ввод/вывод
- До jdk1.4 использовалась модель синхронной блокировки (BIO).
Крупномасштабные службы обычно используют C/C++, потому что асинхронный ввод-вывод (AIO), предоставляемый операционной системой, может быть напрямую запущен. - После jdk1.4 был запущен NIO, который поддерживает неблокирующий ввод-вывод, а jdk1.7 был обновлен для запуска NIO2.0, который обеспечивал функцию AIO и поддерживал асинхронный ввод-вывод файлов и сетевых сокетов.
Модель потоков Netty и шаблон Reactor
Шаблон Reactor (шаблон проектирования реактора) — это шаблон проектирования, управляемый событиями.В приложении, управляемом событиями, запросы одного или нескольких клиентов разделяются и отправляются. В приложениях, управляемых событиями, несколько запросов на обслуживание обрабатываются синхронно и упорядоченным образом. Это относится к преимуществам синхронного неблокирующего ввода-вывода:
- Быстрый отклик и не заблокируется за счет одиночной синхронизации, хотя сам реактор синхронный
- Программирование относительно простое, а сложные проблемы с многопоточностью и синхронизацией избегаются в наибольшей степени, а также избегаются накладные расходы на многопоточность и переключение процессов.
- Масштабируемость, вы можете легко полностью использовать ресурсы ЦП за счет количества экземпляров реактора.
недостаток: - Относительно сложный и не простой в отладке
- Реакторный режим требует поддержки нижнего слоя системы. Например, поддержка селекторов в java, поддержка системных вызовов select в операционной системе.
Однопоточная модель Reactor
- В качестве сервера NIO примите клиентское TCP-соединение, в качестве клиента NIO инициируйте TCP-соединение с сервером.
- Сервер читает данные запроса и отвечает, а клиент пишет запрос и читает ответ
Сцены:
Он подходит для малого бизнеса, а код прост, но не подходит для высокой нагрузки и большого параллелизма. Один поток NIO обрабатывает слишком много запросов, нагрузка высока, а ответ медленный, что приводит к тайм-ауту большого количества запросов, а в случае зависания потока он недоступен.
Многопоточная модель Reactor
Поток Acceptor, группа потоков NIO, обычно использует свой собственный пул потоков, включая очередь задач и несколько доступных сценариев потока: он может соответствовать большинству сценариев, когда Acceptor должен отвечать за операции, такие как аутентификация и другое время. потребляющие операции, также возникают проблемы с производительностью в ситуациях с высоким уровнем параллелизма.
Модель многопоточности Reactor master-slave
Acceptor — это не поток, а группа потоков NIO, а потоки ввода-вывода также являются группой потоков NIO, поэтому существует два пула потоков для обработки сценариев доступа и ввода-вывода: он соответствует большинству текущих сценариев, а также является моделью потоков. BossGroup, рекомендованная Netty. WorkGroup, которая обрабатывает соединение, занимается бизнесом.
Нетти использует NIO вместо AIO
В системе Linux базовая реализация AIO по-прежнему использует epoll, который аналогичен NIO, поэтому очевидного преимущества в производительности нет.Общая архитектура Netty представляет собой модель реактора, использующую механизм epoll, мультиплексирование ввода-вывода и синхронный несинхронный ввод-вывод. блокирующая модель Netty основана на Java Особенности асинхронной коммуникационной структуры, реализованной библиотекой классов NIO: асинхронная неблокирующая, управляемая событиями, высокая производительность, высокая надежность и широкие возможности настройки.
Эхо сервис
Echo Service, сервис для отладки и приборостроения
Анализ исходного кода
EventLoop и EventLoopGroup
Три элемента высокопроизводительной инфраструктуры RPC: модель ввода-вывода, протокол данных (http, brotobuf/thrift), модель потоков. создан для оптимизации ресурсов Использование eventLoopGroup, то есть Каннеля и соединения EventLoopGroup, а EventLoopGroup отвечает за EventLoop
NIO (один поток, обрабатывающий несколько каналов) BIO (один поток, обрабатывающий один канал) события: accept, connect, read, writeEventLoopGroup Количество создаваемых потоков по умолчанию равно количеству ядер ЦП * 2
Bootstrap
- group: задайте модель в потоке, модель потока Reactor сравнивает EventLoopGroup
1) Одинарная нить
EventLoopGroup g = new NioEventLoopGroup(1);
ServerBootstrap strap = new ServerBootstrap();
strap.group(g)
2) Multi-Threading 3) из основного потока
channel
NioServerSocketChannelOioServerSocketChannelEpollServerSocketChannelKQueueServerSocketChannel
childHandler
Для обработки данных в каждом канале
childOption
Действует на соединения после принятия
option
Действует на каждый вновь установленный канал, устанавливая некоторые параметры в TCP-соединении.
- ChannelOption.SO_BACKLOG
Максимальная длина очереди ожидания для хранения запросов, завершивших трехэтапное рукопожатие
Базовые знания о TCP-подключении Linux-сервера:
syn queue: полуподключенная очередь, флуд-атака (поддельный IP, массовая отправка первого пакета рукопожатия), tcpmaxSYN_BACKLOG (изменить VI Semi-Connection /etc/sysctl.conf)
accept queue: полная очередь подключений net.core.somaxconn Максимальное количество подключений на текущей машине
Параметр somaxconn по умолчанию системы должен быть достаточно большим.Если отставание больше, чем somaxconn, последний будет использоваться в первую очередь. - ChannelOption.TCP_NODELAY
Значение по умолчанию - false, что требует высокой производительности в реальном времени. При немедленной отправке данных измените значение на true. Отключите алгоритм Нейгла (алгоритм Нейгла будет накапливать определенный размер перед отправкой, чтобы уменьшить количество отправок ) Алгоритм Nagle разрешает только тот пакет, который не подтвержден ACK. Пакет существует в сети
(TCPsynackretries = 0, чтобы ускорить восстановление полусоединения. Если третий ACK рукопожатия не получен, повторная попытка не будет выполнена. Значение по умолчанию равно 5. Каждый раз после ожидания в течение 30 с полусоединение будет удерживаться около 180 с, tcpsynЗначение повторных попыток по умолчанию равно 5, клиент не получает пакет SYN+ACK, и клиент попытается отправить пакет SYN 5 раз.
childOption
Принять роль после привязки
childHandler
Для обработки данных в каждом канале
Channel
- Channel
Канал соединения, установленный клиентом и сервером - ChannelHandler
Отвечает за логическую обработку канала - ChannelPipeline
Упорядоченный контейнер, отвечающий за управление обработчиками каналов.
Канал содержит ChannelPipeline, и все ChannelHandlers будут добавлены в ChannelPipeline последовательно. При изменении состояния канала запускается соответствующее событие.
государство:
- channelRegistered
Канал зарегистрирован в EventLoop и привязан к селектору. - channelUnRegistered
Канал создан, но не зарегистрирован в EventLoop, то есть не привязан к Селектору - channelActive
Становится активным, подключается к удаленному хосту и может получать и отправлять данные - channelInActive
Канал неактивен и не подключен к удаленному хосту
ChannelHandler и ChannelPipeline
Жизненный цикл ChannelHandler: handlerAdded: вызывается, когда ChannelHandler добавляется в обработчик ChannelPipeline. handlerRemoved: вызывается, когда ChannelHandler удаляется из ChannelPipeline.ChannelInboundHandler (входящий): обработка входных данных и изменений типа состояния канала, адаптер ChannelInboundHandlerAdapter (шаблон проектирования адаптера), обычно используется SimpleChannelInboundHandlerChannelOutboundHandler (исходящий): обработка выходных данных, адаптер Channel
ChannelPipeline: так же, как конвейер в фабрике, вы можете добавить к нему несколько обработчиков ChannelHandler, или его можно рассматривать как серию экземпляров ChannelHandler для перехвата входных и выходных событий, проходящих через канал.ChannelPileline реализует расширенную форму перехватчика, поэтому чтобы пользователи могли получить полный контроль над обработкой событий и взаимодействием между обработчиками каналов.
ChannelHandlerContext
- channelHandlerContext — это мост, соединяющий ChannelHandler и ChannelPipeline.
Некоторые методы ChannelHandlerContext перекрываются с Channel и ChannelPipleline, например вызов метода записи.
Channel, ChannelPipeline, ChannelHandlerContext могут вызывать метод записи, первые два будут распространяться во всем потоке конвейера, а ChannelHandlerContext будет распространяться только в последующих обработчиках. - AbstractChannelHandlerContext
Структура двусвязного списка, следующий/предыдущий преемник, предшествующий узел - DefaultChannelHandlerContext — это класс реализации, но большая его часть выполняется родительским классом.В целом это просто простая реализация некоторых методов, в основном для определения типа обработчика.
Огонь звонит следующему обработчику, если не пожар не позвонит
Порядок выполнения обработчика
InboundHandler выполняется последовательно, OutboundHandler выполняется в обратном порядке.
channel.pipeline().addLast(new OutboundHandler1());
channel.pipeline().addLast(new OutboundHandler2());
channel.pipeline().addLast(new InboundHandler1());
channel.pipeline().addLast(new InboundHandler2());
InboundHandler1 InboundHandler2 OutboundHandler2 OutboundHandler1 InboundHandler1 через метод fireChannelRead() для вызова InboundHandler через ctx.write(msg), перейдите к OutboundHandlerctx.write(msg) для передачи сообщения, Inbound необходимо разместить в конце после исходящего, иначе outboundHandler будет не выполнять, используйте канал .write(msg) или pipline.write(msg), вам не нужно учитывать клиент (механизм распространения): инициировать запрос, а затем принять запрос, сначала исходящий, а затем входящий Сервер: сначала принять запрос, а затем отправить запрос, сначала входящий, а затем исходящий
ChannelFuture
Все операции ввода-вывода в netty являются асинхронными, то есть любой вызов ввода-вывода немедленно возвращается, а ChannelFuture предоставляет информацию о результате или состоянии операции ввода-вывода Создает новый объект, новый изначально неполный, он не является ни успешным, ни отмененным потому что операция ввода-вывода еще не завершена. Завершено: Когда операция ввода/вывода завершена, будь то успех, сбой или отмена, Future помечается как завершенное.В случае сбоя он также содержит конкретную информацию, такую как причина сбоя, но обратите внимание, что даже сбой и отмена относятся к завершенному состоянию. .Примечание. Не вызывайте методы синхронизации и ожидания объекта Future в потоке ввода-вывода, и вы не можете вызывать синхронизацию и ожидание в обработчике каналов.
ChannelPromise
Наследовать ChannelFuture, далее расширить, чтобы установить результат операции ввода-вывода
Кодек
Сериализация/десериализация Java, кодирование и декодирование URL, кодирование и декодирование base64 Собственные недостатки сериализации Java:
- Не могу скрестить язык
- Сериализованный кодовый поток слишком велик, а пакет данных слишком велик.
- Низкая производительность сериализации и десериализации
Другие кодеки в отрасли: PB, Thrift, Marshalling, Kyro.
Кодек в Netty:
- Декодер: в основном отвечает за обработку входящего InboundHandler.
- Кодер: Ответственный за обработку исходящего
Кодек Netty по умолчанию также поддерживает пользовательский кодек
Encoder (кодер), Decoder (декодер), Codec (кодек)
Декодер Нетти Декодер
Декодер соответствует ChannelInboundHandler, в основном метод преобразования байтовых массивов в объекты сообщений:
- декодировать: обычно используется
- Декоделасть: используется для последних нескольких байтов обработки, то есть последнее сообщение, сгенерированное, когда Cahnnel закрыт
декодер: - ByteToMessageDecoder
Используется для преобразования байтов в сообщения, необходимо проверить, достаточно ли байтов в буфере. - ReplayingDecoder
Наследуя ByteToMessageDecoder, не нужно проверять, достаточно ли данных в буфере, немного медленнее, чем ByteToMessageDecoder - MessageToMessageDecoder
Используется для декодирования одного сообщения в другое (например, POJO в POJO)
Часто используемые декодеры: (в основном решают проблему залипания и распаковки внизу TCP) - DelimiterBasedFrameDecoder: декодер, выполняющий разделители сообщений.
- LineBasedFrameDecoder: поскольку новая строка отмечает конец декодера
- ФИЦИЕНТРИЧЕСКИЕЛЕНТСКИЙФОРМАМЕДКЕКОДИРОВАНИЕ: декодер фиксированной длины
- LengthFieldBasedFrameDecoder: сообщение = заголовок + тело, общий декодер на основе декодирования длины
- StringDecoder: текстовый декодер, который преобразует полученное сообщение в строку, которая обычно сочетается с приведенным выше, а затем следует бизнес-обработчик.
Кодировщик Netty Кодировщик
Кодировщик соответствует ChannelOutboundHandler , а объект сообщения преобразуется в кодировщик массива байтов:
- MessageToByteEncoder
Сообщение преобразуется в байтовый массив.При вызове метода записи он сначала определяет, поддерживает ли текущий кодировщик тип отправляемого сообщения.Если нет, то оно будет передано прозрачно. - MessageToMessageEncoder из одного сообщения в другое закодированное сообщение
Кодек кодового кодового кодового кодома
Преимущества: появляются парами, кодирование и декодирование выполняются в одном классе Недостатки: связанность, плохая масштабируемость
- ByteToMessageCodec
- MessageToMessageCode
Прилипший пакет TCP, распаковка
Распаковка TCP: полный пакет может быть разделен протоколом TCP на несколько пакетов для отправки фиксированного пакета TCP: несколько небольших пакетов инкапсулируются в один большой пакет для отправки, а несколько пакетов, отправленных клиентом, приклеиваются к серверу при получении. Причина может возникать как у отправителя, так и у получателя пакета Причина для отправителя: TCP по умолчанию использует алгоритм Nagle Причина для получателя: TCP получает данные и помещает их в кеш, а приложение медленно читает из кеша. Неприлипающие пакеты UDP, проблемы с распаковкой, с граничными соглашениями
Решение для чтения и записи полупакетов TCP
Отправитель: отключите алгоритм Нагла Получатель: TCP представляет собой неограниченный поток данных, и нет механизма для борьбы с явлением залипания пакетов, и сам протокол не может избежать залипания пакетов. быть обработаны на прикладном уровне.Прикладной уровень решает полупакетные методы чтения и записи:
- Установите Сообщение фиксированного длины (10 символов)
abcdefgh11abcdefgh11abcdefgh11 - Установить границы сообщений (? cut)
dfdsfdsfdf?dsfsdfdsf$dsfdsfsdf - Используйте протокол с заголовком сообщения, в заголовке сообщения хранится идентификатор начала сообщения и информация о длине сообщения.
header + body
Netty поставляется с решением для чтения и записи полупакетов TCP.
- DelimiterBasedFrameDecoder: указывает декодер для разделителя сообщения.
- LineBasedFrameDecoder: декодер, который заканчивается символом новой строки.
- FixedLengthFrameDecoder: декодер фиксированной длины
- ProjectFieldbasedFramedecoder: Сообщение = Header + Body, общий декодер на основе декодирования длины
Фактический читатель половины пакета
LineBasedFrameDecoder: декодер, заканчивающийся символом новой строки StringDecoder Декодер преобразует объект в строку
Пользовательские разделители для решения проблем чтения и записи TCP
DelimiterBasedFrameDecodermaxLength: указывает максимальную длину строки. Если длина превышена, настраиваемый разделитель по-прежнему не определяется, и создается исключение TooLongFrameException. Если false, подождите, пока все сообщение не будет декодировано После этого выдайте исключение TooLongFrameException stripDelimiter: удаляет ли декодированное сообщение разделитель разделителей разделители: разделитель, тип ByteBuf
Считыватель полупакетов нестандартной длины LengthFieldBasedFrameDecoder
maxFrameLength Максимальная длина пакета данных lengthFieldOffset Смещение поля длины, где начинается поле длины (поле тела сообщения после пропуска указанной длины байтов) lengthFieldLength Количество байтов, занимаемых полем длины, длина кадра само поле длины данных Длина lengthAdjustment обычно Header + Body, значение компенсации добавляется к полю длины.Если это отрицательное число, разработчик считает, что поле длины этого заголовка является длиной всего пакета сообщения, то Netty следует вычесть соответствующее число initialBytesToStrip из первого декодированного кадра.Количество байтов, которое необходимо удалить каждый раз, после получения полного пакета данных, игнорирует длину байтов предыдущего заданного количества цифр, и декодер приложения получает пакет данных без поле длины
ByteBuf
Байтовый контейнер,
- JDK в оригинальном BYTEBUFFER
Чтение и запись имеют общий индекс, и Flip() требуется для каждой операции изменения.
Расширение хлопотно, и после расширения легко вызвать отходы - Netty ByteBuf
Чтение и запись используют разные индексы, поэтому операция удобна
Автоматическое расширение, удобное
Методы создания ByteBuf и общие узоры
ByteBuf: метод создания контейнера ByteBuf, который передает байтовые данные:
- ByteBufAllocator
После Netty 4.x объединение в пул (PooledByteBufAllocator) используется по умолчанию для повышения производительности и минимизации фрагментации памяти.
Без объединения: UnPooledByteBufAllocator каждый раз возвращает новый экземпляр - Unpooled: предоставляет статический метод для создания нераспределенного ByteBuf, который может создавать память кучи и прямые буферы памяти.
Шаблон использования ByteBuf:
- буфер кучи
Преимущества: буфер кучи хранится в пространстве кучи jvm, быстро выделяется и освобождается.
Недостаток: копирование в прямой буфер (память вне кучи) перед каждым использованием - прямой буфер
Direct buffer
Преимущества: он не занимает кучи памяти JVM и хранится в памяти вне кучи.
Недостаток: выделение и освобождение памяти сложнее, чем в буферах кучи. - составной буфер
Создайте несколько разных байтбуф и поставьте их вместе, но это просто вид
Выбор: чтение и запись большого количества данных ввода-вывода, использование области прямого буфера, использование области кучи буфера для кодирования и декодирования бизнес-сообщений.
Шаблоны проектирования Netty
Шаблон конструктора построителя: Шаблон проектирования цепочки ответственности ServerBootstrap: Шаблон фабрики распространения событий конвейера: Создать адаптер канала Шаблон: HandlerAdapter
Нетти автономный миллионный бой
- Модель сетевого ввода-вывода
- Дескрипторы файлов Linux
Однопроизводительные файловые дескрипторы (ручки) каждый процесс имеет максимальный предел дескриптора файла
Количество дескрипторов глобальных файлов также имеет значение по умолчанию, разные версии системы будут отличаться - Как определить уникальные соединения TCP
Четверка TCP: исходный IP-адрес, исходный порт, целевой IP-адрес, целевой порт
Диапазон портов сервера (1024~65535)
65545
оптимизация: - sudo vim /etc/security/limits.conf Изменить количество локальных fd, перезапустить после модификации, ulimit -n просмотреть текущее максимальное количество FD на процесс этого пользователя
root soft nofile 1000000
root hard nofile 1000000
* soft nofile 1000000
* hard nofile 1000000
- sudo vim /etc/sysctl.conf изменить глобальный номер fd
fs.file-max=1000000
sysctl -p параметр вступил в силу перезапустить cat /proc/sys/fs/file-max посмотреть глобальный номер fd
- перезагрузка для вступления в силу перезагрузка
-Xms5g -Xmx5g -XX:NewSize=3g -XX:MaxNewSize=3g
канал передачи данных
Существует ограничение на количество одновременных ресурсов, загружаемых под одним и тем же доменным именем в браузере.Рекомендуется использовать разные доменные имена для разных ресурсов для ввода доменного имени - "Расписание ядра браузера" - "Локальное разрешение DNS" - "Удаленный DNS". Разрешение — «IP-» Маршрутизация Многоуровневый переход — «Сервер назначения» — «Ядро сервера —» Приложение
Эта статья опубликована в блогеOpenWriteвыпуск!