接着【前端运维】打通任督二脉!(上篇),继续nginx的入门和进阶\后端语言nodejs\go。
同样记住,下面的内容有印象即可,不需要记住,用的时候查资料就行了,就怕你都不知道有这个功能,哈哈,毕竟前端面试不面的东西,我们就以实用性为主。
Nodejs进
nodejs之前已经写过进阶内容了(东西还挺多的),有兴趣的请看:
golang入门
自己之前也写过一些:
- 后端语言很难?前端入门go基础语法只需要3小时!(上)
- 后端语言很难?前端入门go基础语法只需要3小时!(中)
- 后端语言很难?前端入门go基础语法只需要3小时!(下)
- # 前端学go容易被坑的点(1)
nginx
这块是全新的,主要参考了在B站看的nginx资料,综合而成。前端学到这个程度足矣。
前端为什么需要nginx
首先为什么需要nginx,一个最经典的场景就是解决前端跨域问题,也就是反向代理功能,如下图:
图中鼠标位置就是nginx,可以将请求代理到静态资源,或者API接口服务等等。
学习环境
之前讲了docker,直接pull一个nginx镜像就行了,然后进入docker里面操作。
主从模式
1、ng在启动后,会有一个master进程和多个互相独立的worker进程,也就是主从模式。 2、因此在某个worker进程异常退出的时候,可以再起一个新的worker进程服务。
使用主从模式可以大大提高Nginx的可用性和稳定性,降低单点故障的风险。
日志文件切割
Nginx的日志文件切割是指将Nginx服务器生成的大量日志文件分割成较小的文件,以减少磁盘使用量并提高搜索速度。Nginx支持通过配置文件自动切割日志文件。
下面是Nginx配置文件中配置日志切割的一个简单示例:
http {
# $remote_addr 访问的ip地址
# $remote_user 远程用户
# $time_local 时区
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;
# 定义切割日志文件的方式
log_rotate daily;
# 定义保存日志文件的天数
log_rotate_age 30;
# ……
}
上面的代码定义了切割日志文件的方式为每天切割,并定义了保存日志文件的天数为30天。您可以根据自己的需求来修改这些参数。
在配置文件生效后,Nginx将自动按照指定的方式切割日志文件,并在切割后的日志文件名后面加上日期。例如,原始的日志文件名为"access.log",在切割后的日志文件可能为"access.log.2022-01-01"
主配置文件
/etc/nginx/nginx.conf是Nginx服务器的主配置文件,它定义了Nginx服务器的基本行为。
以下是默认这个文件的配置信息:
user nginx; 设置nginx服务的系统使用用户
worker_processes 1; 工作进程数,一般和CPU数量相同
error_log /var/log/nginx/error.log warn; nginx的错误日志
pid /var/run/nginx.pid; nginx服务启动时的pid
events {
worker_connections 1024;每个进程允许的最大连接数 10000
}
http {
include /etc/nginx/mime.types;//文件后缀和类型类型的对应关系
default_type application/octet-stream;// 默认 content-type,就是指上面的mime.types没有匹配上的content-type如何设置返回的content-type
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;//启用sendfile,优化了静态资源访问的速度
#tcp_nopush on;//懒发送
keepalive_timeout 65;// 链接保持65秒不断开
#gzip on; # 启用gzip压缩
include /etc/nginx/conf.d/*.conf;// 包含的子配置,比如http的转发配置很多,就单独写一个文件
}
上面有一些$remote_addr的字段
在nginx $ 开头的都是变量
我们看下这些变量是啥意思:
remote_addr | 客户端地址 |
---|---|
$remote_user | 客户端用户名称 |
$time_local | 访问时间和时区 |
$request | 请求行 |
$status | HTTP请求状态 |
$body_bytes_sent | 发送给客户端文件内容大小 |
/etc/nginx/conf.d/default 默认是http服务器配置文件,也就是上面配置的
include /etc/nginx/conf.d/*.conf;// 包含的子配置,比如http的转发配置很多,就单独写一个文件
我们下面就是把server的配置单独提到一个文件里了
server
- /etc/nginx/conf.d/default.conf
- 一个server下面可以配置多个
location
# 每一个server对应一个网站
server {
listen 80; // 监听的端口号
server_name localhost; // 用域名方式访问的地址
#charset koi8-r; //编码
#access_log /var/log/nginx/host.access.log main; //访问日志文件和名称
location / {
root /usr/share/nginx/html; // 静态文件根目录
index index.html index.htm; // 首页的索引文件
}
#error_page 404 /404.html; //指定错误页面
# redirect server error pages to the static page /50x.html
# 把后台错误重定向到静态的50x.html页面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
# 代理PHP脚本到80端口上的apache服务器
#location ~ .php$ {
# proxy_pass http://127.0.0.1;
#}
}
拓展名文件
/etc/nginx/mime.types,设置http协议的Content-Type与拓展名对应关系
比如说:
types {
text/html html htm shtml;
application/javascript js;
xxx...
}
也就是客户端请求服务器文件,请求行里有conten-type: application/javascript,服务器就会把它当做js文件去处理
缓存目录
/var/cache/nginx nginx的缓存目录
日志目录
/var/log/nginx nginx的日志目录
可执行文件
- nginx服务的启动管理的可执行文件
/usr/sbin/nginx 可执行命令
监控nginx运行状态
首先你要看这个服务是否装上了
nginx -V 2>&1 | grep -o with-http_stub_status_module
修改nginx配置
location /status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
#auth_basic "NginxStatus";
#auth_basic_user_file conf/nginxstaus;
}
这里我们只允许了本机访问(allow 127.0.0.1;)
同时禁止了外网访问(deny all,但是deny会排除allow里的)
最后我们看看nginx会暴露哪些东西查看运行状态:
参数 | 含义 |
---|---|
Active connections | 当前nginx正在处理的活动连接数 |
accepts | 总共处理的连接数 |
handled | 成功创建握手数 |
requests | 总共处理请求数 |
Reading | 读取到客户端的Header信息数 |
Writing | 返回给客户端的Header信息数 |
Waiting | 开启keep-alive的情况下,这个值等于 active – (reading + writing) |
请求限制
语法:
语法: limit_req_zone key zone=name:size rate=rate; 默认值: none 配置段: http
例子:
# $binanry_remote_addr表示限制ip,zone的名字叫req_zone,内存分配了1m,每秒处理1个请求
limit_req_zone $binary_remote_addr zone=req_zone:1m rate=1r/s;
server {
location /{
limit_req req_zone;
# 缓存区队列burst=3个,不延期,即每秒最多可处理rate+burst个.同时处理rate个
limit_req zone=req_zone burst=3 nodelay;
}
}
静态web服务
Web静态资源指的是不需要任何服务端处理,直接通过浏览器就能够使用的资源,如:HTML、CSS、
类型 | 种类 |
---|---|
浏览器渲染 | HTML、CSS、JS |
图片 | JPEG、GIF、PNG |
视频 | FLV、MPEG |
下载文件 | Word、Excel |
这里需要注意一下,nginx有个很牛b的技术,叫零拷贝,就是所有静态资源,它直接使用服务器内核转发静态资源,而不是请求到应用层,然后应用层再调用system call去发静态文件。
所以性能会比较不错,所以这是为啥单机架构我要用nginx的一个重要因素,静态资源调度用它就ok
gzip
Gzip 压缩是一种流式数据压缩算法,在网络上常用来传输压缩后的HTTP内容。Nginx 中的 gzip 压缩是指 Nginx 服务器在发送 HTTP 响应时,对内容进行 gzip 压缩,然后浏览器再解压显示。
例如,如果你访问了一个带有 gzip 压缩的网页,Nginx 服务器会把该网页内容进行压缩,并在 HTTP 响应头中添加一个 "Content-Encoding: gzip" 的字段,表明响应内容已经经过 gzip 压缩。浏览器收到响应后,就会进行解压,显示网页内容。这样做可以减小网络带宽消耗,加快网页加载速度。
我们举一个例子:编辑下面的文件
/etc/nginx/conf.d/default.conf
location ~ .*.(jpg|png|gif)$ { # 匹配jpg等图片
gzip off;# 关闭压缩
root /data/www/images; # 静态文件资源根目录
}
location ~ .*.(html|js|css)$ { # 匹配html,css等文件
gzip on; #启用压缩
gzip_min_length 1k; # 只压缩超过体积超过1k的文件
gzip_http_version 1.1; # 启用gzip压缩所需的HTTP最低版本
gzip_comp_level 9; # 压缩级别,压缩比率越高,文件被压缩的体积越小
gzip_types text/css application/javascript; # 进行压缩的文件类型
root /data/www/html;
}
location ~ ^/download {
gzip_static on; # 启用压缩
tcp_nopush on; # 不要着急发,攒一波再发
root /data/www; # 根目录
}
这里需要强调 gzip_static on;表示如果你把文件压缩过,直接nginx会把压缩的文件传给客户端,而不是自己再压缩一遍(开启gzip会把文件压缩后传给客户端)
还有一个tcp_nopush on; 是指传递文件的时候,先从块设备(硬盘)读取二进制流到一个缓存区,等缓存区满了才发出去,这样的好处就是网络利用率比较高。
浏览器缓存
这是一个经典的面试题,请你谈谈如何优化前端应用,其中最重要的就是加快响应速度,加快中比较重要的一环就是利用缓存,面试官往往会问缓存的机制是什么。
我这里不赘述了,网上一大堆,主要强调的是nginx响应头里面包含了 Etag
和 Last-Modified
这两个用于处理协商缓存的信息,nginx默认是给资源开启缓存的。
我们可以配置nginx的强缓存和协商缓存,如下:
- 强缓存配置
html直接 no-store
表示不用缓存,而其他静态文件,比如css,js,Cache-Control max-age=360000
server {
location ~* .(html)$ {
access_log off;
add_header Cache-Control max-age no-store;
}
location ~* .(css|js|png|jpg|jpeg|gif|gz|svg|mp4|ogg|ogv|webm|htc|xml|woff)$ {
access_log off;
add_header Cache-Control max-age=360000;
}
}
- 协商缓存
location ~* .(gif|jpg|png|bmp|ico)$ {
#设置缓存时间
expires 1d; # 一天的缓存
}
跨域配置
我们这里使用的cors里避免跨域问题,具体机制介绍,请看阮一峰老师的文章:wangdoc.com/javascript/…
location / {
# 允许跨域的请求,可以自定义变量$http_origin,*表示所有
add_header 'Access-Control-Allow-Origin' *;
# 允许携带cookie请求
add_header 'Access-Control-Allow-Credentials' 'true';
# 允许跨域请求的方法:GET,POST,OPTIONS,PUT
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT';
# 允许请求时携带的头部信息,*表示所有
add_header 'Access-Control-Allow-Headers' *;
# 允许发送按段获取资源的请求
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
# 一定要有!!!否则Post请求无法进行跨域!
# 在发送Post跨域请求前,会以Options方式发送预检请求,服务器接受时才会正式请求
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
# 对于Options方式的请求返回204,表示接受跨域请求
return 204;
}
}
防盗链
# 在动静分离的location中开启防盗链机制
location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css){
# 最后面的值在上线前可配置为允许的域名地址
valid_referers none blocked 192.168.12.129;
if ($invalid_referer) {
# 可以配置成返回一张禁止盗取的图片
# rewrite ^/ http://xx.xx.com/NO.jpg;
# 也可直接返回403
return 403;
}
root /soft/nginx/static_resources;
expires 7d;
}
反向代理
Nginx 反向代理是一种代理技术,它允许 Nginx 服务器将请求转发到后端的服务器上,并将后端服务器的响应返回给客户端。这种方式的好处是:
- 可以隐藏后端服务器的真实地址和配置,提高安全性。
- 可以负载均衡,把请求平均分配到多个后端服务器上。
- 可以提高系统的可用性和扩展性。
Nginx 反向代理的配置格式如下:
location /{
proxy_pass http://upstream_server;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
其中:
location /
指定了代理的请求 URL 路径,如果请求 URL 以/
开头,则该请求会被代理。proxy_pass
指定了代理请求的后端服务器地址。proxy_set_header
用于设置代理请求的 HTTP 头部,比如请求的主机名、客户端 IP 地址等。
负载均衡
Nginx 负载均衡是通过代理请求并将请求分发到多个后端服务器上,从而提高系统的可用性和扩展性。它有以下几个特点:
- 使用集群是网站解决高并发、海量数据问题的常用手段。
- 当一台服务器的处理能力、存储空间不足时,不要企图去换更强大的服务器,对大型网站而言,不管多么强大的服务器,都满足不了网站持续增长的业务需求。
- 这种情况下,更恰当的做法是增加一台服务器分担原有服务器的访问及存储压力。通过负载均衡调度服务器,将来自浏览器的访问请求分发到应用服务器集群中的任何一台服务器上,如果有更多的用户,就在集群中加入更多的应用服务器,使应用服务器的负载压力不再成为整个网站的瓶颈。
Nginx 负载均衡的配置格式如下:
upstream upstream_servers {
server server1.example.com;
server server2.example.com;
}
其中:
upstream upstream_servers
定义了后端服务器的地址和名称。server server1.example.com
和server server2.example.com
分别指定了后端服务器的地址。proxy_pass http://upstream_servers;
指定了代理请求的后端服务器地址。
这样,当客户端向 Nginx 服务器发送请求时,Nginx 会将请求转发到 server1.example.com
和 server2.example.com
这两个后端服务器中的一个,从而实现负载均衡。
locaotion
Nginx 的 location
指令是用来配置 URL 路径与后端服务器之间的映射关系。
每一个 location
指令都需要一个匹配规则,如果请求的 URL 路径符合该规则,则 Nginx 会将请求转发到后端服务器进行处理。
举个例子,如果你想将请求路径以 /images/
开头的请求都转发到后端服务器 http://images.example.com/
,则配置如下:
location /images/ {
proxy_pass http://images.example.com/;
}
其中,location /images/
指定了匹配规则,proxy_pass http://images.example.com/;
指定了后端服务器的地址。
以下是常见的用法
= 表示精确匹配,比如:
location = /demo {
}
~ 表示区分大小写的正则匹配,比如:
location ~ ^/demo$ {
}
~* 表示不区分大小写的正则匹配
location ~* ^/demo$ {
}
大概匹配顺序: =
优先级第一, ^~
第二
参考资料
《大型网站架构》--- 李智慧