3. 启动 HAProxy
HAProxy 通过在命令行中传入若干参数来调用 “haproxy” 程序启动。实际语法如下:
其中 [<options>]* 为任意数量的选项。每个选项均以 ‘-’ 开头,后接一个或多个字母,可选地跟随一个或多个额外参数。若未指定任何选项,HAProxy 将显示帮助页面,并提示支持的选项。可用选项可能因操作系统略有差异。其中相当一部分选项与 “global” 段中的等效选项重叠。在此情况下,命令行选项始终优先于配置文件,以便可通过命令行快速强制设置,而无需修改配置文件。当前选项列表如下:
-- <cfgfile>*
所有紧跟 “–” 之后的参数均为需按声明顺序加载和处理的配置文件/目录路径。该选项在依赖 shell 加载按数字顺序排列的多个文件时尤为有用。参见 “-f”。"–" 与 “-f” 的区别在于,"-f" 必须置于每个文件名之前,而 “–” 仅需置于所有文件名之前一次即可。两个选项可同时使用,命令行顺序仍适用。当指定多个文件时,每个文件必须从段边界开始,因此每个文件的第一个关键字必须为 “global”、“defaults”、“peers”、“listen”、“frontend”、“backend” 等之一。文件不能仅包含服务器列表。
-f <cfgfile|cfgdir>
将 <cfgfile> 添加到要加载的配置文件列表中。若 <cfgdir> 为目录,则其包含的所有文件(仅文件)按字典序(使用 LC_COLLATE=C)添加到要加载的配置文件列表中;仅扩展名为 “.cfg” 的文件会被添加,且不包含以 “.” 开头的隐藏文件。配置文件按声明顺序加载并处理。此选项可多次指定,以加载多个文件。另见 “–"。”–" 与 “-f” 的区别在于,前者需在每个文件名前放置一个 “-f”,而后者仅需在所有文件名前放置一个 “–"。两者可同时使用,命令行顺序仍适用。当指定多个文件时,每个文件必须从段边界开始,因此每个文件的第一个关键字必须为 “global”、“defaults”、“peers”、“listen”、“frontend”、“backend” 等之一。例如,文件不能仅包含服务器列表。
-C <dir>
在加载配置文件前更改目录 <dir>。这在使用相对路径时很有用。请注意,使用通配符时需谨慎,尤其是在 “–” 之后,因为这些通配符实际上会在启动 HAProxy 前由 shell 替换。
-D
以守护进程模式启动。进程在 fork 后与当前终端分离,错误信息将不再在终端中输出。这等价于配置文件中 “global” 段的 “daemon” 关键字。建议在任何初始化脚本中始终强制启用此项,以确保配置错误不会阻止系统启动。
-L <name>
将本地对等节点名称更改为 <name>,默认值为本地主机名。此设置仅在对等节点复制时使用。可在配置文件中使用变量 $HAPROXY_LOCALPEER 来引用对等节点名称。
-N <limit>
将每个代理的默认 maxconn 设置为 <limit>,而非内置默认值(通常为 2000)。
仅用于调试。
-V
启用详细模式(禁用安静模式)。恢复 “-q” 或 “quiet” 的效果。
-W
主进程/工作进程模式。该模式等效于配置文件中 “global” 段的 “master-worker” 关键字。此模式将启动一个 “master”,用于监控 “workers”。使用该模式时,可通过向主进程发送 SIGUSR2 信号直接重载 HAProxy。主进程/工作进程模式与前台运行或守护进程模式均兼容。建议在多进程模式下配合 systemd 使用此模式。
-Ws
主进程/工作进程模式,支持 notify 类型的 systemd 服务。
-4
强制 DNS 解析器仅查询并接受 IPv4 地址(“A” 记录)。当在缺乏端到端双栈连接能力的环境中遇到困难时,可使用此选项。该设置会覆盖全局 “dns-accept-family” 指令,并强制其设置为 “ipv4”。
-c
仅检查配置文件并退出,不会尝试绑定。若一切正常,退出状态码为零;若遇到错误,则为非零值。若存在警告,将予以报告。默认情况下,此选项不会输出成功消息。与 “-V” 联用时,成功将输出消息“配置文件有效”。
脚本必须使用退出状态来判断命令执行是否成功。
-cc
在配置的条件块中评估一个条件。若条件为真,退出状态为 0;若条件为假,退出状态为 1;若遇到错误,退出状态为 2。
-d
启用调试模式。此模式会禁用守护进程模式,强制进程在前台运行,并显示进出事件。此模式在初始化脚本中绝不可使用。
-dA[file]
在配置加载完成后,立即将启动时检测到的所有依赖项归档为 tar 格式的指定文件, 此操作等同于 “set-dumpable libs”,但不同于将库保留在内存中,而是将其转储到文件中。 此功能可在生成核心转储后使用,以便向开发者提供所有必要库,从而允许其利用核心转储进行分析。 并非所有操作系统均支持此功能。强烈建议与常规配置文件配合使用,当手动执行时可选择性地配合 “-c”, 以确保 HAProxy 在完成转储后立即退出,而不启动服务。示例:
-dC[key]
转储配置文件。该操作在行被分词后执行,因此注释将被移除,缩进将被强制处理。若指定了非零密钥,则在敏感/机密字段前截断行,并使用与 CLI 匿名模式相同的算法,以该密钥对标识符和地址进行哈希处理后输出。这意味着输出可安全地与需要分析使用相同密钥匿名化转储内容的开发者共享。请参阅 CLI 的“set anon”命令。
-dD
启用诊断模式。此模式将输出关于可疑配置语句的额外警告。即使在 “zero-warning” 模式下,也不会阻止启动,也不会更改退出状态码。
-dF
禁用数据快速转发。该机制通过直接在侧边之间传递数据而不唤醒流来优化数据转发。通过此指令,可禁用此优化。请注意,该指令同时也会禁用任何内核 TCP 拼接功能。此命令并非用于常规使用,通常仅在复杂调试会话中由开发人员建议使用。
-dG
禁用使用 getaddrinfo() 将主机名解析为地址。当怀疑 getaddrinfo() 未能按预期工作时,可以使用此选项。该选项的提供是因为多种系统上存在大量错误实现的 getaddrinfo(),导致难以排查的异常情况。
-dI
启用不安全的 fork。这等效于全局段中的 “insecure-fork-wanted”。在使用 ASAN 运行所有回归测试时,可能需要 fork addr2line 以解析地址,此时该选项较为有用。
-dK<class[,class]*>
输出每个类别中注册的关键词列表。类别列表可通过 “-dKhelp” 获取。可使用 “-dKall” 输出所有类别,否则可指定帮助信息中列出的类别,以逗号分隔。输出格式会因所导出的关键词类别不同而异(例如 “cfg” 将以类似配置文件格式显示已知的配置关键词,而 “smp” 将显示以每个规则集的兼容性矩阵为前缀的样本提取函数)。这些输出通常不会由人工直接使用,但对尝试检测特定位置新关键词出现的外部工具而言,可极大协助自动更新文档、语法高亮文件、配置解析器、API 等。输出格式可能随时间略有变化,因此强烈建议主要将此输出用于与先前存档进行差异检测。请注意,并非所有关键词均被列出,因为许多关键词在不同关键词注册子系统创建之前就已存在,因此不会出现在其中。然而,由于新关键词仅通过现代机制添加,因此可以合理地认为该输出可用于高精度检测语言扩展。关键词仅在配置完全解析后才被导出,因此即使动态创建的关键词也可被导出。一种有效的导出并退出方式是针对现有配置运行静默配置检查:
若无配置文件可用,使用 “-f /dev/null” 也可输出所有默认关键字,但返回状态将不为零,因为此时不存在监听器,该状态必须被忽略。
-dL
输出已加载的动态共享库列表,该列表在配置处理结束时生成。通常,该列表还会包含深层依赖项,例如从 Lua 代码加载的任何内容,以及可执行文件本身。输出格式应便于直接清理并生成所有依赖项的归档包。由于该操作不会阻止程序启动,建议仅与 “-c” 和 “-q” 一同使用,此时仅显示已加载对象的列表(或在出错时无输出)。此外请注意,当提供此类包以协助核心转储分析时,大多数库实际上是符号链接,创建归档包时需解引用这些链接。
以详细模式启动时(-V),除非处于静默模式(-q),否则还会枚举共享库的地址范围。
-dM[<byte>[,]][help|options,...]
强制内存填充,或更改其他调试选项。内存填充指使用 malloc() 或 pool_alloc() 分配的每个内存区域在传递给调用方之前均会被填充为 <byte>。当未指定 <byte> 时,其默认值为 0x50(‘P’)。尽管这会略微降低操作性能,但有助于可靠地触发因代码中遗漏初始化而导致的随机崩溃问题。请注意,-dM0 的作用是将任何 malloc() 调用变为 calloc()。无论何种情况,若启用此选项后出现或消失的缺陷,均表明 HAProxy 存在缺陷,请务必报告。其他若干选项可单独使用,或在字节值后以逗号分隔使用。特殊选项 “help” 将列出当前支持的选项及其当前值。每个调试选项均可强制开启或关闭。通常情况下,最优化选项会在构建时根据操作系统自动选择,无需调整,除非开发者建议。支持的调试选项包括(设置/清除):
- fail / no-fail:
- no-merge / merge:
- 冷优先 / 热优先:
- integrity / no-integrity:
- backup / no-backup:
- no-global / global:
- no-cache / cache:
- caller / no-caller:
- 标签 / 无标签:
- poison / no-poison:
-dR
在监听端口上禁用 SO_REUSEPORT 套接字选项。这等价于 “global” 段中的 “noreuseport” 关键字。在多线程场景下,当观察到 HAProxy 线程间负载分配不均时,可应用此配置(可通过 top 监控)。
-dS
禁用 splice() 系统调用。其效果等同于 “global” 段中的 “nosplice” 关键字。当怀疑 splice() 行为异常或导致性能问题,或使用 strace 查看转发数据(使用 splice() 时数据不会出现)时,可以使用此选项。
-dT
禁用 kTLS 的使用。其效果等同于 “global” 段中的关键字 “noktls”。当怀疑存在与 kTLS 相关的缺陷时,此选项尤为有用。
-dV
在服务器端禁用 SSL 验证。这等效于在 “global” 段中设置 “ssl-server-verify none”。当需要在生产环境之外复现生产环境问题时,此选项非常有用。切勿在初始化脚本中使用,因为它会降低服务器的 SSL 安全性。
-dW
若设置,HAProxy 在处理配置时若发出任何警告,将拒绝启动。 这有助于发现细微错误,并保持配置在不同版本间的一致性与可移植性。 建议在由人工管理配置的服务脚本中设置此选项,但不建议在生成的配置中使用,因为生成的配置通常会发出更多警告。 可与 “-c” 结合使用,使检查配置中的警告导致失败。这等效于全局选项 “zero-warning”。
-dZ
在 “zero-copy” 模式下禁用数据转发。这等效于 “global” 段中的 “tune.disable-zero-copy-forwarding” 关键字。当出现数据丢失或数据完整性问题,或使用 strace 查看转发数据时,此选项可能有所帮助,因为它同时禁用了内核 TCP 拼接功能。
-db
禁用后台模式和多进程模式。进程将保持在前台运行。该模式主要用于开发或小型测试,仅需按 Ctrl-C 即可停止进程。切勿在初始化脚本中使用。
-dc
启用 CPU 亲和性调试。在启动前,将报告所选 CPU 和被驱逐 CPU 的列表及其拓扑信息。
-de
禁用 “epoll” 检查器的使用。这等同于 “global” 段中的关键字 “noepoll”。 当怀疑与此检查器相关的缺陷时,该选项尤为有用。在支持 epoll 的系统上,回退通常为 “poll” 检查器。
-dk
禁用 “kqueue” 检查器的使用。这等价于 “global” 段中的关键字 “nokqueue”。当怀疑与此检查器相关的缺陷时,该选项尤为有用。在支持 kqueue 的系统上,回退机制通常为 “poll” 检查器。
-dp
禁用 “poll” 监听器的使用。这等效于 “global” 段中的关键字 “nopoll”。 当怀疑与此监听器相关的缺陷时,该选项尤为有用。在支持 poll 的系统上,回退机制通常为 “select” 监听器,该监听器无法禁用,且最多支持 1024 个文件描述符。
-dr
忽略服务器地址解析失败。在非生产环境中验证配置时,通常无法访问相同的解析器,导致服务器地址解析失败,从而难以测试配置。此选项将 “none” 方法添加至所有服务器的地址解析方法列表中,确保即使 libc 无法解析地址,启动流程也不会中断。
-dt [<trace_desc>,...]
在标准错误输出中激活追踪功能。若不带参数,将在错误级别启用所有追踪源。此功能特别有助于检测客户端或服务器的协议违规行为。可选参数用于指定使用逗号分隔的多种追踪配置列表。每个元素可激活一个或全部追踪源。此外,可在每个元素中使用冒号作为内部分隔符,可选地指定级别和详细程度。若输入无效的详细程度或级别名称,将显示可用关键字列表。例如,可对每个字段传入 ‘help’ 以先查阅列表。
-dv
禁用 “evports” 轮询器的使用。这等同于 “global” 段中的关键字 “noevports”。当怀疑与此轮询器相关的缺陷时,该选项尤为有用。在支持事件端口的系统上(如 Solaris 10 及更高版本的 SunOS),回退机制通常为 “poll” 轮询器。
-m <limit>
限制可分配内存(用于保存进程数据)为 <limit> 兆字节。这可能导致部分连接被拒绝或出现性能下降,具体取决于正常操作所需的内存数量。该设置主要用于强制 HAProxy 进程在资源受限的环境中运行。请注意,HAProxy 进程之间不共享内存,通过 fork() 系统调用创建的子进程会继承父进程的资源限制。因此,在主进程/工作进程模式下,该内存限制会分别应用于主进程及其 fork 出的工作进程。
-n <limit>
将每个进程的连接数限制为 <limit>。这等效于全局段中的关键字 “maxconn”。该设置优先于该关键字。可在资源限制过低的系统上快速强制降低限制,以避免服务中断。
-p <file>
启动时将所有进程的 PID 写入 <file>。这等价于 “global” 段中的关键字 “pidfile”。该文件在进入 chroot 监狱前打开,并在执行 “-C” 所隐含的 chdir() 之后打开。每个 PID 单独占一行。
-q
设置 “quiet” 模式。此操作将禁用输出消息。可与 “-c” 联用,仅用于检查配置文件是否有效。
-S <bind>[,bind_options...]
在主进程/工作进程模式下,绑定一个主 CLI,该 CLI 可访问所有运行中或已退出的进程。出于安全考虑,建议将主 CLI 绑定到本地 Unix 套接字。绑定选项与配置文件中的关键字 “bind” 相同,但各选项之间使用英文逗号分隔,而非空格。
请注意,此套接字无法用于在无缝重载期间从旧进程获取监听套接字。
-sf <pid>*
在启动完成后,向旧进程发送 “finish” 信号(SIGUSR1),以请求它们完成当前操作并退出。<pid> 是要发送信号的进程 ID 列表(每个参数对应一个进程 ID)。列表在任意以 “-” 开头的选项处结束。如果进程 ID 列表为空也无妨,因此可基于 “pidof” 或 “pgrep” 等命令的执行结果动态构建该列表。
-st <pid>*
在启动完成后,向旧进程发送 “terminate” 信号(SIGTERM)以立即终止它们,而不完成其当前操作。<pid> 是要发送信号的进程 ID 列表(每个参数一个)。列表在任意以 “-” 开头的选项处结束。如果进程 ID 列表为空也无妨,因此可基于 “pidof” 或 “pgrep” 等命令的执行结果动态构建。
-v
报告版本和构建日期。
-vv
显示版本、构建选项、库版本和可用的轮询器。此输出在提交错误报告时会自动请求。
-x <unix_socket>
连接到指定的套接字,并尝试从旧进程获取任何监听套接字,然后使用这些套接字,而非尝试绑定新的套接字。这在 Linux 上重载配置时避免遗漏任何新连接时非常有用。
在未启用主进程/工作进程模式时,必须在配置中使用“expose-fd listeners”在统计信息套接字上启用该功能。
在主进程/工作进程模式下,无需使用“expose-fd listeners”,主进程在使用“sockpair@”语法进行重载时会自动启用此选项,从而允许主进程直接连接到工作进程,而无需依赖配置中声明的任何统计信息套接字。如需禁用此功能,可传递 -x /dev/null.
从初始化文件启动 HAProxy 的安全方式是强制启用守护进程模式,将现有进程 ID 存储到 PID 文件,并使用该 PID 文件通知旧进程终止后再退出:
当配置被拆分为若干特定文件(例如:TCP 与 HTTP)时,建议使用 “-f” 选项:
当预期的文件数量未知时,例如特定客户使用的文件,建议将文件名以固定长度的序列号开头,并使用 “–” 加载这些文件,可在加载部分默认配置之后进行。
有时,由于各种原因可能导致启动失败。此时,务必验证所调用的 HAProxy 版本是否为预期版本,并确认其是否支持预期的功能(例如:SSL、PCRE、压缩、Lua 等)。可通过运行 “haproxy -vv” 来验证。该命令会报告一些重要信息,如特定构建选项、目标系统以及所使用库的版本。提交错误报告时,应系统性提供这些信息:
HAProxy version 1.6-dev7-a088d3-4 2015/10/08 Copyright 2000-2015 Willy Tarreau willy@haproxy.org
Build options:
Default settings:
Encrypted password support via crypt(3): yes Built with zlib version: 1.2.6 Compression algorithms supported: identity(“identity”), deflate(“deflate”), \ raw-deflate(“deflate”), gzip(“gzip”) Built with OpenSSL version: OpenSSL 1.0.1o 12 Jun 2015 Running on OpenSSL version: OpenSSL 1.0.1o 12 Jun 2015 OpenSSL library supports TLS extensions: yes OpenSSL library supports SNI: yes OpenSSL library supports prefer-server-ciphers: yes Built with PCRE version: 8.12 2011-01-15 PCRE library supports JIT: no (USE_PCRE_JIT not set) Built with Lua version: Lua 5.3.1 Built with transparent proxy support using: IP_TRANSPARENT IP_FREEBIND
Available polling systems:
Total: 3 (3 usable), will use epoll.
- the version
1.6-dev7-a088d3-4 表示当前代码位于提交 ID “a088d3”,该提交位于正式版本 “1.6-dev7” 之后的第 4 个提交。版本 1.6-dev7 将显示为 “1.6-dev7-8c1ad7”。真正重要的是 “1.6-dev7”。这是未来将演变为 1.6 版本的第 7 个开发版本。该版本不适合在生产环境中使用(除非完全了解其风险)。稳定版本将显示为三位数字版本,例如 “1.5.14-16f863”,表示在 1.5 版本基础上的第 14 个修复级别。该版本为生产就绪版本。
- the release date
2015/10/08。采用通用的年/月/日格式表示。此处指 2015 年 8 月 8 日。由于稳定版本通常每隔数月发布一次(初期为 1 至 2 个月,产品趋于稳定后可能长达 6 个月),若此处显示的日期较旧,说明可能正受多个已修复的缺陷或安全问题影响,建议访问官方站点进行确认。
- build options
它们适用于自行构建软件包的人员,能够解释为何某些行为不符合预期。例如,上述开发版本是为 Linux 2.6.28 或更高版本构建的,针对通用 CPU(无 CPU 特定优化),且缺乏任何代码优化(-O0),因此在性能方面表现不佳。
- libraries versions
zlib 版本号由库本身报告。通常情况下,zlib 被认为是非常稳定的产品,几乎无需升级。OpenSSL 报告两个版本号,分别为构建时使用的版本和当前系统中实际使用的版本。这两个版本号在末尾字母上可能不同,但数字部分绝不会不同。同时报告构建日期,因为大多数 OpenSSL 的问题均为安全漏洞,必须高度重视,因此该库必须始终保持最新。若此处显示的版本为 4 个月前的版本,则高度可疑,实际上确实遗漏了一次更新。PCRE 提供极快的正则表达式支持,强烈推荐使用。其部分扩展功能(如 JIT)并非所有版本均支持,且仍处于较早期阶段,因此部分用户选择不启用这些功能,这也是为何会报告构建状态。关于 Lua 脚本语言,HAProxy 期望使用 5.3 版本,该版本相对较新,因其发布于 HAProxy 1.6 之前不久。请务必访问 Lua 官方网站,确认该分支是否发布了相关修复。
- Available polling systems will affect the process's scalability when
处理超过一千个并发连接时。这些机制仅在构建时于 TARGET 变量中指定了正确系统的情况下才可用。在 Linux 上强烈建议使用 “epoll” 机制,在 BSD 上强烈建议使用 kqueue 机制。若缺少这些机制,将导致使用 poll() 或甚至 select(),在处理大量连接时会造成较高的 CPU 使用率。