nginx前端必知必会
介绍
- Nginx是异步框架的网页服务器,也可以用作反向代理、负载平衡器和HTTP缓存。该软件由伊戈尔·赛索耶夫创建并于2004年首次公开发布。2011年成立同名公司以提供支持。2019年3月11日,Nginx公司被F5 Networks以6.7亿美元收购。Nginx是免费的开源软件,根据类BSD许可证的条款发布。一大部分Web服务器使用Nginx,通常作为负载均衡器,
特点
- Nginx 是一款面向性能设计的 HTTP 服务器,相较于 Apache、lighttpd 具有占有内存少,稳定性高等优势。与旧版本(<=2.2)的 Apache 不同,nginx 不采用每客户机一线程的设计模型,而是充分使用异步逻辑,削减了上下文调度开销,所以并发服务能力更强。整体采用模块化设计,有丰富的模块库和第三方模块库,配置灵活。在 Linux 操作系统下,nginx 使用 epoll 事件模型,得益于此,nginx 在 Linux 操作系统下效率相当高。同时 Nginx 在 OpenBSD 或 FreeBSD 操作系统上采用类似于 epoll 的高效事件模型 kqueue。可大量平行处理。Nginx 在官方测试的结果中,能够支持五万个平行连接,而在实际的运作中,可以支持二万至四万个平行链接。
安装
- window nginx.exe
- 通过包管理安装
shell
sudo apt-get install nginx #ubuntu
sudo yum install nginx #centos
sudo brew install nginx #mac - 官网下载源码,安装依赖,编译后安装
- docker安装 dockerhub
常用命令
- nginx -v / -V 查看版本 / 查看版本和配置信息(依赖库的本信息)
- nginx -t 检查配置文件语法状态
- nginx -s quite 关闭服务(优雅关闭,等待当前已建立的连接完成后关闭服务)
- nginx -s stop 直接停止服务
- nginx -s reload 热重载,不停止服务的情况下重新加载配置文件,完成服务重启
- nginx -s reopen 重新开始日志文件
常用参数
参数 | 含义 |
---|---|
user | 指定nginx worker进程运行用户及用户组,Windows下不用指定,默认为nobody账号。403的时候可以查看user是否有项目目录权限 |
worker_processes | 设定工作进程数,通常设定为CPU数量或CPU数量的两倍或auto。 |
worker_processes | 设定工作进程数,通常设定为CPU数量或CPU数量的两倍或auto。 |
worker_rlimit_nofile | nginx 进程最大打开文件数, 通常设置65535。(受限于系统上可用的文件描述符的数量可以通过ulimit -n查看系统的最大打开文件数) |
pid | nginx的进程号,当我们需要停止nginx时,使用的其中一种方式就可以是通过进程号杀死进程的方式。 |
worker_connections | 设置一个进程可以打开最大连接数,应该小于最大打开文件数。(反向代理的情况下连接数不能只考虑客户端的连接) 理论上每台Nginx服务器的最大连接数为worker_processes*worker_connections。 |
use | 用于指定事件模型,为windows下无需指定事件模型(Nginx针对不同操作系统会使用不同的事件模型)。Nginx可支持的的worktype有以下几种select、poll、kqueue、epoll、rtsig、/dev/poll |
include mime.types | 文件类型,对应response header中的content-type |
default_type | 当文件类型未在mime.types中定义时会使用这种方式,一般默认类型设置为octet-stream,表示当文件类型未定义时浏览器认为响应的是普通的文件流,并会提示用户下载文件。 |
log_format name | log_formate是Nginx的httplog模块指令,用于指定Ningx的日志输出格式。name为为此日志格式设置的名字,在下面的access_log指令中使用这个名字,就可以按照这个名字定义的格式进行日志输出。 |
access_log | 设置日志路径,根据路径后跟的名字设置日志格式。 |
error_log | 定义错误日志的存放路径。路径后面的参数为错误日志输出级别,分别有debug、info、notice、warn、error、crit六个级别,其中debug级别输出的错误日志最详细,crit级别输出的错误日志最简略 |
sendfile | 用于开启高效文件传输模式,对于普通应用必须设置为on。如果用来进行下载等应用磁盘IO的重负载引用,可以设置为off,平衡磁盘与网络IO的处理速度,降低系统uptime(负载)。 |
tcp_nopush | 此选项仅在使用sendfile时使用。它的作用是,防止网络拥塞,当tcp_nopush设置为on时,当有数据需要发送时,先不着急立刻发送,而是确保数据包已经装满数据才进行发送,减少网络报文段的数量,避免网络拥塞。 |
tcp_nodelay | 此选项仅在使用sendfile时使用。它的作用同上一个选项tcp_nopush刚好相反,当有数据要发送时,立即发送,确保数据尽快发送,提高数据传输效率,适用每次只发送很少字节的业务场景。 |
keepalive_timeout | 在HTTP请求中,当一个请求完成后会保持这个TCP连接的打开状态,若接收到来自客户端的其他请求,服务端就会利用这个未被关闭的连接,而不需要再建立一个新的连接,这就是keep-alive模式,但是保持打开状态的TCP连接同样会占用资源,当资源占用过多就会影响性能,所以这个选项就是指定每个TCP连接最多可以保持多长时间。 |
gzip | 开启实时gzip压缩输出数据流,减少网络传输。 |
gzip_min_length | gzip压缩起点大小,大于设置大小才进行压缩。 |
gzip_buffers | 设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流。4 16k代表申请4个单位为16k的内存作为压缩结果缓存。 |
gzip_http_version | 设置gzip压缩针对的HTTP协议版本。 |
gzip_comp_level | gzip压缩级别,数字越大压缩效果越好,但CPU处理时间越长。 |
gzip_types | 指定何种类型的文件会被进行压缩。需要和mime.type的content-type中对应 |
gzip_vary | 为响应头添加Vary: Accept-Encoding标头,该标头可以告诉前端的缓存服务器同时缓存通过gzip压缩过的资源和未压缩过的资源,这么做的目的是,当客户端使用的是不支持gizp的低版本浏览器时,缓存也可以向其返回未经gzip压缩过的资源,否则,如果缓存服务器只缓存了压缩过后的资源,那么返回压缩过后的资源会导师老版本浏览器无法解压,出现乱码。 |
gzip_disable | 指定哪些不需要gzip压缩的浏览器 |
server_name | 域名 |
listen | 端口号 |
root | 目录 |
proxy_pass | 设置反向代理服务器 |
web服务器
+ 静态资源服务器
+ http
http {
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_min_length 5k;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 4;
gzip_types application/javascript text/plain application/x-javascript text/css application/xml application/json text/javascript;
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
server {
server_name baixiaoxu.com www.baixiaoxu.com;
listen 80;
root /home/baixx2/project;
location / {
index index.htm index.html;
}
# vue-router history模式
location / {
try_files $uri $uri/ /index.html;
}
# 资源设置缓存
location ~ \.(css|js|woff2|png) {
#expires 10d;
add_header Cache-Control max-age=4800;
}
}
}
- https + http2 (个人网站可以使用Let’s Encrypt的https证书)
certbot 可以自动生成证书 [certbot]: https://certbot.eff.org/
http {
# http2 需要nginx >= 1.10.0、openssl >= 1.0.2的版本要求,可以nginx -V查看是否满足
server {
server_name: baixiaoxu.com www.baixiaoxu.com;
listen 443 ssl http2;
ssl_certificate /etc/letsencrypt/live/baixiaoxu.com/fullchain.pem;
# managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/baixiaoxu.com/privkey.pem;
# managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf;
# managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# managed by Certbot
root /home/baixx2/project;
location / {
http2_push /css/style.css;
# server push , 文件路径相对root开始填写
index index.htm index.html;
}
}
}
- 资源匹配规则
- = 表示精确匹配
- ^~ 表示普通字符匹配,如果该选项匹配,只匹配该选项,不匹配别的选项,一般用来匹配目录。
- ~ 正则匹配(区分大小写)
- ~* 正则匹配(不区分大小写)
- !~ 和!~* 分别为区分大小写不匹配及不区分大小写不匹配的正则
- / 任何请求都会匹配
- 首先匹配=, 其次匹配^~ , 其次是按文件中顺序的正则匹配,最后是交给 / 通用匹配。当有匹配成功时候,停止匹配,按当前匹配规则处理请求。
- 反向代理(正向、反向)
http {
upstream backend {
server 192.168.1.110:8080;
server 192.168.1.111:8080;
}
server {
location /api/ {
proxy_pass http://backend/;
# http://127.0.0.1/api/add ->http://127.0.0.1/add
}
location /api/ {
proxy_pass http://backend;
# http://127.0.0.1/api/add ->http://127.0.0.1/api/add
}
location /api {
proxy_pass http://backend/;
# http://127.0.0.1/api/add ->http://127.0.0.1//add
}
location /api {
proxy_pass http://backend;
# http://127.0.0.1/api/add ->http://127.0.0.1/api/add
}
// 透传header
location /api {
proxy_set_header Referer "";
proxy_set_header X-Forwarded-For $http_x_forwarded_for;
proxy_pass http://backend;
}
}
}
- 负载均衡
- 轮询
- 最少连接数
- weight
- ip_hash
- fair (第三方)
upstream backend {
server 192.168.1.110:8080;
server 192.168.1.111:8080;
}
upstream backend {
least_conn;
server 192.168.1.110:8080;
server 192.168.1.111:8080;
}
upstream backend {
server 192.168.1.110:8080 weight=2;
server 192.168.1.111:8080;
}
upstream backend {
ip_hash;
server 192.168.1.110:8080;
server 192.168.1.111:8080;
}
# down 不参与服务
# backup 备用服务
upstream backend {
server 192.168.1.110:8080 down;
server 192.168.1.111:8080 backup;
server 192.168.1.111:8080 max_fails=1 fail_timeout=10s; # 10s内服务不可用次数为1次后,暂停此服务,间隔10s后进行健康检查,检查通过后允许继续服务。
}
动手之一步一步配置你的web服务器(演示)
- 设置正确的端口和root目录指向
server {
server_name localhost;
listen 80;
root /front;
location / {
index index.htm index.html;
}
}
# vue项目并且router使用了history模式
# history模式使用的路由在服务器上并没有实际的服务和文件,所以需要返回index.html
server {
server_name localhost;
listen 80;
root /front;
location / {
try_files $uri $uri/ /index.html;
}
}
- 设置资源缓存
server {
server_name localhost;
listen 80;
root /front;
location / {
index index.htm index.html;
}
location ~ \.(css|js|woff2|png|jpg) {
expires 10d;
#add_header Cache-Control max-age=3600;
}
}
- 发现第一次请求资源体积有点大(开启gzip压缩)
http {
gzip on;
gzip_vary on;
gzip_min_length 5k;
gzip_proxied any;
gzip_comp_level 4;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
server {
server_name localhost;
listen 80;
root /front;
location / {
index index.htm index.html;
}
location ~ \.(css|js|woff2|png|jpg) {
expires 10d;
#add_header Cache-Control max-age=3600;
}
}
}
- 后端联调遇到接口跨域
http {
gzip on;
gzip_vary on;
gzip_min_length 5k;
gzip_proxied any;
gzip_comp_level 4;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
server {
server_name localhost;
listen 80;
root /front;
location / {
index index.htm index.html;
}
location ~ \.(css|js|woff2|png|jpg) {
expires 10d;
#add_header Cache-Control max-age=3600;
}
location /api/ {
proxy_pass http://127.0.0.1:3000/;
# 后端服务地址
}
}
# 如果 你是服务的提供方,那么也可以在nginx中设置请求头,允许跨域
server {
// 直接在nginx中设置请求头解决跨域
location / {
location / {
add_header Access-Control-Allow-Origin *;
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,Authorization';
if ($request_method = 'OPTIONS') {
return 200;
}
proxy_pass hhttp://127.0.0.1:3000/;
}
}
}
日志
- 日志查看
- cat access.log (直接cat文件,当文件内容太多时可能导致无法定位到具体需要的内容,可以通过grep来过滤内容如: cat access.log | grep ” 404″ > a.log )
- vi access.log (日志文件较大的情况时不推荐使用)
- tail -f access.log(实时查看log文件, 可以结合grep来进行使用)
- 日志的分割
- mv access.log ./logBak/20190922.log && nginx -s reopen (结合crontab做定时日志切割)
😛 老铁你也太厉害了吧!
你的网站,好像打不开啊