Предисловие:
Утром нашла сказочный блог! Написано очень подробно и легко для понимания, пожалуйста, перепечатайте~
вперед от:blog.CSDN.net/QQ_41453285…
спасибо~
1. Описание TCP-соединения
- ①При использовании протокола TCP между клиентом и сервером будет установлен виртуальный канал.Этот виртуальный канал относится к соединению.Рекомендуется, чтобы для этого соединения требовалось 3 рукопожатия, а для разрыва соединения требуется 4 волны.Можно видеть, что за установление этого соединения нам приходится платить.Эта стоимость — это стоимость эффективности, которая представляет собой просто стоимость времени., если хотите отправить кусок данных, то надо сначала 3 раза рукопожать (3 пакета туда-сюда), а потом можно отправлять данные.После отправки нужно махнуть 4 раза (4 пакета туда-сюда) для отключения связь
- **②Затраты ресурсов ЦП,** Трехстороннее рукопожатие и 4 волны и данные отправки отправляются и принимаются с сетевой карты и других устройств, таких как брандмауэры, маршрутизаторы и т. д., с точки зрения операционной системы. ядро системы, если мы являемся системой с высоким параллелизмом, если через такой процесс прошло большое количество пакетов данных, это будет потреблять много ресурсов ЦП.
- **③Каждый сокет должен потреблять системный кеш. **Например, система предоставляет некоторые интерфейсы для установки кеша сокета, такие как:
- /proc/sys/net/ipv4/tcp_rmem
- /proc/sys/net/ipv4/tcp_wmem
- /proc/sys/net/ipv4/tcp_mem
- Из-за надежной передачи TCP у нас есть большое количество приложений, использующих протокол TCP для связи, но каждое приложение использует TCP по-разному из-за функций продукта, таких как системы мгновенного чата (WeChat, DingTalk, Tantan).
Два, длинное соединение TCP, короткое соединение TCP
Короткое TCP-соединение
- **Концепция.** Как показано на рисунке ниже, клиент и сервер устанавливают соединение, чтобы начать обмен данными. После завершения одного или указанного числа сеансов связи текущее TCP-соединение разрывается. При следующем сеансе связи TCP соединение устанавливается снова.
- **Преимущества:** Не занимает много времени память сервера, поэтому количество подключений, которые может обработать сервер, относительно велико.
- недостаток:
- Потому что, когда вы хотите отправить данные или получить ресурсы, вы будете запрашивать только установление соединения для отправки данных, иначе соединение будет открыто, так что, если сервер захочет отправить данные клиенту? **Партнер Лян, это невозможно, или вам придется подождать до следующего раза, когда вы захотите запросить данные перед отправкой.Например, если мы используем опрос (30 секунд или дольше) для извлечения сообщений, то связь в реальном времени между сервером и клиентом будут потеряны.
- Клиент использует опрос для получения информации в режиме реального времени, или большое количество клиентов используют короткие соединения для связи, а затемМного ресурсов ЦП и пропускной способности тратится впустую для установления и разрыва соединений, происходит трата ресурсов или даже соединение не может быть установлено.. Например, классический длинный опрос http (веб-клиент WeChat)
TCP длинное соединение
- **Концепция:** Как показано на рисунке ниже, после того, как TCP устанавливает соединение с сервером, он всегда находится в подключенном состоянии и не отключается до тех пор, пока в конце служба больше не будет нужна.
- преимущество:
- Быстрая передача данных
- Сервер может активно передавать данные клиенту в первый раз
- недостаток:
- Поскольку клиент и сервер всегда поддерживают это соединение, количество клиентов в распределенной кластерной системе с высокой степенью параллелизма будет увеличиваться, занимая много системных ресурсов.
- TCP сам по себе является своего рода данными с отслеживанием состояния, и в распределенной системе с высокой степенью параллелизма это усложнит фоновое проектирование.
3. Механизм TCP keepalive (механизм поддержания активности)
- Подробную информацию о «механизме поддержания активности TCP» см.:blog.CSDN.net/QQ_41453285…
-
TCP реализует механизм поддержания активности, основные намерения проекта:
- Клиент и сервер нужныЗнайте, когда убить процесс или отключиться от другой стороны
- В других случаях, хотя обмена данными между процессами приложения нет, все же необходимоСохранение минимального потока данных через соединение может быть очень ресурсоемким.. Механизм поддержания активности может использоваться для обнаружения друг друга и закрытия соединения, когда это необходимо.
- **Основной принцип работы:** Сторона зонда создаст таймер на своей стороне, и когда таймер сработает, он отправит пакет зонда другой стороне. Если партнер отправляет ACK обратно самому себе, это означает, что другая сторона все еще жива; если он не отправляет ACK себе в течение указанного времени, это подтверждает, что другая сторона отключилась, тем самым отключив текущий TCP-соединение
Параметры ядра, связанные с Linux
- **tcp_keepalive_time:** Единицей является секунда, указывающая время простоя канала перед отправкой пробного пакета, по умолчанию 7200.
- **tcp_keepalive_intvl:** Единица измерения — секунда, указывающая временной интервал между отправкой двух тестовых пакетов, по умолчанию — 75.
- **tcp_keepalive_probes: ** указывает количество зондов, по умолчанию 9
Варианты сокетов Posix
Для трех параметров ядра, описанных выше, в Linux-программировании доступны соответствующие параметры сокета.
Для получения дополнительной информации о setsockopt() см.:blog.CSDN.net/QQ_41453285…
int keepalive_time = 30;setsockopt(incomingsock, IPPROTO_TCP,TCP_KEEPIDLE,(void*)(&keepalive_time),(socklen_t)sizeof(keepalive_time)); int keepalive_intvl = 3;setsockopt(incomingsock, IPPROTO_TCP,TCP_KEEPINTVL,(void*)(&keepalive_intvl) ,(socklen_t)sizeof(keepalive_intvl)); int keepalive_probes= 3;setsockopt(incomingsock, IPPROTO_TCP,TCP_KEEPCNT,(void*)(&keepalive_probes),(socklen_t)sizeof(keepalive_probes));
Четыре, дизайн длинного соединения TCP
Зачем нужно длинное соединение
- **Сервер должен активно отправлять сообщение клиенту: **Если нет соединения, сервер никогда не сможет активно найти клиента, и нет возможности вовремя отправить сообщение клиенту
- ** Частая связь между клиентом и сервером: ** Если это короткое соединение, соединение необходимо устанавливать каждый раз, чтобы отправить сообщение.Если параллелизм немного выше, большое количество сокетов в состоянии TIME_WAIT может появляются, то есть последующие заведения не могут подключиться
- **Бизнес-потребности, например сервер должен выполнять некоторую обработку, когда клиент находится в автономном режиме: **Например, очистка его кеша или других ресурсов или других бизнес-значений, таких как аватар QQ, отображаемый в автономном режиме.
Проблемы, которые необходимо учитывать при проектировании длинных TCP-соединений
- ** Тайм-аут проверки активности TCP по умолчанию слишком велик: ** По умолчанию 7200 секунд, что составляет 2 часа, конечно, его можно изменить.
- ** прокси-сервер сокета сделает недействительным поддержку активности tcp: ** все прокси-приложения могут только пересылать данные приложения TCP, но не могут пересылать пакеты внутри протокола TCP
- ** Для мобильной сети требуется сигнализация поддержания активности: ** Смарт-терминалы, такие как мобильные телефоны, используют мобильную сеть для доступа в Интернет, и в целях экономии ресурсов канала операторы пытаются отключиться более чем на 60 секунд или более. 45 секунд без отправки сокета данных
- Механизм обнаружения сердцебиения используется для решения этих проблем ниже.
5. Обнаружение сердцебиения
- Обнаружение пульса — это механизм, реализованный пользователями на уровне приложения., который используется для имитации механизма поддержания активности TCP. Он отправляет пакет обнаружения сердцебиения другой стороне в течение заданного времени. Если он возвращает ответ самому себе в течение указанного времени, то соединение TCP не будет закрыто, если нет ответа в указанное время Отправьте ответ себе, затем выполните соответствующую обработку (например, закрытие текущего TCP-линка)
Реализация в Netyy
Реализация кодирования и основные принципы
- Ссылка на источник на гитхабе:GitHub.com/Восточный Юшэн…
- Код:
- Код заключается в использовании красно-черного дерева для управления таймером.
- Общая структура реализована в режиме Reactor.
- Имеются соответствующие клиент и сервер
- Общая идея такова:
- Мы используем красно-черное дерево для управления всеми узлами событий, где ключ — таймаут сокета события, а значение — сокет
- Вызов wpoll_wait() для обработки всех событий, где последним параметром является время ожидания, которое должно быть установлено в значение узла с самым коротким временем ожидания во всем красно-черном дереве.
- Когда epoll_wait() возвращается, сравните время со временем узла и, если время ожидания истекло, выполните соответствующую обработку.
Разбор кода
- Нижеследующее в основном представляет «сервер» как первую перспективу, чтобы увидеть, как он выполняет обнаружение пульса на клиенте.
- Функция ngx_reactor_loop() из ngx_reactor.c:
- Основная центральная функция обработки Reactor ngx_reactor_loop() получит текущее время до вызова poll_wait()
- Затем выполните epoll_wait(), последним параметром которой является значение времени узла с наименьшим таймаутом в красно-черном дереве.
- После возврата epoll_wait() обновить текущее время (глобальная переменная ngx_current_msec)
- Наконец, снова получите текущее время, а затем выполните вычитание со старым «текущим временем», чтобы получить разницу.Если время ожидания истекло, вызовите функцию ngx_event_expire_timers().
- Функция ngx_event_expire_timers() из ngx_reactor.c:
- Эта функция также является флагом what для инкапсулированного события | последний NGX_EVENT_TIMEOUT, для события установлено время ожидания
- Затем будет вызвана функция обратного вызова события
- В приведенной выше функции обратного вызова функция обратного вызова, которую мы связываем с ней, — это функция client_handler() в ngx_server.c:
- Эта функция будет определять, имеет ли флаг события what флаг NGX_EVENT_TIMEOUT, и если да, то вызывает функцию-обработчик timeout_cb().
- Функция timeout_cb() или оценивает, превышает ли дельта время KEEPALIVE_INTVAL_MSEC и время ожидания 3 раза (KEEPALIVE_INTVAL_PROBES), если это так, вызовите close(), чтобы закрыть клиентский сокет
- Определенный выше макрос выглядит так