Есть много, что может пойти не так, когда разговаривает с серверами в Интернете. Когда вы создаете и управляете веб -сервисом, следить за ошибками необходимо для поиска ошибок и понимания опыта ваших конечных пользователей (и, надеюсь, даже улучшить их).
Хотя с таким большим количеством возможных форм отказа, есть некоторые критические случаи, которые могут провалиться через трещины.
Большая часть мониторинга и регистрации бэкэнд будет обнаружить и сообщать о явное Сбои сервера, от отслеживания количества ответов на ошибки 5xx http, которые вы отправляете на отчеты, брошенные исключения из таких услуг, как Часовой Анкет Для этого поста я хочу выйти за рамки этих поверхностных проверок, но это не значит, что они неважны: прежде чем вы здесь сделаете что -то еще, я настоятельно рекомендую иметь этот фундаментальный мониторинг.
Однако во многих случаях эти чеки могут принести ложную уверенность командам, которые предполагают, что никакие явные ошибки сервера означает, что все работает нормально. Это часто не так. Они не рассказывают всю историю, так как существует целый мир ошибок, которые имеют значение для бэкэнда, и чья основная причина лежит на самом сервере, но который поверхности Клиент Ошибки и никогда не сообщают.
Клиент всегда Верно
Когда мы говорим об ошибках «клиента», я говорю об ошибках, которые обычно обвиняют в плохом поведении клиента. Подумайте о неожиданном сбросе соединения, семантически недействительных HTTP -запросов, синтаксически недействительных HTTP -запросов и тому подобное.
Это проблемы, вызванные тем, как клиент общается с сервером, а не основной логикой приложения сервера. Они часто обрабатываются на более низком уровне вашего стека HTTP, регистрируются и обрабатываются отдельно. 4xx Ошибки часто не включены в метрики по умолчанию, недействительные или отключенные HTTP -запросы часто не получают ответа вообще, и многие из необработанных ошибок, которые эти триггер будут обрабатываться и проглатываться вашим HTTP -сервером или структурой. Это почти невидимые неудачи.
Они игнорируются обычно просто для управления шумом. Там действительно плохие клиенты, от ботов до старых браузеров до отдельных пользователей, которые проводят быстрые тесты с Curl, и вы не хотите слышать об их проблемах. Однако во многих случаях вы управляете клиентом для вашего приложения-будь то мобильное приложение, одностраничное веб-приложение или другие серверы в вашей собственной инфраструктуре-и сбои в связи с ними означает, как ваш продукт нарушен для ваших пользователей. Даже когда вы производите API, используемый третьими сторонами, эти третьи стороны часто являются вашими клиентами, и эти ошибки клиента наносят ущерб вашему опыту вашего продукта, независимо от причины.
Ваши пользователи не заботятся о уровнях вашего программного стека. С их точки зрения, ваше программное обеспечение либо решает свою проблему, либо сломано. Если он сломан из -за ошибки в клиенте, будь то его браузер, их телефон или JS, который вы доставили на их устройство, это так же сломано, как если бы сервер бросил исключение. Мониторинг и реагирование только на явные ошибки сервера, просто потому, что их легче найти, является классическим примером Эффект уличного света где внимание сосредоточено на вопросах, которые легче всего увидеть, а не на наиболее важные проблемы.
Если многие ваши клиенты HTTP вдруг начинают бить ошибки, как человека, ответственного за сервер, вы хотите услышать об этом, и сейчас многие команды не будут.
Давайте посмотрим на некоторые примеры, чтобы сделать это более конкретным:
Ошибки настройки TLS
Если вы запускаете службу HTTPS, первое, что делает любой клиент, когда они подключаются, — это согласовать соединение TLS, создавая безопасный канал с вашим сервером, который он может использовать для своего запроса. Это может потерпеть неудачу.
Есть несколько способов, которыми это может потерпеть неудачу:
- Если ваш сертификат истекает. Автоматизация с такими услугами, как Давайте зашифруем Помогает с этим, но не разумно предполагать, что они непогрешимы. Вы также можете увидеть это, если часы клиента неверны — в Интернете это может быть их проблемой, но если ваш клиент является другим сервером в вашей инфраструктуре, то это определенно то, о чем вы хотите знать.
- Если требования к проверке сертификатов ваших клиентов изменяются. В 2018 году последний Chrome выпустил начал требовать Прозрачность сертификата для всех сертификатов. В сентябре 2020 года Apple будет Прекратить доверительные сертификаты с жизнью дольше 398 дней. Правила для «действительного» сертификата являются непоследовательными и могут быть изменены. Когда они меняются, новые сертификаты HTTPS, выпущенные точно так же, как предыдущие, будут недействительными и нефункциональными.
- Если требования ваших клиентов изменяются. У вашего сервера есть конфигурация, определяющая, какие версии TLS и Sipher Suites он поддерживает, как и каждый клиент TLS. Если сервер и клиент не могут договориться о общей конфигурации, то подключения TLS не удастся. Обновления ваших серверов или обновлений для клиентов могут сделать браузеры, клиенты API и мобильные устройства бесшумно несовместимыми с вашим сервером.
- Если ваш сертификат (CA) остается неуверенным. В 2018 году все сертификаты, подписанные CA Symantec или любые его промежуточные бренды CA (например, Verisign, Geotrust, Thawte, Rapidssl …) были Недоербным всеми основными браузерами Анкет Если вы были одним из сайтов, использующих эти сертификаты, огромная доля веб -браузеров начала отклонять ваши сертификаты почти за ночь.
- Если ваш сертификат отменен. Если ваш личный ключ протекает, вам нужно отозвать свой сертификат, и клиенты должны немедленно перестать доверять ему. Кроме того, иногда CAS делает ошибки и должен Отменить активные сертификаты En-Mass Анкет Проверка отзывов проходит и проходит несколькими способами, но, безусловно, может привести к тому, что ваш сертификат внезапно будет отклонен клиентами.
- Если вы испортите сертификат. С HPKP В браузерах (теперь устаревших, хотя и в целом поддерживаются) или конфигурация закрепления сертификата в мобильные приложения Клиент может быть настроен, чтобы доверять только конкретному сертификату. Если ваш сервер начинает использовать другой сертификат, обслуживает неправильную конфигурацию HPKP, или если мобильное приложение будет неправильно настроено, ваша настройка TLS будет отклонена.
В любом из этих случаев эти запросы терпят неудачу, и ваш продукт нарушен, но не появляется ошибка на стороне сервера. Это плохо. К счастью, это обнаруживается.
Во -первых, рукопожатия TLS могут быть прекращены путем фатального предупреждения TLS (и в некоторых случаях должны быть кодами, определенными для описания различных возможных проблем, например, 42 Плохой сертификат, 44 сертификата, отменено, 45 сертификат истек и т. Д. Это оповещения, отправленные от клиента TLS на сервер до отклонения рукопожатия, и в большинстве случаев ваш сервер уже будет получать эти оповещения, ничего не делая. С большинством веб -серверов вы можете подписаться на них напрямую или автоматически регистрировать их, а затем включить их в свои метрики и отчетность.
К сожалению, не все клиенты закроют все связи с такими ясными оповещениями, когда они не счастливы. Во многих случаях клиенты просто закроют соединение, как только они получат неприемлемые данные TLS, или заполнят рукопожатие «успешно», но затем немедленно закройте соединение без отправки каких -либо данных. Это подводит нас к нашей следующей ошибке:
Неожиданное сбрасывает и закрывает
Как только клиент подключится к вашему серверу, он должен отправить свой запрос ( get/hello
), прослушать ответ, а затем чисто закрыть соединение (на мгновение игнорируя алив).
Если это соединение немедленно сбросится или закрыто, до отправки запроса, вполне вероятно, что это одна из вышеуказанных проблем с настройкой TLS.
Здесь также есть и другие случаи, когда запрос будет закрыт раньше, чем ожидалось в этом процессе, например:
- Проблемы с подключением к клиенту пользователя (возможно, интересные в совокупности, но вряд ли будут важными индивидуально).
- Проблемы с подключением в вашей собственной инфраструктуре, возможно, между кэшами или обратными прокси и вашими серверами.
- Проблемы, в которых определенные статусы или значения заголовка сбивают с толку клиента, убив соединения до того, как ответ может быть завершен.
- Разбитые мобильные приложения или другие клиенты API, которые неправильно обрабатывают их общительные связи.
За исключением случая HTTPS, причины этих разъединений часто могут быть неясными, и многие из них являются просто шумом. Тем не менее, эти случаи очень просты в обнаружении, и в совокупности эти данные могут помочь определить проблемы с сервером и определить сломанных клиентов намного раньше, чем вы бы в противном случае.
Семантически недействительные http -запросы
Клиенты могут отправлять HTTP -запросы, которые являются структурно действительными, но не имеют смысла.
Возможно, это могут быть попытки обновить пользователя, которого не существует, или установить совершенно недопустимое свойство на некотором ресурсе. Запросы на неверные пути, запросы с неправильным методом или запросы с неверными параметрами аутентификации все попадают в этот лагерь. В каждом из этих случаев сервер понимает необработанное содержание запроса клиента, но ваша логика приложений не может или не будет делать то, что он запрашивает.
Эти запросы должны привести к ответам кода состояния 4xx. Однако во многих случаях они полностью отслеживаются отдельно от ответов на ошибки 5xx сервера и в значительной степени игнорируются, хотя многие из них интересны!
Клиенты, отправляющие семантически недействительные запросы на ваш API, подразумевают ошибку в клиенте или сервере. Возможно, клиент использует конечную точку, которую вы удалили, думая, что она не использовалась. Возможно, клиент искренне использует API неправильный, или, возможно, ваш сервер настроен неправильно и отвергает действительные запросы.
В каждом случае это явно реальные ошибки, и они либо являются вашей проблемой, так и необходимы срочные исправления (для 1 -й стороны клиентов), либо эти проблемы в вашей документации, SDK и примеры (для сторонних клиентов API).
Основным исключением из этого является 404 ошибки от клиентов браузера и гусеничных ботов. Они часто, легко перегружены, если вы начнете обращать на них внимание, и они часто являются просто шумом. Тем не менее, стоит отслеживать URL -адреса, которые чаще всего вызывают такие 404 ошибки, и время от времени сниматься в верхней части этого списка, чтобы обнаружить разбитые ссылки и URL -адреса в вашем обслуживании.
Синтаксически недействительные HTTP -запросы
Клиенты могут отправлять HTTP -запросы, которые не имеют смысла. Вместо Получить/index.html Http/1.1
Они могут отправлять бинарные данные, не относящиеся к ASCII, или некоторые другие невыполнимые блюда, так что сервер не может понять, чего они хотят вообще.
Обычно они подразумевают некоторый сбой основных ожиданий связи более низкого уровня. Несколько примеров:
- Отправка трафика HTTPS на сервер, который принимает только HTTP
- Оптимистично отправка трафика HTTP/2.0 на сервер HTTPS, который поддерживает только HTTP/1.1
- Кто -то отправляет вам трафик, который вообще не http
- Заголовки длиннее максимальной длины заголовка вашего сервера приму
- Недопустимые кодирования контента, длины контента или передачи для корпуса запроса
- Тело, содержащее контент с неправильным типом контента, который не может быть проанализирован
Все это означает, что кто -то серьезно неверно истолковывает то, что ожидает ваш сервер. Обычно это означает основную ошибку на сервере или клиенте, и это может иметь серьезные последствия.
Заголовки Overtong являются особенно интересным примером. Хотя спецификация HTTP не определяет максимум, на практике большинство серверов имеют ограничение на длину заголовков, которые они примут в запросе, и немедленно отклонят запросы с ответом 431, если они превзойдут это. Apache по умолчанию до 8 КБ, IIS до 16 КБ, и Node.js недавно сократил их с 80 КБ до 8 КБ как исправление безопасности .
Удивительно легко преодолеть этот предел, особенно если вы устанавливаете несколько больших куки или используете JWT с тяжелым метаданным для аутентификации. Если это произойдет, то когда ваши пользователи отмечают ограничение, их запросы будут все Внезапно, необъяснимо и молча отвергнуто Анкет Почти на всех серверах это простое изменение конфигурации для исправления (или, конечно, вы можете прекратить отправлять так много метаданных в ваших запросах), но если вы не входите все.
Это особенно плохо для файлов cookie, поскольку они могут накапливаться, и многие будут установлены в течение долгого времени, это редко появляется в автоматическом тестировании, и конечный результат состоит в том, чтобы эффективно заблокировать пользователя на неопределенном и невидимо. Упс.
Вы также увидите подобные ошибки в конфигурации Broken Server, например, если вы случайно отключите HTTP/2 на сервере, который ранее поддерживал его, или если анализ вашего корпуса запроса не способен обрабатывать все допустимые входы.
Каждый из других случаев предлагает серьезную ошибку, где -то на сервере или клиентской реализации. Что -то не так, на сервере определенно есть детали, и вы должны изучить это.
Сбор обратной связи с клиентами
Есть много вещей, которые могут пойти не так в запросах клиента. К счастью, во всех этих случаях ваш сервер уже знает, что это происходит, это просто не говорит вам об этом. Большинство серверных фреймворков не сообщают об ошибках клиентов по умолчанию:
- Node.js & Express не сообщает или не сообщает о обработчиках ошибок для большинства клиентских ошибок автоматически, и вам нужно
ClientError
(Для ошибок HTTP) иtlsclienterror
(Для ошибок TLS) слушатели, чтобы услышать о них. - Apache и Nginx не будут регистрировать проблемы с рукопожатием TLS, такие как другие ошибки, если вы явно настройте они Для этого Анкет
- Puma (самый популярный сервер Ruby) имеет Отдельный обработчик ошибок Для всех ошибок низкого уровня (без применения), отделенных от обработки ошибок в приложении для рельсов/синатра/и т. Д.
- API API Gateway автоматически анализирует и обрабатывает многие типы ошибок клиента Для тебя , делая их невидимыми для вашего кода приложения.
- Microsoft IIS имеет Отдельный журнал Для всех ошибок HTTP, которые он обрабатывает за пределами приложения, от подключения сбрасывает до проблем с ошибками TLS.
Вы понимаете идею.
Это не сложная проблема для решения: у серверов есть эта информация, но они часто не включают ее как часть обычного регистрации и обработки ошибок, просто потому, что эти ошибки могут быть неактуальными или шумными. Это не необоснованное дефолт, но, когда у вас появится приложение в производстве, и вам действительно все равно, если это сработает, это хорошо изучить их.
С другой стороны, это определенно не означает, что вы хотите получить уведомление о каждой ошибке клиента или даже для каждого всплеска ошибок, но отслеживание метрик для определения шаблонов и включения уведомлений для конкретных классов этих ошибок может быть полезным. Например:
- Даже небольшой всплеск отрекций сертификата или узоловых запросов предполагает, что где -то была выпущена серьезная ошибка конфигурации.
- График неожиданного соединения закрывается и сброс может быть еще одним простым способом определить проблемы TLS и лучше понять общий опыт вашего продукта ваших пользователей.
- Получение уведомлений для любого 431 Заголовки запроса слишком большие Ошибки, вероятно, являются хорошей идеей, и потенциально другие ошибки 4xx в зависимости от вашего приложения, так как они могут скрыть серьезные и невидимые сбои клиентов.
- Запись и время от времени проверять ваши топ -404 URL -адреса могут выделять интересные случаи разбитых ссылок или клиентских ошибок.
Конкретные случаи, которые имеют значение для вашего приложения, будут варьироваться, и будет шум, который вы тоже хотите игнорировать, но игнорирование всех ошибок клиента полностью — это редко правильный баланс.
Наконец, в дополнение к мониторингу их на сервере, где, конечно, это также полезно провести тесты в местах для ваших клиентских приложений, а также контролировать их в производстве. Для многих случаев, которые это невозможно, (для сторонних клиентов и приложений, просто использующих ваш SDK), это может быть связано с серьезными рисками конфиденциальности (для клиентов, работающих на пользовательских устройствах), и отчетность клиентов с сервера напрямую может сделать проблемы больше непосредственно доступен для команды, наиболее важный для их борьбы. Сбор их на стороне сервера прост и решает это для всех возможных клиентов из коробки.
Проработанный пример
Чтобы завершить, давайте посмотрим, как это выглядит на практике.
В моем собственном случае я интегрировал отчеты о ошибках клиента HTTP в Http Toolkit Анкет Http Toolkit перехватывает HTTP -соединения для отладки и уже выделяет общие случаи, такие как ошибки TLS (чтобы легко заметить клиентов, которые не доверяют сертификату MITM), но я недавно обнаружил, что многие из перечисленных здесь клиентских ошибок были скрыты или не полностью сообщены , затрудняя осмотреть все поведение клиентов. Это Теперь исправлено В основном открытом исходном код Прокси библиотека Таким образом, все эти ошибки будут полностью всплыть в следующем обновлении сервера HTTP Toolkit.
Как это работает?
Для ошибок TLS мы просто слушаем tlsclienterror
События на HTTP -сервере. Это очень просто:
server.on('tlsClientError', (error) => recordClientError(error));
Как упоминалось выше, существует также случай соединений TLS, которые тихо отвергаются, подключив «успешно», а затем немедленно отключившись, не отправляя ничего. Это довольно распространенная схема для клиентов, которые по какой -то причине не доверяют вашему сертификату HTTPS. Чтобы их заметить, вам понадобится что -то вроде этого:
// Takes a new TLS socket, calls the error listener if it's silently closed function ifTlsDropped(socket, errorCallback) { new Promise((resolve, reject) => { socket.once('data', resolve); socket.once('close', reject); socket.once('end', reject); }) .catch(errorCallback); // Called if 'close'/'end' happens before 'data' } // Check for this on all new connections: server.on('secureConnection', (tlsSocket) => ifTlsDropped(tlsSocket, () => recordClientError(new Error("TLS connection closed immediately")) ) );
Эти две быстрые проверки должны позволить вам записать и сообщать о большинстве выпусков HTTPS.
Вы также захотите поймать ошибки клиента без TLS. Для этого вы ищете ClientError мероприятие:
server.on('clientError', (error, socket) => { recordClientError(error); // By listening for this, you take responsibility for cleaning // up the client socket. Here's the equivalent of Node's default // implementation for that: if (socket.writable) { if (error.code === 'HPE_HEADER_OVERFLOW') { socket.write(Buffer.from( "HTTP/1.1 431 Request Header Fields Too Large\r\n" + "Connection: close\r\n\r\n" , 'ascii')); } else { socket.write(Buffer.from( "HTTP/1.1 400 Bad Request\r\n" + "Connection: close\r\n\r\n" , 'ascii')); } } socket.destroy(error); });
Очень просто.
Иметь смысл? Согласен, не согласен или ненавидите всю концепцию? Свяжитесь с нами в Твиттере или Отправить сообщение напрямую И дайте мне знать.
Первоначально опубликовано блог http toolkit
Оригинал: «https://dev.to/pimterry/ignore-http-client-errors-at-your-peril-1p2c»