Что такое сервер тут

О точном времени

Что такое сервер тут. Смотреть фото Что такое сервер тут. Смотреть картинку Что такое сервер тут. Картинка про Что такое сервер тут. Фото Что такое сервер тутК сервису синхронизации времени по протоколу NTP все уже привыкли — оно включено по умолчанию или легко включается для большинства популярных операционных систем. Однако какая точность при этом достигается? Какие бывают сервера точного времени, и с какими можно работать простым смертным? Какие есть подводные камни, и как выбрать «правильные» сервера времени?

Типы серверов

Сервера бывают Stratum 1 и 2, 3(выше редко).

«Простым» смертным обращаться к Stratum-1 серверам строго запрещено, т.к. нагрузка на них и так очень большая (а на многие Stratum-1 сервера вообще нет публичного доступа). Считается что вы можете подключаться к Stratum-1 серверам или просить доступ к ним, если вы держите NTP сервер, обслуживающий не менее 100 клиентов. Полный список серверов можно увидеть тут: support.ntp.org/bin/view/Servers/StratumOneTimeServers. Естественно, желательно подключатся к серверам в своей стране.

Stratum 2 — получают точное время от Stratum-1 серверов. При правильной настройке и выборе серверов-источников точного времени имеют погрешность менее 1мс. Подключатся обычно можно всем, но многие сервера регулярно умирают от нагрузки (например time.windows.com). www.pool.ntp.org поддерживает round-robin списки публичных Stratum-2 NTP серверов. Таким образом обеспечивается балансировка нагрузки, и они практически всегда доступны. Подключиться к этим серверам можно по адресам 0.ru.pool.ntp.org 1.ru.pool.ntp.org 2.ru.pool.ntp.org и 3.ru.pool.ntp.org (это для России, выбираются случайно из списка

Stratum 3 — получают время от Stratum-2 серверов, и т.д.

Практическая точность

Stratum-1
Это график разницы системного времени с временем полученным со Stratum-1 серверов (canonical.com — Stratum-2 сервер, для сравнения).
*.nist.gov — расположены в США, из-за «большого» пинга иногда случаются жуткие «выбросы». Ошибка с Российских Stratum-1 серверов обычно укладыватся в +- 1 мс.
Что такое сервер тут. Смотреть фото Что такое сервер тут. Смотреть картинку Что такое сервер тут. Картинка про Что такое сервер тут. Фото Что такое сервер тут

Stratum-2
Это — разница с Stratum-2 серверами: 4 из Российского пулла, 1 из европейского, дефолтный сервер времени убунты (europium.canonical.com), и те же *.nist.gov:
Что такое сервер тут. Смотреть фото Что такое сервер тут. Смотреть картинку Что такое сервер тут. Картинка про Что такое сервер тут. Фото Что такое сервер тут
Сразу бросаются в глаза сервера, имеющие постоянную ошибку до 20 мс.

Резюме

PS. Кстати, по умолчанию в Ubuntu синхронизация времени происходит один раз при загрузке системы. Если аптайм под полгода — время может сильно уехать. Устанавливаете ntpd — он корректирует время постоянно и «плавно» (без резких рывков, «размазывая» замедление/ускорение времени). В Windows синхронизация происходит раз в сутки неделю одним «скачком», что может вызвать сложности при обработке логов, если набежала большая разница.

Товарищи!

Даешь большое публичных NTP серверов в России! Особенно Stratum-1 (с ними вообще у нас напряженка, 2-3 штуки на весь exUSSR). Кстати, точное время можно брать и с Глонасс, кто возьмётся запустить первый Глонасс-powered сервер?

PPS. Не могу понять, в какой блог перенести, подскажите 🙂

Источник

Как выглядит сервер

Он может быть размером со шкаф или со спичечный коробок

Мы постоянно слышим про серверы в интернете: как на них что-то установить, как настроить, как подключиться. Но что физически собой представляет сервер?

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

Что есть сервер

У слова «сервер» два значения:

Мы сегодня говорим о компьютерах. О программах мы говорим в другом цикле →

Что делают серверы

Главная задача сервера — выполнять запросы пользователей. Пользователи называются клиентами, как клиенты в ресторане. Они отправляют на сервер запрос, а тот должен его исполнить по правилам, которые прописаны в его софте.

Например, запросы могут быть такими:

А вот как серверы могут реагировать:

Получается, что всё, что делает сервер, — это получает запросы и реагирует на них. Больше никакой магии в серверах нет.

Сервер в стойке

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

Что такое сервер тут. Смотреть фото Что такое сервер тут. Смотреть картинку Что такое сервер тут. Картинка про Что такое сервер тут. Фото Что такое сервер тут

Но на самом деле это не сервер, а серверная стойка — специальный железный ящик, куда вкручиваются серверы — широкие и плоские компьютеры:

Что такое сервер тут. Смотреть фото Что такое сервер тут. Смотреть картинку Что такое сервер тут. Картинка про Что такое сервер тут. Фото Что такое сервер тут

Именно такой плоский компьютер и есть сервер, а не вся стойка целиком. У такого компьютера могут быть разъёмы для клавиатуры и монитора, но их подключают, только когда что-то сломалось. Обычно в сервер просто втыкают сетевой кабель и настраивают всё через консоль.

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

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

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

Например, примером такого сервера может быть домашнее файловое хранилище:

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

Что такое сервер тут. Смотреть фото Что такое сервер тут. Смотреть картинку Что такое сервер тут. Картинка про Что такое сервер тут. Фото Что такое сервер тут

Одноплатный сервер

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

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

Что такое сервер тут. Смотреть фото Что такое сервер тут. Смотреть картинку Что такое сервер тут. Картинка про Что такое сервер тут. Фото Что такое сервер тутКомпьютер Onion Omega 2+ — одноплатник, на котором можно запустить Linux

Зачем нам так много серверов?

У каждого сервера своя задача: одни хранят фотки, другие — любые файлы, третьи обслуживают соцсети, четвёртые нужны для работы госучреждений, на пятых крутятся игровые комнаты и так далее.

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

Источник

Что такое облачные серверы: почему они надежнее и выгоднее обычного железа

Мы привыкли к тому, что где-то за пределами нашей компании существуют большие здания — дата-центры, в которых живут мощные компьютеры. Они делают для нас множество работы: хранят данные, запускают приложения, рассчитывают для нас нейросети. Даже те, кто далек от IT, знают, что эти мощные компьютеры в дата-центрах называются серверами и без них наша жизнь была бы намного тяжелей и скучней.

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

Сразу к сути: что такое облачный сервер

Представим себе мощный компьютер, способный делать миллион операций в секунду. Если поставить такой компьютер в офис, то его ресурсы едва ли будут востребованы на 100%. А если купить в офис десять таких компьютеров для десяти сотрудников — все они будут заняты в среднем лишь на 10%. Но что, если бы был способ сэкономить и купить на десять сотрудников один мощный компьютер? Тогда они заняли бы всю мощь железа на 100%, а владелец бизнеса сэкономил много денег.

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

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

Такая концепция называется «облачным сервером» и без нее современное IT было бы намного скучнее, тяжелее и дороже. Подробнее об этом мы писали в статье «Виртуализация в облаке: справляемся с дефицитом инфраструктуры».

Что такое сервер тут. Смотреть фото Что такое сервер тут. Смотреть картинку Что такое сервер тут. Картинка про Что такое сервер тут. Фото Что такое сервер тут

Облачные серверы — это виртуальные серверы на одном или нескольких физических, то есть объединение ресурсов обычных серверов и разделение их на нужное количество виртуальных «кусочков»

В чем же преимущества облачных серверов? Дальше мы поговорим как минимум о трех причинах выбрать облако вместо привычного железа в дата-центре.

Быстрый старт

Когда-то процесс запуска нового сервера в работу был предельно похож на процесс покупки телевизора в магазине. Выбираешь, читаешь обзоры, думаешь. Договариваешься с продавцом. Платишь. Ждешь доставки. Распаковываешь. Читаешь инструкцию. Аккуратно подключаешь нужные проводочки. Включаешь. Аккуратно настраиваешь и пользуешься.

Для современного мира такая многоходовка — слишком долго, муторно и скучно. Современные скорости разработки требуют, чтобы серверные мощности запускались и включались мгновенно. Многодневные поставки серверного оборудования и многочасовые сеансы установки арендного оборудования вызывали фрустрацию у владельцев компаний, администраторов и технического персонала.

Облачный сервер можно создать и отдать в пользование клиенту за секунды. Ведь речь идет не о физической поставке оборудования, а о перераспределении мощности внутри серверной стойки. Провайдеру нужно лишь «запомнить», что 15% мощности процессора и 7% оперативной памяти отдается вот тому клиенту — это перераспределение происходит автоматически, поэтому пользователь всегда получает нужное, практически неограниченное, количество ресурсов серверов по первому требованию за пару кликов.

Что такое сервер тут. Смотреть фото Что такое сервер тут. Смотреть картинку Что такое сервер тут. Картинка про Что такое сервер тут. Фото Что такое сервер тут

Предельная эффективность, а за счет нее экономичность

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

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

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

Источник

Как я решил протестировать нагрузочную способность web сервера

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

Посмотреть, как работает можно, например здесь – бесплатный сервис хранения ссылок http://linkin.link. Про него я писал.

Вступление

Собственно, как тестировать web сервер? Если посмотреть на проблему в лоб – то веб сервер должен отдавать все страницы, которые были запрошены клиентами. И желательно отдавать быстро.

Конечно, есть множество других сценариев. Ведь web сервер не работает сам по себе, как правило, он как минимум работает с какой-нибудь БД, связь с которой — это отдельная большая тема. Опять же могут быть множество отдельных сервисов – авторизационных и прочих. Перед web сервером может стоять балансировщик нагрузок. Всё это может размещается в множестве виртуальных контейнеров, которые опять же могут быть на разных физических серверах. В общем это целый зоопарк каналов передачи данных – каждый из которых может стать узким горлышком.

Начинать надо с малого и для начала решил проверить самый простой и очевидный сценарий. Есть web сервер. Делаем на него запросы. Все запросы должны вернутся без ошибок и вовремя.

Задача поставлена. Тестировать решил так. На одной машине под windows 10 запускаю web сервер. На web сервере запущен сайт. На сайте размещено куча js, сss, mp4 файлов и, собственно, html страничка. Для простоты я просто взял страницу из готового сайта.

Чем досить сервер? Тут 2 пути – скачать что-то готовое или написать свой велосипед. Я решил остановится на втором варианте. И этот выбор я сделал по нескольким причинам.

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

Httpdos

Изначально использовал TcpClient но по каким-то причинам он выдавал почти сразу на старте множество ошибочных загрузок. Не стал разбираться, а спустился пониже. Реализовал отправку на socket.

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

Ошибки считал по 2 сценариям. Все exception – связанные с открытием, отсылкой, приёмом данных. Собирательно если хоть, где что-то не так – убиваем socket, инкрементируем счётчик ошибок. Ещё добавил проверку длины данных. При первой закачке страницы – запоминается длина данных, все повторные закачки – сверяются с этим числом. Отклонение – считается ошибкой. Можно было бы добавить и что-то другое – но для начала мне и этого достаточно.

Всё для эксперимента готово. Запускаем web сервер. Запускаем httpdos – так назвал программу, чтобы дальше можно было использовать это короткое название. И вижу следующую картину.

Тут я уточню некоторые технические данные. Количество потоков делающие запросы получилось 1200. Эта цифра – количество url прочитанных из файла urls.txt, плюс я решил умножить все запросы в 20 раз. Все цифры взял из головы на момент написания программы. В любой момент можно поставить любые другие по желанию. Преимущество велосипеда.

Откуда такая цифра? По моим размышлениям она зависит от многих обстоятельств. Самая очевидное – это какого размера сами запросы. Как я писал выше – я просто скачиваю все данные с определённой web страницы, которая была взята из стороннего web проекта. И там много mp4 файлов, размер которых под 3 мегабайта. Если уменьшить размер запросов, например скачивать только css – наверняка количество обработанных запросов увеличится. Мне даже стало интересно, и я начал играть с исходным кодом как со стороны web сервера, так и со стороны httpdos. Там есть куча различных таймеров, буферов и прочего. Я смотрел, как то или иное изменение, окажет влияние на скорость.

Так же существенное влияние на скорость оказывало, то что web сервер и httpdos был запущен в режиме отладки в Visual Studio.

Решил параллельно с httpdos сделать загрузки js файла через браузер. Файл закачивается мгновенно. Т.е. httpdos не оказывает существенного влияния на web сервер.

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

А у видел я, что по каким-то причинам спустя примерно минуту начали появляться ошибки загрузок.

И я начал расследование.

Такого поведения просто не должно быть!

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

То, что произошло дальше заставило меня напрячься.

В процессе экспериментов я и так и сяк изгалялся над httpdos. И один сценарий привёл к неожиданным результатам.

Если запустить не менее 3 программ. Думаю, что такое количество связанно с количеством одновременных запросов в секунду. Начать dos атаку. Дождаться появления ошибок. Потом резко закрыть программы. То слушающий socket web сервера просто умирает! Вот так – нету никакой ошибки на стороне сервера. Все потоки работают. А socket ничего не принимает. Это уже ни в какие ворота.

Эксперименты показали, что socket оживал примерно через 4 минуты, но, если dos атаку проводить долго – socket умирал навсегда, по крайней мере я минут 15 ждал оживления, а дальше уже и не интересно было. Такого поведения просто не должно быть!

Эксперимент был проведён множество раз – результат всегда один и тот же.

Если перезапускать web сервер, т.е. получается мы пересоздаём слушающий socket, то socket начинал принимать клиентов сразу.

Первый шаг

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

Ну… информативно(сарказм) однако. Вроде как это стоит понимать, что socket, к которому мы хотим подключится как бы и нету.

Что такое сервер тут. Смотреть фото Что такое сервер тут. Смотреть картинку Что такое сервер тут. Картинка про Что такое сервер тут. Фото Что такое сервер тут

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

Пару слов о socket

Как видно – для работы с слушающим socket нужно 3 действия. Создали. Слушаем. Принимаем клиентов. Схема настолько простая что программисту не остаётся никаких способов для манёвров, ну или возможностей отстрелить себе ногу.

Предполагается что используй вот так (куда ещё проще?) и не иначе – и всё у тебя должно работать. Но как показывает практика – есть нюансы.

Хоть схема использования и проста, я всё же решил провести пару экспериментов что бы отсеять весь лишний код из подозрений. Первое что я сделал это очистил код от лишних действий и поставил точку остановки сразу после конструкции:

Затем подвесил socket. Попытались присоединится клиентом. Программа висела в вышеприведённой строчки кода. Тут мы увидели, что проблема не в коде после socket, а где то внутри socket.

Дальше я решил поэкспериментировать с настройками открытия socket. Собственно, в своё время все настройки и так были исследованы, и оставлены только те, что нужно. Но в свете последних событий – никто не уйдёт от (подозрений) экспериментов.

Под подозрения попали следующие настройки.

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

И вообще было проведено большое число разных спонтанных экспериментов. Пришла в голову идея. Изменил код. Запустил. Проверил. Забыл. Десятки секунд, не более.

Что касается тайм аутов. В коде сервера реализованы различные таймауты, но на более высоком уровне. В приёмнике есть таймауты на приём шапки http, определения длины body, расчёт времени на приём body исходя из длины body и сценария наихудшего канала связи, например 1024 кб/c.

Примерно такие же правила и на отправку.

И если таймауты выходят – socket клиента закрывается и удаляется. Для socket вызывается shutdown и close. Всё как и предписывает microsoft.

Поставил таймауты для resive/transmite 2000ms. Не помогло. Идём далее.

Что это за параметр? Wiki говорит:

Получает или задает значение, задающее время существования (TTL) IP-пакетов

Т.е. при прохождении очередного шлюза параметр уменьшается на 1. При достижении 0 – пакет удаляется. И вроде это не наш случай. Потому как наша система вся на localhost. Но! При гугление я нашёл следующую информацию.

Там было сказано, что windows от этого параметра рассчитывает двойное время нахождения socket в режиме TIME_WAIT. Про этот режим более подробно ниже.

Поставил ttl в минимально возможное значение. Не помогло.

Утечка sockets?

Далее я подумал – сервер открывает каждую секунду около 6000 тысяч sockets и закрывает их. И всё это крутится на кучи асинхронных Task. Вдруг количество открытых сокетов и закрытых не совпадает? И есть, некая утечка sockets?

Быстро набросав код – принцип которого заключается в инкременте глобальной переменной при открытии socket и декременте при закрытии и вывода этого числа в консоль.

Весь дополнительный код состоял из 3 блоков:

Разумеется, каждый блок размещается в нужном месте.

Запустив программы, я получил следующее:

Видео можно разделить на три части. Запуск. Рабочее состояние – длится около 3 минут. В этом состоянии ни одной ошибки. И первое появление ошибки. Собственно, вторую часть я вырезал как не интересную.

Как же нам интерпретировать результат? Во-первых, мы видим число примерно 400 выводящееся каждую секунду.

Как работает веб сервер? Идеальный сервер приняв клиента мгновенно формирует ответ, отправляет его клиенту и мгновенно закрывает socket (хотя в реальности socket не закрывается а ожидает следующих запросов, ну условимся что так работает идеальный сервер). Поэтому количество открытых socket в идеальном сервере каждую секунду было бы 0. Но тут мы видим, что каждую секунду у нас примерно 400 обрабатывающихся клиентов. Что ж, для неидеального сервера вполне норма. Вообще количество одновременных клиентов в нашем сервере задаётся глобальной настройкой. В данном случае 10000 – что значительно выше 400.

Так же мы видим, что периодически подпрыгивающее значение до 1000-2000. Связанно это может быть с чем угодно. При желании можно и это выяснить. Может сборщик мусора, может что ещё. Но, собственно, ничего криминального в этом нет.

И вот появились первые ошибки. Я начал закрывать программы. На видео виден характерный момент – при закрытии второй программы, в последней оставшейся программе, посыпались ошибки открытия socket. Это в очередной раз показал своё лицо баг – который мы так пытаемся отловить, пока безуспешно. Одна радость – повторяется он регулярно, поэтому хоть есть возможность поиска. Сама же эта ошибка нам пока ничего не даёт.

Главная цель текущего эксперимента – сопоставить количество открытых и закрытых socket. Окончательная цифра 0. Всё, как и должно быть. Ладно идём дальше.

Динамический диапазон портов

Далее расследование завело меня в область настроек windows. Должны же быть какие-то настройки для работы tcp/ip стека? Гугление мне подкинуло множество, но особо я хотел бы остановится на наиболее подходящих к нашему случаю.

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

Такой способ выдаёт socket с портом из динамического пула windows. Т.е. windows сама решает какой порт тебе выдать. Я поменял этот код на другой – где я сам указывал порты. Но первый запуск показал, что диапазон выбранных мною портов был нашпигован как изюм открытыми портами, плюс доступ к некоторым портам выдавал странные ошибки о некорректном доступе. Это заставляло меня усложнять программу – делать код поиска открытых портов

Поискав готовое решение я увидел, что это не простой способ – в одну строчку. И я не стал развивать эту тему дальше. Windows виднее кокой мне порт дать.

В дальнейшем я и убедился в своей правоте. Как оказалось Microsoft изменила этот диапазон, и он составляет 49152-65535. И того где-то 15k портов. Явно меньше, чем 65535

Поэтому первая настройка – увеличиваем этот диапазон.

Я применил следующую команду:

netsh int ipv4 set dynamicport tcp start=10000 num= 55535

Команду запускаем под администратором. Проверить значение можно командой:

netsh int ipv4 show dynamicport tcp

Изменить то изменили – но как проверить, что диапазон действительно расширен? Да и нужно ещё узнать повлияла ли эта настройка на наш баг.

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

Что показало нам запуск? При старте одной программы вылетела ошибка одного подключения. Не будем на это обращать внимание. А то так можно закопаться по уши в отладке. Дальше работало всё, как и ожидалось. Во-первых, мы чётко увидели, что диапазон выделяемых портов действительно стал 10000-65535. Во-вторых, порты выделяются последовательно без каких-то видимых провалов. Достигнув максимума, цикл повторяется. Я прогнал несколько циклов – никаких отклонений.

Далее я начал закрывать программы – и при закрытии второй программы – серверный socket завис. Порты перестали выделятся. Во второй программе httpdos посыпались ошибки открытия socket.

Выводы – проблема не в портах. По крайней мере порты явно не заканчиваются.

TIME WAIT

А что у нас есть вообще по протоколу TCP? Идём сюда и внимательно читаем.

Под подозрение попадает одно состояние TIME WAIT. Это одно из стояний, в котором может находится socket, т.е. пара ip+port. После его закрытия.

Получается, что мы закрыли socket – но он ещё будет недоступен. Поиск показал, что это время находится в районе 4 минут.

Если бы мы играли в игру холодно-горячо, то я бы заорал горячо! Горячо! Похоже это именно наш случай.

Но зачем такое странное поведение. Опять же из справки получил пояснение. Т.к. протокол tcp/ip гуляет по сети пакетами, а сами пакеты могут пойти по разным маршрутам. И вообще застрять на некоторое время на каком-нибудь шлюзе, может получится ситуация, когда мы открыли socket, поработали с удалённым сервером. Закрыли socket. Потом этот socket открывает другая программа – а ей начинают валится пакеты от предыдущей сессии. Как раз время таймаута и выбрано что бы отставшие все пакеты в сети удалились как мусорные.

OK, а можно ли изменить этот параметр? Оказывается в Windows есть целая ветка реестра, отвечающая за параметры tcp протокола.

Нас интересуют пока 2 параметра:

Цель установить минимальное значение. Минимальное значение 30. Что означает что через 30 секунд порт опять будет доступен. Устанавливаем. Ну а далее наша стандартная проверка.

Запускаем сервер. Запускаем клиенты. Досим. Дожидаемся отказа socket. Потом запускаем консоль и вводим команду:

Такое ощущение что весь выделенный диапазон портов находится в состоянии TIME WAIT. Это пока соответствует ожиданиям. Ждём 30с. Повторяем команду. Листинг уменьшился в разы. Все порты с WAIT TIME пропали.

Проверяем серверный socket на оживление. Глух ((( А такие надежды были на эту настройку.

Впрочем, определённые выводы сделать можно. Настройка наша работает. Пауза 30с. Оставляем – полезная настройка для нагруженного сервера.

Wireshark

Решил посмотреть, что нам покажет Wireshark. Кто не знает — это мощнейший анализатор всевозможных протоколов, в том числе и tcp/ip. До недавнего времени в программе не была реализована функция прослушки localhost и приходилось производить некоторые танцы с бубном. Ставить виртуальную сетевую карту. Трафик пускать через неё. А Wireshark уже мог подключатся к прослушке этой карты.

Недавно подвезли возможность прослушки localhost – что очень облегчило работу.

Далее всё стандартно. Запускаем сервер, клиентов. Убиваем слушающий socket.

Запускаем Wireshark – ставим фильтр на 80 порт. Открываем браузер – пытаемся закачать файл javascript.

Вот какое непотребство мы увидели в сниффере:

Что такое сервер тут. Смотреть фото Что такое сервер тут. Смотреть картинку Что такое сервер тут. Картинка про Что такое сервер тут. Фото Что такое сервер тут

Видно, наш запрос. Браузер с порта 36036 пытается достучатся к порту 80. Выставляет флаг SYN. Это стандартно. Но вот с порта 80 нам возвращается флаг RST — оборвать соединения, сбросить буфер. Всё. И так по кругу.

Вывод. Wireshark – нам особо не помощник. Разве только мы увидели, что слушающий socket не мёртв совсем, а отвечает. Он работает по какой-то своей внутренней логике, а не просто умер.

Журнал windows

Решил посмотреть – может что в журнале событий windows есть что-то интересное. Для этого захожу в журнал.

Панель управления-> Администрирование-> Управление компьютером-> Служебные программы-> Просмотр событий-> Журналы Windows

Либо запустите eventvwr.msc

Там, разумеется, есть миллионы записей. И чтобы не копаться в этих миллионах, я делаю следующее. Убиваю socket. Захожу в журнал – и чищу подразделы. Захожу в браузер – пытаюсь скачать файл. Захожу в журнал – и смотрю что там только что появилось.

К сожалению, никаких событий, кусающихся моей проблемы, не появилось. Я даже нашёл такой раздел Microsoft/Windows/TCPIP. Но кроме одинокой записи – “работает”, там ничего не было.

Финал?

Поиск в интернете всей доступной информации по проблеме периодически выдавал мне страницы подобной этим:

И ещё во многих других местах.

Отсюда я сделала 2 вывода – я со своей проблемой не одинок, и как минимум периодически с ней сталкиваются и другие.

Есть ещё 2 параметра TCP стека с которыми можно поэкспериментировать.

Поиск по этим параметрам для Windows 10 ничего не дал. Только для Windows 2003-2008 Server. Может плохо искал (наверняка). Но я всё же решил их проверить.

Установил следующие значения:

TcpMaxDataRetransmissions REG_DWORD: 00000005 (hex)

Перезагрузился. Повторил в который раз все процедуры. И….

Socket жив. Всё проверив несколько раз, путём добавления и удаления из реестра параметров с последующей перезагрузкой компьютера. Все эксперименты показали, что с параметрами – socket остаётся жив. Это всё?

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

На следующий день, я решил закрепить полученную информацию. Запускаю эксперимент – socket мёртв. Мы вернулись к тому, с чего начинали!

Эти параметры оказались бесполезны в решении нашей проблемы. Но я их всё-таки оставил – потому как по смыслу они полезные.

Финал

Продолжая эксперименты, я обнаружил в коде один хитрый перехватчик исключений на слушающим socket. Точка остановки в этом месте показала, что при возникновении нашего случая – сюда начали валится куча exception со следующим сообщением:

Удаленный хост принудительно разорвал существующее подключение.

В этом exсeption была паузу. С пояснением – исключение на socket случай неординарный, например socket занят другим приложением, делаем паузу что бы всё утряслось и в лог не сыпалось миллионы сообщений.

Как оказалось не неординарный.

Картина сложилась

Получается, что приёмный socket набрал большое число входящих подключений, которые оборвались, и больше не принимает новые подключения пока поток висел в exception на паузе.

Выводы

Ну что ж. Я, конечно, ожидал что геройски одержу победу над некоей эпичной ошибкой. А всё оказалось очень банально. Собственно, как всегда.

Все эксперименты у меня заняли где-то полтора дня. Эту статью я писал намного больше.

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

Узнал новую информацию по поводу работы сети – эти знания пригодятся впоследствии при решения очередного непонятного бага.

Почему у меня заняло так много времени на поиск банального Delay? Я думал над этим и пришёл к выводу, что все эксперименты уводили в сторону от ответа. Сложившееся картина показывала нам что умирал именно socket. Переставал принимать подключения. Спустя время оживал. Все сниферы показывали, что подключений не происходит.

Опять же было неправильное представление, что серверный socket работает в отдельном потоке. И в любом случае должен принимать клиентов. Поэтому я и скал проблему в настройках socket и tcp стека. Главная проблема – я думал поток висит на socket. А в нашем аварийном случае он висел на exeption в Delay.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *