update docs
parent
fbea21b132
commit
3429e18b47
|
@ -1,29 +1,25 @@
|
|||
# EditorConfig helps developers define and maintain consistent
|
||||
# coding styles between different editors and IDEs
|
||||
# http://editorconfig.org
|
||||
# 所有文件换行使用 Unix like 风格(LF),bat 文件使用 win 风格(CRLF)
|
||||
# 缩进 java 4 个空格,其他所有文件 2 个空格
|
||||
# EditorConfig 用于在 IDE 中检查代码的基本 Code Style
|
||||
# @see: https://editorconfig.org/
|
||||
|
||||
# 配置说明:
|
||||
# 所有文件换行使用 Unix 风格(LF),*.bat 文件使用 Windows 风格(CRLF)
|
||||
# java / sh 文件缩进 4 个空格,其他所有文件缩进 2 个空格
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
# Unix-style newlines with a newline ending every file
|
||||
end_of_line = lf
|
||||
|
||||
# Change these settings to your own preference
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
indent_style = tab
|
||||
max_line_length = 120
|
||||
|
||||
# We recommend you to keep these unchanged
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.bat]
|
||||
[*.{bat, cmd}]
|
||||
end_of_line = crlf
|
||||
|
||||
[*.java]
|
||||
[*.{java, groovy, kt, sh}]
|
||||
indent_size = 4
|
||||
|
||||
[*.md]
|
||||
|
|
|
@ -1,17 +1,37 @@
|
|||
################ JAVA ################
|
||||
# temp folders
|
||||
# ---------------------------------------------------------------------
|
||||
# more gitignore templates see https://github.com/github/gitignore
|
||||
# ---------------------------------------------------------------------
|
||||
|
||||
# ------------------------------- java -------------------------------
|
||||
# compiled folders
|
||||
classes
|
||||
target
|
||||
logs
|
||||
.mtj.tmp/
|
||||
|
||||
# temp files
|
||||
# compiled files
|
||||
*.class
|
||||
|
||||
# bluej files
|
||||
*.ctxt
|
||||
|
||||
# package files #
|
||||
*.jar
|
||||
*.war
|
||||
*.versionsBackup
|
||||
*.nar
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
|
||||
# virtual machine crash logs
|
||||
hs_err_pid*
|
||||
|
||||
# maven plugin temp files
|
||||
.flattened-pom.xml
|
||||
|
||||
|
||||
################ JAVASCRIPT ################
|
||||
# ------------------------------- javascript -------------------------------
|
||||
# dependencies
|
||||
node_modules
|
||||
|
||||
|
@ -29,11 +49,11 @@ yarn-error.log*
|
|||
bundle*.js
|
||||
|
||||
|
||||
################ IDEA ################
|
||||
# ------------------------------- intellij -------------------------------
|
||||
.idea
|
||||
*.iml
|
||||
|
||||
|
||||
################ Eclipse ################
|
||||
# ------------------------------- eclipse -------------------------------
|
||||
.classpath
|
||||
.project
|
||||
|
|
11
README.md
11
README.md
|
@ -2,7 +2,7 @@
|
|||
|
||||
> 本项目是一个 Nginx 极简教程,目的在于帮助新手快速入门 Nginx。
|
||||
>
|
||||
> [demos](demos) 目录中的示例模拟了工作中的一些常用实战场景,并且都可以通过脚本一键式启动,让您可以快速看到演示效果。
|
||||
> [**examples**](https://github.com/dunwu/nginx-tutorial/tree/master/examples) 目录中的示例模拟了工作中的一些常用实战场景,并且都可以通过脚本一键式启动,让您可以快速看到演示效果。
|
||||
|
||||
## 简介
|
||||
|
||||
|
@ -20,14 +20,13 @@
|
|||
|
||||
## Nginx 入门
|
||||
|
||||
> 详细安装方法请参考:[Nginx 安装](install-nginx.md)
|
||||
>
|
||||
> 详细安装方法请参考:[Nginx 安装](docs/nginx-install.md)
|
||||
|
||||
nginx 的使用比较简单,就是几条命令。
|
||||
|
||||
常用到的命令如下:
|
||||
|
||||
```bash
|
||||
```batch
|
||||
nginx -s stop 快速关闭Nginx,可能不保存相关信息,并迅速终止web服务。
|
||||
nginx -s quit 平稳关闭Nginx,保存相关信息,有安排的结束web服务。
|
||||
nginx -s reload 因改变了Nginx相关配置,需要重新加载配置而重载。
|
||||
|
@ -40,7 +39,7 @@ nginx -V 显示 nginx 的版本,编译器版本和配置参数。
|
|||
|
||||
如果不想每次都敲命令,可以在 nginx 安装目录下新添一个启动批处理文件**startup.bat**,双击即可运行。内容如下:
|
||||
|
||||
```bat
|
||||
```batch
|
||||
@echo off
|
||||
rem 如果启动前已经启动nginx并记录下pid文件,会kill指定进程
|
||||
nginx.exe -s stop
|
||||
|
@ -596,6 +595,6 @@ server {
|
|||
## 参考
|
||||
|
||||
- [Nginx 的中文维基](http://tool.oschina.net/apidocs/apidoc?api=nginx-zh)
|
||||
- [Nginx开发从入门到精通](http://tengine.taobao.org/book/index.html)
|
||||
- [Nginx 开发从入门到精通](http://tengine.taobao.org/book/index.html)
|
||||
- https://github.com/trimstray/nginx-admins-handbook
|
||||
- [nginxconfig.io](https://nginxconfig.io/) - 一款 Nginx 配置生成器
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 89 KiB |
BIN
assets/nginx.jpg
BIN
assets/nginx.jpg
Binary file not shown.
Before Width: | Height: | Size: 89 KiB |
Binary file not shown.
Before Width: | Height: | Size: 61 KiB |
605
docs/README.md
605
docs/README.md
|
@ -1,601 +1,10 @@
|
|||
# Nginx 极简教程
|
||||
# Nginx 教程
|
||||
|
||||
> 本项目是一个 Nginx 极简教程,目的在于帮助新手快速入门 Nginx。
|
||||
> 🔁 项目同步维护在 [github](https://github.com/dunwu/nginx-tutorial) | [gitee](https://gitee.com/turnon/nginx-tutorial)
|
||||
>
|
||||
> [demos](demos) 目录中的示例模拟了工作中的一些常用实战场景,并且都可以通过脚本一键式启动,让您可以快速看到演示效果。
|
||||
> 📖 [电子书](https://dunwu.github.io/nginx-tutorial/) | [电子书(国内)](http://turnon.gitee.io/nginx-tutorial/)
|
||||
|
||||
## 简介
|
||||
|
||||
**什么是 Nginx?**
|
||||
|
||||
**Nginx (engine x)** 是一款轻量级的 Web 服务器 、反向代理服务器及电子邮件(IMAP/POP3)代理服务器。
|
||||
|
||||
<br><div align="center"><img src="http://dunwu.test.upcdn.net/cs/web/nginx/nginx.jpg!zp"/></div><br>
|
||||
|
||||
**什么是反向代理?**
|
||||
|
||||
反向代理(Reverse Proxy)方式是指以代理服务器来接受 internet 上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给 internet 上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。
|
||||
|
||||
<br><div align="center"><img src="http://dunwu.test.upcdn.net/cs/web/nginx/reverse-proxy.png!zp"/></div><br>
|
||||
|
||||
## Nginx 入门
|
||||
|
||||
> 详细安装方法请参考:[Nginx 安装](install-nginx.md)
|
||||
>
|
||||
|
||||
nginx 的使用比较简单,就是几条命令。
|
||||
|
||||
常用到的命令如下:
|
||||
|
||||
```bash
|
||||
nginx -s stop 快速关闭Nginx,可能不保存相关信息,并迅速终止web服务。
|
||||
nginx -s quit 平稳关闭Nginx,保存相关信息,有安排的结束web服务。
|
||||
nginx -s reload 因改变了Nginx相关配置,需要重新加载配置而重载。
|
||||
nginx -s reopen 重新打开日志文件。
|
||||
nginx -c filename 为 Nginx 指定一个配置文件,来代替缺省的。
|
||||
nginx -t 不运行,仅仅测试配置文件。nginx 将检查配置文件的语法的正确性,并尝试打开配置文件中所引用到的文件。
|
||||
nginx -v 显示 nginx 的版本。
|
||||
nginx -V 显示 nginx 的版本,编译器版本和配置参数。
|
||||
```
|
||||
|
||||
如果不想每次都敲命令,可以在 nginx 安装目录下新添一个启动批处理文件**startup.bat**,双击即可运行。内容如下:
|
||||
|
||||
```bat
|
||||
@echo off
|
||||
rem 如果启动前已经启动nginx并记录下pid文件,会kill指定进程
|
||||
nginx.exe -s stop
|
||||
|
||||
rem 测试配置文件语法正确性
|
||||
nginx.exe -t -c conf/nginx.conf
|
||||
|
||||
rem 显示版本信息
|
||||
nginx.exe -v
|
||||
|
||||
rem 按照指定配置去启动nginx
|
||||
nginx.exe -c conf/nginx.conf
|
||||
```
|
||||
|
||||
如果是运行在 Linux 下,写一个 shell 脚本,大同小异。
|
||||
|
||||
## Nginx 实战
|
||||
|
||||
我始终认为,各种开发工具的配置还是结合实战来讲述,会让人更易理解。
|
||||
|
||||
### Http 反向代理
|
||||
|
||||
我们先实现一个小目标:不考虑复杂的配置,仅仅是完成一个 http 反向代理。
|
||||
|
||||
`nginx.conf` 配置文件如下:
|
||||
|
||||
> **_注:`conf/nginx.conf` 是 nginx 的默认配置文件。你也可以使用 nginx -c 指定你的配置文件_**
|
||||
|
||||
```nginx
|
||||
#运行用户
|
||||
#user somebody;
|
||||
|
||||
#启动进程,通常设置成和cpu的数量相等
|
||||
worker_processes 1;
|
||||
|
||||
#全局错误日志
|
||||
error_log D:/Tools/nginx-1.10.1/logs/error.log;
|
||||
error_log D:/Tools/nginx-1.10.1/logs/notice.log notice;
|
||||
error_log D:/Tools/nginx-1.10.1/logs/info.log info;
|
||||
|
||||
#PID文件,记录当前启动的nginx的进程ID
|
||||
pid D:/Tools/nginx-1.10.1/logs/nginx.pid;
|
||||
|
||||
#工作模式及连接数上限
|
||||
events {
|
||||
worker_connections 1024; #单个后台worker process进程的最大并发链接数
|
||||
}
|
||||
|
||||
#设定http服务器,利用它的反向代理功能提供负载均衡支持
|
||||
http {
|
||||
#设定mime类型(邮件支持类型),类型由mime.types文件定义
|
||||
include D:/Tools/nginx-1.10.1/conf/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
#设定日志
|
||||
log_format main '[$remote_addr] - [$remote_user] [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
access_log D:/Tools/nginx-1.10.1/logs/access.log main;
|
||||
rewrite_log on;
|
||||
|
||||
#sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,对于普通应用,
|
||||
#必须设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,以平衡磁盘与网络I/O处理速度,降低系统的uptime.
|
||||
sendfile on;
|
||||
#tcp_nopush on;
|
||||
|
||||
#连接超时时间
|
||||
keepalive_timeout 120;
|
||||
tcp_nodelay on;
|
||||
|
||||
#gzip压缩开关
|
||||
#gzip on;
|
||||
|
||||
#设定实际的服务器列表
|
||||
upstream zp_server1{
|
||||
server 127.0.0.1:8089;
|
||||
}
|
||||
|
||||
#HTTP服务器
|
||||
server {
|
||||
#监听80端口,80端口是知名端口号,用于HTTP协议
|
||||
listen 80;
|
||||
|
||||
#定义使用www.xx.com访问
|
||||
server_name www.helloworld.com;
|
||||
|
||||
#首页
|
||||
index index.html
|
||||
|
||||
#指向webapp的目录
|
||||
root D:\01_Workspace\Project\github\zp\SpringNotes\spring-security\spring-shiro\src\main\webapp;
|
||||
|
||||
#编码格式
|
||||
charset utf-8;
|
||||
|
||||
#代理配置参数
|
||||
proxy_connect_timeout 180;
|
||||
proxy_send_timeout 180;
|
||||
proxy_read_timeout 180;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarder-For $remote_addr;
|
||||
|
||||
#反向代理的路径(和upstream绑定),location 后面设置映射的路径
|
||||
location / {
|
||||
proxy_pass http://zp_server1;
|
||||
}
|
||||
|
||||
#静态文件,nginx自己处理
|
||||
location ~ ^/(images|javascript|js|css|flash|media|static)/ {
|
||||
root D:\01_Workspace\Project\github\zp\SpringNotes\spring-security\spring-shiro\src\main\webapp\views;
|
||||
#过期30天,静态文件不怎么更新,过期可以设大一点,如果频繁更新,则可以设置得小一点。
|
||||
expires 30d;
|
||||
}
|
||||
|
||||
#设定查看Nginx状态的地址
|
||||
location /NginxStatus {
|
||||
stub_status on;
|
||||
access_log on;
|
||||
auth_basic "NginxStatus";
|
||||
auth_basic_user_file conf/htpasswd;
|
||||
}
|
||||
|
||||
#禁止访问 .htxxx 文件
|
||||
location ~ /\.ht {
|
||||
deny all;
|
||||
}
|
||||
|
||||
#错误处理页面(可选择性配置)
|
||||
#error_page 404 /404.html;
|
||||
#error_page 500 502 503 504 /50x.html;
|
||||
#location = /50x.html {
|
||||
# root html;
|
||||
#}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
好了,让我们来试试吧:
|
||||
|
||||
1. 启动 webapp,注意启动绑定的端口要和 nginx 中的 `upstream` 设置的端口保持一致。
|
||||
2. 更改 host:在 C:\Windows\System32\drivers\etc 目录下的 host 文件中添加一条 DNS 记录
|
||||
|
||||
```
|
||||
127.0.0.1 www.helloworld.com
|
||||
```
|
||||
|
||||
3. 启动前文中 startup.bat 的命令
|
||||
4. 在浏览器中访问 www.helloworld.com,不出意外,已经可以访问了。
|
||||
|
||||
### Https 反向代理
|
||||
|
||||
一些对安全性要求比较高的站点,可能会使用 HTTPS(一种使用 ssl 通信标准的安全 HTTP 协议)。
|
||||
|
||||
这里不科普 HTTP 协议和 SSL 标准。但是,使用 nginx 配置 https 需要知道几点:
|
||||
|
||||
- HTTPS 的固定端口号是 443,不同于 HTTP 的 80 端口
|
||||
- SSL 标准需要引入安全证书,所以在 nginx.conf 中你需要指定证书和它对应的 key
|
||||
|
||||
其他和 http 反向代理基本一样,只是在 `Server` 部分配置有些不同。
|
||||
|
||||
```nginx
|
||||
#HTTP服务器
|
||||
server {
|
||||
#监听443端口。443为知名端口号,主要用于HTTPS协议
|
||||
listen 443 ssl;
|
||||
|
||||
#定义使用www.xx.com访问
|
||||
server_name www.helloworld.com;
|
||||
|
||||
#ssl证书文件位置(常见证书文件格式为:crt/pem)
|
||||
ssl_certificate cert.pem;
|
||||
#ssl证书key位置
|
||||
ssl_certificate_key cert.key;
|
||||
|
||||
#ssl配置参数(选择性配置)
|
||||
ssl_session_cache shared:SSL:1m;
|
||||
ssl_session_timeout 5m;
|
||||
#数字签名,此处使用MD5
|
||||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||
ssl_prefer_server_ciphers on;
|
||||
|
||||
location / {
|
||||
root /root;
|
||||
index index.html index.htm;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 负载均衡
|
||||
|
||||
前面的例子中,代理仅仅指向一个服务器。
|
||||
|
||||
但是,网站在实际运营过程中,大部分都是以集群的方式运行,这时需要使用负载均衡来分流。
|
||||
|
||||
nginx 也可以实现简单的负载均衡功能。
|
||||
|
||||
<br><div align="center"><img src="http://dunwu.test.upcdn.net/cs/web/nginx/nginx-load-balance.png!zp"/></div><br>
|
||||
|
||||
假设这样一个应用场景:将应用部署在 192.168.1.11:80、192.168.1.12:80、192.168.1.13:80 三台 linux 环境的服务器上。网站域名叫 www.helloworld.com,公网 IP 为 192.168.1.11。在公网 IP 所在的服务器上部署 nginx,对所有请求做负载均衡处理(下面例子中使用的是加权轮询策略)。
|
||||
|
||||
nginx.conf 配置如下:
|
||||
|
||||
```nginx
|
||||
http {
|
||||
#设定mime类型,类型由mime.type文件定义
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
#设定日志格式
|
||||
access_log /var/log/nginx/access.log;
|
||||
|
||||
#设定负载均衡的服务器列表
|
||||
upstream load_balance_server {
|
||||
#weigth参数表示权值,权值越高被分配到的几率越大
|
||||
server 192.168.1.11:80 weight=5;
|
||||
server 192.168.1.12:80 weight=1;
|
||||
server 192.168.1.13:80 weight=6;
|
||||
}
|
||||
|
||||
#HTTP服务器
|
||||
server {
|
||||
#侦听80端口
|
||||
listen 80;
|
||||
|
||||
#定义使用www.xx.com访问
|
||||
server_name www.helloworld.com;
|
||||
|
||||
#对所有请求进行负载均衡请求
|
||||
location / {
|
||||
root /root; #定义服务器的默认网站根目录位置
|
||||
index index.html index.htm; #定义首页索引文件的名称
|
||||
proxy_pass http://load_balance_server ;#请求转向load_balance_server 定义的服务器列表
|
||||
|
||||
#以下是一些反向代理的配置(可选择性配置)
|
||||
#proxy_redirect off;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
#后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
proxy_connect_timeout 90; #nginx跟后端服务器连接超时时间(代理连接超时)
|
||||
proxy_send_timeout 90; #后端服务器数据回传时间(代理发送超时)
|
||||
proxy_read_timeout 90; #连接成功后,后端服务器响应时间(代理接收超时)
|
||||
proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小
|
||||
proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
|
||||
proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)
|
||||
proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传
|
||||
|
||||
client_max_body_size 10m; #允许客户端请求的最大单文件字节数
|
||||
client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 负载均衡策略
|
||||
|
||||
Nginx 提供了多种负载均衡策略,让我们来一一了解一下:
|
||||
|
||||
负载均衡策略在各种分布式系统中基本上原理一致,对于原理有兴趣,不妨参考 [负载均衡](https://dunwu.github.io/javaweb/#/theory/load-balance)
|
||||
|
||||
##### 轮询
|
||||
|
||||
```nginx
|
||||
upstream bck_testing_01 {
|
||||
# 默认所有服务器权重为 1
|
||||
server 192.168.250.220:8080
|
||||
server 192.168.250.221:8080
|
||||
server 192.168.250.222:8080
|
||||
}
|
||||
```
|
||||
|
||||
##### 加权轮询
|
||||
|
||||
```nginx
|
||||
upstream bck_testing_01 {
|
||||
server 192.168.250.220:8080 weight=3
|
||||
server 192.168.250.221:8080 # default weight=1
|
||||
server 192.168.250.222:8080 # default weight=1
|
||||
}
|
||||
```
|
||||
|
||||
##### 最少连接
|
||||
|
||||
```nginx
|
||||
upstream bck_testing_01 {
|
||||
least_conn;
|
||||
|
||||
# with default weight for all (weight=1)
|
||||
server 192.168.250.220:8080
|
||||
server 192.168.250.221:8080
|
||||
server 192.168.250.222:8080
|
||||
}
|
||||
```
|
||||
|
||||
##### 加权最少连接
|
||||
|
||||
```nginx
|
||||
upstream bck_testing_01 {
|
||||
least_conn;
|
||||
|
||||
server 192.168.250.220:8080 weight=3
|
||||
server 192.168.250.221:8080 # default weight=1
|
||||
server 192.168.250.222:8080 # default weight=1
|
||||
}
|
||||
```
|
||||
|
||||
##### IP Hash
|
||||
|
||||
```nginx
|
||||
upstream bck_testing_01 {
|
||||
|
||||
ip_hash;
|
||||
|
||||
# with default weight for all (weight=1)
|
||||
server 192.168.250.220:8080
|
||||
server 192.168.250.221:8080
|
||||
server 192.168.250.222:8080
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
##### 普通 Hash
|
||||
|
||||
```nginx
|
||||
upstream bck_testing_01 {
|
||||
|
||||
hash $request_uri;
|
||||
|
||||
# with default weight for all (weight=1)
|
||||
server 192.168.250.220:8080
|
||||
server 192.168.250.221:8080
|
||||
server 192.168.250.222:8080
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
### 网站有多个 webapp 的配置
|
||||
|
||||
当一个网站功能越来越丰富时,往往需要将一些功能相对独立的模块剥离出来,独立维护。这样的话,通常,会有多个 webapp。
|
||||
|
||||
举个例子:假如 www.helloworld.com 站点有好几个 webapp,finance(金融)、product(产品)、admin(用户中心)。访问这些应用的方式通过上下文(context)来进行区分:
|
||||
|
||||
www.helloworld.com/finance/
|
||||
|
||||
www.helloworld.com/product/
|
||||
|
||||
www.helloworld.com/admin/
|
||||
|
||||
我们知道,http 的默认端口号是 80,如果在一台服务器上同时启动这 3 个 webapp 应用,都用 80 端口,肯定是不成的。所以,这三个应用需要分别绑定不同的端口号。
|
||||
|
||||
那么,问题来了,用户在实际访问 www.helloworld.com 站点时,访问不同 webapp,总不会还带着对应的端口号去访问吧。所以,你再次需要用到反向代理来做处理。
|
||||
|
||||
配置也不难,来看看怎么做吧:
|
||||
|
||||
```nginx
|
||||
http {
|
||||
#此处省略一些基本配置
|
||||
|
||||
upstream product_server{
|
||||
server www.helloworld.com:8081;
|
||||
}
|
||||
|
||||
upstream admin_server{
|
||||
server www.helloworld.com:8082;
|
||||
}
|
||||
|
||||
upstream finance_server{
|
||||
server www.helloworld.com:8083;
|
||||
}
|
||||
|
||||
server {
|
||||
#此处省略一些基本配置
|
||||
#默认指向product的server
|
||||
location / {
|
||||
proxy_pass http://product_server;
|
||||
}
|
||||
|
||||
location /product/{
|
||||
proxy_pass http://product_server;
|
||||
}
|
||||
|
||||
location /admin/ {
|
||||
proxy_pass http://admin_server;
|
||||
}
|
||||
|
||||
location /finance/ {
|
||||
proxy_pass http://finance_server;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 静态站点
|
||||
|
||||
有时候,我们需要配置静态站点(即 html 文件和一堆静态资源)。
|
||||
|
||||
举例来说:如果所有的静态资源都放在了 `/app/dist` 目录下,我们只需要在 `nginx.conf` 中指定首页以及这个站点的 host 即可。
|
||||
|
||||
配置如下:
|
||||
|
||||
```nginx
|
||||
worker_processes 1;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
include mime.types;
|
||||
default_type application/octet-stream;
|
||||
sendfile on;
|
||||
keepalive_timeout 65;
|
||||
|
||||
gzip on;
|
||||
gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/javascript image/jpeg image/gif image/png;
|
||||
gzip_vary on;
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name static.zp.cn;
|
||||
|
||||
location / {
|
||||
root /app/dist;
|
||||
index index.html;
|
||||
#转发任何请求到 index.html
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
然后,添加 HOST:
|
||||
|
||||
127.0.0.1 static.zp.cn
|
||||
|
||||
此时,在本地浏览器访问 static.zp.cn ,就可以访问静态站点了。
|
||||
|
||||
### 搭建文件服务器
|
||||
|
||||
有时候,团队需要归档一些数据或资料,那么文件服务器必不可少。使用 Nginx 可以非常快速便捷的搭建一个简易的文件服务。
|
||||
|
||||
Nginx 中的配置要点:
|
||||
|
||||
- 将 autoindex 开启可以显示目录,默认不开启。
|
||||
- 将 autoindex_exact_size 开启可以显示文件的大小。
|
||||
- 将 autoindex_localtime 开启可以显示文件的修改时间。
|
||||
- root 用来设置开放为文件服务的根路径。
|
||||
- charset 设置为 `charset utf-8,gbk;`,可以避免中文乱码问题(windows 服务器下设置后,依然乱码,本人暂时没有找到解决方法)。
|
||||
|
||||
一个最简化的配置如下:
|
||||
|
||||
```nginx
|
||||
autoindex on;# 显示目录
|
||||
autoindex_exact_size on;# 显示文件大小
|
||||
autoindex_localtime on;# 显示文件时间
|
||||
|
||||
server {
|
||||
charset utf-8,gbk; # windows 服务器下设置后,依然乱码,暂时无解
|
||||
listen 9050 default_server;
|
||||
listen [::]:9050 default_server;
|
||||
server_name _;
|
||||
root /share/fs;
|
||||
}
|
||||
```
|
||||
|
||||
### 解决跨域
|
||||
|
||||
web 领域开发中,经常采用前后端分离模式。这种模式下,前端和后端分别是独立的 web 应用程序,例如:后端是 Java 程序,前端是 React 或 Vue 应用。
|
||||
|
||||
各自独立的 web app 在互相访问时,势必存在跨域问题。解决跨域问题一般有两种思路:
|
||||
|
||||
1. **CORS**
|
||||
|
||||
在后端服务器设置 HTTP 响应头,把你需要允许访问的域名加入 `Access-Control-Allow-Origin` 中。
|
||||
|
||||
2. **jsonp**
|
||||
|
||||
把后端根据请求,构造 json 数据,并返回,前端用 jsonp 跨域。
|
||||
|
||||
这两种思路,本文不展开讨论。
|
||||
|
||||
需要说明的是,nginx 根据第一种思路,也提供了一种解决跨域的解决方案。
|
||||
|
||||
举例:www.helloworld.com 网站是由一个前端 app ,一个后端 app 组成的。前端端口号为 9000, 后端端口号为 8080。
|
||||
|
||||
前端和后端如果使用 http 进行交互时,请求会被拒绝,因为存在跨域问题。来看看,nginx 是怎么解决的吧:
|
||||
|
||||
首先,在 enable-cors.conf 文件中设置 cors :
|
||||
|
||||
```nginx
|
||||
# allow origin list
|
||||
set $ACAO '*';
|
||||
|
||||
# set single origin
|
||||
if ($http_origin ~* (www.helloworld.com)$) {
|
||||
set $ACAO $http_origin;
|
||||
}
|
||||
|
||||
if ($cors = "trueget") {
|
||||
add_header 'Access-Control-Allow-Origin' "$http_origin";
|
||||
add_header 'Access-Control-Allow-Credentials' 'true';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
|
||||
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
|
||||
}
|
||||
|
||||
if ($request_method = 'OPTIONS') {
|
||||
set $cors "${cors}options";
|
||||
}
|
||||
|
||||
if ($request_method = 'GET') {
|
||||
set $cors "${cors}get";
|
||||
}
|
||||
|
||||
if ($request_method = 'POST') {
|
||||
set $cors "${cors}post";
|
||||
}
|
||||
```
|
||||
|
||||
接下来,在你的服务器中 `include enable-cors.conf` 来引入跨域配置:
|
||||
|
||||
```nginx
|
||||
# ----------------------------------------------------
|
||||
# 此文件为项目 nginx 配置片段
|
||||
# 可以直接在 nginx config 中 include(推荐)
|
||||
# 或者 copy 到现有 nginx 中,自行配置
|
||||
# www.helloworld.com 域名需配合 dns hosts 进行配置
|
||||
# 其中,api 开启了 cors,需配合本目录下另一份配置文件
|
||||
# ----------------------------------------------------
|
||||
upstream front_server{
|
||||
server www.helloworld.com:9000;
|
||||
}
|
||||
upstream api_server{
|
||||
server www.helloworld.com:8080;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name www.helloworld.com;
|
||||
|
||||
location ~ ^/api/ {
|
||||
include enable-cors.conf;
|
||||
proxy_pass http://api_server;
|
||||
rewrite "^/api/(.*)$" /$1 break;
|
||||
}
|
||||
|
||||
location ~ ^/ {
|
||||
proxy_pass http://front_server;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
到此,就完成了。
|
||||
|
||||
## 参考
|
||||
|
||||
- [Nginx 的中文维基](http://tool.oschina.net/apidocs/apidoc?api=nginx-zh)
|
||||
- [Nginx开发从入门到精通](http://tengine.taobao.org/book/index.html)
|
||||
- https://github.com/trimstray/nginx-admins-handbook
|
||||
- [nginxconfig.io](https://nginxconfig.io/) - 一款 Nginx 配置生成器
|
||||
- [Nginx 快速教程](nginx-quickstart.md)
|
||||
- [Nginx 安装](nginx-install.md)
|
||||
- [Nginx 配置](nginx-configuration.md)
|
||||
- [Nginx 问题](nginx-faq.md)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<div align="center"><img width="100px" src="http://dunwu.test.upcdn.net/cs/others/zp.png"/></div>
|
||||
|
||||
# Nginx Tutorial
|
||||
<div align="center"><img width="100px" src="http://dunwu.test.upcdn.net/common/logo/zp.png"/></div>
|
||||
# nginx-tutorial
|
||||
|
||||
> Nginx 极简教程
|
||||
|
||||
[开始阅读](README.md)
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
|
||||
name="viewport"
|
||||
/>
|
||||
<link href="http://dunwu.test.upcdn.net/images/others/zp_50_50.png" rel="icon" type="image/x-icon"/>
|
||||
<link href="http://dunwu.test.upcdn.net/common/logo/zp_50_50.png" rel="icon" type="image/x-icon"/>
|
||||
<link href="//unpkg.com/docsify/lib/themes/vue.css" rel="stylesheet" title="vue"/>
|
||||
<style>
|
||||
h1 + ul {
|
||||
|
@ -104,10 +104,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
/*.cover-main {*/
|
||||
/*text-shadow: 2px 2px 5px grey;*/
|
||||
/*}*/
|
||||
|
||||
.content h1 a,
|
||||
.content h1 span {
|
||||
color: #399AB2 !important;
|
||||
|
@ -220,7 +216,7 @@
|
|||
window.$docsify = {
|
||||
name: 'Nginx Tutorial',
|
||||
repo: 'https://github.com/dunwu/nginx-tutorial',
|
||||
logo: 'http://dunwu.test.upcdn.net/images/others/zp_100_100.png',
|
||||
logo: 'http://dunwu.test.upcdn.net/common/logo/zp_100_100.png',
|
||||
auto2top: true,
|
||||
coverpage: 'coverpage.md',
|
||||
maxLevel: 4,
|
||||
|
@ -241,10 +237,12 @@
|
|||
<script src="//unpkg.com/docsify/lib/plugins/search.js"></script>
|
||||
|
||||
<!--代码高亮-->
|
||||
<!--@see https://github.com/PrismJS/prism/tree/gh-pages/components-->
|
||||
<!--@see https://github.com/PrismJS/prism -->
|
||||
<script src="//unpkg.com/prismjs/components/prism-basic.min.js"></script>
|
||||
<script src="//unpkg.com/prismjs/components/prism-bash.min.js"></script>
|
||||
<script src="//unpkg.com/prismjs/components/prism-batch.min.js"></script>
|
||||
<script src="//unpkg.com/prismjs/components/prism-nginx.min.js"></script>
|
||||
<script src="//unpkg.com/prismjs/components/prism-markdown.min.js"></script>
|
||||
<script src="//unpkg.com/prismjs/components/prism-vim.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,72 @@
|
|||
# Nginx 问题集
|
||||
|
||||
## Nginx 出现大量 TIME_WAIT
|
||||
|
||||
### 检测TIME_WAIT状态的语句
|
||||
|
||||
```bash
|
||||
$ netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
|
||||
SYN_RECV 7
|
||||
ESTABLISHED 756
|
||||
FIN_WAIT1 21
|
||||
SYN_SENT 3
|
||||
TIME_WAIT 2000
|
||||
```
|
||||
|
||||
状态解析:
|
||||
|
||||
- `CLOSED` - 无连接是活动的或正在进行
|
||||
- `LISTEN` - 服务器在等待进入呼叫
|
||||
- `SYN_RECV` - 一个连接请求已经到达,等待确认
|
||||
- `SYN_SENT` - 应用已经开始,打开一个连接
|
||||
- `ESTABLISHED` - 正常数据传输状态
|
||||
- `FIN_WAIT1` - 应用说它已经完成
|
||||
- `FIN_WAIT2` - 另一边已同意释放
|
||||
- `ITMED_WAIT` - 等待所有分组死掉
|
||||
- `CLOSING` - 两边同时尝试关闭
|
||||
- `TIME_WAIT` - 另一边已初始化一个释放
|
||||
- `LAST_ACK` - 等待所有分组死掉
|
||||
|
||||
### 解决方法
|
||||
|
||||
执行 `vim /etc/sysctl.conf`,并添加下面字段
|
||||
|
||||
```properties
|
||||
net.ipv4.tcp_syncookies = 1
|
||||
net.ipv4.tcp_tw_reuse = 1
|
||||
net.ipv4.tcp_tw_recycle = 1
|
||||
net.ipv4.tcp_fin_timeout = 30
|
||||
```
|
||||
|
||||
执行 /`sbin/sysctl -p` 让修改生效。
|
||||
|
||||
## 上传文件大小限制
|
||||
|
||||
### 问题现象
|
||||
|
||||
显示错误信息:**413 Request Entity Too Large**。
|
||||
|
||||
意思是请求的内容过大,浏览器不能正确显示。常见的情况是发送 `POST` 请求来上传大文件。
|
||||
|
||||
### 解决方法
|
||||
|
||||
- 可以在 `http` 模块中设置:`client_max_body_size 20m;`
|
||||
- 可以在 `server` 模块中设置:`client_max_body_size 20m;`
|
||||
- 可以在 `location` 模块中设置:`client_max_body_size 20m;`
|
||||
|
||||
三者区别是:
|
||||
|
||||
- 如果文大小限制设置在 `http` 模块中,则对所有 Nginx 收到的请求。
|
||||
- 如果文大小限制设置在 `server` 模块中,则只对该 `server` 收到的请求生效。
|
||||
- 如果文大小限制设置在 `location` 模块中,则只对匹配了 `location` 路由规则的请求生效。
|
||||
|
||||
## 请求时间限制
|
||||
|
||||
### 问题现象
|
||||
|
||||
请求时间较长,链接被重置页面刷新。常见的情况是:上传、下载大文件。
|
||||
|
||||
### 解决方法
|
||||
|
||||
修改超时时间
|
||||
|
|
@ -1,14 +1,16 @@
|
|||
# Nginx 安装
|
||||
|
||||
<!-- TOC depthFrom:2 depthTo:3 -->
|
||||
<!-- TOC depthfrom:2 depthto:3 -->
|
||||
|
||||
- [Windows 安装](#windows-安装)
|
||||
- [Linux 安装](#linux-安装)
|
||||
- [rpm 包方式(推荐)](#rpm-包方式推荐)
|
||||
- [源码编译方式](#源码编译方式)
|
||||
- [安装编译工具及库文件](#安装编译工具及库文件)
|
||||
- [安装 Nginx](#安装-nginx)
|
||||
- [Linux 开机自启动](#linux-开机自启动)
|
||||
- [rpm 包方式](#rpm-包方式)
|
||||
- [源码编译方式](#源码编译方式-1)
|
||||
- [源码编译方式](#源码编译方式)
|
||||
- [脚本](#脚本)
|
||||
- [参考资料](#参考资料)
|
||||
|
||||
|
@ -28,7 +30,7 @@
|
|||
|
||||
下面以 C 盘根目录为例说明下:
|
||||
|
||||
```
|
||||
```bash
|
||||
cd C:
|
||||
cd C:\nginx-0.8.54 start nginx
|
||||
```
|
||||
|
@ -41,7 +43,7 @@ cd C:\nginx-0.8.54 start nginx
|
|||
|
||||
(1)进入[下载页面](http://nginx.org/packages/),选择合适版本下载。
|
||||
|
||||
```sh
|
||||
```bash
|
||||
$ wget http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
|
||||
```
|
||||
|
||||
|
@ -49,19 +51,19 @@ $ wget http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.e
|
|||
|
||||
nginx rpm 包实际上安装的是 nginx 的 yum 源。
|
||||
|
||||
```
|
||||
```bash
|
||||
$ rpm -ivh nginx-*.rpm
|
||||
```
|
||||
|
||||
(3)正式安装 rpm 包
|
||||
|
||||
```
|
||||
```bash
|
||||
$ yum install nginx
|
||||
```
|
||||
|
||||
(4)关闭防火墙
|
||||
|
||||
```sh
|
||||
```bash
|
||||
$ firewall-cmd --zone=public --add-port=80/tcp --permanent
|
||||
$ firewall-cmd --reload
|
||||
```
|
||||
|
@ -72,7 +74,7 @@ $ firewall-cmd --reload
|
|||
|
||||
Nginx 源码的编译依赖于 gcc 以及一些库文件,所以必须提前安装。
|
||||
|
||||
```sh
|
||||
```bash
|
||||
$ yum -y install make zlib zlib-devel gcc-c++ libtool openssl openssl-devel
|
||||
```
|
||||
|
||||
|
@ -84,7 +86,7 @@ Nginx 依赖 pcre 库,安装步骤如下:
|
|||
|
||||
我选择的是 8.35 版本:
|
||||
|
||||
```
|
||||
```bash
|
||||
wget -O /opt/pcre/pcre-8.35.tar.gz http://downloads.sourceforge.net/project/pcre/pcre/8.35/pcre-8.35.tar.gz
|
||||
cd /opt/pcre
|
||||
tar zxvf pcre-8.35.tar.gz
|
||||
|
@ -94,7 +96,7 @@ tar zxvf pcre-8.35.tar.gz
|
|||
|
||||
执行以下命令:
|
||||
|
||||
```
|
||||
```bash
|
||||
cd /opt/pcre/pcre-8.35
|
||||
./configure
|
||||
make && make install
|
||||
|
@ -114,7 +116,7 @@ make && make install
|
|||
|
||||
我选择的是 1.12.2 版本:http://downloads.sourceforge.net/project/pcre/pcre/8.35/pcre-8.35.tar.gz
|
||||
|
||||
```
|
||||
```bash
|
||||
wget -O /opt/nginx/nginx-1.12.2.tar.gz http://nginx.org/download/nginx-1.12.2.tar.gz
|
||||
cd /opt/nginx
|
||||
tar zxvf nginx-1.12.2.tar.gz
|
||||
|
@ -124,14 +126,14 @@ tar zxvf nginx-1.12.2.tar.gz
|
|||
|
||||
执行以下命令:
|
||||
|
||||
```
|
||||
```bash
|
||||
cd /opt/nginx/nginx-1.12.2
|
||||
./configure --with-http_stub_status_module --with-http_ssl_module --with-pcre=/opt/pcre/pcre-8.35
|
||||
```
|
||||
|
||||
(3)关闭防火墙
|
||||
|
||||
```sh
|
||||
```bash
|
||||
$ firewall-cmd --zone=public --add-port=80/tcp --permanent
|
||||
$ firewall-cmd --reload
|
||||
```
|
||||
|
@ -154,7 +156,7 @@ Centos7 以上是用 Systemd 进行系统初始化的,Systemd 是 Linux 系统
|
|||
|
||||
直接用命令:
|
||||
|
||||
```sh
|
||||
```bash
|
||||
$ systemctl enable nginx.service
|
||||
```
|
||||
|
|
@ -0,0 +1,616 @@
|
|||
# Nginx 极简教程
|
||||
|
||||
> **Nginx 是一个开源的 HTTP 和反向代理服务器,一个邮件代理服务器以及一个通用的 TCP / UDP 代理服务器**。
|
||||
>
|
||||
> 本项目是一个 Nginx 极简教程,目的在于帮助新手快速入门 Nginx。
|
||||
>
|
||||
> [**examples**](https://github.com/dunwu/nginx-tutorial/tree/master/examples) 目录中的示例模拟了工作中的一些常用实战场景,并且都可以通过脚本一键式启动,让您可以快速看到演示效果。
|
||||
|
||||
## 简介
|
||||
|
||||
### 什么是 Nginx?
|
||||
|
||||
Nginx 是一种快速、轻巧且功能强大的 Web 服务器,也可以用作:
|
||||
|
||||
- 快速 HTTP 反向代理
|
||||
- 可靠的负载均衡器
|
||||
- 高性能缓存服务器
|
||||
- 完善的网络平台
|
||||
|
||||
### Nginx 模块化结构
|
||||
|
||||
Nginx 有一个主进程和几个工作进程。**主流程的主要目的是读取和评估配置,以及维护工作流程**。**工作进程对请求进行实际处理**。Nginx 使用基于事件的模型和依赖于操作系统的机制来有效地在工作进程之间分配请求。
|
||||
|
||||
Nginx 服务完全遵循模块化设计思想。
|
||||
|
||||
<br><div align="center"><img src="http://dunwu.test.upcdn.net/cs/web/nginx/nginx.jpg!zp"/></div><br>
|
||||
|
||||
### 什么是反向代理?
|
||||
|
||||
反向代理(Reverse Proxy)方式是指以代理服务器来接受 internet 上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给 internet 上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。
|
||||
|
||||
<br><div align="center"><img src="http://dunwu.test.upcdn.net/cs/web/nginx/reverse-proxy.png!zp"/></div><br>
|
||||
|
||||
## Nginx 命令
|
||||
|
||||
> 详细安装方法请参考:[Nginx 安装](nginx-install.md)
|
||||
|
||||
nginx 的使用比较简单,就是几条命令。
|
||||
|
||||
常用到的命令如下:
|
||||
|
||||
- `nginx -h` - 显示帮助
|
||||
- `nginx -v` - 显示 Nginx 的版本
|
||||
- `nginx -V` - 显示 Nginx 的版本,编译器版本和配置参数。
|
||||
- `nginx -t` - 测试 Nginx 配置
|
||||
- `nginx -c <文件名>` - 设置配置文件(默认:`/etc/nginx/nginx.conf`)
|
||||
- `nginx -p <目录>` - 设置前缀路径(默认值:`/etc/nginx/`)
|
||||
- `nginx -T` - 测试 Nginx 配置并在屏幕上打印经过验证的配置
|
||||
- `nginx -s <signal>` - 向 Nginx 主进程发送信号:
|
||||
- `stop` - 快速关闭 Nginx,可能不保存相关信息,并迅速终止 web 服务
|
||||
- `quit` - 平稳关闭 Nginx,保存相关信息,有安排的结束 web 服务
|
||||
- `reload` - 重新加载配置而不停止进程
|
||||
- `reopen` - 重新打开日志文件
|
||||
- `nginx -g <指令>` - 将全局指令设置为超出配置文件
|
||||
|
||||
如果不想每次都敲命令,可以在 nginx 安装目录下新添一个启动批处理文件**startup.bat**,双击即可运行。内容如下:
|
||||
|
||||
```batch
|
||||
@echo off
|
||||
rem 如果启动前已经启动nginx并记录下pid文件,会kill指定进程
|
||||
nginx.exe -s stop
|
||||
|
||||
rem 测试配置文件语法正确性
|
||||
nginx.exe -t -c conf/nginx.conf
|
||||
|
||||
rem 显示版本信息
|
||||
nginx.exe -v
|
||||
|
||||
rem 按照指定配置去启动nginx
|
||||
nginx.exe -c conf/nginx.conf
|
||||
```
|
||||
|
||||
如果是运行在 Linux 下,写一个 shell 脚本,大同小异。
|
||||
|
||||
## Nginx 实战
|
||||
|
||||
我始终认为,各种开发工具的配置还是结合实战来讲述,会让人更易理解。
|
||||
|
||||
### Http 反向代理
|
||||
|
||||
我们先实现一个小目标:不考虑复杂的配置,仅仅是完成一个 http 反向代理。
|
||||
|
||||
`nginx.conf` 配置文件如下:
|
||||
|
||||
> **_注:`conf/nginx.conf` 是 nginx 的默认配置文件。你也可以使用 nginx -c 指定你的配置文件_**
|
||||
|
||||
```nginx
|
||||
#运行用户
|
||||
#user somebody;
|
||||
|
||||
#启动进程,通常设置成和cpu的数量相等
|
||||
worker_processes 1;
|
||||
|
||||
#全局错误日志
|
||||
error_log D:/Tools/nginx-1.10.1/logs/error.log;
|
||||
error_log D:/Tools/nginx-1.10.1/logs/notice.log notice;
|
||||
error_log D:/Tools/nginx-1.10.1/logs/info.log info;
|
||||
|
||||
#PID文件,记录当前启动的nginx的进程ID
|
||||
pid D:/Tools/nginx-1.10.1/logs/nginx.pid;
|
||||
|
||||
#工作模式及连接数上限
|
||||
events {
|
||||
worker_connections 1024; #单个后台worker process进程的最大并发链接数
|
||||
}
|
||||
|
||||
#设定http服务器,利用它的反向代理功能提供负载均衡支持
|
||||
http {
|
||||
#设定mime类型(邮件支持类型),类型由mime.types文件定义
|
||||
include D:/Tools/nginx-1.10.1/conf/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
#设定日志
|
||||
log_format main '[$remote_addr] - [$remote_user] [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
access_log D:/Tools/nginx-1.10.1/logs/access.log main;
|
||||
rewrite_log on;
|
||||
|
||||
#sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,对于普通应用,
|
||||
#必须设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,以平衡磁盘与网络I/O处理速度,降低系统的uptime.
|
||||
sendfile on;
|
||||
#tcp_nopush on;
|
||||
|
||||
#连接超时时间
|
||||
keepalive_timeout 120;
|
||||
tcp_nodelay on;
|
||||
|
||||
#gzip压缩开关
|
||||
#gzip on;
|
||||
|
||||
#设定实际的服务器列表
|
||||
upstream zp_server1{
|
||||
server 127.0.0.1:8089;
|
||||
}
|
||||
|
||||
#HTTP服务器
|
||||
server {
|
||||
#监听80端口,80端口是知名端口号,用于HTTP协议
|
||||
listen 80;
|
||||
|
||||
#定义使用www.xx.com访问
|
||||
server_name www.helloworld.com;
|
||||
|
||||
#首页
|
||||
index index.html
|
||||
|
||||
#指向webapp的目录
|
||||
root D:\01_Workspace\Project\github\zp\SpringNotes\spring-security\spring-shiro\src\main\webapp;
|
||||
|
||||
#编码格式
|
||||
charset utf-8;
|
||||
|
||||
#代理配置参数
|
||||
proxy_connect_timeout 180;
|
||||
proxy_send_timeout 180;
|
||||
proxy_read_timeout 180;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarder-For $remote_addr;
|
||||
|
||||
#反向代理的路径(和upstream绑定),location 后面设置映射的路径
|
||||
location / {
|
||||
proxy_pass http://zp_server1;
|
||||
}
|
||||
|
||||
#静态文件,nginx自己处理
|
||||
location ~ ^/(images|javascript|js|css|flash|media|static)/ {
|
||||
root D:\01_Workspace\Project\github\zp\SpringNotes\spring-security\spring-shiro\src\main\webapp\views;
|
||||
#过期30天,静态文件不怎么更新,过期可以设大一点,如果频繁更新,则可以设置得小一点。
|
||||
expires 30d;
|
||||
}
|
||||
|
||||
#设定查看Nginx状态的地址
|
||||
location /NginxStatus {
|
||||
stub_status on;
|
||||
access_log on;
|
||||
auth_basic "NginxStatus";
|
||||
auth_basic_user_file conf/htpasswd;
|
||||
}
|
||||
|
||||
#禁止访问 .htxxx 文件
|
||||
location ~ /\.ht {
|
||||
deny all;
|
||||
}
|
||||
|
||||
#错误处理页面(可选择性配置)
|
||||
#error_page 404 /404.html;
|
||||
#error_page 500 502 503 504 /50x.html;
|
||||
#location = /50x.html {
|
||||
# root html;
|
||||
#}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
好了,让我们来试试吧:
|
||||
|
||||
1. 启动 webapp,注意启动绑定的端口要和 nginx 中的 `upstream` 设置的端口保持一致。
|
||||
2. 更改 host:在 C:\Windows\System32\drivers\etc 目录下的 host 文件中添加一条 DNS 记录
|
||||
|
||||
```
|
||||
127.0.0.1 www.helloworld.com
|
||||
```
|
||||
|
||||
3. 启动前文中 startup.bat 的命令
|
||||
4. 在浏览器中访问 www.helloworld.com,不出意外,已经可以访问了。
|
||||
|
||||
### Https 反向代理
|
||||
|
||||
一些对安全性要求比较高的站点,可能会使用 HTTPS(一种使用 ssl 通信标准的安全 HTTP 协议)。
|
||||
|
||||
这里不科普 HTTP 协议和 SSL 标准。但是,使用 nginx 配置 https 需要知道几点:
|
||||
|
||||
- HTTPS 的固定端口号是 443,不同于 HTTP 的 80 端口
|
||||
- SSL 标准需要引入安全证书,所以在 nginx.conf 中你需要指定证书和它对应的 key
|
||||
|
||||
其他和 http 反向代理基本一样,只是在 `Server` 部分配置有些不同。
|
||||
|
||||
```nginx
|
||||
#HTTP服务器
|
||||
server {
|
||||
#监听443端口。443为知名端口号,主要用于HTTPS协议
|
||||
listen 443 ssl;
|
||||
|
||||
#定义使用www.xx.com访问
|
||||
server_name www.helloworld.com;
|
||||
|
||||
#ssl证书文件位置(常见证书文件格式为:crt/pem)
|
||||
ssl_certificate cert.pem;
|
||||
#ssl证书key位置
|
||||
ssl_certificate_key cert.key;
|
||||
|
||||
#ssl配置参数(选择性配置)
|
||||
ssl_session_cache shared:SSL:1m;
|
||||
ssl_session_timeout 5m;
|
||||
#数字签名,此处使用MD5
|
||||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||
ssl_prefer_server_ciphers on;
|
||||
|
||||
location / {
|
||||
root /root;
|
||||
index index.html index.htm;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 负载均衡
|
||||
|
||||
前面的例子中,代理仅仅指向一个服务器。
|
||||
|
||||
但是,网站在实际运营过程中,大部分都是以集群的方式运行,这时需要使用负载均衡来分流。
|
||||
|
||||
nginx 也可以实现简单的负载均衡功能。
|
||||
|
||||
<br><div align="center"><img src="http://dunwu.test.upcdn.net/cs/web/nginx/nginx-load-balance.png!zp"/></div><br>
|
||||
|
||||
假设这样一个应用场景:将应用部署在 192.168.1.11:80、192.168.1.12:80、192.168.1.13:80 三台 linux 环境的服务器上。网站域名叫 www.helloworld.com,公网 IP 为 192.168.1.11。在公网 IP 所在的服务器上部署 nginx,对所有请求做负载均衡处理(下面例子中使用的是加权轮询策略)。
|
||||
|
||||
nginx.conf 配置如下:
|
||||
|
||||
```nginx
|
||||
http {
|
||||
#设定mime类型,类型由mime.type文件定义
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
#设定日志格式
|
||||
access_log /var/log/nginx/access.log;
|
||||
|
||||
#设定负载均衡的服务器列表
|
||||
upstream load_balance_server {
|
||||
#weigth参数表示权值,权值越高被分配到的几率越大
|
||||
server 192.168.1.11:80 weight=5;
|
||||
server 192.168.1.12:80 weight=1;
|
||||
server 192.168.1.13:80 weight=6;
|
||||
}
|
||||
|
||||
#HTTP服务器
|
||||
server {
|
||||
#侦听80端口
|
||||
listen 80;
|
||||
|
||||
#定义使用www.xx.com访问
|
||||
server_name www.helloworld.com;
|
||||
|
||||
#对所有请求进行负载均衡请求
|
||||
location / {
|
||||
root /root; #定义服务器的默认网站根目录位置
|
||||
index index.html index.htm; #定义首页索引文件的名称
|
||||
proxy_pass http://load_balance_server ;#请求转向load_balance_server 定义的服务器列表
|
||||
|
||||
#以下是一些反向代理的配置(可选择性配置)
|
||||
#proxy_redirect off;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
#后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
proxy_connect_timeout 90; #nginx跟后端服务器连接超时时间(代理连接超时)
|
||||
proxy_send_timeout 90; #后端服务器数据回传时间(代理发送超时)
|
||||
proxy_read_timeout 90; #连接成功后,后端服务器响应时间(代理接收超时)
|
||||
proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小
|
||||
proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
|
||||
proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)
|
||||
proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传
|
||||
|
||||
client_max_body_size 10m; #允许客户端请求的最大单文件字节数
|
||||
client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 负载均衡策略
|
||||
|
||||
Nginx 提供了多种负载均衡策略,让我们来一一了解一下:
|
||||
|
||||
负载均衡策略在各种分布式系统中基本上原理一致,对于原理有兴趣,不妨参考 [负载均衡](https://dunwu.github.io/javaweb/#/theory/load-balance)
|
||||
|
||||
##### 轮询
|
||||
|
||||
```nginx
|
||||
upstream bck_testing_01 {
|
||||
# 默认所有服务器权重为 1
|
||||
server 192.168.250.220:8080
|
||||
server 192.168.250.221:8080
|
||||
server 192.168.250.222:8080
|
||||
}
|
||||
```
|
||||
|
||||
##### 加权轮询
|
||||
|
||||
```nginx
|
||||
upstream bck_testing_01 {
|
||||
server 192.168.250.220:8080 weight=3
|
||||
server 192.168.250.221:8080 # default weight=1
|
||||
server 192.168.250.222:8080 # default weight=1
|
||||
}
|
||||
```
|
||||
|
||||
##### 最少连接
|
||||
|
||||
```nginx
|
||||
upstream bck_testing_01 {
|
||||
least_conn;
|
||||
|
||||
# with default weight for all (weight=1)
|
||||
server 192.168.250.220:8080
|
||||
server 192.168.250.221:8080
|
||||
server 192.168.250.222:8080
|
||||
}
|
||||
```
|
||||
|
||||
##### 加权最少连接
|
||||
|
||||
```nginx
|
||||
upstream bck_testing_01 {
|
||||
least_conn;
|
||||
|
||||
server 192.168.250.220:8080 weight=3
|
||||
server 192.168.250.221:8080 # default weight=1
|
||||
server 192.168.250.222:8080 # default weight=1
|
||||
}
|
||||
```
|
||||
|
||||
##### IP Hash
|
||||
|
||||
```nginx
|
||||
upstream bck_testing_01 {
|
||||
|
||||
ip_hash;
|
||||
|
||||
# with default weight for all (weight=1)
|
||||
server 192.168.250.220:8080
|
||||
server 192.168.250.221:8080
|
||||
server 192.168.250.222:8080
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
##### 普通 Hash
|
||||
|
||||
```nginx
|
||||
upstream bck_testing_01 {
|
||||
|
||||
hash $request_uri;
|
||||
|
||||
# with default weight for all (weight=1)
|
||||
server 192.168.250.220:8080
|
||||
server 192.168.250.221:8080
|
||||
server 192.168.250.222:8080
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
### 网站有多个 webapp 的配置
|
||||
|
||||
当一个网站功能越来越丰富时,往往需要将一些功能相对独立的模块剥离出来,独立维护。这样的话,通常,会有多个 webapp。
|
||||
|
||||
举个例子:假如 www.helloworld.com 站点有好几个 webapp,finance(金融)、product(产品)、admin(用户中心)。访问这些应用的方式通过上下文(context)来进行区分:
|
||||
|
||||
www.helloworld.com/finance/
|
||||
|
||||
www.helloworld.com/product/
|
||||
|
||||
www.helloworld.com/admin/
|
||||
|
||||
我们知道,http 的默认端口号是 80,如果在一台服务器上同时启动这 3 个 webapp 应用,都用 80 端口,肯定是不成的。所以,这三个应用需要分别绑定不同的端口号。
|
||||
|
||||
那么,问题来了,用户在实际访问 www.helloworld.com 站点时,访问不同 webapp,总不会还带着对应的端口号去访问吧。所以,你再次需要用到反向代理来做处理。
|
||||
|
||||
配置也不难,来看看怎么做吧:
|
||||
|
||||
```nginx
|
||||
http {
|
||||
#此处省略一些基本配置
|
||||
|
||||
upstream product_server{
|
||||
server www.helloworld.com:8081;
|
||||
}
|
||||
|
||||
upstream admin_server{
|
||||
server www.helloworld.com:8082;
|
||||
}
|
||||
|
||||
upstream finance_server{
|
||||
server www.helloworld.com:8083;
|
||||
}
|
||||
|
||||
server {
|
||||
#此处省略一些基本配置
|
||||
#默认指向product的server
|
||||
location / {
|
||||
proxy_pass http://product_server;
|
||||
}
|
||||
|
||||
location /product/{
|
||||
proxy_pass http://product_server;
|
||||
}
|
||||
|
||||
location /admin/ {
|
||||
proxy_pass http://admin_server;
|
||||
}
|
||||
|
||||
location /finance/ {
|
||||
proxy_pass http://finance_server;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 静态站点
|
||||
|
||||
有时候,我们需要配置静态站点(即 html 文件和一堆静态资源)。
|
||||
|
||||
举例来说:如果所有的静态资源都放在了 `/app/dist` 目录下,我们只需要在 `nginx.conf` 中指定首页以及这个站点的 host 即可。
|
||||
|
||||
配置如下:
|
||||
|
||||
```nginx
|
||||
worker_processes 1;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
include mime.types;
|
||||
default_type application/octet-stream;
|
||||
sendfile on;
|
||||
keepalive_timeout 65;
|
||||
|
||||
gzip on;
|
||||
gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/javascript image/jpeg image/gif image/png;
|
||||
gzip_vary on;
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name static.zp.cn;
|
||||
|
||||
location / {
|
||||
root /app/dist;
|
||||
index index.html;
|
||||
#转发任何请求到 index.html
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
然后,添加 HOST:
|
||||
|
||||
127.0.0.1 static.zp.cn
|
||||
|
||||
此时,在本地浏览器访问 static.zp.cn ,就可以访问静态站点了。
|
||||
|
||||
### 搭建文件服务器
|
||||
|
||||
有时候,团队需要归档一些数据或资料,那么文件服务器必不可少。使用 Nginx 可以非常快速便捷的搭建一个简易的文件服务。
|
||||
|
||||
Nginx 中的配置要点:
|
||||
|
||||
- 将 autoindex 开启可以显示目录,默认不开启。
|
||||
- 将 autoindex_exact_size 开启可以显示文件的大小。
|
||||
- 将 autoindex_localtime 开启可以显示文件的修改时间。
|
||||
- root 用来设置开放为文件服务的根路径。
|
||||
- charset 设置为 `charset utf-8,gbk;`,可以避免中文乱码问题(windows 服务器下设置后,依然乱码,本人暂时没有找到解决方法)。
|
||||
|
||||
一个最简化的配置如下:
|
||||
|
||||
```nginx
|
||||
autoindex on;# 显示目录
|
||||
autoindex_exact_size on;# 显示文件大小
|
||||
autoindex_localtime on;# 显示文件时间
|
||||
|
||||
server {
|
||||
charset utf-8,gbk; # windows 服务器下设置后,依然乱码,暂时无解
|
||||
listen 9050 default_server;
|
||||
listen [::]:9050 default_server;
|
||||
server_name _;
|
||||
root /share/fs;
|
||||
}
|
||||
```
|
||||
|
||||
### 解决跨域
|
||||
|
||||
web 领域开发中,经常采用前后端分离模式。这种模式下,前端和后端分别是独立的 web 应用程序,例如:后端是 Java 程序,前端是 React 或 Vue 应用。
|
||||
|
||||
各自独立的 web app 在互相访问时,势必存在跨域问题。解决跨域问题一般有两种思路:
|
||||
|
||||
1. **CORS**
|
||||
|
||||
在后端服务器设置 HTTP 响应头,把你需要允许访问的域名加入 `Access-Control-Allow-Origin` 中。
|
||||
|
||||
2. **jsonp**
|
||||
|
||||
把后端根据请求,构造 json 数据,并返回,前端用 jsonp 跨域。
|
||||
|
||||
这两种思路,本文不展开讨论。
|
||||
|
||||
需要说明的是,nginx 根据第一种思路,也提供了一种解决跨域的解决方案。
|
||||
|
||||
举例:www.helloworld.com 网站是由一个前端 app ,一个后端 app 组成的。前端端口号为 9000, 后端端口号为 8080。
|
||||
|
||||
前端和后端如果使用 http 进行交互时,请求会被拒绝,因为存在跨域问题。来看看,nginx 是怎么解决的吧:
|
||||
|
||||
首先,在 enable-cors.conf 文件中设置 cors :
|
||||
|
||||
```nginx
|
||||
# allow origin list
|
||||
set $ACAO '*';
|
||||
|
||||
# set single origin
|
||||
if ($http_origin ~* (www.helloworld.com)$) {
|
||||
set $ACAO $http_origin;
|
||||
}
|
||||
|
||||
if ($cors = "trueget") {
|
||||
add_header 'Access-Control-Allow-Origin' "$http_origin";
|
||||
add_header 'Access-Control-Allow-Credentials' 'true';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
|
||||
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
|
||||
}
|
||||
|
||||
if ($request_method = 'OPTIONS') {
|
||||
set $cors "${cors}options";
|
||||
}
|
||||
|
||||
if ($request_method = 'GET') {
|
||||
set $cors "${cors}get";
|
||||
}
|
||||
|
||||
if ($request_method = 'POST') {
|
||||
set $cors "${cors}post";
|
||||
}
|
||||
```
|
||||
|
||||
接下来,在你的服务器中 `include enable-cors.conf` 来引入跨域配置:
|
||||
|
||||
```nginx
|
||||
# ----------------------------------------------------
|
||||
# 此文件为项目 nginx 配置片段
|
||||
# 可以直接在 nginx config 中 include(推荐)
|
||||
# 或者 copy 到现有 nginx 中,自行配置
|
||||
# www.helloworld.com 域名需配合 dns hosts 进行配置
|
||||
# 其中,api 开启了 cors,需配合本目录下另一份配置文件
|
||||
# ----------------------------------------------------
|
||||
upstream front_server{
|
||||
server www.helloworld.com:9000;
|
||||
}
|
||||
upstream api_server{
|
||||
server www.helloworld.com:8080;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name www.helloworld.com;
|
||||
|
||||
location ~ ^/api/ {
|
||||
include enable-cors.conf;
|
||||
proxy_pass http://api_server;
|
||||
rewrite "^/api/(.*)$" /$1 break;
|
||||
}
|
||||
|
||||
location ~ ^/ {
|
||||
proxy_pass http://front_server;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
到此,就完成了。
|
||||
|
||||
## 参考
|
||||
|
||||
- [Nginx 的中文维基](http://tool.oschina.net/apidocs/apidoc?api=nginx-zh)
|
||||
- [Nginx 开发从入门到精通](http://tengine.taobao.org/book/index.html)
|
||||
- https://github.com/trimstray/nginx-admins-handbook
|
||||
- [nginxconfig.io](https://nginxconfig.io/) - 一款 Nginx 配置生成器
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "NginxTutorial",
|
||||
"name": "nginx-tutorial",
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"start": "docsify serve ./ --port 4000"
|
||||
|
|
Loading…
Reference in New Issue