Как сделать сетевое программирование, чтобы оно считалось элегантным? xjjdog to wave сводка

Архитектура TCP/IP Интернет вещей

图片

Оригинал: Miss Sister Taste (идентификатор публичной учетной записи WeChat: xjjdog), добро пожаловать, пожалуйста, сохраните источник для перепечатки.

Говорят, что очарование web2.0 заключается в переходе от статических ресурсов к интерактивным ресурсам, а очарование web3.0 заключается в его децентрализованных ресурсах, в которых каждый может участвовать и пользоваться благами времени. Однако, какой бы причудливой ни была концепция верхнего уровня, коммуникация нижнего уровня по-прежнему основана на технологии, сформированной web1.0.

Нашей конечной целью является фактическая централизация во имя децентрализации.

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

1. Обратите внимание, чтобы избежать большого количества клиентов в Интернете

Каким бы мощным ни был ваш сервер, при поступлении большого количества подключений и выполнении бизнес-услуг возникнут мгновенные проблемы.

Например, если к вашему серверу MQTT подключены сотни тысяч устройств. Когда ваш MQTT-сервер отключается и перезапускается, он примет сотни тысяч одновременных запросов, которые почти ни один сервис не выдержит.

В прошлом опыте xjjdog было бесчисленное количество аварий с блокировкой, вызванных проблемами с перезапуском сервера.

Этот сценарий на самом деле очень похож на концепцию разбивки кэша. Когда горячие данные в кеше централизованно выходят из строя, все запросы будут разбиты на уровень базы данных, что вызовет проблемы.

图片

Как показано на рисунке выше, для решения проблемы разбивки кеша нужно добавить к каждому ключу случайное значение времени истечения, чтобы они не истекали одновременно. Точно так же мы можем добавить случайное время, когда клиент повторно подключается к серверу. Случайные числа — это хорошо, они позволяют нашим массивным связям расти почти линейно в случайных временных окнах.

2. Очередь с несколькими сетевыми картами

Для виртуальных машин, предполагаемых на виртуальных платформах, таких как openstack, службы часто зависают после того, как трафик достигает определенного уровня из-за слабых возможностей сетевой карты. Это связано с тем, что один ЦП создает узкое место при обработке прерываний. Через команду dstat или iftop можно посмотреть текущий сетевой трафик.

图片

Например, после того, как новая машина Kafka подключается к сети, будет выполнено крупномасштабное копирование данных.В это время, если вы пропингуете связанную машину, вы обнаружите, что значение ping становится очень большим. в то же время,Recv-Qа такжеSend-Qзначение также увеличится.

В это время вам нужно включить режим мульти-очереди сетевой карты.

использоватьethtoolВы можете увидеть информацию об очереди сетевой карты.

ethtool -l eth0 | grep 'Combined'

Combined: 1

Конечно, с помощью следующей команды вы можете увеличить очередь сетевой карты.

ethtool -L eth0 combined 2

Одновременно рекомендуется включить службу балансировки прерываний.

systemctl start irqbalance

3. Время от времени отключайте длинное соединение

Если клиент и сервер соединены и сохраняют соединение, не закрывая друг друга, то это длинное соединение. Длинные соединения позволяют избежать накладных расходов, связанных с частым созданием соединений. От HTTP1 до HTTP2 и HTTP3 были предприняты усилия по сокращению количества соединений и повторному использованию соединений. Обычно длинное соединение является первым выбором.

Но есть какие-то частные случаи, надеемся, что длинное соединение не будет держаться там постоянно, и нам нужно увеличить ему TTL. Такая ситуация обычно возникает в сценариях балансировки нагрузки.

Такие как LVS, HAProxy и т. д.

Если в бэкенде есть три машины A, B и C, после загрузки LVS на эти три машины распределяется 90 подключений. Но в какой-то момент A выходит из строя, и 30 удерживаемых им соединений будут перезагружены на B и C, которые в данный момент удерживают по 45 соединений.

Когда A перезагружается, он больше не может получать новые соединения. Если операция LVS будет перебалансирована один раз, влияние также будет относительно большим. Поэтому мы надеемся, что созданное длительное соединение может иметь свойство продолжительности жизни и достигать постепенной перебалансировки в течение определенного интервала времени.

4. диапазон портов k8s

Чтобы k8s не конфликтовал с другими программами, диапазон портов по умолчанию 30000-32767. Если вы используете платформу k8s, порт узла настроен, но к нему нет доступа, обратите внимание, не слишком ли мал установленный номер порта.

5. TIME_WAIT

TIME_WAIT — это состояние, поддерживаемое стороной, которая активно закрывает соединение.Как и nginx и серверы-краулеры, часто возникает большое количество соединений в состоянии time_wait. TCP обычно ждет 2 мс после активного закрытия соединения, а затем полностью закрывает соединение. Поскольку HTTP использует протокол TCP, на этих серверах существует задержка соединений в состоянии TIME_WAIT, которые часто переключают соединения.

Некоторые системы могут видеть следующую информацию через dmesg.

__ratelimit: 2170 callbacks suppressed
TCP: time wait bucket table overflow
TCP: time wait bucket table overflow
TCP: time wait bucket table overflow
TCP: time wait bucket table overflow

Эти параметры можно установить с помощью команды sysctl.Если вы хотите, чтобы перезапуск вступил в силу, добавьте его в файл /etc/sysctl.conf.

# 修改阈值
net.ipv4.tcp_max_tw_buckets = 50000 
# 表示开启TCP连接中TIME-WAIT sockets的快速回收
net.ipv4.tcp_tw_reuse = 1
#启用timewait 快速回收。这个一定要开启,默认是关闭的。
net.ipv4.tcp_tw_recycle= 1   
# 修改系統默认的TIMEOUT时间,默认是60s
net.ipv4.tcp_fin_timeout = 10

Для проверки параметров вы можете использовать команду вида sysctl -w net.ipv4.tcp_tw_reuse = 1. Если он записан в файл, используйте sysctl -p, чтобы он вступил в силу.

6. CLOSE_WAIT

CLOSE_WAIT обычно вызывается тем фактом, что одноранговый конец активно закрывается, и мы не обрабатываем его правильно. Грубо говоря, есть проблема с написанием программы, довольно вредная.

Всем известно, что TCP-соединение представляет собой трехстороннее рукопожатие и четыре волны, потому что TCP-соединение допускает одностороннее закрытие.

图片

Как показано на рисунке, когда соединение инициирует активное завершение работы, оно переходит в состояние fin_wait_1. При этом пассивная закрывающая сторона, получившая сообщение fin, переходит в состояние close_wait, а после ответа на ack активная закрывающая сторона переходит в состояние fin_wait_2. Это одностороннее закрытие.

В это время, если пассивная закрывающая сторона по какой-либо причине не отправляет сообщение fin активной закрывающей стороне, она всегда будет находиться в состоянии close_wait. Например, EOF получен, но операция закрытия не инициирована.

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

7. Сетевое соединение, которое может открыть процесс

图片

Даже если Linux открывает порт, он может принимать огромное количество подключений. Верхний предел этих подключений ограничен количеством дескрипторов файлов одного процесса и количеством дескрипторов файлов операционной системы, то есть ulimit и file-max.

Чтобы иметь возможность сохранять изменения параметров, мы склонны записывать изменения в файл. Предел дескриптора файла процесса, который может быть помещен в/etc/security/limits.conf, его верхний предел равенfs.nr_openограничений; ограничение файловой системы операционной системы, которое может быть помещено в/etc/sysctl.confв файле. Наконец, не забудьте/proc/$id/limitsфайла, подтвердите, вступят ли изменения в силу для процесса.

Пример конфигурации /etc/security/limits.conf:

root soft nofile 1000000
root hard nofile 1000000
* soft nofile 1000000
* hard nofile 1000000
es  -  nofile  65535

8. SO_KEEPALIVE

Если вы открываете эту опцию сокета, клиентская сокет отправляется каждый сегмент (примерно два часа), чтобы отправить пакет на сервер с помощью простоя.

У этого пакета нет другой цели, просто проверить, активен ли сервер.

Если сервер не отвечает на этот пакет, примерно через 11 минут клиентский сокет отправляет еще один пакет, и если сервер не отвечает в течение 12 минут, клиентский сокет закрывается. Если опция Socket отключена, клиентский Socket может не закрываться в течение длительного времени, если сервер недействителен.

9. Какую проблему решает SO_REUSEADDR?

Когда мы разрабатываем в Интернете, мы часто сталкиваемсяaddress already in useисключение, это связано с тем, что когда приложение закрыто, сетевое соединение соответствующего порта все еще находится в состоянииTIME_WAITвызвано государством.

Состояние TIME_WAIT обычно длится некоторое время (2 мл). Настройка SO_REUSEADDR может поддерживать быстрое мультиплексирование портов и быстрый перезапуск приложений.

10. Проверка работоспособности с помощью сердцебиения приложения

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

В нашем воображении соединение должно быть линией. Но на самом деле это всего 2 точки, и путь каждый раз может быть разным. В какой-то момент вам нужно отправить пакет пульса, а затем получить ответ, чтобы узнать, жива ли другая сторона.

Механизм сердцебиения, который поставляется с tcp, может знать только, жива ли другая сторона, доступна ли служба или нет, и состояние работоспособности неизвестно, а конфигурация тайм-аута часто конфликтует с механизмом повторной передачи тайм-аута.

Следовательно, необходимо пульсирование прикладного уровня с точным значением.

11. SO_LINGER

Этот параметр Socket может повлиять на поведение метода закрытия.

По умолчанию, при вызове метода close он немедленно возвращается, если в это время еще остались неотправленные пакеты, эти пакеты будут отброшены.

Если для параметра задержки задано положительное целое число n (максимальное значение n равно 65 535), после вызова метода close он будет заблокирован не более чем на n секунд.

В течение этих n секунд система попытается отправить неотправленные пакеты данных, если более n секунд, если еще есть неотправленные пакеты данных, эти пакеты данных будут отброшены, и метод close вернется немедленно.

Установка задержки на 0 имеет тот же эффект, что и отключение опции SO_LINGER.

12. SO_TIMEOUT

Этот параметр можно использовать для установки времени ожидания чтения данных.

Когда метод чтения входного потока заблокирован, если установлен тайм-аут (единица тайм-аута — миллисекунды), система выдаст исключение InterruptedIOException после ожидания тайм-аута в миллисекундах.

После того, как исключение выброшено, входной поток не закрывается, и вы можете продолжить чтение данных через метод чтения.

13. SO_SNDBUF, SO_RCVBUF

По умолчанию буфер отправки выходного потока составляет 8096 байт (8 КБ). Это значение представляет собой размер выходного буфера, предложенный Java.

Если это значение по умолчанию не соответствует требованиям, вы можете использовать метод setSendBufferSize для сброса размера буфера. Но лучше не устанавливать выходной буфер слишком маленьким, иначе это вызовет слишком частую передачу данных, что снизит эффективность передачи по сети.

14. SO_OOBINLINE

Если этот параметр Socket включен, однобайтовые данные могут быть отправлены на сервер с помощью метода sendUrgentData класса Socket.

Эти однобайтовые данные не проходят через выходной буфер, а отправляются немедленно.

Хотя клиент не использует OutputStream для отправки данных на сервер, в серверной программе эти однобайтовые данные смешиваются с другими обычными данными. Поэтому серверная программа не знает, отправляются ли данные, отправленные клиентом, с помощью OutputStream или sendUrgentData.

End

Я был очень удивлен, обнаружив, что некоторые сетевые среды по-прежнему представляют собой гигабитные сетевые карты, в том числе некоторые более профессиональные тестовые среды. Когда в этих средах выполняется фактический стресс-тест, когда трафик превышает лимит сетевой карты, отклик приложения становится чрезвычайно медленным. Компьютерная система - это целое, ЦП, память, сеть, ввод-вывод, любое узкое место вызовет проблемы.

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

Также вас ждет интернет-киоск.

Об авторе:Мисс сестра вкус(xjjdog), публичная учетная запись, которая не позволяет программистам идти в обход. Сосредоточьтесь на инфраструктуре и Linux. Десять лет архитектуры, десятки миллиардов ежедневного трафика, обсуждение с вами мира высокой параллелизма, дающие вам другой вкус. Мой личный WeChat xjjdog0, добро пожаловать в друзья для дальнейшего общения.

Рекомендуемое чтение:

1. Играйте в линукс
2. Альбом «Какой вкус»

3. блютуз как мечта
4. Убийство!
5. Отключил архитектора, оставил только скрипт
6. ОШИБКА, написанная архитектором, необычна

Мисс сестра вкус

Не завидуйте мандаринкам или бессмертным, просто долго корректируйте строчку кода

318 оригинальный контент