补充小知识点:
hosts是一个没有扩展名的系统文件,可以用记事本等工具打开,其作用就是将一些常用的网址域名与其对应的IP地址建立一个关联“数据库”,当用户在浏览器中输入一个需要登录的网址时,系统会首先自动从hosts文件中寻找对应的IP地址,一旦找到,系统会立即打开对应网页,如果没有找到,则系统会再将网址提交DNS域名解析服务器进行IP地址的解析。
所以我们可以使用修改hosts文件来制作一些虚拟域名来使用。
windows:C:\Windows\System32\drivers\etc
centos:/etc/hosts
1. 精确匹配
server{
sever_name www.example.com www.example.cn;
2. 使用通配符(* :可以匹配个多个单词)
server_name中支持通配符"*",但需要注意的是通配符不能出现在域名的中间,只能出现在首段或尾段。有一种形如 ".example.org" 的特殊通配符,它可以既匹配确切的名字"example.org",又可以匹配一般的通配符名字 "*.example.org"。
server{
sever_name *.example.com www.example.* .example.com www.example.;
匹配的url
前缀匹配 *.example.com;*: 表示前面可以匹配多个单词
www.example.com,www.blog.example.com,www.blog.show.example.com ...
后缀匹配 www.example.*; *: 表示后面可以匹配多个单词
www.example.com, www.example.com.cn.xyz, www.example.com.cn.xyz.org ...
3. 使用正则表达式配置
使用~作为正则表达式字符串的开始标记
使用~开头进行匹配,一般都写上^和$,来限定域名
正则中可以抓取变量部分,进行后面语法中的使用
如果在正则里面存在“{”和”}”,则需要将域名用引号引起来:
server{
listen 9091;
sever_name "~^(?\w\d{1,3}+)\.example\.net$";
defalut_type text/plain;
return 200 "name:$name";
正则内容捕获,也可以用常用的是用$number来表示
server{
server_name ~^(www\.)?(?.+)$;
defalut_type text/plain;
# $1 (www\.) $2 (.+)
return 200 "$1$2";
如果配置完 重启,报错如下,则说明系统的PCRE库版本过旧需要更新
pcre_compile() failed: unrecognized character after (?< in ...
匹配执行顺序
由于server_name指令支持通配符和正则表达式,因此在包含多个虚拟主机的配置文件中,可能会出现一个名称被多个虚拟主机的server_name匹配成功,当遇到这种情况,当前的请求交给谁来处理呢?
server{
listen 9091;
sever_name ~^(www\.)?(.+)$;
default_type text/plain;
return 200 'regex_success';
server{
listen 9091;
server_name www.myweb.*;
default_type text/plain;
return 200 'wildcard_after_success';
server{
listen 9091;
server_name *.myweb.com;
default_type text/plain;
return 200 'wildcard_before_success';
server{
listen 9091;
server_name www.myweb.com;
default_type text/plain;
return 200 'exact_success';
server{
listen 9091 default_server;
server_name _;
default_type text/plain;
return 200 'default_server not found server!!';
exact_success 精准匹配
wildcard_before_success 前通配符
wildcard_after_success 后通配符
regex_success 正则匹配
default_server not found server!!
如果需要处理请求而没有默认的服务器块中的“主机”头字段,则应指定一个空名称:
如果在服务器块中没有定义server_name,那么nginx将使用空名作为服务器名称。
server {
listen 80;
server_name example.org www.example.org "";
在全部服务器示例中,可以看到奇怪的名称“_ ”:
这个名字没有什么特别之处,它只是无数个无效域名的其中一个,永远不会与任何真实姓名相交。其他无效名称,如“ –”和“ !@#”也可以同样使用。
表示:找不到任何配的主机名,就用这个默认的匹配的。
server {
listen 80 default_server;
server_name _;
return 444;
精确匹配域名,泛域名,正则域名会对应创建三张表和侦听端口关联。
先搜索精确匹配表,然后泛域名表,最后搜索正则域名表。
泛域名表的查询比精确匹配表查询慢。
正则域名表则会依次查询,效率最低。
尽可能的采用精确匹配域名,来获得最大化效率
域名过长的情况
如果定义了一个过长的域名,则可能需要修改http上下文中server_names_hash_max_size
和 server_names_hash_bucket_size 两个属性值,否则启动nginx会出现报错。
默认的 server_names_hash_max_size 和 server_names_hash_bucket_size 的值和环境中cpu cache line size相关,32或者64。
查看cpu cache line size可以用getconf命令:
getconf -a | grep -i _CACHE_LINESIZE
LEVEL2_CACHE_LINESIZE 64
LEVEL3_CACHE_LINESIZE 64
如果服务器是监听端口的唯一服务器,则nginx将不会测试服务器名称(并且不会为监听端口构建哈希表)。但是有一个例外。如果服务器名称是带有捕获的正则表达式,则nginx必须执行表达式才能获取捕获。