一、初始Nginx
Nginx是一个高性能的http和反向代理web服务器,同时也为我们提供了IMAP/POP3/SMTP服务。其源码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、简单的配置文集和低系统资源的消耗而闻名。Nginx是一款轻量级的web服务器和反向代理服务器以及电子邮件代理服务器,其特点是占用内存少,并发能力强的特点。
openresty官网:openresty.org/cn/
nginx官网下载:nginx.org/en/download…
二、Nginx安装
1)、linux环境安装
1.官网地址下载,根据自己需要安的操作系统选择不同包下载,下载地址:nginx.org/en/download…
2.上传下载的压缩包到虚拟机新建的环境上;
3.解压压缩包文件:
tar -zxvf nginx-1.22.1.tar.gz
4.进入解压后的文件夹,编辑安装,通过使用cd ./nginx命令进入解压后的nginx目录下;
配置configure --prefix 代表安装的路径,--with-http_ssl_module 安装ssl,--with-http_stub_status_module查看nginx的客户端状态
./configure --prefix=/usr/local/nginx-1.22.1 --with-http_ssl_module --with-http_stub_status_module
如果你执行的时候出现以下问题:
提示:
checking for OS + Linux3.10.0-693.el7.x86_64 x86_64 checking for C compiler ... not found ./configure: error: C compiler cc is not found
安装gcc ,执行命令 yum install -y gcc
提示:
./confgure:error: the HTTP rewrite moudle requires the PCRE library. You can either disable the moudle by using --without-http_rewrite_moudle option,or install the PCRE library into the system,or build the PCRE library statically from the source with nginx by using --with-pcre<path>option.
安装:yum install -y pcre pcre-devel
提示:
./configration:/error:the HTTP gzip moudle requires the zlib libarary....
安装zlib库:yum install -y zlib zlib-devel
接下来执行:
make
make install
5.启动Nginx
进入安装好的目录/usr/lcoal/nginx/sbin:
./nginx 启动
./nginx -s stop 快速停止
./nginx -s quit 优雅关闭 在删除前完成已经接受的请求连接
./nginx -s reload 重新加载配置
6.关于防火墙:
关闭防火墙:systemctl stop firewalld.service
禁止防火墙开机启动:systemctl disable firewalld.service
放行端口:firewalld -cmd --zone=public --add-port=80/tcp --permanent
重启防火墙:firewall -cmd --reload
7.安装成系统服务:
创建服务脚本:vim /usr/lib/systemd/system/nginx.service
脚本内容:
[Unit]
Description = nginx - web server After = network.target remote-fs.target nss-lookup.target[Service]
Type = config PIDFile = usr/local/logs/nginx.pid ExecStartPre = /usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf ExecStart = /usr/lcoal/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf ExecReload = /usr/lcoal/nginx/sbin/nginx -s reload ExecStop = /usr/lcoal/nginx/sbin/nginx -s stop ExecQuit = /usr/lcoal/nginx/sbin/nginx -s quit PrivateTmp = true[Install]
重启加载系统服务: systemctl demon-reload
启动服务:systemctl start nginx.service
开机启动:systemctl start nginx.service
2)、容器dokcer安装
1.拉取镜像,拉取nginx镜像 这个没有版本要求 , 我这里直接拉取最新的:docker pull nginx
2.复制配置文件.我们先简单运行nginx :docker run --name nginx -d -p 80:80 nginx
需要拷贝其配置文件:
#创建文件夹
mkdir -p /config/nginx/{logs,ssl,html,conf/conf.d}
#复制配置文件
docker cp nginx:/etc/nginx/nginx.conf /config/nginx/conf/nginx.conf
docker cp nginx:/etc/nginx/conf.d /config/nginx/conf
3.准备工作完成
#停止
docker stop nginx
#删除
docker rm nginx
4.修改 nginx.conf配置文件 (根据情况自行操作)
vi /config/nginx/conf/nginx.conf
5.重新运行挂载
docker run --detach --name nginx -p 443:443 -p 80:80 --restart=always --privileged=true
-v /config/nginx/html:/usr/share/nginx/html:rw
-v /config/nginx/conf/nginx.conf:/etc/nginx/nginx.conf
-v /config/nginx/conf/conf.d:/etc/nginx/conf.d
-v /config/nginx/logs:/var/log/nginx
-v /config/nginx/ssl:/ssl
-id nginx
注:通过docker方式安装nginx过程中会出现的问题以及解决思路:
Using default tag: latest
Error response from daemon: Get https://registry-1.docker.io/v2/: dial tcp: lookup registry-1.docker.io on [::1]:53: read udp [::1]:32894->[::1]:53: read: connection refused
修改docker配置文件,新加以下代理配置信息:
root@justin:/home/justin/Desktop# vim /usr/lib/systemd/system/docker.service
通过以下命令重启系统以及docker容器:
root@justin:/home/justin/Desktop# systemctl daemon-reload
root@justin:/home/justin/Desktop# systemctl restart docker
三、Nginx基本使用
1)、Nginx基本请求流程
2)、Nginx.conf最小配置解析
1、worker_processes worker_processes: 1 默认值为1 表示开启一个业务进程
2、work_connetions work_connetions: 1024; 单个业务进程可以接收的连接数
3、include mime.type include mime.type; 引入http mime类型;
4、default_type application/octet-stream default_type application/octet-stream; 如果mime类型没有匹配上 默认使用二进制流的方式传输;
5、sendfile on sendfile on; 使用linux的sendFile(socket、file、len)高效网络传输,也就是数据0拷贝。
6、keepalive_timeout keepalive_timeout 65; 保持连接 超时时间
7、server 虚拟主机(vhost)
未配置sendfile:
配置sendfile
3)、nginx虚拟主机实战
- 域名 dns ip关系:
IP地址是IP协议提供的一种统一的地址格式,他为互联网上的每一台主机和每一个网络都分配一个唯一的逻辑地址,以此来屏蔽物理地址的差异;常用的ip地址分为IPv4和IPv6两大类; ip地址是数字型的,为了方便记忆,才有了域名,通过域名地址就能找到ip地址; ip地址和域名在某些方面可以理解为等效关系。DNS (Domain name system)则是关联IP和域名的域名系统,可以将域名映射到IP地址。 - 虚拟主机原理:
如果有这样一个场景,假如一台主机只挂载了一个站点,当这个站点并没有太多的访问量时,就会造成资源过剩(有剩余资源),这时我们可以开启虚拟主机,挂载多个站点,合理的利用主机的资源。一个IP地址可以对应多个域名,根据域名的不同,我们去寻找这些域名对应的资源目录,找到这些资源之后,返回给用户。当然,我们需要在请求报文中加上这个域名,不然服务器不知道我们需要哪个域名的资源。 - 使用host文件解析域名: 进入windows系统盘,打开hosts文件,添加如下配置:192.168.10.132 zyt.com(如若报错 则修改权限即可)
- 公网域名解析流程:
1、用户通过Web浏览器输入网站域名www.zyt.com。
2、Web浏览器将对域名www.zyt.com的查询请求路由到Local DNS。
3、Local DNS缓存域名解析数据,并提供递归查询功能。Local DNS通常是Internet服务商提供的DNS。
4、Local DNS在缓存中没有查询到域名的解析记录,将对域名www.zyt.com的查询请求路由到根域名服务器。
5、因域名后缀为.com,根域名服务器向Local DNS返回.com顶级域服务器的地址。
6、Local DNS将对域名www.zyt.com的查询请求路由到.com顶级域服务器。
7、.com顶级域服务器向Local DNS返回为域名example.com提供权威解析服务的一级域服务器地址。
8、Local DNS将对域名www.zyt.com的查询请求路由到一级域服务器。
9、若域名www.zyt.com的DNS服务器设置为华为云DNS服务器地址,则云解析服务作为一级域服务器为域名提供权威的解析记录。
10、一级域服务器向Local DNS返回域名对应的网站IP地址。
11、Local DNS向Web浏览器返回网站IP地址。
12、Web浏览器通过网站IP地址访问网站服务器。
13、网站服务器向Web浏览器返回网站主页。
14、终端用户从Web浏览器获取网站主页,对网站的访问成功。
- 虚拟主机域名配置:
虚拟主机可以通过配置监听的端口号、server_name区分访问不同的资源,对于通过server_name方式。需要在公网下配置相关域名。
同端口号请求,响应不同内容:
server {
listen 80;
server_name localhost; #主机名/域名
location = / {
root /www/music;
index index.html index.htm;
>} } -- 页面展示/www/music 目录下index内容
server {
listen 88;
server_name localhost; #主机名/域名
location = / {
root /www/video;
index index.html index.htm;
}} -- 页面展示/www/video; 目录下index内容
- servername匹配规则
原本一台服务器只能对应一个站点,通过虚拟主机技术可以虚拟化成多个站点同时对外提供服务。
- servername匹配规则 我们需要注意的是servername匹配分先后顺序,写在前面的匹配上就不会继续往下匹配了。
- 完整匹配 我们可以在同一servername中匹配多个域名
server_name www.zyt1.com www1.zyt1.com;
- 通配符匹配
server_name *.zyt1.com
- 通配符结束匹配
server_name www.*;
- 正则匹配
server_name ~^[0-9]+\.zyt\.com$;
三、Nginx反向代理与负载均衡
1)、什么是代理
代理也被叫做网络代理,是一种比较特殊的网络服务,允许一个终端(通常指客户端)通过这个服务与另一个终端(通常指服务器端)进行非直接的连接。例如:一些网关、路由器等网络设备都具备网络代理的功能。代理服务有利于保障网络终端的隐私或者安全,可以在一定程度上阻止网络攻击(因为通过代理,可以隐藏真正的服务器端/客户端)。
2)、正向代理
正向代理是一个位于客户端和原始服务器之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端才能使用正向代理。正向代理的典型用途是为在防火墙内的局域网客户端提供访问Internet的途径。正向代理还可以使用缓冲特性减少网络使用率。比如:当前用户访问谷歌网站,不可以直接访问,需要在客户端配置一个代理服务器,然后通过代理服务完成网络访问。
3)、反向代理
反向代理服务器位于用户与目标服务器之间,但是对于用户而言,反向代理服务器就相当于目标服务器,即用户直接访问反向代理服务器就可以获得目标服务器的资源。同时,用户不需要知道目标服务器的地址,也无须在用户端作任何设定。反向代理服务器通常可用来作为Web加速,即使用反向代理作为Web服务器的前置机来降低网络和服务器的负载,提高访问效率。此时,该nginx作为中继站。
4)、Nginx反向代理企业级项目应用场景
5)、负载均衡
客户端发送多个请求到服务器,服务器处理请求,有一些可能要与数据库进行交互,服务器处理完毕后,再将结果返回给客户端。
这种架构模式对于早期的系统相对单一,并发请求相对较少的情况下是比较适合的,成本也低。但是随着信息数量的不断增长,访问量和数据量的飞速增长,以及系统业务的复杂度增加,这种架构会造成服务器相应客户端的请求日益缓慢,并发量特别大的时候,还容易造成服务器直接崩溃。很明显这是由于服务器性能的瓶颈造成的问题,那么如何解决这种情况呢?
我们首先想到的可能是升级服务器的配置,比如提高 CPU 执行频率,加大内存等提高机器的物理性能来解决此问题,但是我们知道摩尔定律的日益失效,硬件的性能提升已经不能满足日益提升的需求了。最明显的一个例子,天猫双十一当天,某个热销商品的瞬时访问量是极其庞大的,那么类似上面的系统架构,将机器都增加到现有的顶级物理配置,都是不能够满足需求的。那么怎么办呢?
上面的分析我们去掉了增加服务器物理配置来解决问题的办法,也就是说纵向解决问题的办法行不通了,那么横向增加服务器的数量呢?这时候集群的概念产生了,单个服务器解决不了,我们增加服务器的数量,然后将请求分发到各个服务器上,将原先请求集中到单个服务器上的情况改为将请求分发到多个服务器上,将负载分发到不同的服务器,也就是我们所说的负载均衡。
6)、反向代理基本配置
用户访问http://192.168.10.132时 跳转到百度。配置如下:
server {
listen 80;
server_name localhost;
location = / {
proxy_pass http://www.baidu.com
}
}
server {
listen 80;
server_name localhost;
location = / {
proxy_pass http://192.168.10.132
} // 跳转到某个服务器
}
7)、负载均衡器基本配置
以下为负载均衡基本配置,当浏览器访问xxx:80时候,每刷新一次,就会轮流请求192.168.10.132:80;192.168.10.133:80获取对应的资源并展示到页面。
upstream httpds {
//会轮训访问配置的两个服务器地址
server 192.168.10.132:80;
server 192.168.10.133:80;
}
server {
listen 80;
server_name localhost;
location = / {
proxy_pass http://httpds
}
}
8)、负载均衡策略
1、轮循策略
默认情况下使用轮询方式,逐一转发,这种方式适用于无状态请求。比如我们在服务器上配置了三台应用服务器:www.zyt1.com、www.zyt2.com、www.zyt3.com; 在Nginx服务器配置文件配置了轮循策略的时候,页面请求xxx:80地址,每请求一次,就会轮循请求到三台服务器中的一台。配置如下:
http {
upstream httpd {
server 127.0.0.1:8050;
server 127.0.0.1:8060;
server 127.0.0.1:8060;
}
server {
listen 80;
location / {
proxy_pass http://httpd;
}
}
}
2、weight(权重)策略
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
http {
upstream httpd {
server 127.0.0.1:8050 weight=10 down;
server 127.0.0.1:8060 weight=1;
server 127.0.0.1:8070 weight=1 backup;
}
server {
listen 80;
location / {
proxy_pass http://httpd;
}
}
}
- weight: 权重 权重越高 请求命中率越高;
- down:表示当前服务下线 不参与负载均衡;
- backup: 表示当前服务处于备用状态 不参与负载均衡(除非没有服务可以参与负载均衡 才启用该服务)
3、ip_hash策略
配置 IP 哈希负载均衡,只需要将 ip_hash 指令添加到服务器 upstream 组配置中即可。
http {
upstream httpd {
ip_hash;
server 127.0.0.1:8050;
server 127.0.0.1:8060;
server 127.0.0.1:8070;
}
server {
listen 80;
location / {
proxy_pass http://httpd;
}
}
}
4、least_conn策略
负载均衡的规则是最少连接。在一些请求需要更长的时间才能完成的情况下,最少连接可以更公正地控制应用程序实例的负载。使用最少连接的负载均衡,nginx 将尽量不给过于繁忙的应用服务器负载过多的请求,而是将新的请求分发到不太忙的服务器。当使用 least_conn 指令作为服务组配置的一部分时,将激活 nginx 中的最少连接负载均衡。
http {
upstream httpd {
least_conn;
server 127.0.0.1:8050;
server 127.0.0.1:8060;
server 127.0.0.1:8070;
}
server {
listen 80;
location / {
proxy_pass http://httpd;
}
}
}
5、url_hash策略
主要根据url进行hash计算处理操作
http {
upstream httpd {
hash $request_uri;
server 127.0.0.1:8050;
server 127.0.0.1:8060;
server 127.0.0.1:8070;
}
server {
listen 80;
location / {
proxy_pass http://httpd;
}
}
}
6、fair策略
根据后端服务器响应时间转发请求
四、Nginx动静分离
1)、动静分离概念引入
动静分离应该是听的次数较多的性能优化方案,那先思考一个问题:为什么需要做动静分离呢?它带来的好处是什么? 其实这个问题也并不难回答,当你搞懂了网站的本质后,自然就理解了动静分离的重要性。先来以淘宝为例分析看看:
2)、动静分离概述与原理
概述:动静分离指的是将动态请求和静态请求分隔开,然后分别路由到相应的后端服务器。通常用户的请求中,一部分需要后台程序处理,例如查询数据库或者进行一些数据运算,这类请求我们称之为动态请求;还有一部分不需要后台程序处理,如请求 css、html、js、图片等静态资源,这类请求我们称之为静态请求。Nginx 实现动静分离的基础是它可以根据配置对不同的请求做不同的转发,动静分离有利于提高整个服务器系统的性能。(将静态资源存放到nginx服务器、动态资源通过代理方式完成请求获取数据)
原理:服务端接收来自客户端的请求中。既有静态资源也有动态资源,静态资源由Nginx提供服务,动态资源Nginx转发至后端。如下图:
Nginx配置动静分离初尝试:
在centos操作系统安装tomact服务器,并将静态资源上传到tomact服务器。在nginx配置文件中配置以下内容:
location / {
proxy_pass http://127.0.0.1:8080;
root html;
index index.html index.htm;
}
请求http://10.96.16.63/#, 页面响应如下:
注:静态资源包括css、js、image等等信息,我们可以分别配置访问各自信息访问路径。具体如下;
location /css {
root /usr/local/nginx/static;
index index.html index.htm;
}
location /images {
root /usr/local/nginx/static;
index index.html index.htm;
}
location /js {
root /usr/local/nginx/static;
index index.html index.htm;
}
3)、Nginx配置文件中location配置
- / 通用匹配,任何请求都会匹配到。
- = 精准匹配,不是以指定模式开头
- ~ 正则匹配,区分大小写
- ~* 正则匹配,不区分大小写
- ^~ 非正则匹配,匹配以指定模式开头的location
location匹配顺序:
- 多个正则location直接按书写顺序匹配,成功后就不会继续往后面匹配
- 普通(非正则)location会一直往下,直到找到匹配度最高的(最大前缀匹配)
- 当普通location与正则location同时存在,如果正则匹配成功,则不会再执行普通匹配
- 所有类型location存在时,“=”匹配 > “^~”匹配 > 正则匹配 > 普通(最大前缀匹配)
举例:
server {
listen 80;
server_name localhost;
location = / {
proxy_pass http://192.168.10.132:8080;
}
location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css){
root /soft/nginx/static_resources; // 创建存在静态资源数据
}
}
4)、location的作用
location指令的作用是根据用户请求的URI来执行不同的应用,也就是根据用户请求的网站URL进行匹配,匹配成功即进行相关的操作。一个server可以有多个location配置, 对于用户的请求在面对多个location时,需要一定的location匹配规则和location优先级来确定具体匹配到哪个location。
5)、alias与root区别
root用来设置根目录,而alias在接受请求的时候在路径上不会加上location。
- alias指定的目录是准确的,即location匹配访问的path目录下的文件直接是在alias目录下查找的;
- root指定的目录是location匹配访问的path目录的上一级目录,这个path目录一定要是真实存在root指定目录下的;
- 使用alias标签的目录块中不能使用rewrite的break(具体原因不明);另外,alias指定的目录后面必须要加上"/"符号;
- alias虚拟目录配置中,location匹配的path目录如果后面不带"/",那么访问的url地址中这个path目录后面加不加"/"不影响访问,访问时它会自动加上"/"; 但是如果location匹配的path目录后面加上"/",那么访问的url地址中这个path目录必须要加上"/",访问时它不会自动加上"/"。如果不加上"/",访问就会失败;
- root目录配置中,location匹配的path目录后面带不带"/",都不会影响访问。
location ~*/(css|img|js) {
root /usr/local/nginx/static;
index index.html index.htm;
}
location /css {
alias /usr/local/nginx/static/css;
index index.html index.htm;
}
6)、Nginx伪静态配置UrlRewrite
1、rewrite语法格式及参数语法:
rewrite是实现URL重写的关键指令,根据regex (正则表达式)部分内容,重定向到replacement,结尾是flag标记。
rewrite <regex> <replacement> [flag];
关键字 正则 替代内容 flag标记
关键字:其中关键字error_log不能改变;
正则:perl兼容正则表达式语句进行规则匹配
替代内容:将正则匹配的内容替换成replacement
flag标记:rewrite支持的flag标记
rewrite参数的标签段位置:
server,location,if
flag标记说明:
last #本条规则匹配完成后,继续向下匹配新的location URI规则
break #本条规则匹配完成即终止,不再匹配后面的任何规则
redirect #返回302临时重定向,浏览器地址会显示跳转后的URL地址
permanent #返回301永久重定向,浏览器地址栏会显示跳转后的URL地址
和apache等web服务软件一样,rewrite的组要功能是实现RUL地址的重定向。Nginx的rewrite功能需要PCRE软件的支持,即通过perl兼容正则表达式语句进行规则匹配的。默认参数编译nginx就会支持rewrite的模块,但是也必须要PCRE的支持。rewrite是实现URL重写的关键指令,根据regex(正则表达式)部分内容,重定向到replacement,结尾是flag标记。
2、rewrite实操举例
比如:真实访问: http://192.168.10.132:9999/product/detail?id=1
=> http://192.168.10.132:9999/product/detail/1 其配置如下:
rewrite ^/(/d+)/(.+)/ /$2?id=$1 last;
五、Nginx网关
1)、什么是Nginx网关
Nginx作为网关中间件,其主要资源是为了隔离外部互联网与内网服务器,保证了内网服务器的安全。其具有方向代理、动静分离、负载均衡的资源。其在网络架构设计中存在的位置见下图:
2)、应用服务器防火墙配置
1、开启防火墙:
systemctl start firewalld
2、重启防火墙:
systemctl restart firewalld
3、重载规则:
firewall-cmd --reload
4、查看已配置规则:
firewall-cmd --list-all
5、指定端口和ip访问:
firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.10.132"
port protocol="tcp" port="8080" accept"
6、移除规则
firewall-cmd --permanent --remove-rich-rule="rule family="ipv4" source
address="192.168.10.132" port port="8080" protocol="tcp" accept"
注:在应用服务器网关加上可信赖的服务器(暴露给互联网的服务器)地址,此时应用服务器资源只有通过该可信赖的服务器代理去访问,不能直接进行访问。
3)、网关配置
upstream httpds {
server 192.168.44.102 weight=8 down;
server 192.168.44.103:8080 weight=2;
server 192.168.44.104:8080 weight=1 backup;
}
location / {
rewrite ^/(/d+)/(.+)/ /$2?id=$1 last redirect;
; proxy_pass http://httpds ;
}
六、Nginx防盗链
1)、什么是Nginx防盗链
防盗链简单来说就是存在我们服务中的一些资源,只有我们规定的合法的一类人才能去访问,其他人就不能去访问的资源(如css,js,img等资源)。具体点就是用户发送请求给nginx服务器,nginx服务器根据请求去寻找资源,请求的比如说是有个index.html文件,这个文件中会包含很多js,css,img等资源,这些文件在这个骨架中会被二次请求,在第二次请求时,会在请求头部上加上有个referer,这个referer只会在第二次请求时才会被加上。(referer表示第二次资源的来源地址。
2)、Nginx实现原理
客户端向服务器端请求资源时,为了减少网络带宽,提高响应时间,服务器一般不会一次将所有资源完整地传回客户端。比如请求一个网页时,首先会传回该网页的文本内容,当客户端浏览器在解析文本的过程中发现有图片存在时,会再次向服务器发起对该图片资源的请求,服务器将存储的图片资源再发送给客户端。但是如果这个图片是链接到其他站点的服务器上去了呢,比如在我项目中,我引用了的是淘宝中的一张图片的话,那么当我们网站重新加载的时候,就会请求淘宝的服务器,那么这就很有可能造成淘宝服务器负担。因此这个就是盗链行为。因此我们要实现防盗链。
3)、防盗链基本配置
Nginx中有一个指令 valid_referers. 该指令可以用来获取 Referer 头域中的值,并且根据该值的情况给 Nginx全局变量 invalidreferer赋值。如果Referer头域中没有符合validreferers指令的值的话,invalid_referer 赋值。如果Referer头域中没有符合 valid_referers指令的值的话,invalidreferer赋值。如果Referer头域中没有符合validreferers指令的值的话,invalid_referer变量将会赋值为1. valid_referers 指令基本语法如下:
valid_referers none | blocked | server_names | strings ....;
- none, 检测 Referer 头域不存在的情况。
- blocked,检测 Referer 头域的值被防火墙或者代理服务器删除或伪装的情况。这种情况该头域的值不以 “http://” 或 “https://” 开头。
- server_names ,设置一个或多个 URL ,检测 Referer 头域的值是否是这些 URL 中的某一个。
因此我们有了 valid_referers指令和$invalid_referer变量的话,我们就可以通过 Rewrite功能来实现防盗链。
下面我们介绍两种方案:第一:根据请求资源的类型。第二:根据请求目录。 1、根据请求文件类型实现防盗链配置如下:
server {
listen 8080;
server_name localhost;
location ~* ^.+.(gif|jpg|png|swf|flv|rar|zip)$ {
valid_referers none blocked www.zyt1.com www.zyt2.com *.zyt.com;
if ($invalid_referer) {
rewrite ^/ http://www.xxx.com/images/forbidden.png;
}
}
}
如上基本配置,当有网络连接对以 gif、jpg、png为后缀的图片资源时候、当有以swf、flv为后缀的媒体资源时、或以 rar、zip为后缀的压缩资源发起请求时,如果检测到Referer头域中没有符合 valid_referers指令的话,那么说明不是本站的资源请求。
valid_referers none blocked www.zyt1.com www.zyt2.com; 可以理解为白名单,允许文件链出的域名白名单,
如果请求的资源文件不是以这些域名开头的话,就说明请求的资源文件不是该域下的请求,因此可以判断它是盗链。
因此如果不是该域下的请求,就会使用 Rewrite进行重定向到 www.zyt1.com/images/forb… 这个图片,
比如这张图片是一个x或其他的标识,然后其他的网站就访问不了你这个图片哦。
2、根据请求目录实现防盗链的配置实列如下:
server {
listen 9999;
server_name localhost;
location /file/ {
root /server/file/;
valid_referers none blocked www.zyt1.com www.zyt2.com ;
if ($invalid_referer) {
rewrite ^/ http://www.xxx.com/images/forbidden.png;
}
}
}
4)、使用curl测试
curl -e "http://www.baidu.com" -I http://192.168.10.132/img/logo.png
七、Nginx高可用
1)、什么是Nginx高可用
线上如果采用单个节点的方式部署Nginx,难免会出现天灾人祸,比如系统异常、程序宕机、服务器断电、机房爆炸、地球毁灭....哈哈哈,夸张了。但实际生产环境中确实存在隐患问题,由于Nginx作为整个系统的网关层接入外部流量,所以一旦Nginx宕机,最终就会导致整个系统不可用,这无疑对于用户的体验感是极差的,因此也得保障Nginx高可用的特性。接下来则会通过keepalived的VIP机制,实现Nginx的高可用。VIP并不是只会员的意思,而是指Virtual IP,即虚拟IP。
2)、Keepalived搭建Nginx高可用集群
1、KeepAlived概述
Keepalived是以VRRP(Virtual Router Redundancy Protocol,虚拟路由冗余协议)协议为实现基础的,这个协议可以认为是实现了路由器高可用的协议,将多台提供相同功能的路由器组成一个路由器组。
原理:在整个Keepalived集群中会有一个主机master和多个备用机backup,master节点上有一个对外提供服务的Virtual IP(VIP),并且master会发组播的心跳信息,当backup收不到VRRP包时就认为master宕掉了,这时就需要根据VRRP优先级来选举一个backup作为master,当master恢复时,backup又会释放在master故障时自身接管的IP资源和服务,恢复到原来的备用角色,这样就可以保证路由器的高可用。
2、KeepAlived安装
- 编译安装:
- 安装包下载:www.keepalived.org/download.ht… ;
- 创建文件夹并将下载的安装包上传到对应创建的文件下;
- 使用
./configure编译安装;
- 如遇报错提示信息:
configure: error:
!!! OpenSSL is not properly installed on your system. !!!
!!! Can not include OpenSSL headers files. !!!
通过安装相关依赖库即可:yum install openssl-devel;
- yum安装
执行yum安装命令即可完成KeepAlived安装:
yum install keepalived;
3、配置KeepAlived
Keepalived提供了两种模式
抢占式:master与backup节点上state配置不同,当master节点宕掉后由backup节点接手master节点的VIP与服务,在master节点恢复后重新由master节点来接手VIP与服务,backup节点继续回到备用状态。
非抢占式:master与backup节点上state配置都为backup,且在vrrp_instance块下两个节点都增加nopreempt,表示不争抢VIP。两个节点启动后默认都为backup状态,双方在发送组播信息后,会根据优先级来选举一个master出来,由于两者都配置了nopreempt,所以master从故障中恢复后不会抢占VIP,这样会避免VIP切换可能造成的服务延迟。
注:此处只以通过编辑的方式安装的KeepAlived方式进行配置
- 进入安装目录的
/soft/keepalived/etc/keepalived/并编辑配置文件:
cd /soft/keepalived/etc/keepalived/
vi keepalived.conf
- 编辑主机的
keepalived.conf核心配置文件,如下:
global_defs {
# 自带的邮件提醒服务,建议用独立的监控或第三方SMTP,也可选择配置邮件发送。
notification_email {
root@localhost
}
notification_email_from root@localhost
smtp_server localhost
smtp_connect_timeout 30
# 高可用集群主机身份标识(集群中主机身份标识名称不能重复,建议配置成本机IP)
router_id 192.168.12.132
}
# 定义虚拟路由,VI_1为虚拟路由的标示符(可自定义名称)
vrrp_instance VI_1 {
# 当前节点的身份标识:用来决定主从(MASTER为主机,BACKUP为从机)
state MASTER
# 绑定虚拟IP的网络接口,根据自己的机器的网卡配置
interface ens33
# 虚拟路由的ID号,这个标识是一个数字,同一个vrrp实例使用唯一的标识 主从两个节点设置必须一样
virtual_router_id 999
# 填写本机IP
mcast_src_ip 192.168.12.132
# 定义优先级;数字越大,优先级越高(0-255)
# 在同一个vrrp_instance下,“MASTER”的优先级必须大于“BACKUP”的优先级
priority 100
# 优先级高的设置nopreempt,解决异常恢复后再次抢占造成的脑裂问题
nopreempt
# 组播信息发送间隔,设定MASTER与BACKUP负载均衡器之间同步检查的时间间隔,两个节点设置必须一样,默认1s(类似于心跳检测)
advert_int 1
# 设置验证类型和密码
authentication {
# 设置验证类型,主要有PASS和AH两种
auth_type PASS
# 设置验证密码,在同一个vrrp_instance下,MASTER与BACKUP必须使用相同的密码才能正常通信
auth_pass 1111
}
# 有故障时是否激活邮件通知
#smtp_alert
# 禁止抢占服务
# 默认情况,当MASTER服务挂掉之后,BACKUP自动升级为MASTER并接替它的任务
# 当MASTER服务恢复后,升级为MASTER的BACKUP服务又自动降为BACKUP,把工作权交给原MASTER
# 当配置了nopreempt,MASTER从挂掉到恢复,不再将服务抢占过来。
#nopreempt
# 虚拟IP,两个节点设置必须一样。可以设置多个,一行写一个
virtual_ipaddress {
192.168.12.199
}
}
编辑从机的keepalived.conf文件,如下:
global_defs {
# 自带的邮件提醒服务,建议用独立的监控或第三方SMTP,也可选择配置邮件发送。
notification_email {
root@localhost
}
notification_email_from root@localhost
smtp_server localhost
smtp_connect_timeout 30
# 高可用集群主机身份标识(集群中主机身份标识名称不能重复,建议配置成本机IP)
router_id 192.168.12.133
}
# 定义虚拟路由,VI_1为虚拟路由的标示符(可自定义名称)
vrrp_instance VI_1 {
# 当前节点的身份标识:用来决定主从(MASTER为主机,BACKUP为从机)
state BACKUP
# 绑定虚拟IP的网络接口,根据自己的机器的网卡配置
interface ens33
# 虚拟路由的ID号,这个标识是一个数字,同一个vrrp实例使用唯一的标识 主从两个节点设置必须一样
virtual_router_id 999
# 填写本机IP
mcast_src_ip 192.168.12.133
# 定义优先级;数字越大,优先级越高(0-255)
# 在同一个vrrp_instance下,“MASTER”的优先级必须大于“BACKUP”的优先级
priority 50
# 优先级高的设置nopreempt,解决异常恢复后再次抢占造成的脑裂问题
nopreempt
# 组播信息发送间隔,设定MASTER与BACKUP负载均衡器之间同步检查的时间间隔,两个节点设置必须一样,默认1s(类似于心跳检测)
advert_int 1
# 设置验证类型和密码
authentication {
# 设置验证类型,主要有PASS和AH两种
auth_type PASS
# 设置验证密码,在同一个vrrp_instance下,MASTER与BACKUP必须使用相同的密码才能正常通信
auth_pass 1111
}
# 有故障时是否激活邮件通知
#smtp_alert
# 禁止抢占服务
# 默认情况,当MASTER服务挂掉之后,BACKUP自动升级为MASTER并接替它的任务
# 当MASTER服务恢复后,升级为MASTER的BACKUP服务又自动降为BACKUP,把工作权交给原MASTER
# 当配置了nopreempt,MASTER从挂掉到恢复,不再将服务抢占过来。
#nopreempt
# 虚拟IP,两个节点设置必须一样。可以设置多个,一行写一个
virtual_ipaddress {
192.168.12.199
}
}
4、启动KeepAlived
通过以下命令即可启动主机、从机的KeepAlived。然后主机、从机均会多一个虚拟ip。
systemctl start keepalived
systemctl enable keepalived
八、Nginx高级篇之扩容
1)、为什么需要Nginx扩容
对于单机的Nginx服务,可能不太满足当下互联网中台所要求的的代理服务要求。为了提高吞吐量,可以对nginx进行扩容处理。
nginx两种扩容方式:(1)单机垂直扩容;(2)水平扩展
2)、单机垂直扩容
增加硬件资源,提高性能,物理手段。主要方式有:
- 云服务资源增加
- 整机:IBM、浪潮、DELL、HP等
- CPU/主板:更新到主流
- 网卡:10G/40G网卡
- 磁盘:SAS(SCSI) HDD(机械)、HHD(混合)、SATA SSD、PCI-e SSD、 MVMe SSD
- SSD
- 多副本机制
- 系统盘/热点数据/数据库存储
- HDD
- 冷数据存储
3)、水平扩展
常用Nginx高级负载均衡:
- ip_hash
- hash $cookie_jsessionid;
- hash $request_uri;
- 使用lua逻辑定向分发
- Redis + SpringSession
1、 ip_hash
ip_hash技术能够将某个ip 的请求定向到同一台后端web机器中,这样一来这个ip 下的客户端和某个后端 web机器就能建立起稳固的session.(保持会话)。ip_hash机制能够让某一客户机在相当长的一段时间内只访问固定的后端的某台真实的web服务器,这样会话就会得以保持,在网站页面进行login的时候就不会在后面的web服务器之间跳来跳去了,也不会出现登录一次的网站又提醒重新登录的情况。了解了ip_hash,我们知道nginx是靠c语言来实现的,那么ip_hash是怎么实现的呢?只有从根上出发才能更好的了解ip_hash 。
ip_hash算法实现
for ( ;; ) {
for (i = 0; i < 3; i++) {
hash = (hash * 113 + iphp->addr[i]) % 6271; //iphp->addr[i]为ip的点分十进制法的第i段
}
p = hash % iphp->rrp.peers->number;
n = p / (8 * sizeof(uintptr_t));
m = (uintptr_t) 1 << p % (8 * sizeof(uintptr_t));
if (!(iphp->rrp.tried[n] & m)) {
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
"get ip hash peer, hash: %ui %04XA", p, m);
peer = &iphp->rrp.peers->peer[p];
/* ngx_lock_mutex(iphp->rrp.peers->mutex); */
if (!peer->down) {
if (peer->max_fails == 0 || peer->fails < peer->max_fails) {
break;
}
if (now - peer->accessed > peer->fail_timeout) {
peer->fails = 0;
break;
}
}
iphp->rrp.tried[n] |= m;
/* ngx_unlock_mutex(iphp->rrp.peers->mutex); */
pc->tries--;
}
if (++iphp->tries >= 20) {
return iphp->get_rr_peer(pc, &iphp->rrp);
}
}
hash核心计算代码:
p = hash % iphp->rrp.peers->number;
n = p / (8 * sizeof(uintptr_t));
m = (uintptr_t) 1 << p % (8 * sizeof(uintptr_t));
ip_hash实现案例
upstream httpds {
ip_hash;
server 192.168.10.132 ;
server 192.168.10.133 ;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://httpds;
# root html;
}
location ~*/(css|img|js) {
root /usr/local/nginx/html;
}
适用业务场景:适用于需要账号登录的系统,会话连接保持的业务。
2、hash $request_uri
hash request_uri是针对客户端访问的uri来做的绑定。客户端访问同一个uri的时候,会被分配到同一个服务器上去。这样提高了缓存的命中率。并且这个request_uri就是完整url中刨去最前面host剩下的部分,比如http://192.168.10.132/zyt/test1?fid=3 这个url,去掉192.168.10.132剩下的就是了,日志里会看到打印出来的request_uri其实是/zyt/test1?fid=3。如果只访问192.168.10.132,$request_uri 里也会有个/的。这种方式也是通过hash算法来实现的,基本实现都是一样的,每个uri进行hash计算得到一个数值,这个数值除以整个节点数量取余数。(取模算法)
如果一个节点挂了,那么整个全局都会乱掉。因为整个的节点数变了,因为除数变了。
hash $request_uri实现案例
upstream httpds {
hash $request_uri;
server 192.168.10.132 ;
server 192.168.10.132 ;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://httpds;
# root html;
}
location ~*/(css|img|js) {
root /usr/local/nginx/html;
}
}
适用于后端服务器为缓存服务器时比较有效。
(1)在不支持cookie的情况下
(2)资源不平均分区
3、使用sticky模块完成对Nginx的负载均衡
介绍说明
nginx.org/en/docs/htt…
tengine中有session_sticky模块我们通过第三方的方式安装在开源版本中
sticky是第三方模块,需要重新编译Nginx。
Sticky基于cookie的一种nginx的负载均衡解决方案,通过分发和识别cookie,来使同一个客户端的请求落在同一台服务器上,默认标识名为route。
1.客户端首次发起访问请求,nginx接收后,发现请求头没有cookie,则以轮询方式将请求分发给后端服务器。
2.后端服务器处理完请求,将响应数据返回给nginx。
3.此时nginx生成带route的cookie,返回给客户端。route的值与后端服务器对应,可能是明文,也可能是md5、sha1等Hash值。
4.客户端接收请求,并保存带route的cookie。
5.当客户端下一次发送请求时,会带上route,nginx根据接收到的cookie中的route值,转发给对应的后端服务器。
下载安装
项目官网:
bitbucket.org/nginx-goodi…
另外一个版本
github.com/bymaximus/n…
bitbucket.org/nginx-goodi…
上传解压
将Sticky上传到负载均衡器所在服务器并解压缩:
重新编译Nginx
添加依赖openssl-devel,进到源码目录重新编译
./configure --prefix=/usr/local/nginx --add-module=/root/nginx-goodies-nginx-sticky-module-ng-c78b7dd79d0d
如遇到以下错误:
打开
ngx_http_sticky_misc.c文件,在12行添加
#include <openssl/sha.h>
#include <openssl/md5.h>
添加完成之后重新编译。
通过
yum install openssl添加openssl库即可。
升级检测
通过命令make upgrade进行升级检查
备份并把编译好的Nginx程序替换到原来的目录里
把编译好的Nginx程序替换到原来的目录里
mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old
cp objs/nginx /usr/local/nginx/sbin/
重启nginx
sticky实战
upstream httpget {
sticky name=route expires=6h;
server 192.168.44.132;
server 192.168.44.133;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://httpds;
# root html;
}
location ~*/(css|img|js) {
root /usr/local/nginx/html;
}
}
温馨提示:Sticky基于cookie的一种nginx的负载均衡解决方案
九、Nginx高级篇之KeepAlive
1)、KeepAlive概述
Keepalive是Linux系统下的一个轻量级高可用解决方案。高可用(High Avaliability简称HA)就是主机的冗余和接管。
基本功能:心跳检测、资源接管、检测集群中的服务、在集群节点转移共享IP地址的所有者。
Keepalive主要是通过路由冗余来实现高可用功能,配置简单,只需要一个配置文件即可完成。
Keepalive起初是为LVS(Linux Virtual Server虚拟的服务器集群负载均衡系统)设计的,专门用来监控集群系统中各个服务节点的状态,它根据TCP/IP参考模型的第三、第四层、第五层交换机制检测每个服务节点的状态,如果某个服务器节点出现异常,或者工作出现故障,Keepalived将检测到,并将出现的故障的服务器节点从集群系统中剔除,这些工作全部是自动完成的,不需要人工干涉,需要人工完成的只是修复出现故障的服务节点。
官网介绍:
nginx.org/en/docs/htt…
2)、KeepAlive对客户端、上游服务器配置详述
proxy_pass 向上游服务器请求数据共有6个阶段:
- 初始化
- 与上游服务器建立连接
- 向上游服务器发送请求
- 处理响应头
- 处理响应体
- 结束
3)、客户端配置KeepAlive实例
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65 65; #超过这个时间 没有活动,会让keepalive失效
keepalive_time 1h; # 一个tcp连接总时长,超过之后 强制失效
send_timeout 60;# 默认60s 此处有坑!! 系统中 若有耗时操作,超过 send_timeout 强制断开连接。 注意:准备过程中,不是传输过程
keepalive_requests 1000; #一个tcp复用中 可以并发接收的请求个数
}
4)、服务端配置KeepAlive实例
server {
listen 80;
server_name localhost;
proxy_http_version 1.1;#配置http版本号
默认使用http1.0协议,需要在request中增加”Connection: keep-alive“ header才能够支持,而HTTP1.1默认支持。
proxy_set_header Connection "";#清楚close信息
location / {
proxy_pass http://httpds;
# root html;
}
location ~*/(css|img|js) {
root /usr/local/nginx/html;
}
}
5)、Nginx对客户端的缓冲区限制
可配置位置:http、server、location
1. client_body_buffer_size
对客户端请求中的body缓冲区大小,默认32位8k 64位16k,如果请求体大于配置,则写入临时文件
2、client_header_buffer_size
设置读取客户端请求体的缓冲区大小。 如果请求体大于缓冲区,则将整个请求体或仅将其部分写入临时文件。 默认32位8K。 64位平台16K。
3、client_max_body_size 1000M
默认1m,如果一个请求的大小超过配置的值,会返回413 (request Entity Too Large)错误给客户端,将size设置为0将禁用对客户端请求正文大小的检查。
4、client_body_timeout
指定客户端与服务端建立连接后发送 request body 的超时时间。如果客户端在指定时间内没有发送任何内容,Nginx 返回 HTTP 408(Request Timed Out)
5、client_header_timeout
客户端向服务端发送一个完整的 request header 的超时时间。如果客户端在指定时间内没有发送一个完整的 request header,Nginx 返回 HTTP 408(Request Timed Out)。
6、client_body_temp_path** *path* [*level1* [*level2* [*level3*]]]
在磁盘上客户端的body临时缓冲区位置
7、client_body_in_file_only on
把body写入磁盘文件,请求结束也不会删除
8、client_body_in_single_buffer
尽量缓冲body的时候在内存中使用连续单一缓冲区,在二次开发时使用$request_body读取数据时性能会有所提高
9、client_header_buffer_size
设置读取客户端请求头的缓冲区大小,如果一个请求行或者一个请求头字段不能放入这个缓冲区,那么就会使用large_client_header_buffers
10、large_client_header_buffers 默认8k
6)、实战
http{
proxy_connect_timeout 10;
proxy_read_timeout 120;
proxy_send_timeout 10;
proxy_buffering on;
client_body_buffer_size 512k;
proxy_buffers 4 64k;
proxy_buffer_size 16k;
proxy_busy_buffers_size 128k;
proxy_temp_file_write_size 128k;
proxy_temp_path /soft/nginx/temp_buffer;
}
十、Nginx高级篇之资源压缩
1)、Nginx资源压缩概述
资源压缩建立在动静分离的基础之上,如果一个静态资源的Size越小,那么自然传输速度会更快,同时也会更节省带宽,因此我们在部署项目时,也可以通过Nginx对于静态资源实现压缩传输,一方面可以节省带宽资源,第二方面也可以加快响应速度并提升系统整体吞吐。
2)、Nginx支持的资源压缩的模块
在Nginx也提供了三个支持资源压缩的模块ngx_http_gzip_module、ngx_http_gzip_static_module、ngx_http_gunzip_module,其中ngx_http_gzip_module属于内置模块,代表着可以直接使用该模块下的一些压缩指令,后续的资源压缩操作都基于该模块,先来看看压缩配置的一些参数/指令:
在上述的压缩配置中,最后一个gzip_proxied选项,可以根据系统的实际情况决定,总共存在多种选项:
- off:关闭Nginx对后台服务器的响应结果进行压缩。
- expired:如果响应头中包含Expires信息,则开启压缩。
- no-cache:如果响应头中包含Cache-Control:no-cache信息,则开启压缩。
- no-store:如果响应头中包含Cache-Control:no-store信息,则开启压缩。
- private:如果响应头中包含Cache-Control:private信息,则开启压缩。
- no_last_modified:如果响应头中不包含Last-Modified信息,则开启压缩。
- no_etag:如果响应头中不包含ETag信息,则开启压缩。
- auth:如果响应头中包含Authorization信息,则开启压缩。
- any:无条件对后端的响应结果开启压缩机制。
3)、资源压缩原理
对于要压缩的文件,首先使用LZ77算法的一个变种进行压缩,对得到的结果再使用哈夫曼编码(根据情况,使用静态哈弗曼编码或动态哈夫曼编码)的方法进行压缩。
Gzip是一种流行的文件压缩算法,现在的应用十分广泛,尤其是在Linux平台。当应用Gzip压缩到一个纯文本文件时,效果是非常明显的,大约可以减少70%以上的文件大小。这取决于文件中的内容。
LZ77的核心思路是如果一个串中有两个重复的串,那么只需要知道后面的串与前面串重复的长度和后面串起始字符与前面串起始字符相对于起始位置的距离。
哈夫曼编码是数据结构课程中一种常见的算法。哈夫曼编码使用变长编码表对源符号进行编码,变长编码表通过一种评估来源符号出现概率的方法得到,出现概率较高的字母使用较短的编码,反之出现概率低的使用较长的编码,这样使编码之后的字符串的平均长度、期望值降低,从而达到无损压缩数据的目的。
4)、案例实战
http{
# 开启压缩机制
gzip on;
# 指定会被压缩的文件类型(也可自己配置其他类型)
gzip_types text/plain application/javascript text/css application/xml text/javascript image/jpeg image/gif image/png;
# 设置压缩级别,越高资源消耗越大,但压缩效果越好
gzip_comp_level 5;
# 在头部中添加Vary: Accept-Encoding(建议开启)
gzip_vary on;
# 处理压缩请求的缓冲区数量和大小
gzip_buffers 16 8k;
# 对于不支持压缩功能的客户端请求不开启压缩机制
gzip_disable "MSIE [1-6]\."; # 低版本的IE浏览器不支持压缩
# 设置压缩响应所支持的HTTP最低版本
gzip_http_version 1.1;
# 设置触发压缩的最小阈值
gzip_min_length 2k;
# 关闭对后端服务器的响应结果进行压缩
gzip_proxied off;
}
引入一个js文件并配置文件压缩,示例结果:
温馨提示:
①对于图片、视频类型的数据,会默认开启压缩机制,因此一般无需再次开启压缩。
②对于.js文件而言,需要指定压缩类型为application/javascript,而并非text/javascript、application/x-javascript。
5)、第三方压缩工具Brotli
Brotli is a generic-purpose lossless compression algorithm that compresses data using a combination of a modern variant of the LZ77 algorithm, Huffman coding and 2nd order context modeling, with a compression ratio comparable to the best currently available general-purpose compression methods. It is similar in speed with deflate but offers more dense compression.ngx_brotli is a set of two nginx modules:
- ngx_ brotli滤波器模块-用于动态压缩响应
- ngx_brotli静态模块-用于提供预压缩文件
官网
https://github.com/google/ngx_brotlihttps://codeload.github.com/google/brotli/tar.gz/refs/tags/v1.0.9
下载安装
- 进入官网地址下载源码包
- 模块化编译
./configure --with-compat --add-dynamic-module=/root/ngx_brotli-1.0.0rc --prefix=/usr/local/nginx/
- make
- 将
ngx_http_brotli_filter_module.songx_http_brotli_static_module.so拷贝到/usr/local/nginx/modules/ - 复制nginx主程序
- 配置文件中添加
load_module "/usr/local/nginx/modules/ngx_http_brotli_filter_module.so";
load_module "/usr/local/nginx/modules/ngx_http_brotli_static_module.so";
第三方压缩工具实战
http{
# 开启压缩机制
gzip on;
# 指定会被压缩的文件类型(也可自己配置其他类型)
gzip_types text/plain application/javascript text/css application/xml text/javascript image/jpeg image/gif image/png;
# 设置压缩级别,越高资源消耗越大,但压缩效果越好
gzip_comp_level 5;
# 在头部中添加Vary: Accept-Encoding(建议开启)
gzip_vary on;
# 处理压缩请求的缓冲区数量和大小
gzip_buffers 16 8k;
# 对于不支持压缩功能的客户端请求不开启压缩机制
gzip_disable "MSIE [1-6]\."; # 低版本的IE浏览器不支持压缩
# 设置压缩响应所支持的HTTP最低版本
gzip_http_version 1.1;
# 设置触发压缩的最小阈值
gzip_min_length 2k;
# 关闭对后端服务器的响应结果进行压缩
gzip_proxied off;
#brotli与gzip可共存
brotli on;
brotli_static on;
brotli_comp_level 6;
brotli_buffers 16 8k;
brotli_min_length 20;
brotli_types text/plain text/css text/javascript application/javascript text/xml application/xml application/xml+rss application/json image/jpeg image/gif image/png;
}
测试
curl -H 'Accept-Encoding: gzip' -I http://localhost
6)、Nginx客户端资源压缩
- Nginx官方介绍 www.nginx.com/resources/w…
- git地址 github.com/alibaba/ngi…
- 安装 下载源码解压缩编译安装
location /{
concat on;
concat_max_files 30;
}
十一、Nginx高级篇之实现IP黑白名单
1)、什么是IP黑白名单
有时候往往有些需求,可能某些接口只能开放给对应的合作商,或者购买/接入API的合作伙伴,那么此时就需要实现类似于IP白名单的功能。而有时候有些恶意攻击者或爬虫程序,被识别后需要禁止其再次访问网站,因此也需要实现IP黑名单。那么这些功能无需交由后端实现,可直接在Nginx中处理。
2)、Nginx配置IP黑名单
Nginx做黑白名单机制,主要是通过allow、deny配置项来实现:
allow xxx.xxx.xxx.xxx; # 允许指定的IP访问,可以用于实现白名单。
deny xxx.xxx.xxx.xxx; # 禁止指定的IP访问,可以用于实现黑名单。
如果要同时屏蔽/开放多个IP访问时,如果所有IP全部写在nginx.conf文件中定然是不现实的,这种方式不仅冗余而且难以维护,那么可以新建两个文件BlocksIP.conf、WhiteIP.conf(配置文件信息位于Nginx配置文件目录下或者自己新建一个目录):
# --------黑名单:BlocksIP.conf---------
deny 192.168.10.100; # 屏蔽192.168.10.100访问
deny 192.168.10.101; # 屏蔽92.168.10.101访问
deny 192.0.0.0/8; # 屏蔽192.0.0.1到192.255.255.254网段中的所有IP访问
# --------白名单:WhiteIP.conf---------
allow 192.168.10.132; # 允许192.168.10.132访问
allow 192.168.10.133; # 允许192.168.10.133访问
allow 192.168.130.0/16; # 允许192.168.130.1到192.168.255.254网段中的所有IP访问
deny all; # 除开上述IP外,其他IP全部禁止访问
分别将要禁止/开放的IP添加到对应的文件后,可以再将这两个文件在nginx.conf中导入:
http{
# 屏蔽该文件中的所有IP
include /soft/nginx/IP/BlocksIP.conf;
server{
location xxx {
# 某一系列接口只开放给白名单中的IP
include /soft/nginx/IP/blockip.conf;
}
}
}
对于文件具体在哪儿导入,这个也并非随意的,如果要整站屏蔽/开放就在http中导入,如果只需要一个域名下屏蔽/开放就在sever中导入,如果只需要针对于某一系列接口屏蔽/开放IP,那么就在location中导入即可。
十二、Nginx高级篇之跨域配置
跨域问题在之前的单体架构开发中,其实是比较少见的问题,除非是需要接入第三方SDK时,才需要处理此问题。但随着现在前后端分离、分布式架构的流行,跨域问题也成为了每个Java开发必须要懂得解决的一个问题。
1)、为什么会产生跨域问题
产生跨域问题的主要原因就在于同源策略,为了保证用户信息安全,防止恶意网站窃取数据,同源策略是必须的,否则cookie可以共享。由于http无状态协议通常会借助cookie来实现有状态的信息记录,例如用户的身份/密码等,因此一旦cookie被共享,那么会导致用户的身份信息被盗取。
同源策略主要是指三点相同,协议+域名+端口 相同的两个请求,则可以被看做是同源的,但如果其中任意一点存在不同,则代表是两个不同源的请求,同源策略会限制了不同源之间的资源交互。
2)、跨域解决配置
在nginx.conf中添加以下配置即可:
http{
server{
listen 9999;
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;
}
}
}
}
十三、Nginx高级配置之配置SSL证书
1)、Nginx为什么需要配置SSL证书
随着越来越多的网站接入HTTPS,因此Nginx中仅配置HTTP还不够,往往还需要监听443端口的请求。HTTPS为了确保通信安全,所以服务端需配置对应的数字证书,当项目使用Nginx作为网关时,那么证书在Nginx中也需要配置。
2)、SSL证书配置过程:
- 先去CA机构或从云控制台中申请对应的SSL证书,审核通过后下载Nginx版本的证书。 下载数字证书后,完整的文件总共有三个:.crt、.key、.pem;
- crt:数字证书文件,.crt是.pem的拓展文件,因此有些人下载后可能没有。
- key:服务器的私钥文件,及非对称加密的私钥,用于解密公钥传输的数据。
- pem:Base64-encoded编码格式的源证书文本文件,可自行根需求修改拓展名。
- 在Nginx目录下新建certificate目录,并将下载好的证书/私钥等文件上传至该目录;
- 修改一下nginx.conf文件;
3)、配置文件配置SSL证书实践
# ----------HTTPS配置-----------
server {
# 监听HTTPS默认的443端口
listen 443;
# 配置自己项目的域名
server_name www.zyt.com;
# 打开SSL加密传输
ssl on;
# 输入域名后,首页文件所在的目录
root html;
# 配置首页的文件名
index index.html index.htm index.jsp index.ftl;
# 配置自己下载的数字证书
ssl_certificate certificate/xxx.pem;
# 配置自己下载的服务器私钥
ssl_certificate_key certificate/xxx.key;
# 停止通信时,加密会话的有效期,在该时间段内不需要重新交换密钥
ssl_session_timeout 5m;
# TLS握手时,服务器采用的密码套件
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
# 服务器支持的TLS版本
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# 开启由服务器决定采用的密码套件
ssl_prefer_server_ciphers on;
location / {
....
}
}
# ---------HTTP请求转HTTPS-------------
server {
# 监听HTTP默认的80端口
listen 80;
# 如果80端口出现访问该域名的请求
server_name www.zyt1.com;
# 将请求改写为HTTPS(这里写你配置了HTTPS的域名)
rewrite ^(.*)$ https://www.zyt.com;
}
至此,根据如上配置了Nginx后,你的网站即可通过https:// 的方式访问,并且当客户端使用http:// 的方式访问时,会自动将其改写为HTTPS请求。
十四、Nginx高级篇之大文件传输配置
在某些业务场景中需要传输一些大文件,但大文件传输时往往都会会出现一些Bug,比如文件超出限制、文件传输过程中请求超时等,那么此时就可以在Nginx稍微做一些配置,先来了解一些关于大文件传输时可能会用的配置项:
在传输大文件时,client_max_body_size、client_header_timeout、proxy_read_timeout、proxy_send_timeout这四个参数值都可以根据自己项目的实际情况来配置。
十五、Nginx终极篇之性能优化
优化一、打开长连接配置
upstream xxx {
# 长连接数
keepalive 32;
# 每个长连接提供的最大请求数
keepalived_requests 100;
# 每个长连接没有新的请求时,保持的最长时间
keepalive_timeout 60s;
}
优化二、开启零拷贝
sendfile on; # 开启零拷贝机制
优化三、开启无延迟或多包共发技术
TCP/IP协议中默认是采用了Nagle算法的,即在网络数据传输过程中,每个数据报文并不会立马发送出去,而是会等待一段时间,将后面的几个数据包一起组合成一个数据报文发送,但这个算法虽然提高了网络吞吐量,但是实时性却降低了在Nginx中有两个较为关键的性能参数,即tcp_nodelay、tcp_nopush,开启方式如下:
tcp_nodelay on;
tcp_nopush on;