Bazel 系统实现为长时间运行的服务器进程。这样一来,它就可以执行许多批处理实现无法实现的优化,例如将一个 build 中的 BUILD 文件、依赖关系图和其他元数据缓存到下一个 build 中。这提高了增量构建的速度,并允许 build
和 query
等不同命令共享已加载软件包的同一缓存,从而使查询速度非常快。每个服务器一次最多只能处理一个调用;进一步的并发调用将阻塞或快速失败(请参阅 --block_for_lock
)。
运行 bazel
时,您运行的是客户端。客户端会根据输出库查找服务器,默认情况下,输出库由基本工作区目录的路径和您的用户 ID 确定,因此如果您在多个工作区中进行构建,则会有多个输出库,从而有多个 Bazel 服务器进程。同一工作站上的多个用户可以在同一工作区中同时进行 build,因为他们的输出库会不同(不同的用户 ID)。
如果客户端找不到正在运行的服务器实例,则会启动一个新实例。为此,它会检查输出库是否存在,如果存在,则表示 blaze 归档已解压缩。否则,如果输出库不存在,客户端会解压缩归档文件,并将其 mtime
设置为未来 9 年的日期。安装完成后,客户端会确认解压缩文件的 mtime
是否等于遥远的未来日期,以确保未发生安装篡改。
服务器进程会在一段时间不活动后停止(默认情况下为 3 小时,可以使用启动选项 --max_idle_secs
修改)。在大多数情况下,用户看不到服务器正在运行,但有时记住这一点会有所帮助。例如,如果您运行的脚本会在不同目录中执行大量自动化 build,请务必确保不会累积大量空闲服务器;为此,您可以在完成服务器操作后明确将其关闭,也可以指定较短的超时时间段。
在 ps x
或 ps -e f
的输出中,Bazel 服务器进程的名称显示为 bazel(dirname)
,其中 dirname 是封装工作区目录根目录的目录的基本名称。例如:
ps -e f
16143 ? Sl 3:00 bazel(src-johndoe2) -server -Djava.library.path=...
这样一来,您就可以更轻松地确定哪个服务器进程属于给定的工作区。(请注意,如果 ps
使用某些其他选项,Bazel 服务器进程可能仅命名为 java
。)可以使用 shutdown 命令停止 Bazel 服务器。
运行 bazel
时,客户端会先检查服务器是否为相应版本;如果不是,则停止服务器并启动新服务器。这样可确保长时间运行的服务器进程不会干扰正常的版本控制。