├── .gitignore ├── LICENSE ├── README.md ├── SUMMARY.md ├── docs ├── compression-and-decompression.md ├── hello-world.md ├── https-server.md ├── installation.md ├── introduction.md ├── load-balancer.md ├── references.md └── server-names.md ├── images ├── hello-world │ └── hello-world.jpg ├── installation │ ├── nginx-welcome.jpg │ └── nginx-win32.jpg └── nginx-logo.png └── samples └── hello-world └── index.html /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Mobile Tools for Java (J2ME) 4 | .mtj.tmp/ 5 | 6 | # Package Files # 7 | *.jar 8 | *.war 9 | *.ear 10 | 11 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 12 | hs_err_pid* 13 | 14 | *.project 15 | *.md.html 16 | .idea 17 | 18 | /target/ 19 | /.idea/ 20 | /.settings/ 21 | .classpath 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Way Lau 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NGINX Tutorial.《NGINX 教程》 2 | 3 | ![](images/nginx-logo.png) 4 | 5 | NGINX Tutorial takes you to learn [NGINX](http://nginx.org/) step by step with a large number of samples. There is also a GitBook version of the book: . 6 | Let's [READ](SUMMARY.md)! 7 | 8 | ## 关于本书 9 | 10 | NGINX Tutorial 是一本关于 [NGINX](http://nginx.org/) 学习的开源书。利用业余时间写了本书,图文并茂,用大量实例带你一步一步走进 NGINX 的世界。如有疏漏欢迎指正,欢迎提问。感谢您的参与! 11 | 12 | ## 什么是 NGINX 13 | 14 | NGINX [engine x] 是一款来自俄罗斯的高性能的 HTTP 和反向代理(reverse proxy)服务器、邮件服务器,以及通用的 TCP/UDP 代理服务器,被业界广泛采用,包括Netflix、Wordpress、FastMail 等。它具有有很多非常优越的特性: 15 | 16 | * **作为 Web 服务器**:相比 Apache,NGINX 使用更少的资源,支持更多的并发连接,体现更高的效率,这点使 NGINX 尤其受到虚拟主机提供商的欢迎; 17 | * **作为负载均衡服务器**:NGINX 既可以在内部直接支持 Rails 和 PHP,也可以支持作为 HTTP 代理服务器 对外进行服务。NGINX 用 C 编写,系统资源开销小, CPU 使用效率高; 18 | * **作为邮件代理服务器**: NGINX 同时也是一个非常优秀的邮件代理服务器(最早开发这个产品的目的之一也是作为邮件代理服务器)。 19 | 20 | ## Get Started 如何开始阅读 21 | 22 | 选择下面入口之一: 23 | 24 | * 的 [SUMMARY.md](SUMMARY.md)(源码) 25 | * 点击 Read 按钮(同步更新,国内访问速度一般) 26 | 27 | ## Code 源码 28 | 29 | 书中所有示例源码,移步至 `samples` 目录下 30 | 31 | ## Issue 意见、建议 32 | 33 | 如有勘误、意见或建议欢迎拍砖 34 | 35 | ## Contact 联系作者: 36 | 37 | * Blog: [waylau.com](https://waylau.com) 38 | * Gmail: [waylau521(at)gmail.com](mailto:waylau521@gmail.com) 39 | * Weibo: [waylau521](http://weibo.com/waylau521) 40 | * Twitter: [waylau521](https://twitter.com/waylau521) 41 | * Github : [waylau](https://github.com/waylau) 42 | 43 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | 4 | * [简介](docs/introduction.md) 5 | * [下载、安装、运行](docs/installation.md) 6 | * [Hello World! 作为 HTTP 服务器](docs/hello-world.md) 7 | * [配置服务器名称](docs/server-names.md) 8 | * [配置 HTTPS 服务器](docs/https-server.md) 9 | * [作为 HTTP 负载均衡器](docs/load-balancer.md) 10 | * [压缩与解压](docs/compression-and-decompression.md) 11 | * [参考资料](docs/references.md) 12 | * To be continued ...未完待续... 13 | 14 | -------------------------------------------------------------------------------- /docs/compression-and-decompression.md: -------------------------------------------------------------------------------- 1 | # 压缩与解压 2 | 3 | 压缩响应通常会显着减少传输数据的大小。 然而,由于压缩在运行时发生,所以会增加处理开销,这可能会对性能产生负面影响。 4 | 5 | 在向客户端发送响应之前,NGINX 会执行压缩,但不会“重复压缩”已经压缩过的响应。 6 | 7 | ## 启用压缩 8 | 9 | 要启用压缩,在 gzip 指令上请使用`on`参数: 10 | 11 | ``` 12 | gzip on; 13 | ``` 14 | 15 | 默认情况下,NGINX 仅压缩使用MIME 类型 为 `text/html`的响应。要压缩其他 MIME 类型的响应,请包含`gzip_types`指令并列出相应的类型。 16 | 17 | ``` 18 | gzip_types text/plain application/xml; 19 | ``` 20 | 21 | 要指定要压缩的响应的最小长度,请使用`gzip_min_length`指令。默认值为20字节,下面示例调整为1000: 22 | 23 | ``` 24 | gzip_min_length 1000; 25 | ``` 26 | 27 | 默认情况下,NGINX 不会压缩对代理请求的响应(来自代理服务器的请求)。请求是否来自代理服务器是由请求中`Via`头字段的是否存来确定的。要配置这些响应的压缩,请使用`gzip_proxied`指令。该指令具有多个参数来指定 NGINX 应压缩哪种代理请求。例如,仅对不会在代理服务器上缓存的请求进行压缩响应,为此,`gzip_proxied`指令具有指示 NGINX 在响应中检查`Cache-Control`头字段的参数,如果值是 no-cache、no-store 或 private,则压缩响应。另外,您必须包括 expired 的参数来检查`Expires`头字段的值。这些参数在以下示例中与 auth 参数一起设置,该参数检查`Authorization`头字段的存在(授权响应特定于最终用户,并且通常不被缓存): 28 | 29 | ``` 30 | gzip_proxied no-cache no-store private expired auth; 31 | ``` 32 | 33 | 与大多数其他指令一样,配置压缩的指令可以包含在`http`上下文中,也可以包含在 `server` 或 `location` 块中。 34 | 35 | gzip 压缩的整体配置可能如下所示。 36 | 37 | ``` 38 | server { 39 | gzip on; 40 | gzip_types text/plain application/xml; 41 | gzip_proxied no-cache no-store private expired auth; 42 | gzip_min_length 1000; 43 | ... 44 | } 45 | ``` 46 | 47 | ## 启用解压 48 | 49 | 某些客户端不支持使用 gzip 编码方法的响应。同时,可能需要存储压缩数据,或者即时压缩响应并将它们存储在缓存中。为了都能成功地服务于接受或者不接受压缩数据的客户端,针对后一种类型的客户端时,NGINX 可以在将数据发送时即时解压缩数据。 50 | 51 | 要启用运行时解压缩,请使用`gunzip`指令。 52 | 53 | ``` 54 | location /storage/ { 55 | gunzip on; 56 | ... 57 | } 58 | ``` 59 | 60 | 61 | `gunzip`指令可以在与`gzip`指令相同的上下文中指定: 62 | 63 | ``` 64 | server { 65 | gzip on; 66 | gzip_min_length 1000; 67 | gunzip on; 68 | ... 69 | } 70 | ``` 71 | 72 | 73 | 请注意,此指令在单独的模块中定义(见`ngx_http_gunzip_module`),默认情况下可能不包含在开源 NGINX 构建中。 74 | 75 | ## 发送压缩文件 76 | 77 | 要将文件的压缩版本发送到客户端而不是常规文件,请在适当的上下文中将`gzip_static`指令设置为 on。 78 | 79 | 80 | ``` 81 | location / { 82 | gzip_static on; 83 | } 84 | ``` 85 | 86 | 87 | 在这种情况下,为了服务`/path/to/file`的请求,NGINX 尝试查找并发送文件`/path/to/file.gz`。如果文件不存在,或客户端不支持 gzip,则 NGINX 将发送未压缩版本的文件。 88 | 89 | 请注意,`gzip_static`指令不启用即时压缩。它只是使用压缩工具预先压缩的文件。要在运行时压缩内容(而不仅仅是静态内容),请使用`gzip`指令。 90 | 91 | 该指令在单独的模块中定义(见`ngx_http_gzip_static_module`),默认情况下可能不包含在开源NGINX构建中。 -------------------------------------------------------------------------------- /docs/hello-world.md: -------------------------------------------------------------------------------- 1 | # Hello World! 作为 HTTP 服务器 2 | 3 | 按照编程惯例,我们要编写第一个“Hello World”应用案例。该案例是使用 NGINX 来作为 HTTP 服务器。 4 | 5 | 众所周知, NGINX 一款高性能的 HTTP 服务器。 6 | 7 | 8 | ## 编写示例代码 9 | 10 | 我们新建了一个“hello-world”目录,用作我们的项目目录。在该目录下,新建一个 index.html 静态页面,页面内容如下: 11 | 12 | ```html 13 | 14 | 15 | 16 | 17 | Hello World 18 | 19 | 20 |

Hello World!

21 |

柳伟卫/老卫/Way Lau's Personal Site - 关注编程、系统架构、性能优化

22 |

23 | Welcome to waylau.com. 24 |

25 | 26 | 27 | ``` 28 | 29 | 页面内容非常简单,我们只是考虑如何将这个静态页面在 NGINX 上进行部署。 30 | 31 | 32 | ## 部署项目 33 | 34 | 在 NGINX 的按照目录下,我们能找到`html`目录,该目录就是用于部署静态页面。 35 | 36 | 在该目录下,事先已经有了几个演示页面: 37 | 38 | ```shell 39 | ├─html 40 | │ 50x.html 41 | │ index.html 42 | ``` 43 | 44 | 也可以删除,或者保留该演示页面。我们将“hello-world”项目复制到`html`目录下。 45 | 46 | 此时,整个目录情况如下: 47 | 48 | ```shell 49 | ├─html 50 | │ │ 50x.html 51 | │ │ index.html 52 | │ │ 53 | │ └─hello-world 54 | │ index.html 55 | ``` 56 | 57 | ## 验证 58 | 59 | NGINX 正常启动后会占用,打开浏览器,访问 就能看到我们编写的项目的页面。 60 | 61 | ![](../images/hello-world/hello-world.jpg) 62 | 63 | -------------------------------------------------------------------------------- /docs/https-server.md: -------------------------------------------------------------------------------- 1 | # 配置 HTTPS 服务器 2 | 3 | HTTPS(Hyper Text Transfer Protocol over Secure Socket Layer)是基于 SSL/TLS 安全连接的 HTTP 协议。HTTPS 是通过 SSL/TLS 提供的数据加密、身份验证和消息完整性验证等安全机制,来为 Web 访问提供了安全性保证,并广泛应用于网上银行、电子商务等领域。近年以来,在主要互联网公司和浏览器开发商的推动之下,HTTPS 在加速普及,而 HTTP 正在被加速淘汰。不加密的 HTTP 连接是不安全的,数据能在传输过程中被任何中间人能轻易地读取和操纵。 4 | 5 | 本章节将演示如何将 NGINX 配置为 HTTPS 服务器。 6 | 7 | ## 修改 nginx.conf 8 | 9 | 修改 `conf/nginx.conf` 文件,必须在配置文件 server 块中的监听指令 listen 后启用 ssl 参数,并且指定服务器证书 `ssl_certificate` 和私钥 `ssl_certificate_key` 的位置: 10 | 11 | ``` 12 | server { 13 | listen 443 ssl; 14 | server_name www.example.com; 15 | ssl_certificate www.example.com.crt; 16 | ssl_certificate_key www.example.com.key; 17 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 18 | ssl_ciphers HIGH:!aNULL:!MD5; 19 | ... 20 | } 21 | ``` 22 | 23 | 24 | 服务器证书是一个公共实体,它被发送给连接到服务器的每一个客户机。私钥是一个安全实体,应该存储在具有受限访问的文件中,但它必须可被nginx主进程读取。私钥也可以存储在与服务器证书相同的文件中: 25 | 26 | ``` 27 | ssl_certificate www.example.com.cert; 28 | ssl_certificate_key www.example.com.cert; 29 | ``` 30 | 31 | 在这种情况下,这个证书文件的访问权限也应受到限制。虽然证书和密钥存储在一个文件中,但只有证书被发送到客户端。 32 | 33 | 指令 `ssl_protocols` 和 `ssl_ciphers` 可用于限制仅包括强版本和密码的 SSL/TLS 连接。 默认情况下,NGINX 使 用`ssl_protocols TLSv1 TLSv1.1 TLSv1.2`版本和`ssl_ciphers HIGH:!aNULL:!MD5`密码,因此通常不需要显式地配置它们。需要注意的是,这些指令的默认值在不同的版本里面已经变更好几次了。如果想确认下不同版本的默认值,请参阅。 34 | 35 | ## HTTPS 服务器优化 36 | 37 | SSL 操作会消耗额外的 CPU 资源。 在多处理器系统上,应该运行不少于可用 CPU 内核数的多个 工作进程 。最耗 CPU 的操作是 SSL 握手。有两种方法来最小化每个客户端执行这些操作的次数: 38 | 39 | * **启用 `keepalive_timeout`参数**。来让这些 keepalive 的连接在一个连接中发送多个请求 40 | * **重用 SSL 会话参数**。可以避免并行和后续连接的 SSL 握手。这些会话存储在 NGINX 工作程序的共享 SSL 会话缓存中,并由`ssl_session_cache`指令配置。 1M 的高速缓存包含大约4000个会话。默认的缓存超时时间为5分钟,可以通过使用`ssl_session_timeout`配置来增大。 下面是针对具有 10M 共享缓存的多核心系统的优化示例配置: 41 | 42 | ``` 43 | worker_processes auto; 44 | 45 | http { 46 | ssl_session_cache shared:SSL:10m; 47 | ssl_session_timeout 10m; 48 | 49 | server { 50 | listen 443 ssl; 51 | server_name www.example.com; 52 | keepalive_timeout 70; 53 | 54 | ssl_certificate www.example.com.crt; 55 | ssl_certificate_key www.example.com.key; 56 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 57 | ssl_ciphers HIGH:!aNULL:!MD5; 58 | ... 59 | ``` 60 | 61 | ## SSL 证书链 62 | 63 | 有些浏览器可能警示由知名证书颁发机构签名的证书,而其他浏览器却能无问题的接受这些证书。这是因为这些证书颁发机构使用了中间证书来签署服务器证书,所签署的证书不存在于特定浏览器发行时内置的可信证书颁发机构颁发的证书库中。在这种情况下,颁发机构提供一组与颁发的服务器证书(根证书)串接的捆绑证书,并让服务器证书(根证书)出现在合并后文件(证书链)的捆绑证书之前: 64 | 65 | ```shell 66 | $ cat www.example.com.crt bundle.crt > www.example.com.chained.crt 67 | ``` 68 | 69 | 70 | 生成的证书链文件应该放在 `ssl_certificate`配置中: 71 | 72 | ``` 73 | server { 74 | listen 443 ssl; 75 | server_name www.example.com; 76 | ssl_certificate www.example.com.chained.crt; 77 | ssl_certificate_key www.example.com.key; 78 | ... 79 | } 80 | ``` 81 | 82 | 如果根证书和捆绑证书使用了错误的链接顺序,NGINX 将会启动失败并显示如下错误信息: 83 | 84 | ```shell 85 | SSL_CTX_use_PrivateKey_file(" ... /www.example.com.key") failed 86 | (SSL: error:0B080074:x509 certificate routines: 87 | X509_check_private_key:key values mismatch) 88 | ``` 89 | 90 | 这是因为 NGINX 尝试去使用私钥与捆绑后证书的第一个证书验证而不是它本该去验证的服务器证书。 91 | 92 | 浏览器通常会存储他们接收到的由可信证书颁发机构签发的中间证书,因此被活跃使用的浏览器可能已经拥有所需的中间证书,这样证书即使没有捆绑到证书链也不会有问题。为了确保服务器发送的是完整的证书链,可以使用 `openssl`命令行来查看,例如: 93 | 94 | ```shell 95 | $ openssl s_client -connect www.godaddy.com:443 96 | ... 97 | Certificate chain 98 | 0 s:/C=US/ST=Arizona/L=Scottsdale/1.3.6.1.4.1.311.60.2.1.3=US 99 | /1.3.6.1.4.1.311.60.2.1.2=AZ/O=GoDaddy.com, Inc 100 | /OU=MIS Department/CN=www.GoDaddy.com 101 | /serialNumber=0796928-7/2.5.4.15=V1.0, Clause 5.(b) 102 | i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc. 103 | /OU=http://certificates.godaddy.com/repository 104 | /CN=Go Daddy Secure Certification Authority 105 | /serialNumber=07969287 106 | 1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc. 107 | /OU=http://certificates.godaddy.com/repository 108 | /CN=Go Daddy Secure Certification Authority 109 | /serialNumber=07969287 110 | i:/C=US/O=The Go Daddy Group, Inc. 111 | /OU=Go Daddy Class 2 Certification Authority 112 | 2 s:/C=US/O=The Go Daddy Group, Inc. 113 | /OU=Go Daddy Class 2 Certification Authority 114 | i:/L=ValiCert Validation Network/O=ValiCert, Inc. 115 | /OU=ValiCert Class 2 Policy Validation Authority 116 | /CN=http://www.valicert.com//emailAddress=info@valicert.com 117 | ... 118 | ``` 119 | 120 | 在本示例中, www.GoDaddy.com 证书链中的 #0 号证书的证书请求者("s")由签发者("i")签发,而签发者("i")本身又是 #1 号证书的请求者("s"),它的证书签发者是 #2 号证书的请求者,它请求的证书由知名发布者 ValiCert 公司 签发,其证书存储在浏览器的内置证书库中。 121 | 122 | 如果捆绑证书没有被添加到证书链,那只有 #0 号证书会被展示出来。 123 | 124 | 125 | ## 单个 HTTP/HTTPS 虚拟主机 126 | 127 | 现在,在单个 NGINX 虚拟主上可以配置同时处理 HTTP 和 HTTPS 请求: 128 | 129 | ``` 130 | server { 131 | listen 80; 132 | listen 443 ssl; 133 | server_name www.example.com; 134 | ssl_certificate www.example.com.crt; 135 | ssl_certificate_key www.example.com.key; 136 | ... 137 | } 138 | ``` 139 | 140 | 在0.7.14之前的版本无法向上面那样为单个侦听套接字选择性启用SSL,而只能使用`ssl`指令为整个服务器启用 SSL,从而无法设置单个 HTTP/HTTPS 虚拟主机服务器,所以在 `listen`指令后增加了`ssl` 参数来解决此问题。因此不建议在现代版本中使用 `ssl` 这个指令。 141 | 142 | 143 | ## 基于名称的 HTTPS 服务器 144 | 145 | 当配置两个或多个HTTPS虚拟主机服务器侦听同一个 IP 地址时会出现常见问题: 146 | 147 | 148 | ``` 149 | server { 150 | listen 443 ssl; 151 | server_name www.example.com; 152 | ssl_certificate www.example.com.crt; 153 | ... 154 | } 155 | 156 | server { 157 | listen 443 ssl; 158 | server_name www.example.org; 159 | ssl_certificate www.example.org.crt; 160 | ... 161 | } 162 | ``` 163 | 164 | 使用这种配置,浏览器接收默认服务器的证书,即"www.example.com" 而不管请求的实际服务器名称,这是由SSL协议行为造成的。 SSL连接建立在浏览器发送 HTTP 请求之前,这时候 NGINX 还不知道请求的服务器名称。因此,它只能提供默认的服务器证书。 165 | 166 | 解决此问题最古老和最可靠的方法是为每个 HTTPS 虚拟主机服务器指定一个单独的IP地址: 167 | 168 | ``` 169 | server { 170 | listen 192.168.1.1:443 ssl; 171 | server_name www.example.com; 172 | ssl_certificate www.example.com.crt; 173 | ... 174 | } 175 | 176 | server { 177 | listen 192.168.1.2:443 ssl; 178 | server_name www.example.org; 179 | ssl_certificate www.example.org.crt; 180 | ... 181 | } 182 | ``` 183 | 184 | ## 包含多个名称的 SSL 证书 185 | 186 | 还有其他方法允许在几个HTTPS虚拟主机服务器之间共享单个IP地址。然而,他们都有自己的缺点。其中一种方法是在证书的 SubjectAltName 字段中使用多个名称,例如 `www.example.com` 和 `www.example.org` 。 但是, SubjectAltName 字段长度有限。 187 | 188 | 另一种方法是使用带有通配符名称的证书,例如 `*.example.org` 。 通配符证书能保护指定域的所有子域,但只限一个级别。此证书与 `www.example.org` 匹配,但不匹配 `example.org` 和 `www.sub.example.org` 。这两种方法也可以结合。证书可以在 SubjectAltName 字段中包含完全匹配和通配符名称,例如 `example.org` 和 `*.example.org` 。 189 | 190 | 最好在配置文件的 `http`区块中放置具有多个名称的证书文件及其私钥文件,以在所有其下的虚拟主机服务器中继承其单个内存副本: 191 | 192 | ``` 193 | ssl_certificate common.crt; 194 | ssl_certificate_key common.key; 195 | 196 | server { 197 | listen 443 ssl; 198 | server_name www.example.com; 199 | ... 200 | } 201 | 202 | server { 203 | listen 443 ssl; 204 | server_name www.example.org; 205 | ... 206 | } 207 | ``` 208 | 209 | ## 服务器名称指示 210 | 211 | 单个 IP 地址上运行多个 HTTPS 虚拟服务器的更通用的解决方案是 TLS 服务器名称指示扩展 (SNI,RFC 6066),其允许浏览器在 SSL 握手期间同时发送请求的服务器名称,因此,服务器就知道它应该给这个连接使用哪个证书。然而,SNI 限制了它支持的浏览器。 目前支持从以下浏览器版本及其后的版本: 212 | 213 | * Opera 8.0; 214 | * IE 7.0 (Windows Vista及更高版本); 215 | * Firefox 2.0 及其他使用 Mozilla Platform rv:1.8.1 的浏览器; 216 | * Safari 3.2.1 (Windows版本支持Windows Vista及更高版本); 217 | * Chrome (Windows版本支持Windows Vista及更高版本). 218 | 219 | 只有域名可以在 SNI 中传递,然而如果请求包含 IP 地址,一些浏览器可能错误地把服务器的 IP 地址作为其名称进行传递,我们不能依赖于这个。 220 | 221 | 为了在nginx中使用 SNI,必须在构建 NGINX 的 OpenSSL 库以及运行时的动态链接库中支持它。OpenSSL从0.9.8f版本支持SNI,如果在编译时给`config`增加了 `--enable-tlsext` 选项;从OpenSSL 0.9.8j版本开始默认启用此选项。如果NGINX是以支持SNI方式构建的,当使用“-V”参数运行时,NGINX 会显示这一信息: 222 | 223 | 224 | ``` 225 | $ nginx -V 226 | ... 227 | TLS SNI support enabled 228 | ... 229 | ``` 230 | 231 | 但是,如果启用 SNI 的 NGINX与没有 SNI 支持的 OpenSSL 库动态链接,NGINX 将显示警告: 232 | 233 | ``` 234 | nginx was built with SNI support, however, now it is linked 235 | dynamically to an OpenSSL library which has no tlsext support, 236 | therefore SNI is not available 237 | ``` 238 | 239 | -------------------------------------------------------------------------------- /docs/installation.md: -------------------------------------------------------------------------------- 1 | # 下载、安装、运行 2 | 3 | ## 下载 4 | 5 | NGINX 下载地址为:。 6 | 7 | 8 | ## 安装 9 | 10 | ### Linux 和 BSD 的预构建软件包 11 | 12 | 大多数 Linux 发行版和 BSD 版本在通常的软件包存储库中都有 NGINX,它们可以通过任何通常用于安装软件的方法进行安装,如在 Debian 平台使用 `apt-get`,在 Gentoo 平台使用 `emerge`,FreeBSD 平台使用 `ports`等。 13 | 14 | 请注意,这些软件包通常有些过时。 如果您想要最新的功能和错误修复,建议从源代码或直接从 nginx.org 使用软件包。 15 | 16 | 17 | ### Red Hat/CentOS 18 | 19 | 首先添加 NGINX 的 yum 库,接着创建名为`/etc/yum.repos.d/nginx.repo` 的文件,并粘贴如下配置到文件中: 20 | 21 | #### CentOS 22 | 23 | ```shell 24 | [nginx] 25 | name=nginx repo 26 | baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ 27 | gpgcheck=0 28 | enabled=1 29 | ``` 30 | 31 | 32 | #### RHEL 33 | 34 | ```shell 35 | [nginx] 36 | name=nginx repo 37 | baseurl=http://nginx.org/packages/rhel/$releasever/$basearch/ 38 | gpgcheck=0 39 | enabled=1 40 | ``` 41 | 42 | 由于CentOS、RHEL 和 Scientific Linux 之间填充`$releasever`变量的差异,有必要根据您的操作系统版本手动将`$releasever`变量的替换为5(5.x)或6(6.x))。 43 | 44 | 45 | ### Debian/Ubuntu 46 | 47 | #### Ubuntu: 48 | 49 | 此分发页面列出了可用的N GINX Ubuntu 版本支持。 有关Ubuntu版本映射到发布名称,请访问官方 Ubuntu 版本页面。 50 | 51 | 在`/etc/apt/sources.list`中附加适当的脚本。 如果担心存储库添加的持久性(即DigitalOcean Droplets),则可以将适当的部分添加到`/etc/apt/sources.list.d/`下的其他列表文件中,例如`/etc/apt/sources.list.d/nginx.list`。 52 | 53 | ```shell 54 | ## Replace $release with your corresponding Ubuntu release. 55 | deb http://nginx.org/packages/ubuntu/ $release nginx 56 | deb-src http://nginx.org/packages/ubuntu/ $release nginx 57 | ``` 58 | 59 | 比如 Ubuntu 16.04 (Xenial) 版本,设置如下: 60 | 61 | ```shell 62 | deb http://nginx.org/packages/ubuntu/ xenial nginx 63 | deb-src http://nginx.org/packages/ubuntu/ xenial nginx 64 | ``` 65 | 66 | 要想安装,执行如下脚本: 67 | 68 | ``` 69 | sudo apt-get update 70 | sudo apt-get install nginx 71 | ``` 72 | 73 | 安装过程如果有如下的错误: 74 | 75 | ``` 76 | W: GPG error: http://nginx.org/packages/ubuntu xenial Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY $key 77 | ``` 78 | 79 | 则执行下面命令: 80 | 81 | ```shell 82 | ## Replace $key with the corresponding $key from your GPG error. 83 | sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys $key 84 | sudo apt-get update 85 | sudo apt-get install nginx 86 | ``` 87 | 88 | 89 | #### Debian 6 90 | 91 | 添加下面脚本到`/etc/apt/sources.list`: 92 | 93 | ```shell 94 | deb http://nginx.org/packages/debian/ squeeze nginx 95 | deb-src http://nginx.org/packages/debian/ squeeze nginx 96 | ``` 97 | 98 | #### Ubuntu PPA 99 | 100 | 这 个PPA 由志愿者维护,不由 nginx.org 分发。 由于它有一些额外的编译模块,所以可能更适合您的环境。 101 | 102 | 您可以从 Launchpad上 的[NGINX PPA](https://launchpad.net/~nginx/+archive/ubuntu/development) 获取最新的稳定版本的 NGINX。您将需要具有root权限才能执行以下命令。 103 | 104 | Ubuntu 10.04 及更新版本: 105 | 106 | ```shell 107 | sudo -s 108 | nginx=stable # use nginx=development for latest development version 109 | add-apt-repository ppa:nginx/$nginx 110 | apt-get update 111 | apt-get install nginx 112 | ``` 113 | 114 | 如果有关于`add-apt-repository`的错误,则可能先要安装`python-software-properties`。对于其他基于 Debian/Ubuntu 的发行版,您可以尝试使用最可能在旧版套件上工作的 PPA 的变体: 115 | 116 | ```shell 117 | sudo -s 118 | nginx=stable # use nginx=development for latest development version 119 | echo "deb http://ppa.launchpad.net/nginx/$nginx/ubuntu lucid main" > /etc/apt/sources.list.d/nginx-$nginx-lucid.list 120 | apt-key adv --keyserver keyserver.ubuntu.com --recv-keys C300EE8C 121 | apt-get update 122 | apt-get install nginx 123 | ``` 124 | 125 | ### Win32 126 | 127 | 安装命令为: 128 | 129 | ```shell 130 | cd c:\ 131 | unzip nginx-1.13.0.zip 132 | ren nginx-1.13.0 nginx 133 | cd nginx 134 | start nginx 135 | ``` 136 | 137 | 如果有那问题,可以参看日志 `c:nginxlogserror.log`。 138 | 139 | 此外,目前,NGINX 官网只提供了 32位的安装包,如果想安装 64位的版本,可以查看由 Kevin Worthington 维护 Windows 版本 140 | 141 | 142 | 143 | ## 验证安装 144 | 145 | NGINX 正常启动后会占用 80 端口。打开任务管理器中,能够看到相关的 NGINX 活动线程。 146 | 147 | ![](../images/installation/nginx-win32.jpg) 148 | 149 | 打开浏览器,访问 (其中 80 端口号可以省略)就能看到 NGINX 的欢迎页面。 150 | 151 | ![](../images/installation/nginx-welcome.jpg) 152 | 153 | 关闭 NGINX 执行: 154 | 155 | ```shell 156 | nginx -s stop 157 | ``` 158 | 159 | ## 控制语句 160 | 161 | 162 | NGINX 启动后,有一个主进程(master process)和一个或多个工作进程(worker process),主进程的作用主要是读入和检查NGINX的配置信息,以及维护工作进程;工作进程才是真正处理客户端请求的进程。具体要启动多少个工作进程,可以在 NGINX 的配置文件`nginx.conf`中通过`worker_processes`指令指定。 163 | 可以通过以下这些命令来控制 NGINX: 164 | 165 | ``` 166 | nginx -s [ stop | quit | reopen | reload ] 167 | ``` 168 | 169 | 其中: 170 | 171 | * `nginx -s stop`: 强制停止NGINX,不管工作进程当前是否正在处理用户请求,都会立即退出。 172 | * `nginx -s quit`:“优雅地”退出NGINX,执行这个命令后,工作进程会将当前正在处理的请求处理完毕后,再退出。 173 | * `nginx -s reload`:重载配置信息。当NGINX的配置文件改变之后,同过执行这个命令,使更改的配置信息生效,而无需重新启动nginx. 174 | * `nginx -s reopen`:重新打开日志文件。 175 | 176 | > 当重载配置信息时,NGINX 的主进程首先检查配置信息,如果配置信息没有错误,主进程会启动新的工作进程,并发出信息通知旧的工作进程退出,旧的工作进程接收到信号后,会等到处理完当前正在处理的请求后退出。如果nginx检查配置信息发现错误,就会回滚所做的更改,沿用旧的工作进程继续工作。 -------------------------------------------------------------------------------- /docs/introduction.md: -------------------------------------------------------------------------------- 1 | # NGINX 简介 2 | 3 | ## 什么是 NGINX 4 | 5 | 6 | NGINX是一个免费的、开源的、高性能的 HTTP 服务器和反向代理,以及一个 IMAP/POP3 代理服务器。 NGINX以其高性能、稳定性、丰富的功能集、简单的配置和低资源消耗而闻名。 7 | 8 | NGINX 是为解决[C10K](http://www.kegel.com/c10k.html) 问题而编写的少数服务器之一。与传统服务器不同,NGINX 不依赖于线程来处理请求。相反,它使用更加可扩展的事件驱动(异步)架构。这种架构在负载下使用小的但更重要的是可预测的内存量。即使您不希望处理数千个并发请求,您仍然可以从 NGINX 的高性能和小内存中获益。 NGINX 在各个方向扩展:从最小的 VPS 一直到大型服务器集群。 9 | 10 | > 所谓 C10K 问题,指的是服务器同时支持成千上万个客户端的问题,也就是"Concurrent 10000 Connection"(这也是c10k这个名字的由来)。由于硬件成本的大幅度降低和硬件技术的进步,如果一台服务器同时能够服务更多的客户端,那么也就意味着服务每一个客户端的成本大幅度降低,从这个角度来看,C10K 问题显得非常有意义。 11 | 12 | NGINX拥有诸如 Netflix、Hulu、Pinterest、CloudFlare、Airbnb、WordPress.com、GitHub、SoundCloud、Zynga、Eventbrite、Zappos、Media Temple、Heroku、RightScale、Engine、Yard、MaxCDN 等众多高知名度网站。 13 | 。 14 | 15 | NGINX 它具有有很多非常优越的特性: 16 | 17 | * **作为 Web 服务器**:相比 Apache,NGINX 使用更少的资源,支持更多的并发连接,体现更高的效率,这点使 NGINX 尤其受到虚拟主机提供商的欢迎; 18 | * **作为负载均衡服务器**:NGINX 既可以在内部直接支持 Rails 和 PHP,也可以支持作为 HTTP 代理服务器 对外进行服务。NGINX 用 C 编写,系统资源开销小, CPU 使用效率高; 19 | * **作为邮件代理服务器**: NGINX 同时也是一个非常优秀的邮件代理服务器(最早开发这个产品的目的之一也是作为邮件代理服务器)。 20 | -------------------------------------------------------------------------------- /docs/load-balancer.md: -------------------------------------------------------------------------------- 1 | # 作为 HTTP 负载均衡器 2 | 3 | 跨多个应用程序实例的负载均衡是优化资源利用率,最大限度地提高吞吐量,降低延迟,并确保容错配置一个常用的技术。 4 | 5 | 可以使用 NGINX 作为非常有效的 HTTP 负载平衡器,将流量分配给多个应用服务器,并通过 NGINX 提高 Web 应用程序的性能、可扩展性和可靠性。 6 | 7 | ## 负载均衡的方法 8 | 9 | NGINX 支持如下负载均衡的机制(或方法): 10 | 11 | * **轮询(round-robin)** : 以循环的方式将请求分发到应用服务; 12 | * **最少连接(least-connected) **: 下次请求指派到激活连接数最少的服务; 13 | * **IP 哈希(ip-hash)** : 基于客户端的IP地址,利用哈希函数,决定下次请求应该选中哪个服务。 14 | 15 | ### 1. 轮询 16 | 17 | 如果没有指定负载均衡的方法,那么 NGINX 默认采用的是轮询的方式。最简单的负载均衡配置如下: 18 | 19 | ``` 20 | http { 21 | upstream myapp1 { 22 | server srv1.example.com; 23 | server srv2.example.com; 24 | server srv3.example.com; 25 | } 26 | 27 | server { 28 | listen 80; 29 | 30 | location / { 31 | proxy_pass http://myapp1; 32 | } 33 | } 34 | } 35 | ``` 36 | 37 | 3个同样实例的应用(srv1-srv3)是采用轮询方式。所有请求被代理到一组服务`myapp1`,同时,NGINX 运用 HTTP 负载均衡来分发请求。 38 | 39 | 反向代理被应用在 NGINX 内,包括负载均衡针对 HTTP、HTTPS、FASTCGI、uwsgi、SCGI 以及 memcached。 40 | 41 | 配置负载均衡针对 HTTPS 替代 HTTP 的话,仅仅使用 https 协议即可(proxy_pass https://myapp1)。 42 | 43 | 在为 FASTCGI、uwsgi、SCGI 或 memcached 设置负载均衡时,分别使用 fastcgi_pass、uwsgi_pass、scgi_pass 和 memcached_pass 指令。 44 | 45 | ### 2. 最少连接 46 | 47 | 在一些请求需要更长时间才能完成的情况下,最少连接可以更公正地控制应用程序实例的负载。 48 | 49 | 使用最少连接的负载平衡,NGINX 将不会加重一个有过多请求的应用服务负担,而是将它分发新的请求给最不繁忙的服务器。 50 | 51 | 在 NGINX 中需要通过设置`least_conn`来激活最少连接的负载均衡策略配置: 52 | 53 | ``` 54 | upstream myapp1 { 55 | least_conn; 56 | server srv1.example.com; 57 | server srv2.example.com; 58 | server srv3.example.com; 59 | } 60 | ``` 61 | 62 | ### 3. IP 哈希(会话持久) 63 | 64 | 注意,采用轮询或者最少连接的负载均衡策略,每个客户端的后续请求可能被分配带不同的服务器,不能保证同一个客户端总是指向同一个服务。如果需要告诉客户端分配到一个特定的应用服务,换句话,就是保持客户端的会话粘性(sticky)或者会话持久性(persitent),即总是尝试选着同一个特定的服务器,IP 哈希 负载均衡机制可以被使用。 65 | 66 | 采用 IP 哈希的策略,客户端的 IP 地址被用作一个哈希 key,决定哪个服务应该被选中来服务客户端的请求。这种方式,确保了同一个客户端来的请求将总是被指向同一个服务,除非这个服务不可用了。 67 | 68 | 配置IP 哈希负载均衡,只需要通过设置`ip_hash`来激活: 69 | 70 | ``` 71 | upstream myapp1 { 72 | ip_hash; 73 | server srv1.example.com; 74 | server srv2.example.com; 75 | server srv3.example.com; 76 | } 77 | ``` 78 | 79 | ## 权重(weight) 80 | 81 | 可以通过使用服务器的权重来影响 NGINX 的负载均衡算法,在上述轮询、最少请求、基于IP 哈希负载均衡配置中,服务器的权重没有配置,意味着所有服务器的权重都是一样的。特别是轮询,它意味着或多或少平等的分发请求到服务器(请求够多,并且请求以均匀方式进行处理,并完成够快) 82 | 83 | 当配置了一个 weight 变量到一个指定的服务后,权重被作为一个 NGINX 的负载均衡的决定的一部分: 84 | 85 | ``` 86 | upstream myapp1 { 87 | server srv1.example.com weight=3; 88 | server srv2.example.com; 89 | server srv3.example.com; 90 | } 91 | ``` 92 | 93 | 采用上面的配置,如果来了5个请求,3个到srv1,1个到srv2,1个到srv3。在最近的NGINX版本中,同样可以使用权重针对最少连接和IP 哈希的负载均衡策略。 94 | 95 | ## 健康监测 96 | 97 | 反向代理在 NGINX 中实现了被动的健康监测,如果响应从一个特定的服务器失败,携带着错误,NGINX 将标记这个服务器是失败的,并将尝试一段时间避免选择这个服务器作为后续请求的服务器。 98 | 99 | `fail_timeout` 和 `max_fails` 用于设定指定时间内,应该发生连续不成功的数目。默认`max_fail`等于1,如果设置成0,相当于关闭这个服务器的健康监测。`fail_timeout`参数,定义多久服务器被标识失败。过了服务器`fail_timeout`失败超时间隔后,NGINX 将开始探测存活的客户端的请求,如果探测成功,服务被标识成存活状态。 100 | -------------------------------------------------------------------------------- /docs/references.md: -------------------------------------------------------------------------------- 1 | # 参考资料 2 | 3 | * http://nginx.org/en/docs/ 4 | * https://www.nginx.com/resources/wiki/start/topics/tutorials/install/ 5 | * http://nginx.org/en/docs/http/load_balancing.html 6 | * http://nginx.org/en/docs/http/server_names.html -------------------------------------------------------------------------------- /docs/server-names.md: -------------------------------------------------------------------------------- 1 | # 配置服务器名称 2 | 3 | 服务器名称是用`server_name`指令来定义的,并且它决定了哪一个`server`块将用来处理给定的请求。可以使用精确名称、通配符、正则表达式来定义服务器名称。 4 | 5 | ``` 6 | server { 7 | listen 80; 8 | server_name example.org www.example.org; 9 | ... 10 | } 11 | 12 | server { 13 | listen 80; 14 | server_name *.example.org; 15 | ... 16 | } 17 | 18 | server { 19 | listen 80; 20 | server_name mail.*; 21 | ... 22 | } 23 | 24 | server { 25 | listen 80; 26 | server_name ~^(?.+)\.example\.net$; 27 | ... 28 | } 29 | ``` 30 | 31 | 32 | 当寻找一个虚拟服务器的名字,如果指定的名称匹配多个变量,例如,通配符和正则表达式都匹配,将会按照以下的顺序选择第一个匹配的变量: 33 | 34 | * 精确名称 35 | * 以星号(*)开头的最长的通配符,例如“*.example.org” 36 | * 以星号(*)结尾的最长的通配符,例如“mail.*” 37 | * 第一个匹配的正则表达式(根据在配置文件中出现的顺序) 38 | 39 | 40 | ## 通配符名称 41 | 42 | 通配符名称包含的星号(*)只能在名称的开头或结尾,并且只能在点号(.)的边上。像“www.*.example.org”和“w*.example.org”都是不可用的。然而,这样的名称可以使用正则表达式来指定,例如,“~^www\..+\.example\.org$” 和 “~^w.*\.example\.org$”。星号可以匹配好几个名称部分。“*.example.org”不仅能匹配`www.example.org`,还能匹配`www.sub.example.org`。 43 | 44 | 一种特殊形式的通配符“.example.org”可以用来匹配精确名称“example.org”和通配符“*.example.org”。 45 | 46 | ## 正则表达式名称 47 | 48 | NGINX 中使用的正则表达式兼容 Perl 编程语言中的正则表达式(PCRE)。使用正则表达式时,服务器名称必须使用波浪线(~)开头: 49 | 50 | ``` 51 | server_name ~^www\d+\.example\.net$; 52 | ``` 53 | 54 | 要不然就会被当做精确名称对待,或者如果包含星号(*)的话,会被当成通配符(当然多数情况下会被当成不可用的)。在正则表达式中不要忘记使用“^”和"$"标记,并不是语法上的要求,而是逻辑上的要求。同时还要记住,域名中的点号(.)之前要加反斜杠转义。如果正则表达式中包含中括号“{”和“}”,需要用引号括起来: 55 | 56 | ``` 57 | server_name "~^(?\w\d{1,3}+)\.example\.net$"; 58 | ``` 59 | 60 | 要不然 NGINX 会启动失败并且显示错误信息: 61 | 62 | ``` 63 | directive "server_name" is not terminated by ";" in ... 64 | ``` 65 | 66 | 指定正则表达式捕获片段之后可以当做一个变量来使用: 67 | 68 | 69 | ``` 70 | server { 71 | server_name ~^(www\.)?(?.+)$; 72 | 73 | location / { 74 | root /sites/$domain; 75 | } 76 | } 77 | ``` 78 | 79 | PCRE库支持以下语法使用捕获片段: 80 | 81 | * `?`: Perl 5.10兼容语法,从PCRE-7.0开始支持 82 | * `?'name'`: Perl 5.10兼容语法,从PCRE-7.0开始支持 83 | * `?P`: Python兼容语法,从PCRE-4.0开始支持 84 | 85 | 如果 NGINX 启动失败,并且显示错误信息: 86 | 87 | ``` 88 | pcre_compile() failed: unrecognized character after (?< in ... 89 | ``` 90 | 91 | 这就意味着PCRE库太老了,这种语法“?P”应该被替换。捕获片段也可以使用数字形式引用: 92 | 93 | 94 | ``` 95 | server { 96 | server_name ~^(www\.)?(.+)$; 97 | 98 | location / { 99 | root /sites/$2; 100 | } 101 | } 102 | ``` 103 | 104 | 105 | 然而,这种使用方式尽量限制在简单案例中使用(就像上面这样),因为数字引用形式很容易被覆盖。 106 | 107 | ## 混杂名称 108 | 109 | 有些服务器名称被区别对待。 110 | 111 | 如果没有“Host”头信息的请求需要被一个不是默认的`server`块处理,一个空的名称要被指定: 112 | 113 | ``` 114 | server { 115 | listen 80; 116 | server_name example.org www.example.org ""; 117 | ... 118 | } 119 | ``` 120 | 121 | 如果在一个`server`块中没有`server_name`被指定,NGINX 会使用空名称作为服务器名称。 122 | 123 | > 在NGINX 0.8.48之前的版本中,机器的hostname(主机名称)会被用作服务器名称。 124 | 125 | 如果服务器名称被定义成“$hostname”(从0.9.4版开始),机器的hostname(主机名称)会被使用。 126 | 127 | 如果处理请求时想使用IP地址代替服务器名称,“Host”请求头会包含IP地址,并且会把IP地址当做服务器名称来处理请求: 128 | 129 | ``` 130 | server { 131 | listen 80; 132 | server_name example.org 133 | www.example.org 134 | "" 135 | 192.168.1.1 136 | ; 137 | ... 138 | } 139 | ``` 140 | 141 | 万能服务器示例中可以看到奇怪的名字“_”: 142 | 143 | ``` 144 | server { 145 | listen 80 default_server; 146 | server_name _; 147 | return 444; 148 | } 149 | ``` 150 | 151 | 这个名称并不奇怪,这只是众多的与真实名称永远不会相交的无效域名中的一个。其他的无效名称像“— —”和“!@#”也可以同样适用。 152 | 153 | NGINX 0.6.25之前的版本支持特殊的名称“*”,这被错误地解释为万能的名称。它从来都不具备万能的或通配符名称的功能。作为替代,它之前提供的功能现在被“server_name_in_redirect”指令取代。特殊名称“*”现在已经不建议使用了,而建议使用“server_name_in_redirect”指令。请注意使用“server_name”指令没有办法指定万能名称或默认服务器。这是“listen”指令的属性而不是“server_name”指令的属性。可以在`*:80`和`*:8080`上监听,一个将`*:8080`端口设为默认,另一个将`*:80`端口设为默认: 154 | 155 | ``` 156 | server { 157 | listen 80; 158 | listen 8080 default_server; 159 | server_name example.net; 160 | ... 161 | } 162 | 163 | server { 164 | listen 80 default_server; 165 | listen 8080; 166 | server_name example.org; 167 | ... 168 | } 169 | ``` 170 | 171 | ## 优化 172 | 173 | 精确名称,以星号开头的通配符,以星号结尾的通配符被存储在绑定到监听端口上的三张哈希表中。哈希表的大小在配置阶段被优化,因此一个名称在最少CPU缓存空隙被找到。 174 | 175 | 精确名称的哈希表最先被搜索。如果没找到一个名字,接着以星号开头的通配符哈希表会被搜索。如果还没找到,以星号结尾的哈希表才会被搜索。 176 | 177 | 搜索通配符名称的哈希表速度会比搜索精确名称的哈希表慢,因为名称是根据域名部分搜索的。记住,这种特殊的通配符形式“.example.org”是存储在通配符名称的哈希表中而不是存储在精确名称的哈希表中。 178 | 179 | 正则表达式会被按序测试,因为它是最慢的并且不可伸缩。 180 | 181 | 基于这些原因,尽可能使用精确名称会更好。例如,最经常被请求的服务器名称是`example.org`和`www.example.org`,像下面这样定义会更高效: 182 | 183 | ``` 184 | server { 185 | listen 80; 186 | server_name example.org www.example.org *.example.org; 187 | ... 188 | } 189 | ``` 190 | 191 | 比这种形式更高效: 192 | 193 | ``` 194 | server { 195 | listen 80; 196 | server_name .example.org; 197 | ... 198 | } 199 | ``` 200 | 201 | 如果大量的服务器名称被定义,或者特别长的服务器名称被定义,在`http`块中使用`server_names_hash_max_size`和`server_names_hash_bucket_size`就显得有必要了。根据CPU缓存行的大小,默认的`server_names_hash_bucket_size`指令的值可能是32、64或其他值。如果默认值是32,服务器名称被定义为`too.long.server.name.example.org`,NGINX 就会启动失败并显示错误信息: 202 | 203 | ``` 204 | could not build the server_names_hash, 205 | you should increase server_names_hash_bucket_size: 32 206 | ``` 207 | 208 | 在这种情况下,这个指令的值应该增加到两倍的值: 209 | 210 | ``` 211 | http { 212 | server_names_hash_bucket_size 64; 213 | ... 214 | ``` 215 | 216 | 217 | 如果是大量的服务器名称被定义,另一个错误信息会显示: 218 | 219 | ``` 220 | could not build the server_names_hash, 221 | you should increase either server_names_hash_max_size: 512 222 | or server_names_hash_bucket_size: 32 223 | ``` 224 | 225 | 226 | 在这种情况下,首先尝试去设置`server_names_hash_max_size`的值接近于服务器名称的数量。只有当这种情况无效时,或者 NGINX 的启动时间太长无法接受,再去增大`server_names_hash_bucket_size`。 227 | 228 | 如果一个端口上只定义了一个服务器名称,那么 NGINX 就不会再去测试服务器名称了(也不会在端口上建立哈希表)。然而,有一种例外的情况。如果服务器名称是带有捕捉片段的正则表达式,那么必须去执行表达式获取捕捉片段。 -------------------------------------------------------------------------------- /images/hello-world/hello-world.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waylau/nginx-tutorial/6159fcd479b3703ab4ecc80ac216a5a609649fa6/images/hello-world/hello-world.jpg -------------------------------------------------------------------------------- /images/installation/nginx-welcome.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waylau/nginx-tutorial/6159fcd479b3703ab4ecc80ac216a5a609649fa6/images/installation/nginx-welcome.jpg -------------------------------------------------------------------------------- /images/installation/nginx-win32.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waylau/nginx-tutorial/6159fcd479b3703ab4ecc80ac216a5a609649fa6/images/installation/nginx-win32.jpg -------------------------------------------------------------------------------- /images/nginx-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waylau/nginx-tutorial/6159fcd479b3703ab4ecc80ac216a5a609649fa6/images/nginx-logo.png -------------------------------------------------------------------------------- /samples/hello-world/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Hello World 6 | 7 | 8 |

Hello World!

9 |

柳伟卫/老卫/Way Lau's Personal Site - 关注编程、系统架构、性能优化

10 |

11 | Welcome to waylau.com. 12 |

13 | 14 | --------------------------------------------------------------------------------