科技,  计算机,  随想

从输入URL到页面展示

从输入URL到页面展示,这期间发生了什么?这是一道经典的面试题,标准答案如下:

  1. 输入URL
  2. 浏览器查找域名的 IP 地址 查找顺序 host文件->本地的DNS服务器->DNS根服务器->域服务器
  3. 浏览器向 web 服务器发送一个 HTTP 请求,建立TCP连接
  4. 服务器处理请求,返回一个 HTTP 响应
  5. 返回HTML网页,浏览器渲染显示网页
  6. 浏览器发送请求获取嵌入在 HTML 中的资源(如图片、音频、视频、CSS、JS等等)

但是,答案深度并不止于此。例如,当我们使用edge浏览器访问www.baidu.com,浏览器内部和百度服务器内部是如何对请求进行处理的呢?

有幸的是,本人恰好在百度做过后端研发并且在微软做过edge浏览器的开发,刚好有资格解答这两个问题。

浏览器

启动浏览器时,浏览器会启动多个进程,每个进程又有多个线程。浏览器的主进程(Browser process)和其他的进程是隔离的,主进程负责管理其他进程,utility进程负责发送接收请求,render进程负责渲染页面。即便某个进程崩溃,主进程也不会受到影响。

进程类型

打开一个标签页,每个标签页都对应一个独立的进程。访问某个网站,同一域名下的多个标签页可能会由于资源的复用而共用同一个进程。

Chrome的任务管理器

网页的本质是HTML文档,浏览器负责解析HTML文档。浏览器内部的每个render进程会对应一个或者多个page(tab),一个tab对应多个frame,每个frame对应一个Document、对应一个JavaScript里的window.document对象。以这样的顺序层层解析,最后通过Blink、V8引擎来渲染页面。

浏览器的渲染过程

每个进程都有一个主线程和IO线程。进程之间采用IPC(InterProcess Communication)进行通信。程序员通过mojom或idl的接口定义语言(类似protobuf)预先定义接口,通过接口进行通信。IPC会编译出很多底层文件,在不同的进程中继承这些文件,创建发送端和接收端的变量,就可以进行通信了。

浏览器架构

每个页面都需要浏览器引擎的渲染。渲染引擎Blink由一个主线程,N个工作线程和几个内部线程组成。所有重要的事情都发生在主线程中,如JavaScript(除了worker)、DOM、CSS、样式和布局计算。对于跨线程通信,必须使用PostTask api(也就是闭包)来使用消息传递。也可以通过线程池中手动设置线程的优先级来启动线程。

进程通过管道、函数指针进行通信,相比共享内存的优点就是减少等待,进程通信通过闭包的方式将函数指针传给另一个进程,接收方的进程执行完后将返回的结果传入函数指针中,再启动线程执行预先定义好的操作。出于对并发的要求,可能上一个进程的函数还没有执行完,下游的进程就已经开始工作了。

浏览器内部的RPC调用,出于安全和隔离的考虑,一般放在utility进程中。比如我们做钱包的时候用到的bloom filter、白名单服务、上链操作、KEK云端备份、MFA登录验证等操作,都会和微软的内部服务交互。微软的服务部署在Azure云上,浏览器发出的请求实际上会发送到Azure服务器上的后端服务。

存储方面,浏览器的数据存在内存、数据库、TPM以及本地文件中。C++里的类变量都会保存在内存中;数据库使用SQLite,将数据持久化的存储在一个本地文件中;TPM是一种硬件加密的芯片,提供加解密的功能以及基本的存储,用于保存密码等;用户配置会保存在本地文件preference等。

总而言之,浏览器是一个客户端。程序员在本地编写C/C++的底层代码,代码经过编译后在Windows、Linux、Android、ARM、x86、x64等多个平台和架构上运行。新的功能随新版本发布后,经过逐步的给用户放量,成千上万的用户就能使用到浏览器的新功能。浏览器作为公司基建,给公司带来盈利。

服务器

百度内部请求流转

用户在各种设备、平台上使用百度,例如PC端、手机百度App、小程序。尽管页面展示方式不同,但是对于服务器来说,本质是一样的,都是http请求。

首先,DNS会解析baidu的域名,得到对应的IP。DNS会根据配置的NS记录、CNAME、A记录得到对应的IP。百度内部有大量服务器,百度内部会对IP进行复用,对外只暴露一个VIP。

DNS解析配置

随后,请求会到达BGW百度网关,根据不同的应用层信息将请求转发给不同的服务,到达BFE百度统一前端,然后会达到inrouter接入层,用作BFE和业务服务器的反向代理、负载均衡,根据uri和host进行转发和分流。最后会达到业务线,根据不同的服务和模块到达具体的实例。

服务器会执行我们编写的业务代码,执行业务逻辑,访问各种数据库(MySQL Doris DDBS)、缓存(Redis memcache)、RPC服务和中间件。同时,部署在每台服务器的Minos会采集服务器的日志和状态,生成监控和打点信息,经过队列资源的计算和存储,生成离线报表和报警,对业务进行监控。

在业务部门的每台服务器上,都部署着PHP脚本(也可能是java或者go)。每种语言都有各自的优化空间。Java是JVM的参数,Go语言可能是GC和协程,PHP是PHP-FPM。PHP-FPM中,master进程负责与 Web 服务器进行通信,接收 HTTP 请求,再将请求转发给 worker 进程进行处理,worker进程主要负责动态执行 PHP 代码,处理完成后,将处理结果返回给 Web 服务器。

PHP-FPM(FastCGI Process Manager)
springMVC请求流程

百度背靠搜索资源,垂类社区流量大部分来源于大搜,从搜索页、阿拉丁卡片到达我们的垂类页面,称之为自然流量。每天都有几亿的人使用百度。用户从搜索、到垂类社区、到信息展示完成了一个消费闭环,百度就这样从中赚取广告费。

参考文档

ChromeDoc

Mojom绑定API

Blink

一文看懂Chrome

最后更新于 2024年6月19日 by qlili

0 0 votes
Article Rating
guest

1 Comment
Newest
Oldest Most Voted
Inline Feedbacks
View all comments
1
0
Would love your thoughts, please comment.x
()
x