文章目录
Nginx简介
Nginx 是一款高性能的 HTTP 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。
Nginx版本:
- Mainline version : Mainline是Nginx目前主力在做的版本,可以说是开发版
- Stable version :最新稳定版,生产环境上建议使用的版本
- Legacy versions :遗留的老版本的稳定版
Nginx 的应用场景
- HTTP 服务器:Nginx 是一个 HTTP 服务可以独立提供 HTTP 服务。可以做网页静态服务器。
- 虚拟主机:可以实现在一台服务器虚拟出多个网站。例如个人网站使用的虚拟主机。
- 反向代理,负载均衡:当网站的访问量达到一定程度后,单台服务器不能满足用户的请求时,需要用多台服务器集群可以使用 Nginx 做反向代理。并且多台服务器可以平均分担负载,不会因为某台服务器负载高宕机而某台服务器闲置的情况。
基于 Docker 部署 Nginx
编写docker-compose.yml
数据卷只会创建目录不会创建文件所以预先创建好./conf/nginx.conf文件和./html目录,不然会报错显示挂载异常.
version: '3.1'
services:
nginx:
restart: always
image: nginx
container_name: nginx
ports:
- 80:80
volumes:
- ./conf/nginx.conf:/etc/nginx/nginx.conf
- ./html:/usr/share/nginx/html
- ./cert:/etc/nginx/cert
- ./logs:/var/log/nginx
Nginx命令
nginx -h #帮助信息
start nginx #启动nginx
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配置
nginx.conf 配置文件的结构
# 全局配置
# ...
events {
# ...
}
http {
# ...
upstream {
# ...
}
server{
# ...
}
# ...
server{
# ...
}
}
注意: 每个 server 就是一个虚拟主机
全局配置
user nobody; #置用户或者组,默认为nobody
worker_processes 1; #允许生成的进程数,默认为1,通常设置成和 CPU 的数量相等
error_1og 1ogs/error.1og;#制定日志路径,级别。这个设置可以放入全局块,http块,server块,级别依次为:debug info notice warn error crit alert emerg
error_log logs/error.log notice;
pid 1ogs/nginx.pid;#指定nginx进程运行文件存放地址
events 配置
accept_mutex on;#默认为on .当一个新连接到达时,如果激活了accept_mutex,那么多个Worker将以串行方式来处理,其中有一个Worker会被唤醒,其他的Worker继续保持休眠状态;如果没有激活accept_mutex,那么所有的Worker都会被唤醒,不过只有一个Worker能获取新连接,其它的Worker会重新进入休眠状态,这就是「惊群问题」,但当访问量大时不激活反而更快。
multi_accept off;#设置一个进程是否同时接受多个网络连接,默认为off
use epo11;#事件驱动模型,select po11 kqueue epo11 resigl /dev/po11 eventport
worker_connections 1024;#最大连接数,默认为1024(早期是512)
事件驱动模型:
- epoll 是多路复用 IO(I/O Multiplexing) 中的一种方式,但是仅用于 linux2.6 以上内核,可以大大提高 nginx 的性能
http 配置
#配置nginx支持哪些文件扩展名与文件类型映射表。在conf/mime.types查看支持哪些类型
include mime.types;
#默认文件类型(流)类型,支持很多文件、图片、js/css等
default_type application/octet-stream;
#自定义日志格式
1og_format myFormat 'Sremote_addr-Sremote_user[Stime_local]Srequest Sstatus Sbody_bytes_sent Shttp_referer httpuser_agent Shttp-x_forwarded_for';
#日志配置 access_log off; 取消服务日志
access_log 1og/access.1og myFormat;
#优化参数允许sendfile方式传输文件,开启高校效传输模式,对于普通应用,必须设为 on,如果用来进行下载等应用磁盘 IO 重负载应用,可设置为 off,以平衡磁盘与网络 I/O 处理速度,降低系统的 uptime.
sendfile on;
#防止网络阻塞
tcp-nopush on;
#长连接超时时间(单位秒)
keepalive_timeout 65;
#每个进程每次调用传输数量不能大于设定的值,默认为0,即不设上限。
sendfile_max_chunk 100k;
# 设定请求缓冲
client_header_buffer_size 2k;
#开启gzip压缩,对响应数据进行在线实时压缩,减少数据传输量。
gzip on;
#静态压缩,文件必须预先完成gzip压缩
gzip_static on;
gzip_http_version 1.0;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript;
gzip_vary on;
#对IE6浏览器的数据不进行 GZIP 压缩。
gzip_disable "msie6";
#设定通过nginx上传文件的大小
client_max_body_size 8m;
#错误页
error_page 500 502 503 504 /50x.html;
upstream 配置
# 定义反向代理,负载均衡设备的 Ip及设备状态
upstream mysvr {
# ip_hash; # 使用源Ip哈希模式(默认轮询),可以解决session问题
server 127.0.0.1:9090 down;
server 127.0.0.1:8080 weight=2;
server 127.0.0.1:6060;
server 127.0.0.1:7070 backup;
}
upstream设置每个设备的状态:
- down:表示当前的 server 暂时不参与负载
- weight:默认为 1 weight 越大,负载的权重就越大。
- max_fails:允许请求失败的次数默认为 1 当超过最大次数时,返回 proxy_next_upstream 模块定义的错误
- fail_timeout:max_fails 次失败后,暂停的时间。
- backup:其它所有的非 backup 机器 down 或者忙的时候,请求 backup 机器。所以这台机器压力会最轻
server配置
keepalive_requests 120; #单连接请求上限次数。
listen 80; #监听端口
server_name 127.0.0.1; #监听地址,这里可配置 IP 也可配置域名,支持多域名配置,支持泛域名解析(*.a.com),支持对于域名的正则匹配
# 将ssl证书上传到nginx数据卷暴露出来的cert目录中
# listen可同时配置多个,使得http和https都可访问
listen 443 ssl; #SSL协议访问端口号为443。此处如未添加ssl,可能会造成Nginx无法启动。
server_name localhost; #将localhost修改为您证书绑定的域名,例如:www.example.com。
ssl_certificate cert/domain name.pem; #将domain name.pem替换成您证书的文件名。
ssl_certificate_key cert/domain name.key; #将domain name.key替换成您证书的密钥文件名。
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; #使用此加密套件。
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #使用该协议进行配置。
ssl_prefer_server_ciphers on;
rewrite ^(.*)$ https://$host$1 permanent; #将所有http请求通过rewrite重定向到https。
root /xxhtml; # 根目录
index index.html index.htm;
location /{
#root path; #根目录
#index vv.html; #设置默认页
proxy_pass http://mysvr; #请求转向 upstream mysvr 定义的服务器列表
deny 127.0.0.1; #拒绝的ip
allow 172.18.5.54; #允许的ip
}
location匹配规则及顺序:
- = 表示精确匹配。只有请求的url路径与后面的字符串完全相等时,才会命中。
- ^~ 前缀匹配,表示如果该符号后面的字符是最佳匹配,采用该规则,不再进行后续的查找。
- ~ 表示该规则是使用正则定义的,区分大小写。
- ~* 表示该规则是使用正则定义的,不区分大小写。
- /uri 字符串匹配,匹配符合以后,还要继续往下搜索
只有后面的正则表达式没有匹配到时,这一条才会采用这一条 - / 通用匹配, 如果没有其它匹配,任何请求都会匹配到
nginx自定义请求头
http://www.51niux.com/?id=135
语法: proxy_set_header field value;
默认值:
proxy_set_header Host $proxy_host;
proxy_set_header Connection close;
上下文: http, server, location
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
Nginx 虚拟主机
虚拟主机是一种特殊的软硬件技术,它可以将网络上的一台计算机分成多个虚拟主机,每个虚拟主机可以独立对外提供 www 服务,这样就可以实现一台主机对外提供多个 web 服务,每个虚拟主机之间是独立的,互不影响的。
通过 Nginx 可以实现虚拟主机的配置,Nginx 支持三种类型的虚拟主机配置
- 基于 IP 的虚拟主机
- 基于域名的虚拟主机
- 基于端口的虚拟主机
操作流程
- 创建目录及文件,在 /usr/local/docker/nginx/html 目录下创建 html80 和 html8080 两个目录,并分别创建两个 index.html 文件
- 配置虚拟主机,创建并修改 /usr/local/docker/nginx/conf 目录下的 nginx.conf
- 修改docker-compose.yml文件暴露8080端口,up启动
# 启动进程,通常设置成和 CPU 的数量相等
worker_processes 1;
events {
# epoll 是多路复用 IO(I/O Multiplexing) 中的一种方式
# 但是仅用于 linux2.6 以上内核,可以大大提高 nginx 的性能
use epoll;
# 单个后台 worker process 进程的最大并发链接数
worker_connections 1024;
}
http {
# 设定 mime 类型,类型由 mime.type 文件定义
include mime.types;
default_type application/octet-stream;
# sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,对于普通应用,
# 必须设为 on,如果用来进行下载等应用磁盘 IO 重负载应用,可设置为 off,以平衡磁盘与网络 I/O 处理速度,降低系统的 uptime.
sendfile on;
# 连接超时时间
keepalive_timeout 65;
# 设定请求缓冲
client_header_buffer_size 2k;
# 配置虚拟主机,根据server_name和listen的不同实习虚拟主机功能
server {
# 监听端口
listen 80;
# 虚拟主机名称,这里可配置 IP 也可配置域名
server_name 192.168.141.121;
# 所有的请求都以 / 开始,所有的请求都可以匹配此 location
location / {
# 使用 root 指令指定虚拟主机目录即网页存放目录
# 比如访问 http://ip/index.html 将找到 /usr/local/docker/nginx/html/html80/index.html
# 比如访问 http://ip/item/index.html 将找到 /usr/local/docker/nginx/html/html80/item/index.html
root /usr/share/nginx/html/html80;
# 指定欢迎页面,按从左到右顺序查找
index index.html index.htm;
}
}
# 配置虚拟主机
server {
listen 8080;
server_name 192.168.141.121;
location / {
root /usr/share/nginx/html/html8080;
index index.html index.htm;
}
}
}
Nginx 反向代理
代理服务器
代理服务器,客户机在发送请求时,不会直接发送给目的主机,而是先发送给代理服务器,代理服务接受客户机请求之后,再向主机发出,并接收目的主机返回的数据,存放在代理服务器的硬盘中,再发送给客户机。
代理服务器功能
- 提高访问速度: 由于目标主机返回的数据会存放在代理服务器的硬盘中,因此下一次客户再访问相同的站点数据时,会直接从代理服务器的硬盘中读取,起到了缓存的作用,尤其对于热门站点能明显提高请求速度。
- 防火墙作用: 由于所有的客户机请求都必须通过代理服务器访问远程站点,因此可在代理服务器上设限,过滤某些不安全信息。
- 通过代理服务器访问不能访问的目标站点: 互联网上有许多开放的代理服务器,客户机在访问受限时,可通过不受限的代理服务器访问目标站点,通俗说,我们使用的翻墙浏览器就是利用了代理服务器,虽然不能出国,但也可直接访问外网。
正向代理
正向代理,架设在客户机与目标主机之间,只用于代理内部网络对 Internet 的连接请求,客户机必须指定代理服务器,并将本来要直接发送到 Web 服务器上的 HTTP 请求发送到代理服务器中。
反向代理
反向代理服务器架设在服务器端,通过缓冲经常被请求的页面来缓解服务器的工作量,将客户机请求转发给内部网络上的目标服务器;并将从服务器上得到的结果返回给 Internet 上请求连接的客户端,此时代理服务器与目标主机一起对外表现为一个服务器。
使用 Nginx 反向代理 Tomcat
启动 Tomcat 容器
启动两个 Tomcat 容器,映射端口为 8081 和 8082,docker-compose.yml 如下:
version: '3.1'
services:
tomcat1:
image: tomcat
container_name: tomcat1
ports:
- 8081:8080
tomcat2:
image: tomcat
container_name: tomcat2
ports:
- 8082:8080
配置 Nginx 反向代理
修改 /usr/local/docker/nginx/conf 目录下的 nginx.conf 配置文件:
#Nginx用户及组:用户 组。window下不指定
user nginx;
worker_processes 1;
events {
use epoll;
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# 配置一个代理即 tomcat1 服务器
#如果nginx和tomcat在同一个局域网,可以使用 服务名:8080 进行代理通信,并且tomcat可以不用暴露端口
upstream tomcatServer1 {
server 192.168.141.121:8081;
}
# 配置一个代理即 tomcat2 服务器
upstream tomcatServer2 {
server 192.168.141.121:8082;
}
# 配置一个虚拟主机
server {
listen 80;
server_name service1.funtl.com;
location / {
# 域名 service1.funtl.com 的请求全部转发到 tomcatServer1 即 tomcat1 服务上
proxy_pass http://tomcatServer1;
# 欢迎页面,按照从左到右的顺序查找页面
index index.jsp index.html index.htm;
}
}
server {
listen 80;
server_name service2.funtl.com;
location / {
# 域名 service2.funtl.com 的请求全部转发到 tomcatServer2 即 tomcat2 服务上
proxy_pass http://tomcatServer2;
index index.jsp index.html index.htm;
}
}
}
注意: 新版 Nginx的upstream配置中的名称不可以有下划线("_"),否则会报 400 错误
反向代理中url的传递问题
proxy_pass url中的url只是host:port地址,不包含任何资源路径哪怕一个/,nginx会将完整路径将直接传递给代理服务器.
// 访问: / 后端: /
// 访问: /api/xx 后端: /api/xx
// 访问: /api/xx?aa 后端: /api/xx?aa
location / {
proxy_pass http://node:8080;
}
// 访问: /api/ 后端: /api/
// 访问: /api/xx 后端: /api/xx
// 访问: /api/xx?aa 后端: /api/xx?aa
// 访问: /api-xx?aa 后端:
location /api/ {
proxy_pass http://node:8080;
}
proxy_pass url中的url包含了资源路径,nginx会将location 匹配后的链接传递给代理服务器
// 访问: / 后端: /
// 访问: /api/xx 后端: /api/xx
// 访问: /api/xx?aa 后端: /api/xx?aa
location / {
proxy_pass http://node:8080/;
}
// 访问: /api/ 后端: /
// 访问: /api/xx 后端: /xx
// 访问: /api/xx?aa 后端: /xx?aa
// 访问: /api-xx?aa 未匹配
location /api/ {
proxy_pass http://node:8080/;
}
// 访问: /api 后端: /
// 访问: /api/ 后端: //
// 访问: /api/xx 后端: //xx
// 访问: /api/xx?aa 后端: //xx?aa
// 访问: /api-xx?aa 后端: /-xx?aa
location /api {
proxy_pass http://node:8080/;
}
// 访问: /api/ 后端: /v1
// 访问: /api/xx 后端: /v1xx
// 访问: /api/xx?aa 后端: /v1xx
// 访问: /api-xx?aa 未匹配
location /api/ {
proxy_pass http://node:8080/v1;
}
// 访问: /api/ 后端: /v1/
// 访问: /api/xx 后端: /v1/xx
// 访问: /api/xx?aa 后端: /v1/xx
// 访问: /api-xx?aa 未匹配
location /api/ {
proxy_pass http://node:8080/v1/;
}
当 location 以正则形式匹配时,proxy_pass 不能包含路径.
反向代理解决跨域问题
当服务器无法设置 header 或提供 callback 时我们就可以采用 Nginx 反向代理的方式解决跨域问题。
user nginx;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name upload.myshop.com;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
location / {
proxy_pass http://192.168.0.104:8888;
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,PATCH,OPTIONS;
# 解决假请求问题,如果是简单请求则没有这个问题,但这里是上传文件,首次请求为 OPTIONS 方式,实际请求为 POST 方式
# Provisional headers are shown.
# Request header field Cache-Control is not allowed by Access-Control-Allow-Headers in preflight response.
add_header Access-Control-Allow-Headers DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range;
return 200;
}
}
}
}
Nginx 负载均衡
修改 /usr/local/docker/nginx/conf 目录下的 nginx.conf 配置文件:
user nginx;
worker_processes 1;
events {
use epoll;
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# 定义负载均衡设备的 Ip及设备状态
upstream myServer {
server 127.0.0.1:9090 down;
server 127.0.0.1:8080 weight=2;
server 127.0.0.1:6060;
server 127.0.0.1:7070 backup;
}
server {
listen 80;
server_name nginx.funtl.com;
location / {
#代理
proxy_pass http://myapp1;
index index.jsp index.html index.htm;
}
}
}
upstream设置每个设备的状态:
- down:表示当前的 server 暂时不参与负载
- weight:默认为 1 weight 越大,负载的权重就越大。
- max_fails:允许请求失败的次数默认为 1 当超过最大次数时,返回 proxy_next_upstream 模块定义的错误
- fail_timeout:max_fails 次失败后,暂停的时间。
- backup:其它所有的非 backup 机器 down 或者忙的时候,请求 backup 机器。所以这台机器压力会最轻