hostname kangle web server

 人参与 | 时间:2026-10-17 07:31:54

一台服务器上跑着几十个网站,每个网站绑着不同的域名,用户访问时各看各的,互不干扰。这事听起来普通,但背后有个关键角色:hostname。在Kangle Web Server里,hostname不只是一个标签,它决定了请求到底被扔进哪个虚拟主机的处理管道。

Kangle的虚拟主机匹配逻辑很直接。请求进来,服务器先看HTTP头里的Host字段,拿这个值去跟配置文件里的hostname做比对。匹配上了,就交给对应的站点根目录、PHP进程池、访问日志。匹配不上,走默认站点或者直接返回403。我见过有人把hostname写成带端口的格式,比如example.com:8080,结果非标准端口的请求全挂——Kangle在匹配时会剥掉端口,只比较域名部分,这个细节在文档里藏得很深。

配置hostname的时候有个坑。Kangle的vhs(虚拟主机)模块里,hostname支持通配符,写法是*.example.com,但只支持最左一级匹配。想同时匹配a.example.com和a.b.example.com,得写两条规则,或者干脆用正则表达式——Kangle支持~开头的正则hostname,这个功能用的人少,但处理泛域名时比通配符灵活得多。我自己管过一台机器,上面有200多个泛解析子域名,全用正则一条搞定,比堆通配符清爽。

还有个容易忽略的点:Kangle匹配hostname时大小写敏感。HTTP规范说Host头应该大小写不敏感,但Kangle默认按字面比对。用户浏览器发Example.com,你配置里写的是example.com,那就匹配失败。解决办法是在hostname配置里开启ignore_case选项,或者统一用小写。这个坑我踩过,排查了半天,最后抓包才看到Host头里有个大写字母。

反向代理场景下hostname的玩法又不一样。Kangle做前端,后端是Nginx或者Tomcat,这时候Kangle的hostname匹配的是用户请求的域名,转发给后端时可以通过proxy_set_header Host $host把原始hostname传过去。但Kangle的配置语法跟Nginx不同,它用request_header和response_header来操作头信息。我试过在Kangle里改Host头转发,得在vhs的request段里加header指令,写法跟Nginx的proxy_set_header逻辑一样但语法完全不同。

日志这块也跟hostname绑得紧。Kangle的访问日志默认按虚拟主机分文件,日志文件名里会嵌入hostname。如果hostname里有*或者正则符号,日志文件名会变得很奇怪,甚至写不进去。我一般建议把日志路径单独配置,别依赖自动生成的文件名。另外,Kangle的access_log指令里可以用%{ Host}i来记录请求的Host头,这样即使hostname匹配失败,日志里也能看到用户到底请求了哪个域名,排查DNS或者CDN回源问题的时候特别有用。

性能方面,hostname匹配本身开销极小,就是字符串比较。但如果你配了几千个虚拟主机,而且每个hostname都是独立条目,Kangle会线性遍历。这时候用正则hostname反而更快,因为正则引擎会先做前缀树优化。我实测过,5000个精确hostname条目,匹配耗时大概在微秒级,对QPS的影响可以忽略。真正影响性能的是每个虚拟主机背后的PHP进程池或者FastCGI连接池,那才是资源大头。

最后说个实际案例。有次帮人迁站,旧服务器用Apache,VirtualHost里写的是ServerName www.example.com,但用户实际访问的是example.com,Apache会自动做www跳转。迁到Kangle后,只配了www.example.com的hostname,结果不带www的请求全部404。原因就是Kangle不会自动做域名补全或者跳转,hostname必须精确匹配。后来加了一条example.com的vhs,在里面写301跳转到www,问题解决。Kangle的哲学是:你配什么就是什么,它不猜你的意图。

顶: 277踩: 4