文章目录
Nginx总结
1.简述
1.1正向代理
Nginx不仅可以做反向代理,实现负载均衡。还能用作正向代理进行上网等功能。
正向代理:如果把局域网外的Internet想象成一个巨大的资源库,则局域网中的客户端要访问Internet,则需要通过代理服务器来访问,这种代理服务称为正向代理。
- 即:在客户端(浏览器)配置代理服务器,通过代理服务器进行互联网访问
1.2反向代理
反向代理,其实客户端对代理是无感知的,因为客户端不需要任何配置就可以访问,我们只需要将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后,在返回客户端,此时反向代理服务器和目标服务器对外就是一个服务器,暴漏的是代理服务器地址,隐藏了真实服务器IP地址
- 即:我们只需要将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据,在返回给客户端,此时反向代理服务器和目标服务器就是一个服务器,暴漏的是代理服务器地址,隐藏了真是服务器IP地址
1.3负载均衡
负载均衡(Load Balance)其意思就是分摊到多个操作单元上进行执行,可以理解为N台服务器平均分担负载;例如Web服务器、FTP服务器、其它关键任务服务器等,从而共同完成工作任务。
当一台服务器的单位时间内的访问量越大时,服务器压力就越大,大到超过自身承受能力时,服务器就会崩溃。为了避免服务器崩溃,让用户有更好的体验,我们通过负载均衡的方式来分担服务器压力。
负载均衡的优点
减少服务器的压力,将原本一台服务器索要承受的访问量分给多台,并提高项目的可用性,当一台服务器挂掉的时候不会导致项目瘫痪
1.4动静分离
为了加快网站的解析速度,可以把动态页面和静态页面由不同的服务器来解析,加快解析速度。降低单个服务器的压力
2.安装Nginx
2.1Docker方式安装
docker pull nginx #拉取镜像
docker images #查看
docker run -di --name=nginx -p 80:80 nginx #守护方式创建容器
docker cp nginx:/etc/nginx /usr/local/nginx #复制目录
cd /usr/local/nginx
mv nginx config
docker stop nginx #停止
docker rm nginx #删除容器
docker run -di --name=nginx -p 80:80 -v /usr/local/nginx/:/etc/nginx nginx #挂载Nginx目录
docker ps #查看
docker exec -it nginx /bin/bash #进入nginx
2.2YUM方式
安装依赖包
yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel
下载并解压安装包
#创建一个文件夹
cd /usr/local
mkdir nginx
cd nginx
#下载tar包
wget http://nginx.org/download/nginx-1.13.7.tar.gz
tar -xvf nginx-1.13.7.tar.gz
安装Nginx
#进入nginx目录
cd /usr/local/nginx
#进入目录
cd nginx-1.13.7
#执行命令 考虑到后续安装ssl证书 添加两个模块
./configure --with-http_stub_status_module --with-http_ssl_module
#编译安装nginx
make & make install
#进入sbin目录执行启动
./nginx
#虚拟机需要关闭防火墙
systemctl stop firewalld
推荐防火墙自定设置
#查看开发的防火墙端口号
firewall-cmd --list-all
#设置开放的端口号
sudo firewall-cmd --add-port=80/tcp --permanent
#重启
firewall-cmd --reload
3.Nginx常用命令
进入/nginx/sbin目录
#查看版本
./nginx -v
#启动Nginx
./nginx
#停止nginx
./nginx -s stop
#重新加载
./nginx -s reload
4.Nginx配置文件
位置:/nginx/conf/nginx.conf
4.1全局模块
从配置文件开始到events块之间的内容,主要会设置一些影响nginx服务器整理运行的质量,主要包括配置运营Nginx服务器的用户(组)、允许生成的worker process数,进程PID存放路径、日志存放路径和类型以及配置文件的引入等。
#全局块开始
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
#全局块结束
events {
worker_connections 1024;
}
worker_processes 1;
这是Nginx服务器并发处理服务的关键配置,worker_processes的值越大,可以支持的并发处理量也越多,但是会受到硬件、软件等设备的制约
4.2events模块
events模块涉及的指令主要影响Nginx服务器与用户网络连接,比如worker_connections 1024; 支持最大连接数为1024,这部分的配置对Nginx的性能影响较大,在实际中应当灵活配置
events {
worker_connections 1024;
}
4.3Server模块
这算是Nginx服务器配置中最频繁的部分,代理、缓存和日志定义等大多数功能和第三方模块的配置都在这里。
需要注意的是:http模块也可以包含http全局块、server块。
4.3.1Http全局块
Http全局块配置的指令包括文件引入、MIME-TYPE定义、日志定义、连接超时时间、单链接请求上线等。
4.3.2Server块
一个Server可以配置多个location块
这块的主要作用是基于Nginx服务器接收到的请求字符串,对虚拟主机名称之外的字符串进行匹配,对特定的请求进行处理、地址定向、数据缓存和应答控制等功能,此外许多第三方模块的配置也可以在此
#设置一个虚拟机主机,可以包含自己的全局快,同时也可以包含多个locating模块。比如本虚拟机监听的端口、本虚拟机的名称和IP配置,多个server 可以使用一个端口,比如都使用80端口提供web服务、一个server相当于一个代理服务器,可以配置多个server。
server {
#配置server监听的端口
listen 80;
#本server的名称,当访问此名称的时候nginx会调用当前serevr内部的配置进程匹配,以空格方式隔开多个FQDN,当然也支持正则表达式的方式匹配主机名。
server_name localhost;
#指定编码格式,推荐修改为UTF-8字符编码
#charset koi8-r;
#access_log logs/host.access.log main;
#location其实是server的一个指令,为nginx服务器提供比较多而且灵活的指令,都是在location中体现的,主要是基于nginx接受到的请求字符串,对用户请求的UIL进行匹配,并对特定的指令进行处理,包括地址重定向、数据缓存和应答控制等功能都是在这部分实现,另外很多第三方模块的配置也是在location模块中配置。
location / {
#相当于默认页面的目录名称,默认是相对路径(如果是基于yum方式安装则是"/usr/share/nginx/html/",如果是基于源码方式安装,则在安装目录的下,如"/usr/local/nginx/html/"),当然咱们也可以使用绝对路径配置。
root html;
#转发端口配置
proxy_pass http://192.168.3.3:8080;
#默认的页面文件名称
index index.html index.htm;
}
#错误页面的文件名称
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
#location处理对应的不同错误码的页面定义到/50x.html,这个跟对应其server中定义的目录下。
location = /50x.html {
#定义默认页面所在的目录
root html;
}
}
4.3.2.1location匹配规则
= 精准匹配,请求的内容和uri一一对应,区分大小写
^~ URI左半部分匹配,不区分大小写,如果最长匹配前缀位置具有“ ^~”修饰符,则不检查正则表达式。
~ 区分大小写匹配
~* 不区分大小写进行匹配
注意:这里的不区分大小写指的是匹配的文件名字不区分大小写,但是linux的文件系统去查找时会区分大小写。
/ 主目录定义,一般其他没匹配到就会去这里查找。
匹配优先级从高到低:= ^~ ~/ ~* /
5.反向代理配置实例
监听本地80端口转发到百度
增加/test请求转发到京东
server {
listen 80;
server_name localhost;
location / {
root html;
proxy_pass http://www.baidu.com;
index index.html index.htm;
}
location /test {
root html;
proxy_pass http://www.jd.com/;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
6.负载均衡配置实例
upstream 名字{
server 192.168.169.130:8081;
server 192.168.169.130:8082;
}
#demo
upstream webservers{
server 192.168.9.134:8081 weight=8;
server 192.168.9.134:8082 weight=2;
}
location / {
#转发到负载服务上
proxy_pass http://webservers/api/;
}
默认情况下,nginx采用的是轮询策略,nginx还提供了其他几种常用的负载均衡配置
1、ip_hash
每个请求按访问IP的hash结果进行分配,这样每个访客就可以固定访问一个后端服务,一定程度上可以解决session问题;
upstream webservers {
ip_hash;
server 192.168.9.134:8081;
server 192.168.9.134:8082;
}
2、weight
weight代表权重,默认为1,权重越高,被分配的客户端请求就会越多
upstream webservers{
server 192.168.9.134:8081 weight=8;
server 192.168.9.134:8082 weight=2;
}
3、url_hash
按访问URL的hash结果分配。这样相同的url会被分配到同一个节点,主要为了提高缓存命中率。比如,为了提高访问性能,服务端有大量数据或者资源文件需要被缓存。使用这种策略,可以节省缓存空间,提高缓存命中率
upstream webservers{
hash &request_uri;
server 192.168.9.134:8081;
server 192.168.9.134:8082;
}
4、least_conn
按节点连接数分配,把请求优先分配给连接数少的节点。该策略主要为了解决,各个节点请求处理时间长短不一造成某些节点超负荷的情况。
upstream webservers{
least_conn;
server 192.168.9.134:8081;
server 192.168.9.134:8082;
}
4、fail(第三方)
按后端服务器的响应时间来分配请求,响应时间短的将会被优先分配
upstream webservers{
server 192.168.9.134:8081;
server 192.168.9.134:8082;
fair;
}
7.动静分离
动静分离是指在web服务器架构中,将静态页面与动态页面或者静态内容接口和动态内容接口分开不同系统访问的架构设计方法,进而提升整个服务访问性能和可维护性。
简单点来说,就是用户在请求的时候,如果只是简单的访问图片,html等静态的请求时,nginx直接返回,如果是发送动态请求时候,需要程序进行就由nginx把请求发送给程序,进行动态处理。
实例一:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sA5oS3tD-1689085239106)(C:\Users\Mr.Zhang\AppData\Roaming\Typora\typora-user-images\image-20230710231559730.png)]
实例二:
#通过url判断如下后缀为静态文件,并转至静态文件路径获取文件
location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css)$
{
#某用户下的 静态文件路径
root /opt/nginx/static/;
#缓存有效期 30d = 30天,也可以去掉
expires 30d;
}
8.高可用
1.什么是高可用
高可用HA(High Availability)是分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计减少系统不能提供服务的时间。
2.分析原理
3.开始搭建
1.需要的环境
两台 Linux 并各自安装 Nginx 和 keepalived
192.168.75.129----master主节点
192.168.75.131----backup从节点
2.安装 keepalived
yum -y install keepalived
3.检查是否安装keepalived
rpm -q -a keepalived
默认安装路径: /etc/keepalived
4.修改keepalived.conf的配置内容
ifconfig
添加nginx_check.sh脚本文件
放到 /usr/local/src中
6.分别启动—keepalived
systemctl start keepalived.service
记得关闭防火墙,启动nginx ,启动keepalived
7.访问虚拟ip
8. 关闭主节点nginx和keepalived
/usr/soft/nginx/sbin/nginx -s stop
systemctl stop keepalived.service
9.关闭主节点后再访问虚拟ip
9.Nginx原理解析
1.master与worker
Nginx在启动后,会有一个master进程和多个worker进程。master进程主要用来管理worker进程,包含:接收来自外界的信号,向各worker进程发送信号,监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程。而基本的网络事件,则是放在worker进程中来处理了。多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。worker进程的个数是可以设置的,一般我们会设置与机器cpu核数一致,这里面的原因与nginx的进程模型以及事件处理模型是分不开的
2.worker如何工作的
3.一个maser和多个worker的好处
1)可以用热部署方式
nginx -s reload
2)每个worker都是独立的进程,如果有其中一个worker出现问题,其他独立的worke会继续进行争抢,实现请求过程,不会造成服务的中段r
4.设置多少worker合适
woker数和服务器的cpu数字相当最为适宜
5.连接数worker_connection
1)发送请求占用了个worker几个连接?
如果是静态资源是2个连接数、如果是动态资源则是4个
2)nginx有一个master,四个worker,每个worker支持最大连接数1024,支持的最大并发是多少?
静态:worker_connections * worker_processes / 2
HTTP反向代理:worker_connections * worker_processes / 4
1024*4/2
GJ5zUfLI-1689085239108)]
2.worker如何工作的
[外链图片转存中…(img-uv8uy40M-1689085239109)]
3.一个maser和多个worker的好处
1)可以用热部署方式
nginx -s reload
2)每个worker都是独立的进程,如果有其中一个worker出现问题,其他独立的worke会继续进行争抢,实现请求过程,不会造成服务的中段r
4.设置多少worker合适
woker数和服务器的cpu数字相当最为适宜
5.连接数worker_connection
1)发送请求占用了个worker几个连接?
如果是静态资源是2个连接数、如果是动态资源则是4个
2)nginx有一个master,四个worker,每个worker支持最大连接数1024,支持的最大并发是多少?
静态:worker_connections * worker_processes / 2
HTTP反向代理:worker_connections * worker_processes / 4
1024*4/2
10.跨域问题
跨域主要设计到4个响应头:
Access-Control-Allow-Origin 用于设置允许跨域请求源地址 (预检请求和正式请求在跨域时候都会验证)
Access-Control-Allow-Headers 跨域允许携带的特殊头信息字段 (只在预检请求验证)
Access-Control-Allow-Methods 跨域允许的请求方法或者说HTTP动词 (只在预检请求验证)
Access-Control-Allow-Credentials 是否允许跨域使用cookies,如果要跨域使用cookies,可以添加上此请求响应头,值设为true(设置或者不设置,都不会影响请求发送,只会影响在跨域时候是否要携带cookies,但是如果设置,预检请求和正式请求都需要设置)。不过不建议跨域使用,除非必要,因为有很多方案可以代替。
# 允许跨域请求的域,*代表所有
add_header 'Access-Control-Allow-Origin' *;
# 允许带上cookie请求
add_header 'Access-Control-Allow-Credentials' 'true';
#允许请求的方法,如GET/POST/PUT/DELETE
add_header 'Access-Control-Allow-Methods' *;
#允许请求的header
add_header 'Access-Control-Allow-Headers ' *
跨域请求时会先发送预检请求,浏览器首先会询问服务器,当前网页所在的域名是否在服务器的许可列表中,以及可以使用的请求头和请求方法。若得到肯定的答复,才会发送正式请求Xhr请求,否则报错
10.1 概念
首先明确一个概念,前端项目、后端项目、以及nginx,这就是三个server项目,他们只是互相之间交流数据;
三个项目都有自己的ip:port组合,哪怕你是在同一台服务器上启动这三个server,他们的port也是不可能有一样的;
所以,前端项目,不论访问nginx还是访问后端项目,都会产生跨域问题。
解决跨域问题
以下举例都是项目在同一台机器上,所以IP相同,只以端口区分前端项目(8081)、后端项目(8082)和nginx(8080)。
方法1:在nginx中配置地址重写(或者转发也行)
访问地址以/resource开头的都会被这个模块捕获,转发到http://192.168.137.189:8082的后端项目上去。例如此时访问http://192.168.137.189:8080/resource/userList/engineer,就会转发到http://192.168.137.189:8082/userList/engineer。
访问地址以/js开头的也被这个模块捕获,转发到http://192.168.137.189:8082的前端项目上去。
server
{
listen 8080;
location /resource {
rewrite ^/resource/?(.*)$ /$1 break;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.137.189:8082/; # 转发地址
}
location /js {
rewrite ^/js/?(.*)$ /$1 break;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.137.189:8081/; # 转发地址
}
}
此时统一通过nginx访问前后端项目,通过/js标识转发到前端项目,通过/resource标识转发到后端项目。浏览器同源策略记录的就是http://192.168.137.189:8080/,浏览器也只访问这个nginx的8080地址,跨域问题也就得到了解决。
方法2:nginx中添加允许跨域请求头
server
{
listen 8080;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
location /resource {
rewrite ^/resource/?(.*)$ /$1 break;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.137.189:8082/; # 转发地址
}
}
这就和不用nginx,直接在后端项目中(tomcat或者自己写的服务端代码)配置允许跨域一样,只不过把允许跨域的配置放在nginx中,这个配置解决了前端项目访问nginx的跨域问题,而nginx访问后端项目不存在跨域问题(不是浏览器,没有同源策略限制)。此时nginx对于后端就相当于一个代理分发服务器。
10.2参数解释
Access-Control-Allow-Origin
服务器默认是不被允许跨域的。给Nginx服务器配置Access-Control-Allow-Origin *
后,表示服务器可以接受所有的请求源(Origin),即接受所有跨域的请求。
Access-Control-Allow-Headers 是为了防止出现以下错误:
Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
这个错误表示当前请求Content-Type的值不被支持。其实是我们发起了”application/json”的类型请求导致的。这里涉及到一个概念:预检请求(preflight request),请看下面”预检请求”的介绍。
Access-Control-Allow-Methods 是为了防止出现以下错误:
Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
给OPTIONS 添加 204的返回,是为了处理在发送POST请求时Nginx依然拒绝访问的错误
发送”预检请求”时,需要用到方法 OPTIONS ,所以服务器需要允许该方法。
10.3总结
浏览器的同源策略只记录他访问对象的ip和port,访问其他资源如果还是这个ip:port,就不存在跨域问题,如果不是这个ip:port,就用nginx讲这个ip:port转发到要访问的ip:port,让他仍然访问这个同源策略的ip:port。
参考文献:
https://www.jianshu.com/p/1080014a234f
https://segmentfault.com/a/1190000012550346
11.防盗链
配置nginx
方式一:通过Referer,网站可以检测目标网页访问的来源网页是否合法
location ~* ^.+\.(jpg|gif|png|swf|flv|wma|wmv|asf|mp3|mmf|zip|rar)$ {
valid_referers none blocked www.benet.com benet.com;
if ($invalid_referer) {
#return 302 http://www.benet.com/img/nolink.jpg;
return 404;
break;
}
access_log off;
}
参数说明:
参数名 | 含义 |
---|---|
none | 允许没有http_refer的请求访问资源 |
blocked | 允许不是http://开头的,不带协议的请求访问资源 |
server_names | 表示一个或多个主机名称。从Nginx 0.5.33版本开始,server_names中可以使用通配符"*"号。 |