基于Docker部署并试用Nginx主要功能
1 Web服务器功能
1.1 基于域名访问
1.1.1 需求说明
- 局域网内部有A和B两个网站,利用Nginx可以做为Web服务器的功能,把这两个网站部署到同一台Nginx类型的Web服务器上,并在Nginx中设置按域名来访问这两个网站,其中对域名
aaa.test.com
的访问请求由A网站处理,对域名bbb.test.com
的访问请求由B网站处理。 - 在Ubuntu中部署一个Nginx的Docker容器,该容器即为Nginx Web服务器,其中A网站部署在Nginx Web服务器的
/usr/local/html/aaa
目录下,B网站部署在Nginx Web服务器的/usr/local/html/bbb
目录下。
1.1.2 准备工作
- 在ubuntu的
/mnt/share/config/nginx/web/aaa
目录下创建一个index.html网页文件,该文件表示A网站主页,其内容如下:<html> <head> <title>index</title> </head> <body> <b2>This is aaa index page</b2> </body> </html>
- 在ubuntu的
/mnt/share/config/nginx/web/bbb
目录下创建一个index.hmtl网页文件,该文件表示B网站主页,其内容如下:<html> <head> <title>index</title> </head> <body> <b2>This is bbb index page</b2> </body> </html>
1.1.3 实战过程
-
在
ubuntu的/mnt/share/config/nginx
目录下创建名称为nginx.conf的配置文件,该配置文件会被用于Nginx服务器,其内容如下:user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/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 /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; server { listen 80; server_name aaa.test.com; location / { root /usr/local/html/aaa; index index.html; } } server { listen 80; server_name bbb.test.com; location / { root /usr/local/html/bbb; index index.html; } } }
-
在ubuntu中运行以下docker命令以创建nginx服务器:
docker run -d -p 80:80 \ -v /mnt/share/config/nginx/nginx.conf:/etc/nginx/nginx.conf:ro \ -v /mnt/share/config/nginx/web:/usr/local/html \ --name nginx --restart always nginx:1.18.0
-
在windows的
C://Windows/System32/drivers/etc/host
文件中加上以下DNS映射配置。说明:本文ubuntu虚拟机的ip地址为192.168.1.238,请换成读者自己的虚拟机的ip地址
。192.168.1.238 aaa.test.com 192.168.1.238 bbb.test.com
1.1.4 功能测试
- 在windows浏览器中访问
http://aaa.test.com
,如果显示的页面如下图所示,则表示访问的是A网站。
- 在windows浏览器中访问 http://bbb.test.com ,如果显示的页面如下图所示,则表示访问的是B网站。
1.2 基于端口访问
1.2.1 需求说明
- 局域网内部有A和B两个网站,利用Nginx可以做为Web服务器的功能,把这两个网站部署到同一台Nginx类型的Web服务器上,并在Nginx中设置按端口来访问这两个网站,其中对端口
8081
的访问请求由A网站处理,对端口8082
的访问请求由B网站处理。 - 在Ubuntu中部署一个Nginx的Docker容器,该容器即为Nginx Web服务器,其中A网站部署在Nginx Web服务器的
/usr/local/html/aaa
目录下,B网站部署在Nginx Web服务器的/usr/local/html/bbb
目录下。
1.2.2 准备工作
- 在ubuntu的
/mnt/share/config/nginx/web/aaa
目录下创建一个index.html网页文件,该文件表示A网站主页,其内容如下:<html> <head> <title>index</title> </head> <body> <b2>This is aaa index page</b2> </body> </html>
- 在ubuntu的
/mnt/share/config/nginx/web/bbb
目录下创建一个index.hmtl网页文件,该文件表示B网站主页,其内容如下:<html> <head> <title>index</title> </head> <body> <b2>This is bbb index page</b2> </body> </html>
1.2.3 实战过程
-
在ubuntu的
/mnt/share/config/nginx
目录下创建名称为nginx.conf的配置文件,该配置文件会被用于Nginx服务器,其内容如下:user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/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 /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; server { listen 8081; server_name 127.0.0.1; location / { root /usr/local/html/aaa; index index.html; } } server { listen 8082; server_name 127.0.0.1; location / { root /usr/local/html/bbb; index index.html; } } }
-
在ubuntu中运行以下docker命令以创建nginx服务器:
docker run -d -p 8081:8081 -p 8082:8082 \ -v /mnt/share/config/nginx/nginx.conf:/etc/nginx/nginx.conf:ro \ -v /mnt/share/config/nginx/web:/usr/local/html \ --name nginx --restart always nginx:1.18.0
1.2.4 功能测试
- 在windows浏览器中访问
http://192.168.1.238:8081
,如果显示的页面如下图所示,则表示访问的是A网站。
- 在windows浏览器中访问
http://192.168.1.238:8082
,如果显示的页面如下图所示,则表示访问的是B网站。
2 反向代理功能
2.1 需求说明
- 局域网内部有A和B两个网站,这两个网站分别部署在各自的Nginx Web服务器中,利用Nginx的反向代理功能,把请求url以
/aaa
开头的访问请求反向代理到A网站,把请求url以/bbb
开头的访问请求反向代理到B网站。 - 在Ubuntu中部署两个Nginx Web服务器,其中A网站部署在第一个Nginx Web服务器的
/usr/local/html/aaa
目录下,B网站部署在第二个Nginx Web服务器的/usr/local/html/bbb
目录下,然后再创建一个Nginx服务器用于反向代理。
2.2 准备工作
- 在ubuntu的
/mnt/share/config/nginx/web/aaa
目录下创建一个index.html网页文件,该文件表示A网站主页,其内容如下:<html> <head> <title>index</title> </head> <body> <b2>This is aaa index page</b2> </body> </html>
- 在ubuntu的
/mnt/share/config/nginx/web/bbb
目录下创建一个index.hmtl网页文件,该文件表示B网站主页,其内容如下:<html> <head> <title>index</title> </head> <body> <b2>This is bbb index page</b2> </body> </html>
- 在ubuntu中运行以下docker命令以创建两个nginx服务器,这两个nginx服务器分别用于部署A网站和B网站:
docker run -d -p 8081:80 \ -v /mnt/share/config/nginx/web/aaa:/usr/share/nginx/html \ --name nginx-1 --restart always nginx:1.18.0 docker run -d -p 8082:80 \ -v /mnt/share/config/nginx/web/bbb:/usr/share/nginx/html \ --name nginx-2 --restart always nginx:1.18.0
2.3 实战过程
- 在ubuntu的
/mnt/share/config/nginx
目录下创建名称为nginx.conf的配置文件,该配置文件会被用于Nginx服务器,其内容如下:user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/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 /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; server { listen 80; server_name localhost; location /aaa/ { proxy_pass http://192.168.1.238:8081/; index index.html; } location /bbb/ { proxy_pass http://192.168.1.238:8082/; index index.html; } } }
- 在ubuntu中运行以下docker命令以创建nginx服务器,该nginx服务器用于反向代理:
docker run -d -p 80:80 \ -v /mnt/share/config/nginx/nginx.conf:/etc/nginx/nginx.conf:ro \ --name nginx --restart always nginx:1.18.0
2.4 功能测试
- 在windows浏览器中访问
http://192.168.1.238/aaa
,如果显示的页面如下图所示,则表示访问的是A网站。
- 在windows浏览器中访问
http://192.168.1.238/bbb
,如果显示的页面如下图所示,则表示访问的是B网站。
3 负载均衡功能
3.1 需求说明
- 局域网内部有一个网站,该网站部署了A和B两个实例,通过Nginx负载均衡的功能,把对该网站的访问按照指定的负载均衡策略转发到A和B这两个实例上。
- 在Ubuntu中部署两个Nginx Web服务器,其中A实例部署在第一个Nginx Web服务器的
/usr/local/html/aaa
目录下,B实例部署在第二个Nginx Web服务器的/usr/local/html/bbb
目录下,然后再创建一个Nginx服务器用于负载均衡。
3.2 准备工作
- 在ubuntu的
/mnt/share/config/nginx/web/aaa
目录下创建一个index.html网页文件,该文件表示A实例的主页,其内容如下:<html> <head> <title>index</title> </head> <body> <b2>This is aaa index page</b2> </body> </html>
- 在ubuntu的
/mnt/share/config/nginx/web/bbb
目录下创建一个index.hmtl网页文件,该文件表示B实例的主页,其内容如下:<html> <head> <title>index</title> </head> <body> <b2>This is bbb index page</b2> </body> </html>
- 在ubuntu中运行以下docker命令以创建两个nginx服务器,这两个nginx服务器分别用于部署A实例和B实例:
docker run -d -p 8081:80 \ -v /mnt/share/config/nginx/web/aaa:/usr/share/nginx/html \ --name nginx-1 --restart always nginx:1.18.0 docker run -d -p 8082:80 \ -v /mnt/share/config/nginx/web/bbb:/usr/share/nginx/html \ --name nginx-2 --restart always nginx:1.18.0
3.3 实战过程
- 在ubuntu的
/mnt/share/config/nginx
目录下创建名称为nginx.conf的配置文件,该配置文件会被用于Nginx服务器,其内容如下:user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/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 /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; # 默认按照轮询来负载 upstream backend-server{ server 192.168.1.238:8081; server 192.168.1.238:8082; } # 按访问者ip的哈希值来负载 #upstream backend-server{ # ip_hash; # server 192.168.1.238:8081; # server 192.168.1.238:8082; #} # 按照权重来负载 #upstream backend-server{ # server 192.168.1.238:8081 weight=1; # server 192.168.1.238:8082 weight=2; #} server { listen 80; server_name localhost; location / { proxy_pass http://backend-server; index index.html; } } }
- 在ubuntu中运行以下docker命令以创建nginx服务器,该nginx服务器用于负载均衡:
docker run -d -p 80:80 \ -v /mnt/share/config/nginx/nginx.conf:/etc/nginx/nginx.conf:ro \ --name nginx --restart always nginx:1.18.0
3.4 功能测试
- 在windows浏览器中多次访问
http://192.168.1.238
,如果显示的页面分别如下图所示,则表示访问分别被负载到了A实例和B实例。
4 流量限制功能
4.1 需求说明
- 局域网内部有一个网站,该网站部署了A和B两个实例,通过Nginx负载均衡的功能,把对该网站的访问按照指定的负载均衡策略转发到A和B这两个实例上,然后通过Nginx的流量限制功能,限制来自于同一个ip的用户每分钟最多只能请求2次。
- 在Ubuntu中部署两个Nginx Web服务器,其中A实例部署在第一个Nginx Web服务器的
/usr/local/html/aaa
目录下,B实例部署在第二个Nginx Web服务器的/usr/local/html/bbb
目录下,然后再创建一个Nginx服务器用于负载均衡和流量限制。
4.2 准备工作
- 在ubuntu的
/mnt/share/config/nginx/web/aaa
目录下创建一个index.html网页文件,该文件表示A实例的主页,其内容如下:<html> <head> <title>index</title> </head> <body> <b2>This is aaa index page</b2> </body> </html>
- 在ubuntu的
/mnt/share/config/nginx/web/bbb
目录下创建一个index.hmtl网页文件,该文件表示B实例的主页,其内容如下:<html> <head> <title>index</title> </head> <body> <b2>This is bbb index page</b2> </body> </html>
- 在ubuntu中运行以下docker命令以创建两个nginx服务器,这两个nginx服务器分别用于部署A实例和B实例:
docker run -d -p 8081:80 \ -v /mnt/share/config/nginx/web/aaa:/usr/share/nginx/html \ --name nginx-1 --restart always nginx:1.18.0 docker run -d -p 8082:80 \ -v /mnt/share/config/nginx/web/bbb:/usr/share/nginx/html \ --name nginx-2 --restart always nginx:1.18.0
4.3 实战过程
- 在ubuntu的
/mnt/share/config/nginx
目录下创建名称为nginx.conf的配置文件,该配置文件会被用于Nginx服务器,其内容如下:user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/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 /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; upstream backend-server{ server 192.168.1.238:8081 weight=1; server 192.168.1.238:8082 weight=2; } # 基于请求者的ip地址进行限流,创建一个名称为ip-limit且大小为10m的区域用于保存限流相关的信息,指定每分钟最多允许请求2次。 limit_req_zone $binary_remote_addr zone=ip-limit:10m rate=2r/m; server { listen 80; server_name localhost; location / { proxy_pass http://backend-server; index index.html; # 指定使用名称为ip-limit的区域来进行限流,当请求个数大于限流个数时,直接拒绝处理。 #limit_req zone=ip-limit; # 指定使用名称为ip-limit的区域来进行限流,且当请求个数大于限流个数时,最多缓存2个请求,这2个请求会依次被处理,超过的请求直接拒绝处理。 #limit_req zone=ip-limit burst=2; # 指定使用名称为ip-limit的区域来进行限流,且当请求个数大于限流个数时,最多缓存2个请求,这2个请求会同时被处理,超过的请求直接拒绝处理。 limit_req zone=ip-limit burst=2 nodelay; # 设置被拒绝的请求的返回状态码(只能在400到599之间) limit_req_status 403; } } }
- 在ubuntu中运行以下docker命令以创建nginx服务器,该nginx服务器用于负载均衡和流量限制:
docker run -d -p 80:80 \ -v /mnt/share/config/nginx/nginx.conf:/etc/nginx/nginx.conf:ro \ --name nginx --restart always nginx:1.18.0
4.4 功能测试
- 在windows浏览器中1分钟内多次访问
http://192.168.1.238
,结果如下图所示,其中前3次请求成功,后2次请求被拒绝了,说明流量限制功能起到了作用。说明:这里限制的是1分钟内最多只能请求2次,但这里1分钟内成功了3次,是因为在上述配置文件中设置了rate=2r/m(每分钟最多2次),即每30秒内最多允许请求1次,并且设置了burst=2(最多缓存2个请求),所以在30秒之最多允许3次请求成功,所以才出现了如下图所示的情况。
5 Location说明
5.1 Location的作用
- Location指令的作用是根据用户请求的URI来进行匹配,匹配成功即进行相关的操作。
5.2 Location的语法
- 以
=
开头表示精确匹配,后面不能带任何字符串。 - 以
^~
开头表示URI以某个常规字符串开头,不是正则匹配。 - 以
~
开头表示区分大小写的正则匹配。 - 以
~*
开头表示不区分大小写的正则匹配。 - 以
/
通用匹配, 如果没有其它匹配,任何请求都会匹配到。
5.3 Location的示例
-
只匹配根路径
server { listen 80; server_name localhost; location =/ { proxy_pass http://backend-server; index index.html; } }
-
只匹配以/aaa开头的路径
server { listen 80; server_name localhost; location /aaa/ { proxy_pass http://backend-server; index index.html; } }
-
匹配所有没有匹配到的路径
server { listen 80; server_name localhost; location / { proxy_pass http://backend-server; index index.html; } }
6 Nginx配置
6.1 Nginx配置说明
- Nginx配置说明:
user www www; #定义Nginx运行的用户和用户组 worker_processes 8; #启动进程,通常设置成和cpu的数量相等 #为每个进程分配cpu,这里将8个进程分配到8个cpu,当然可以写多个,或者将一个进程分配到多个cpu。 worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000; #这个指令是指当一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(ulimit -n)与nginx进程数相除,但是nginx分配请求并不是那么均匀,所以最好与ulimit -n的值保持一致。 worker_rlimit_nofile 65535; #全局错误日志及PID文件 error_log /usr/local/nginx/logs/error.log; #错误日志定义等级[ debug | info | notice | warn | error | crit ] pid /usr/local/nginx/nginx.pid; #工作模式及连接数上限 events { use epoll; #epoll是多路复用IO(I/O Multiplexing)中的一种方式,但是仅用于linux2.6以上内核,可以大大提高nginx的性能 worker_connections 102400; #单个后台worker process进程的最大并发链接数(最大连接数=连接数*进程数) multi_accept on; #尽可能多的接受请求 } #设定http服务器,利用它的反向代理功能提供负载均衡支持 http { include mime.types; #设定mime类型,类型由mime.type文件定义 default_type application/octet-stream; access_log /usr/local/nginx/log/nginx/access.log; #设定日志格式 sendfile on; #sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,对于普通应用必须设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,以平衡磁盘与网络I/O处理速度,降低系统的uptime. #autoindex on; #开启目录列表访问,合适下载服务器,默认关闭。 tcp_nopush on; #防止网络阻塞 keepalive_timeout 60; #keepalive超时时间,客户端到服务器端的连接持续有效时间,当出现对服务器的后,继请求时,keepalive-timeout功能可避免建立或重新建立连接。 tcp_nodelay on; #提高数据的实时响应性 gzip on; #开启gzip压缩 gzip_min_length 1k; gzip_buffers 4 16k; gzip_http_version 1.1; #压缩级别大小,最大为9,值越小,压缩后比例越小,CPU处理更快,值越大,消耗CPU比较高。 gzip_comp_level 2; gzip_types text/plain application/x-javascript text/css application/xml; gzip_vary on; client_max_body_size 10m; #允许客户端请求的最大单文件字节数 client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数, 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) large_client_header_buffers 4 4k; #设定请求缓冲 client_header_buffer_size 4k; #客户端请求头部的缓冲区大小,这个可以根据你的系统分页大小来设置,一般一个请求的头部大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。分页大小可以用命令getconf PAGESIZE取得。 open_file_cache max=102400 inactive=20s; #这个将为打开文件指定缓存,默认是没有启用的,max指定缓存数量,建议和打开文件数一致,inactive是指经过多长时间文件没被请求后删除缓存。 open_file_cache_valid 30s; #这个是指多长时间检查一次缓存的有效信息。 open_file_cache_min_uses 1; #open_file_cache指令中的inactive参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如上例,如果有一个文件在inactive include vhosts.conf; #包含其它配置文件,如自定义的虚拟主机 #这里为后端服务器应用集群配置,根据后端实际情况修改即可,test为负载均衡名称,可以任意指定。weight配置权重,在fail_timeout内检查max_fails次数,失败则剔除均衡。 upstream test { server 127.0.0.1:8080 weight=1 max_fails=2 fail_timeout=30s; server 127.0.0.1:8081 weight=1 max_fails=2 fail_timeout=30s; } #虚拟主机配置 server { listen 80; #侦听80端口 server_name www.test.com; #定义使用www.test.com访问,前提为此域名必须解析了此主机IP。 access_log logs/access.log main; #设定本虚拟主机的访问日志 root /data/webapps/maxt; #定义服务器的默认网站根目录位置 index index.php index.html index.htm; #定义首页索引文件的名称 #默认请求 location ~ /{ root /data/www/maxt; #定义服务器的默认网站根目录位置 index index.php index.html index.htm; #定义首页索引文件的名称 #以下是一些反向代理的配置. proxy_next_upstream http_502 http_504 error timeout invalid_header; proxy_redirect off; #如果后端的服务器返回502、504、执行超时等错误,自动将请求转发到upstream负载均衡池中的另一台服务器,实现故障转移。 proxy_set_header Host $host; #后端的Web服务器可以通过X-Forwarded-For获取用户真实IP proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://tdt_wugk; #请求转向后端定义的均衡模块 } # 定义错误提示页面 error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } #配置Nginx动静分离,定义的静态页面直接从Nginx发布目录读取。 location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css)$ { root /data/www/maxt; expires 3d; #expires定义用户浏览器缓存的时间为3天,如果静态页面不常更新,可以设置更长,这样可以节省带宽和缓解服务器的压力。 } #PHP脚本请求全部转发到 FastCGI处理. 使用FastCGI默认配置. location ~ \.php$ { root /root; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /data/www/wugk$fastcgi_script_name; include fastcgi_params; } #设定查看Nginx状态的地址 location /NginxStatus { stub_status on; } } }