Это очень классический вопрос.Я считаю, что у вас есть высокая вероятность интервью или интервью других людей, и это может быть только частью этого, чтобы задавать вопросы. Этот вопрос охватывает много точек знаний, и исследование относительно всеобъемлющее.В Интернете есть сотни статей.Разные люди имеют разные мнения, но большинство из них совпадают. Если вы не изучили его досконально и систематически, полагаясь только на механическое запоминание, интервьюер спрашивает немного о каком-то моменте или спрашивает по-другому, это может выявить недостатки. Если хорошенько подумать, то обучение накопилось до определенного этапа, а также необходимо провести всестороннюю сводку системы знаний на основе технических резервов.
Открытые вопросы без фиксированных ответов касаются различных дисциплин и областей, таких как компьютерная графика, операционные системы, принципы компиляции, компьютерные сети, принципы связи, распределенные системы и принципы браузера. Но независимо от того, с какой области вы начинаете, с точки зрения программного или аппаратного обеспечения, это может быть долгая история. Если вы много лет специализируетесь в какой-то предметной области, то у вас должен быть более глубокий опыт и уникальные знания в этой области, чем у меня, и предложения приветствуются.
С моей точки зрения, если смысл вопроса недостаточно ясен, не хватает ситуации и квалификации, ответить прямо невозможно. В сегодняшних все более сложных компьютерах любое изменение и комбинация условий могут создать тысячи возможностей и нарушить рутину. Что касается самого названия, оно будет включать, помимо прочего, следующие условия:
- Тип ресурса запроса
- Тип и версия браузера
- Тип и версия сервера
- Тип и версия сетевого протокола
- статус сетевого соединения
- через какие промежуточные устройства
- Типы и стандарты локальных сетей
- Тип физического носителя
- маршрут перевозчика
Если запрос на статические ресурсы, то трафик может дойти до CDN-сервера, если запрос на динамические ресурсы, то ситуация сложнее, и трафик может проходить через прокси/шлюз, веб-сервер, сервер приложений и базу данных в перемена. На рисунке 1 представлена схема высокодоступного развертывания Alibaba Cloud SLB (Server Load Balancer, балансировка нагрузки), которая отличается от традиционного режима переключения «активный-резервный», который слишком сильно зависит от вычислительных возможностей одной машины. общедоступная сеть проходит через ECMP (многопутевая маршрутизация с равной стоимостью, многоканальная маршрутизация с равной стоимостью) перенаправляет трафик в кластер LVS (уровень 4 SLB), для запросов TCP/UDP, LVS Кластер напрямую перенаправляется на серверный кластер ECS. Для HTTP-запросов он перенаправляется на кластер Tengine (семиуровневый SLB), который затем перенаправляется на внутренний кластер ECS. Кластеры реализуют синхронизацию сеансов, работоспособность проверка и другие механизмы, обеспечивающие высокую производительность.
С непрерывным расширением масштабов бизнеса, чтобы обеспечить десятки миллионов или даже сотни миллионов трафика и объемных хранилищ, требования к многокомнатному аварийному восстановлению и бесплатному расширению системы становятся все выше и выше, и система может эволюционировать в удаленную многоактивную архитектуру (рис. 2). В отличие от традиционной схемы аварийного восстановления, несколько центров обработки данных одновременно предоставляют внешние службы, обеспечивая при этом согласованность и целостность данных базы данных между удаленными подразделениями (теория CAP). Вся архитектура системы разделена на уровень трафика, уровень приложений и уровень данных.Технология DNS используется для реализации GSLB (Global Server Load Balance, глобальная балансировка нагрузки), и пользователи могут получить доступ поблизости. При общем сбое системы в определенном регионе все запросы трафика будут переключаться в другой регион для выполнения удаленного аварийного восстановления, что также аналогично текущему этапу Ele.me.Общая структурастроить планы.
Однако, в отличие от динамических ресурсов, с учетом затрат на развертывание и затрат на трафик, статические ресурсы обычно кешируются через CDN и промежуточные серверы. сервер.
Поэтому реальная ситуация в мире постоянно меняется, и вам сложно представить, что запрос GET запускает даже операцию банковского перевода, все зависит от человеческой реализации. Возвращаясь к теме этой статьи, исключим все особые условия и упростим задачу, если только учесть:
- хром браузер
- Linux-сервер
- Сделать HTML-запрос
- Не учитывает никаких механизмов кэширования и оптимизации
- Принять протокол HTTP/1.1 + TLS/1.2 + TCP
Процесс выглядит следующим образом:
Процесс разрешения DNS
Сначала браузер инициирует запрос к локальному DNS-серверу. Поскольку локальный DNS-сервер не имеет кеша, он не может напрямую преобразовать доменное имя в IP-адрес. Необходимо использовать рекурсивный или итеративный метод запроса (рис. 3). , Сервер инициирует запрос запроса до тех пор, пока не найдет один или группу IP-адресов и не вернет их в браузер. Как правило, локальный DNS-адрес динамически назначается интернет-провайдером (интернет-провайдером) через протокол DHCP. Мы по-прежнему можем вручную изменить его на общедоступный DNS, например 8.8.8.8, предоставляемый Google, и 114.114.114.114 в Китае. распределены в разных географических точках, с помощью Технология Anycast, которая направляет запросы на ближайший к пользователю DNS-сервер. Чтобы сделать разрешение DNS более точным, клиенту также необходимо указать свой собственный исходный IP-адрес в пакете запроса, иначе DNS-сервер, такой как GSLB, не сможет точно сопоставить целевой IP-адрес, ближайший к пользователю.
Процесс HTTP-запроса
Поскольку HTTP основан на более удобочитаемом текстовом формате, помимо инициирования HTTP непосредственно в браузере, вы также можете использовать командную строкуtelnetУстановить TCP-соединение с указанным портом сервера и отправить заголовок запроса и объект запроса в соответствии с форматом, указанным протоколом. Кроме того, если вы хотите просмотреть подробное и конкретное содержимое пакетов, вы можете использовать инструмент анализа сетевых пакетов Wireshark или командную строкуtcpdump, для захвата пакетов на сетевую карту. На предыдущем шаге, после того как мы получили IP-адрес сервера через DNS-разрешение, браузер вызывает интерфейс Socket к серверу через систему 443.
Весь процесс можно разделить на пять частей: установление соединения, отправка HTTP-запроса, возврат HTTP-ответа, поддержание соединения и разрыв соединения (рис. 4). Стрелка, показанная на рисунке, может представлять сегмент TCP или полный пакет прикладного уровня.В фактическом процессе передачи он будет объединен в один или фрагментирован на несколько сегментов TCP.
установить соединение
- Прежде чем соединение будет установлено, сервер должен быть готов принять соединение и выполнить задачи по привязке IP-адреса общедоступной сети, прослушиванию порта 443 и принятию запроса, вызвав четыре функции сокета, привязки, прослушивания и принятия.
- Клиент активно открывает соединение через функции socket и connect, отправляет пакет с флагом SYN на сервер, случайным образом генерирует начальный порядковый номер x и прикрепляет дополнительную информацию, такую как MSS (Maximum Segment Size, максимальный размер сегмента). Чтобы избежать фрагментации протоколом IP на сетевом уровне, что увеличивает вероятность ошибок с потерями и обеспечивает наилучший эффект передачи, значение MSS обычно представляет собой значение Ethernet MTU (максимальная единица передачи) за вычетом заголовка IP. .и размер заголовка TCP, равный 1460 байтам.
- Сервер должен подтвердить получение пакета клиента, отправить пакет с битом флага SYN+ACK, случайным образом сгенерировать начальный порядковый номер y, номер подтверждения — x+1 и дополнительную информацию, такую как MSS. Когда один конец получает значение MSS другого конца, он определяет последующий максимальный размер сегмента TCP в соответствии с минимальным значением MSS из двух.
- Клиент подтверждает, что он получил пакет от сервера, и отправляет пакет с флагом ACK и номером подтверждения y+1, тем самым устанавливая TCP-соединение.
- Если клиент ранее не устанавливал сеанс с сервером, обе стороны должны выполнить полное четырехстороннее рукопожатие TLS. Сначала клиент отправляет на сервер пакет Client Hello, который содержит случайное число, версию протокола TLS и список наборов шифров, отсортированных по приоритету.
- Сервер отправляет клиенту пакет Server Hello, содержащий новое случайное число, версию протокола TLS и выбранный набор шифров.
- Сервер отправляет клиенту сообщение сертификата, включая цепочку сертификатов сервера X.509, где первым является первичный сертификат, промежуточный сертификат следует за первичным сертификатом по порядку, а корневой сертификат ЦС обычно встроен в операционную систему или браузер, отправка на сервер не требуется.
- Если для обмена ключами выбран алгоритм DH, сервер отправит клиенту сообщение Server Key Exchange, включая параметры DH, необходимые для обмена ключами; если для обмена ключами выбран алгоритм RSA, пропустите этот шаг.
- Сервер отправляет клиенту сообщение Server Hello Done, указывающее, что все сообщения квитирования отправлены.
- Клиент отправляет серверу сообщение Client Key Exchange. Если для обмена ключами выбран алгоритм RSA, клиент сгенерирует предварительный мастер-ключ и зашифрует его с помощью открытого ключа в сертификате сервера. Если он включен в сообщение, серверу нужно использовать только свой собственный Предмастер-ключ можно извлечь, расшифровав закрытый ключ клиента; если для обмена ключами выбран алгоритм DH, клиент включит в сообщение свои собственные параметры DH, и то обе стороны будут вычислять один и тот же предварительный мастер-ключ в соответствии с алгоритмом DH. Следует отметить, что обмен ключами является только предварительным мастер-ключом. Это значение необходимо дополнительно обработать. В сочетании с двумя начальными числами случайных чисел клиента и сервера обе стороны используют PRF (псевдослучайная функция, псевдослучайная функция). функция) для создания одного и того же мастер-ключа.
- Клиент отправляет на сервер сообщение Change Cipher Spec, указывающее, что главный ключ сгенерирован, и этот главный ключ используется для симметричного шифрования сообщения в последующем процессе передачи.
- Клиент отправляет на сервер сообщение Finished, которое зашифровано, поэтому Wireshark показывает сообщение Encrypted Handshake Message. Если сервер может расшифровать содержимое сообщения, это означает, что мастер-ключи, сгенерированные обеими сторонами, одинаковы.
- Сервер отправляет клиенту сообщение «Новый билет сеанса», и этот билет сеанса может быть расшифрован только сервером.Клиент сохраняет его и приносит с собой в последующем процессе повторного установления связи TLS для быстрого восстановления сеанса, уменьшая количество раундов. задержка поездки.
- Сервер отправляет клиенту сообщение Change Cipher Spec, в котором также указывается, что мастер-ключ сгенерирован и используется для симметричного шифрования сообщения в последующем процессе передачи.
- Сервер отправляет клиенту сообщение Finished.Если клиент может расшифровать содержимое сообщения, это означает, что мастер-ключи, сгенерированные обеими сторонами, одинаковы. На этом все переговоры о рукопожатии завершены.
отправить HTTP-запрос
После установления безопасного зашифрованного канала браузер начинает отправлять HTTP-запросы.Сообщение запроса состоит из строки запроса, заголовка запроса, пустой строки и сущности (запрос Get отсутствует). Заголовок запроса состоит из общего заголовка, заголовка запроса, заголовка объекта и заголовка расширения. Среди них общий заголовок указывает, что можно использовать как сообщение запроса, так и сообщение ответа, например Дата; заголовок запроса указывает, что он имеет смысл только в сообщении запроса, которое разделено на заголовок Accept, заголовок условного запроса , заголовок запроса безопасности и заголовок запроса прокси.Эти четыре категории: заголовок объекта воздействует на содержимое объекта и делится на две категории: заголовок контента и заголовок кеша; заголовок расширения представляет собой определяемый пользователем заголовок черезX-префикс добавить. Еще одна вещь, которую следует отметить, это то, что HTTP
Заголовок запроса нечувствителен к регистру, он кодируется на основе ASCII, в то время как сущность может быть основана на других кодировках,Content-TypeПринимать решение.
вернуть HTTP-ответ
Сервер принимает и обрабатывает запрос и возвращает ответ HTTP.Формат сообщения ответа в основном такой же, как и у сообщения запроса, которое состоит из строки ответа, заголовка ответа, пустой строки и объекта. В отличие от заголовка запроса, заголовок ответа имеет собственный набор заголовков ответа, таких как Vary, Set-Cookie и другие общие заголовки, заголовки объектов и заголовки расширений являются общими. Кроме того, браузер и сервер должны обеспечивать порядок передачи HTTP, а порядок запросов/ответов в очередях, поддерживаемых каждым из них, должен соответствовать один к одному, иначе возникнут ошибки вне очереди.
оставаться на связи
После выполнения HTTP-запроса сервер не сразу отключается от клиента. В HTTP/1.1,Connection: keep-aliveОн включен по умолчанию, что указывает на постоянное соединение, чтобы обрабатывать новые запросы, поступающие в ближайшем будущем, без необходимости повторного установления соединения и увеличения служебных данных медленного запуска и повышения пропускной способности сети. В программном обеспечении обратного прокси Nginx значение тайм-аута постоянного соединения по умолчанию составляет 75 секунд, если в течение 75 секунд не будет нового запроса, соединение с клиентом будет разорвано. В то же время браузер будет каждые 45 секунд отправлять на сервер пакеты проверки активности TCP, чтобы оценить состояние TCP-соединения.
Ответ ACK, затем активно отключитесь от сервера. Обратите внимание, что хотя HTTP keep-alive и TCP keep-alive являются механизмами проверки активности, они совершенно разные: один действует на прикладном уровне, а другой — на транспортном уровне.
Отключить
- Сервер отправляет клиенту сообщение Alert типа Close Notify, уведомляя клиента о том, что он больше не будет отправлять данные и закроет соединение.Также это сообщение также зашифровано.
- Сервер активно закрывает соединение, вызывая функцию закрытия, и отправляет клиенту пакет с флагом FIN и порядковым номером m.
- Клиент подтверждает, что пакет получен, и группа отправляется на сервер с пакетом флага ACK, и число подтверждения равно m + 1.
- После того, как клиент отправил все данные, он отправляет на сервер пакет с флагом FIN, порядковый номер которого равен n.
- Сервер подтверждает получение пакета и отправляет клиенту пакет с флагом ACK, порядковый номер n+1. После того, как клиент получает пакет подтверждения, он сразу переходит в состояние CLOSED, при этом сервер ждет 2 MSL (Maximum Segment Lifetime, максимальное время жизни сообщения), а затем переходит в состояние CLOSED.
Процесс парсинга в браузере
Современный браузер — это огромная часть программного обеспечения, в некотором роде не меньше, чем операционная система, состоящая из поддержки мультимедиа, отображения графики, рендеринга графического процессора, управления процессами, управления памятью, песочницы, систем хранения, сетей. Управление сотнями компонентов разного размера. . Хотя разработчикам не нужно заботиться о базовых деталях реализации при разработке веб-приложений, им нужно только доставить код страницы в браузер для вычислений для отображения расширенного содержимого. Но производительность страницы зависит не только от реализации браузера, но и от уровня разработчика, знакомства с инструментом, а оптимизация кода бесконечна. Очевидно, что понимание основных принципов работы браузеров, технических стандартов W3C, сетевых протоколов, а также проектирование и разработка высокопроизводительного веб-приложения Приложение очень помогает.
Когда мы используем браузер Chrome, движок, стоящий за ним, — это проект Google Chromium с открытым исходным кодом, а ядром Chromium является движок рендеринга Blink (на основе Webkit) и движок JavaScript V8. Прежде чем объяснять, как браузеры анализируют HTML-файлы, давайте кратко представим многопроцессорную многопоточную архитектуру Chromium (рис. 5), которая включает в себя несколько процессов:
- процесс браузера
- Несколько процессов визуализации
- процесс графического процессора
- Несколько процессов рендеринга NPAPI
- Несколько процессов плагина Pepper
И каждый процесс включает в себя несколько потоков:
- основной поток
- В процессе браузера: рендеринг интерфейса обновления
- В процессе рендеринга: используйте удерживаемый экземпляр ядра Blink для разрешения интерфейса обновления рендеринга.
- поток ввода-вывода
- В процессе браузера: обрабатывает связь IPC и сетевые запросы.
- В процессе визуализации: обрабатывает связь IPC с процессом браузера.
- набор выделенных потоков
- общий пул потоков
Chromium поддерживает множество различных способов управления процессами рендерера, не только каждой открытой вкладкой, но и страницами iframe.Каждый процесс рендерера представляет собой независимую песочницу, которая изолирована друг от друга.
- Процесс для экземпляра сайта: запуск процесса для каждого доменного имени, и новые страницы, открытые по ссылке на страницу, совместно используют процесс (за исключением атрибута noopener), который является режимом по умолчанию.
- Процесс для каждого сайта: запуск процесса для каждого доменного имени
- Процесс на вкладке: запуск процесса на странице вкладки
- Один процесс: все страницы совместно используют процесс
Когда процессу визуализации необходимо получить доступ к модулю сетевых запросов (XHR, Fetch) и системе хранения (синхронное локальное хранилище, синхронное хранилище файлов cookie, асинхронное хранилище файлов cookie), он вызывает глобальный объект RenderProcess для установления канала IPC с объектом RenderProcessHost в Браузерный процесс через IO thread, нижний слой реализован через socketpair. Благодаря этому механизму Chromium может лучше управлять ресурсами и планировать их унифицированным образом, эффективно снижая нагрузку на сеть и производительность.
основной процесс
Работа по синтаксическому анализу страницы выполняется в процессе Renderer.Процесс Renderer анализирует содержимое HTML при получении через экземпляр Blink, хранящийся в основном потоке (рис. 6), и каждый раз считывает данные в пределах 8 КБ из сетевого буфера. Браузер анализирует содержимое HTML построчно сверху вниз и строит DOM-дерево после лексического и синтаксического анализа. При обнаружении внешних ссылок CSS основной поток вызывает модуль сетевых запросов для асинхронного получения ресурсов и продолжает строить дерево DOM без блокировки. После загрузки CSS основной поток анализирует содержимое CSS в нужное время и строит дерево CSSOM после лексического и синтаксического анализа. Привязка браузера к DOM
Дерево и дерево CSSOM строят дерево рендеринга и вычисляют свойства макета, геометрические свойства каждого узла и положение в системе координат, и, наконец, рисуют и отображают его на экране. При обнаружении внешней ссылки JS основной поток вызывает модуль сетевых запросов для асинхронного получения ресурсов.Поскольку JS может изменять дерево DOM и дерево CSSOM и вызывать перекомпоновку и перерисовку, построение дерева DOM в это время заблокировано. Тем не менее, основной поток не будет приостановлен, браузер будет использовать облегченный сканер для поиска внешних ресурсов, которые необходимо загрузить позже, и заранее инициировать сетевые запросы, но ресурсы внутри скрипта не будут распознаны, такие какdocument.write. когда
После загрузки JS браузер вызывает механизм V8 для анализа и компиляции содержимого JS в потоке Script Streamer и выполнения его в основном потоке (рис. 7).
процесс рендеринга
Когда DOM-дерево готово, также необходимо пройти несколько преобразований, и они имеют множество промежуточных представлений (рисунок 8). Сначала рассчитайте компоновку, стиль рисования и преобразуйте в дерево объектов рендеринга (также называемое деревом рендеринга). Преобразуйте в RenderLayer Tree, когда у renderObject одинаковая система координат (такая как Canvas, Absolute), они сольются в renderLayer, который отвечает за CPU. Затем конвертируйте в дерево GraphicsLayer, когда рендерлей удовлетворяет условию синтетического слоя (например, Transform, аппаратное ускорение ускоряется), у него будет свой собственный GraphicsLayer, в противном случае слияние с родительским узлом, этот шаг также выполняется процессором. Наконец, каждый GraphicsLayer имеет объект GraphicsContext, который отвечает за отрисовку растрового изображения в виде текстуры для графического процессора, который отвечает за синтез нескольких текстур графическим процессором, которые в конечном итоге отображаются на экране.
Кроме того, для повышения эффективности рендеринга браузер будет иметь выделенный поток Compositor, который будет отвечать за композицию слоев (рис. 9), а также обрабатывать некоторые интерактивные события (например, прокрутку, касание) и напрямую реагировать на обновления пользовательского интерфейса. без блокировки основного потока. Основной поток синхронизирует дерево RenderLayer с потоком Compositor, который запускает несколько потоков Rasterizer, выполняет обработку растеризации, преобразует данные вершин во фрагменты в видимой области в единицах тайлов и, наконец, доставляет их в GPU для окончательного композитного рендеринга.
жизненный цикл страницы
Страница начинается с инициирования запроса и заканчивается переходом, обновлением или закрытием, она будет проходить через множество изменений состояния и уведомлений о событиях, поэтому необходимо понимать жизненный цикл всего процесса. браузер предоставляетNavigation Timingа такжеResource TimingСуществует два API для регистрации времени возникновения события каждого ресурса.Вы можете использовать его для сбора данных RUM (Real User Monitoring, мониторинг реальных пользователей), отправки их в серверную службу мониторинга и всестороннего анализа производительности страницы для постоянно улучшать пользовательский опыт. На рис. 10 показан весь процесс записи события загрузки HTML-ресурса, а средняя желтая часть представляет собой процесс записи события загрузки других ресурсов (CSS, JS, IMG, XHR), и все они могут быть записаны вызовомwindow.performance.getEntries()для получения конкретных индикаторных данных.
Есть много способов измерить производительность страницы, но что дает пользователям непосредственное ощущение, так это то, когда страница визуализируется, интерактивна и загружается. Среди них есть два очень важных события жизненного цикла: событие DOMContentLoaded указывает на то, что дерево DOM построено и все узлы Node, события привязки и т. д. дерева DOM доступны для безопасного доступа, событие загрузки указывает на то, что все ресурсы были загружены, изображения, фоны и содержимое. Все было обработано, и страница находится в интерактивном состоянии. Но до сих пор браузеры не могли полностью контролировать состояние приложения, как приложения для Android и iOS: при переключении между фронтом и бэком ресурсы перераспределяются, а память используется разумно. На самом деле, современные браузеры уже делают эту оптимизацию, а поскольку Доступно в Chrome 68 и более поздних версиях.Page LifecycleAPI, определяющий новый жизненный цикл браузера (рис. 11), позволяющий разработчикам создавать более качественные приложения.
Теперь вы можете сделать это, предоставивwindowа такжеdocumentПривяжите все события мониторинга жизненного цикла (рис. 12) для отслеживания процесса изменения состояния, вызванного переключением страниц и взаимодействием с пользователем. Однако разработчики могут только воспринимать, когда происходит событие, и не могут напрямую получить состояние страницы в определенный момент (СОСТОЯНИЕ на рис. 11). Тем не менее, этот API позволяет сценариям выполнять задачу или предоставлять обратную связь пользовательскому интерфейсу в нужный момент.
Суммировать
Из-за ограниченного объема эта статья не является большим и всеобъемлющим сборником интервью, в ней представлены лишь некоторые ключевые пути и точки знаний, а также в начале упоминается, что на сам вопрос нет стандартного ответа. Так же в статье много мест не проанализированных глубоко.Одно слишком отклоняется от темы,а другое ограничено личными возможностями,такими как правила кодирования,алгоритмы шифрования,алгоритмы дайджеста,алгоритмы маршрутизации,алгоритмы сжатия,протокол стандарты, механизмы кэширования, принципы V8, принципы GPU и т. д. Подождите. Если вы хотите досконально разобраться в технических деталях и принципах каждой части, вы можете обратиться к другим книгам, материалам и исходному коду.
⚠️Наконец, будьте осторожны, чтобы не упасть.
использованная литература
- UNIX Network Programming Volume 1: Sockets API
- Сетевое программирование UNIX, том 2: Межпроцессное взаимодействие
- Полное руководство по HTTP
- Полное руководство по HTTPS
- Инсайдер технологии WebKit
- Объяснение TCP/IP, том 1: Протоколы
- инфраструктура балансировки нагрузки
- Четыре уровня балансировки нагрузки Высокая доступность SLB
- Многоактивное решение для удаленной базы данных
- Dissecting TLS Using Wireshark
- How Browsers Work
- Multi-process Architecture
- How Blink works
- Life of a Pixel 2018
- Multi-process Resource Loading
- Process Models
- How Chromium Displays Web Pages
- Threading and Tasks in Chrome
- V8 Background Compilation
- JavaScript engine fundamentals
- Compositor Thread Architecture
- GPU Accelerated Compositing in Chrome
- Page Lifecycle API
- Web Fundamentals