Nginx
一、什么是Nginx?
Nginx是一款轻量级的Web服务器/反向代理服务器、邮件服务器(pop3/imap),是俄罗斯程序员开发的。
特点:占用资源少,并发能力强
Nginx官方网站:https://nginx.org
二、Apache跟Nginx对比
1.Nginx处理请求是异步非阻塞,运用了epoll模型,提供了一个队列,排队解决。Apache则是阻塞,在高并发下nginx能保持低资源、低消耗、高性能
2.rewrite重写,apache的重写模块很强大,基本能想到的点都包含了,很少有bug,nginx的bug相对较多。(出身好,其不高)
3.Nginx配置简洁,apache配置复杂
三、安装Nginx并启动
3.1、准备工作
准备工作
.关闭防火墙
[root@wb ~]# systemctl stop firewalld 关闭防火墙
[root@wb ~]# systemctl disable firewalld 开机不自启
.关闭selinux
[root@wb ~]# setenforce 0
setenforce: SELinux is disabled
[root@wb ~]# vim /etc/selinux/config
SELINUX=disabled
安装依赖
gcc pcre-devel zlib zlib-devel
[root@wb ~]# yum install gcc zlib zlib-devel pcre-devel -y
3.2、下载并安装Nginx
1.下载nginx
官方网站下载即可
[root@wb ~]# wget http://nginx.org/download/nginx-1.18.0.tar.gz
2.解压安装包
nginx安装包是.tar.gz 结尾的,所以使用tar命令进行解压
[root@wb opt]# tar xf nginx-1.18.0.tar.gz
安装三部曲
配置--->编译--->安装
3.configure配置
进入解压后的源码目录,进行配置,执行configure命令进行配置。
[root@wb opt]# cd nginx-1.18.0
[root@wb nginx-1.19.5]# ./configure --prefix=/opt/nginx (指定安装目录,默认是装在/usr/local/)
4.编译
[root@wb nginx-1.19.5]# make
5.安装
[root@wb nginx-1.19.5]# make install
6.启动nginx
[root@wb sbin]# pwd
/opt/nginx/sbin
[root@wb sbin]# ./nginx (可执行文件)
3.3、验证
(Nginx默认监听端口号80,出现以下情况说明启动成功)
[root@wb sbin]# lsof -i:80 查看端口
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 3276 root 6u IPv4 28428 0t0 TCP *:http (LISTEN)
nginx 3277 nobody 6u IPv4 28428 0t0 TCP *:http (LISTEN)
[root@wb sbin]# ss -lnp | grep nginx 查看端口
tcp LISTEN 0 128 *:80 *:* users:(("nginx",pid=3277,fd=6),("nginx",pid=3276,fd=6))
[root@wb sbin]# ps -ef | grep nginx 查看进程
root 3276 1 0 01:32 ? 00:00:00 nginx: master process ./nginx
nobody 3277 3276 0 01:32 ? 00:00:00 nginx: worker process
[root@wb sbin]# elinks http://192.168.0.129 --dump 文本浏览器查看
3.4、Nginx目录
安装好之后,会在/opt/下面生成nginx目录(编译前的配置已经指定好的)
[root@wb opt]# ll
drwxr-xr-x 11 root root 151 Nov 26 23:49 nginx 安装目录
drwxr-xr-x 9 1001 1001 186 Nov 26 23:37 nginx-1.19.5 源码文件
-rw-r--r-- 1 root root 1055590 Nov 24 23:15 nginx-1.19.5.tar.gz 源码压缩文件
1.Nginx安装目录
[root@wb nginx]# pwd
/opt/nginx
[root@wb nginx]# ll
drwxr-xr-x 2 root root 333 Nov 28 01:32 conf
drwxr-xr-x 4 root root 30 Nov 28 01:05 html
drwxr-xr-x 2 root root 81 Nov 28 01:32 logs
drwxr-xr-x 2 root root 19 Nov 26 23:43 sbin
conf:Nginx配置目录
---nginx.conf:Nginx主配文件
html:网页代码存放目录
logs:日志存放目录
---error 错误日志
---access 访问日志
sbin:Nginx可执行程序存放位置
服务三要素
1.监听地址 0.0.0.0 代表所有本地地址,127.0.0.1 回环地址
2.端口 http:80 sshd:22 mysql:3306 telent:23
3.协议 http https
3.5、Nginx命令
Nginx启动之后,可以调用-s参数的可执行文件来控制它
语法: nginx -s 信号
信号可以是:
nginx -s stop 快速关机
nginx -s reload 重新加载配置文件
nginx -s reopen 重新打开日志文件
nginx -s quit 优雅的关机(停止Nginx进程,等待工作进程完成当前的请求服务,再关机)
快速读取配置文件
前提,必须安装killall,必须保证配置文件无错误
killall -s HUP nginx
echo `ps aux | grep "nginx: master" | grep -v pts | awk '{print $2;}'` > /var/run/nginx.pid
nginx -t 检查主配文件语法是否正确
nginx -c xxxx.conf 指定检查配置文件语法是否正确
四、状态码
200 - 请求成功
301 - 资源被转移到其他url,代表重写
404 - 代表资源不存在
403 - 访问资源服务器拒绝
500 - 服务器内部错误
五、配置文件详解
#user nobody; 指定启动Nginx工作进程的用户
worker_processes 1; 工作进程的数量,进程数,建议设置为cpu一样的核数
#error_log logs/error.log; 错误日志及存放目录
#error_log logs/error.log notice; 日志级别
#error_log logs/error.log info;
#pid logs/nginx.pid; nginx启动之后pid存放位置
events {
#每个进程的连接数
worker_connections 1024;
}
http模块设置
http {
nginx支持类型
include mime.types;
default_type application/octet-stream;
访问日志 日志记录类型
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
$remote_addr与$http_x_forwarded_for 记录客户端ip地址
$remote_user 记录客户端用户名称
$time_local 记录访问时间与时区
$request 记录请求的url跟http协议
$status 记录请求状态;成功是200
$body_bytes_sent 记录发送给客户端文件主体内容大小
$http_referer 记录用户从哪个页面链接访问过来的
$http_user_agent 记录客户端浏览器的相关信息。
访问日志 日志存放目录/日志文件名 日志记录类型
#access_log logs/access.log main;
零拷贝
sendfile on;
#tcp_nopush on;
连接超时,时间 单位s
#keepalive_timeout 0;
keepalive_timeout 65;
开启gzip压缩
#gzip on;
虚拟主机
server {
监听端口
listen 80;
域名
server_name localhost;
字符集
#charset koi8-r;
定义访问日志
#access_log logs/host.access.log main;
默认请求
location / { location后面/的内容是在浏览器中uri输入的内容
root html; 定义虚拟主机默认网站的目录(网站代码)
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 {
root html;
}
六、访问控制
介绍:
在公网环境下,一个网站会有很多目录,我们需要对web目录做访问控制。
实验:
网页目录有abc三个,a需要做访问控制,只能是本机访问。
1.创建实验环境
创建网页目录
[root@10-255-20-182 html]# mkdir {a..c} -p
添加目录的索引页(首页)
[root@10-255-20-182 html]# echo aaaa >a/index.html
[root@10-255-20-182 html]# echo bbbb >b/index.html
[root@10-255-20-182 html]# echo cccc >c/index.html
2.修改Nginxd配置文件
allow代表允许,deny代表禁止
[root@10-255-20-182 sbin]# vim ../conf/nginx.conf
server {
......
location /a {
allow 127.0.0.1;
allow 117.51.154.71;
deny all;
}
}
3.验证
[root@10-255-20-182 sbin]# elinks http://127.0.0.1/a --dump
aaaa
[root@10-255-20-182 sbin]# elinks http://127.0.0.1/b --dump
bbbb
[root@10-255-20-182 sbin]# elinks http://127.0.0.1/c --dump
cccc
[root@10-255-20-182 sbin]# elinks http://117.51.154.71/c --dump
cccc
[root@10-255-20-182 sbin]# elinks http://117.51.154.71/a --dump
403 Forbidden
七、用户认证
介绍:
通过使用“http基本身份验证”协议验证用户名和密码来限制对资源的访问。
auth_basic模块
Syntax: auth_basic string | off;
Default:
auth_basic off;
Context: http, server, location, limit_except
指定保存用户密码的文件
Syntax: auth_basic_user_file file;
Default: —
Context: http, server, location, limit_except
例子:
location / {
auth_basic "closed site";
auth_basic_user_file conf/htpasswd;
}
实验:任何人任何IP都能访问b,但是需要用户名跟密码进行验证,才能看到详细内容
1.准备实验环境
安装htpasswd密码加密工具
[root@10-255-20-182 ~]# yum install httpd-tools -y
创建用户密码文件目录
[root@10-255-20-182 ~]# mkdir /opt/nginx/passwd/ -p
生成用户名跟密码
htpasswd [命令选项] 用户名密码文件 用户名
常用选项
-c 创建文件然后添加用户密码加密
-m 对已有的文件进行用户密码加密
[root@10-255-20-182 ~]# htpasswd -c /opt/nginx/passwd/htpasswd xwx
New password:
Re-type new password:
Adding password for user xwx
[root@10-255-20-182 ~]# htpasswd -m /opt/nginx/passwd/htpasswd xb
New password:
Re-type new password:
Adding password for user xb
[root@10-255-20-182 ~]# cat /opt/nginx/passwd/htpasswd
xwx:$apr1$4VQhbelh$5AFRToMz0aMYp6lUWE9a81
xb:$apr1$G8YSrNYW$D.bqKot1GMhVJSrvGbnSO1
2.修改Nginx配置文件
[root@10-255-20-182 ~]# vim /opt/nginx/conf/nginx.conf
server {
......
location /b {
auth_basic "test";
auth_basic_user_file /opt/nginx/passwd/htpasswd;
}
}
[root@10-255-20-182 ~]# /opt/nginx/sbin/nginx -t
nginx: the configuration file /opt/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /opt/nginx/conf/nginx.conf test is successful
[root@10-255-20-182 ~]# /opt/nginx/sbin/nginx -s stop
[root@10-255-20-182 ~]# /opt/nginx/sbin/nginx
3.验证
[root@10-255-20-182 ~]# elinks http://117.51.154.71/b --dump
401 Authorization Required
[root@10-255-20-182 ~]# elinks http://117.51.154.71/c --dump
cccc
八、日志管理
配置文件支持定义全局日志跟虚拟主机日志,log_format定义日志格式必须放在http块中。server块(虚拟主机直接调用日志格式就可以了)
实验:
需求
web1 记录客户端访问时间,ip,状态码,请求方式.
web2 记录客户端访问时间,ip,状态码,浏览器信息.
$remote_addr与$http_x_forwarded_for 记录客户端ip地址
$remote_user 记录客户端用户名称
$time_local 记录访问时间与时区
$request 记录请求的url跟http协议
$status 记录请求状态;成功是200
$body_bytes_sent 记录发送给客户端文件主体内容大小
$http_referer 记录用户从哪个页面链接访问过来的
$http_user_agent 记录客户端浏览器的相关信息
1.准备实验环境
[root@10-255-20-182 html]# mkdir c -p
[root@10-255-20-182 html]# echo ccccc >c/index.html
[root@10-255-20-182 html]# pwd
/opt/nginx/html
2.修改配置文件
定义全局日志格式
http {
......
log_format web1 '[$time_local] $remote_addr $status - "$request" ';
log_format web2 '[$time_local] $remote_addr $status $http_user_agent';
......
}
修改虚拟主机日志配置
http{
......
server {
access_log logs/web1.access.log web1;
}
server {
access_log logs/web1.access.log web2;
}
......
}
3.验证
[root@10-255-20-182 logs]# tailf web1.access.log
[28/Nov/2020:11:33:07 +0800] 58.222.16.90 304 - "GET /b/ HTTP/1.1"
[28/Nov/2020:11:33:07 +0800] 58.222.16.90 304 - "GET /b/ HTTP/1.1"
[28/Nov/2020:11:33:08 +0800] 58.222.16.90 304 - "GET /b/ HTTP/1.1"
[28/Nov/2020:11:33:08 +0800] 58.222.16.90 304 - "GET /b/ HTTP/1.1"
[28/Nov/2020:11:33:09 +0800] 58.222.16.90 304 - "GET /b/ HTTP/1.1"
[28/Nov/2020:11:33:13 +0800] 36.57.155.236 200 - "GET / HTTP/1.1"
[28/Nov/2020:11:33:13 +0800] 36.57.155.236 404 - "GET /favicon.ico HTTP/1.1"
[28/Nov/2020:11:33:14 +0800] 223.246.177.253 404 - "GET /favicon.ico HTTP/1.1"
[28/Nov/2020:11:33:16 +0800] 58.222.16.90 301 - "GET /c HTTP/1.1"
[28/Nov/2020:11:33:16 +0800] 58.222.16.90 200 - "GET /c/ HTTP/1.1"
[root@10-255-20-182 logs]# tailf web2.access.log
[28/Nov/2020:11:35:01 +0800] 36.57.155.236 301 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.67 Safari/537.36 Edg/87.0.664.47
[28/Nov/2020:11:35:01 +0800] 36.57.155.236 200 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.67 Safari/537.36 Edg/87.0.664.47
[28/Nov/2020:11:35:01 +0800] 36.57.155.236 404 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.67 Safari/537.36 Edg/87.0.664.47
[28/Nov/2020:11:35:12 +0800] 223.246.177.253 301 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36
[28/Nov/2020:11:35:12 +0800] 223.246.177.253 200 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36
[28/Nov/2020:11:35:12 +0800] 223.246.177.253 404 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36
九、防盗链
介绍:
我们有个业务服务器存储照片,用户访问是免费的,但是我们需要支付运营商带宽费,我很希望用户来访问我的网站,增长访问率,带来曝光率,增加搜索引擎的排名。这时候有个中国最大的盗链生产商百度横插一脚,用爬虫来获取我的图片,用户可以直接在百度搜到我的图片,这样一来用户就不会直接访问我的网站,但是我还要一直支付运营商的带宽费。这个时候我们就可以设置防盗链来减少爬虫爬到图片的几率。
nginx location语法
= 严格匹配。如果这个查询匹配,那么将停止搜索并立即处理此请求。
~ 为区分大小写匹配(可用正则表达式)
!~为区分大小写不匹配
~* 为不区分大小写匹配(可用正则表达式)
!~*为不区分大小写不匹配
^~ 如果把这个前缀用于一个常规字符串,那么告诉nginx 如果路径匹配那么不测试正则表达式。
原理:
基于请求头中的referer,来进行判断。referer里面存储的时候用户来源信息。
valid_referers
该指令"valid_referers"的语法:
valid_referers [none|blocked|server_names] ...
默认值:none
使用环境:server,location
该指令会根据Referer Header头的内容分配一个值为0或1给变量$invalid_referer。如果Referer Header头不符合valid_referers指令设置的有效Referer,变量$invalid_referer
将被设置为1.
该指令的参数可以为下面的内容:
none:表示无Referer值的情况。
blocked:表示Referer值被防火墙进行伪装。
server_names:表示一个或多个主机名称。
实验:
需求
1.不加防盗链模仿盗链。
2.Nginx配置防盗链,查看是不是可以阻止。
步骤:
1.把图片放入业务服务器,把盗链的html代码放入盗链服务器中,然后浏览器打开盗链html点击查看。
2.在1的基础上,再在业务服务器配置防盗链
https://img.ivsky.com/img/tupian/t/202103/10/sunyunzhu_wuxiushan_baoshenqun-005.jpg
[root@10-255-20-182 sbin]# vim ../conf/nginx.conf
server{
location ~* \.(jpg)$ {
valid_referers none blocked http://117.51.154.71;
if ($invalid_referer) {
return 403;
}
}
}
在盗链服务器:
selinux 与 firewalld 关闭
进入/var/www/html目录下
盗链html代码(仅供参考)
<html>
<head>
<title>dao lian test</title>
</head>
<body>
<font size="5">
<a href="http://117.51.154.71/0.jpg">daolian</a> 这里的IP是图片服务器的地址
<br></br>
</font>
</body>
</html>
十、虚拟主机
介绍:
一个web软件,默认只能发布一个网站,这样不符合国情,我们可以配置多个虚拟主机,基于ip/端口/域名,做出差异化。什么是虚拟主机呢,就是把一个物理服务器划分成多个虚拟服务器,每个虚拟主机都有独立的web页面目录,各个虚拟主机都是完全独立,在外面看来就是一台台单独的机器,其实就是虚拟化的逻辑主机。
优点:
共享一台真实主机的资源,减少服务器的管理,配置简单减少复杂性。
类别:三要素
1.基于IP的虚拟主机,很少使用,需要多个公网IP,成功高。
2.基于端口的虚拟主机,用户必须知道你的端口,才能访问,一般用于 成人网站/博彩网站,会有专门的消息推送
3.基于域名的虚拟主机,通过域名来区分,符合真正的企业去使用。
10.1、基于IP的虚拟主机
1.准备环境
创建网页读取的目录
[root@wb html]# mkdir web1 web2
创建目录下的索引页
[root@wb html]# echo web1 > web1/index.html
[root@wb html]# echo web2 > web2/index.html
启动网卡
[root@wb html]# ifconfig ens33:1 192.168.0.130/24 up
2.修改配置文件
server {
listen 192.168.0.129:80;
server_name localhost;
location /web1 {
root html;
index index.html index.htm;
}
}
server {
listen 192.168.0.130:80;
server_name localhost;
location /web2 {
root html;
index index.html index.htm;
}
}
3.启动并验证
[root@wb html]# ../sbin/nginx -t
nginx: the configuration file /opt/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /opt/nginx/conf/nginx.conf test is successful
[root@wb html]# ../sbin/nginx -s stop
[root@wb html]# ../sbin/nginx
[root@wb html]# elinks http://192.168.0.129/web1 --dump
web1
[root@wb html]# elinks http://192.168.0.130/web2 --dump
web2
10.2、基于端口的虚拟主机
1.编写配置文件
[root@wb html]# vim ../conf/nginx.conf
server {
listen 80;
server_name localhost;
location /web1 {
root html;
index index.html index.htm;
}
}
server {
listen 8080;
server_name localhost;
location /web2 {
root html;
index index.html index.htm;
}
}
2.启动并验证
[root@wb html]# ../sbin/nginx -t
nginx: the configuration file /opt/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /opt/nginx/conf/nginx.conf test is successful
[root@wb html]# ../sbin/nginx -s stop
[root@wb html]# ../sbin/nginx
[root@wb html]# elinks http://192.168.0.129/web1 --dump
web1
[root@wb html]# elinks http://192.168.0.129:8080/web2 --dump
web2
10.3、基于域名的虚拟主机
1.修改配置文件
[root@wb html]# vim ../conf/nginx.conf
server {
listen 80;
server_name www.abc.com;
location /web1 {
root html;
index index.html index.htm;
}
}
server {
listen 8080;
server_name www.aaa.com;
location /web2 {
root html;
index index.html index.htm;
}
}
2.环境准备,写入到/etc/hosts文件中
3.启动并验证
[root@wb html]# elinks http://www.abc.com(url)/web1(uri) --dump
web1
[root@wb html]# elinks http://www.aaa.com/web2 --dump
web2
十一、正向代理和反向代理
11.1、正向代理
介绍:
我是一个用户,我访问google,访问不了,但是我能访问一个代理服务器,这个代理服务器呢,它可以访问我不能访问的google,与是我先连上代理服务器,告诉代理服务器我需要访问google网站,代理服务器去取,然后返回给我,我们经常使用的vpn就是正向代理。
特别注意:
客户端必须设置正向代理服务器,前提要知道正向代理服务器的IP地址跟代理程序的端口。
11.2、反向代理
介绍:
是指以代理服务器来接受网络上的请求,然后将请求转发给内部网络上的服务器,并将代理服务器上得到的结果返回给网络上请求连接的客户端,此时代理服务器对外表现就是一个反向代理服务器
特别注意:
反向代理隐藏了真实的服务端,背后可能有成千上万服务器为我们服务,具体哪一台,用户不知道,也不需要知道。
代理服务器·的·相关优化:
server{
location / {
Client_max_body_size 10M;
Client_body_buffer_size 128k;
proxy_connect_timeout 90
proxy_set_header X-Real-IP $remote_addr; 客户端原始ip
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 客户端请求头信息
}
}
实验:
需求
业务服务器的端口为8080,用户访问需要知道端口号,很不方便,我们用反向代理设置,直接输入反向代理的ip就能显示业务服务器的内容。
在反向代理服务器中的nginx配置
[root@wb sbin]# vim ../conf/nginx.conf
server{
location / {
proxy_pass http://117.51.154.71:8080;
proxy_set_header X-Real-IP $remote_addr; 客户端原始ip
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 客户端请求头信息
}
}
在业务服务器中
http{
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 logs/access.log main;
}
重启并验证
[root@wb sbin]# ./nginx -t
nginx: the configuration file /opt/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /opt/nginx/conf/nginx.conf test is successful
[root@wb sbin]# ./nginx -s stop
[root@wb sbin]# ./nginx
[root@wb sbin]# elinks http://192.168.0.129 --dump
Welcome to didi!
查看日志
业务服务器的日志:
[root@localhost logs]# tailf access.log
192.168.136.131 (代理服务器ip)- - [04/Jan/2021:20:13:11 +0800] "GET / HTTP/1.0" 200 5 "-" "ELinks/0.12pre6 (textmode; Linux; -)" "192.168.136.131"(客户端发出请求的ip)
192.168.136.131 - - [04/Jan/2021:20:13:46 +0800] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0" "192.168.136.1"
192.168.136.131 - - [04/Jan/2021:20:15:36 +0800] "GET / HTTP/1.0" 200 5 "-" "ELinks/0.12pre6 (textmode; Linux; -)" "192.168.136.131"
192.168.136.131 - - [04/Jan/2021:20:17:36 +0800] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0" "192.168.136.1"
192.168.136.131 - - [04/Jan/2021:20:18:02 +0800] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0" "192.168.136.1"
代理服务器的日志
[root@localhost logs]# tailf access.log
192.168.136.131 (客户端ip)- - [04/Jan/2021:20:15:36 +0800] "GET / HTTP/1.1" 200 5 "-" "ELinks/0.12pre6 (textmode; Linux; -)"
192.168.136.1 - - [04/Jan/2021:20:17:37 +0800] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0"
192.168.136.1 - - [04/Jan/2021:20:18:02 +0800] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0"
十二、限速
介绍:
为什么要限速?
服务器面对海量刷新,服务器会扛不住,所以可以限速控制,达到一定的请求数之后就不进行处理。
为了安全方面去考虑,可以防止黑客恶意攻击,大量读写会对磁盘IO有影响。
原理:
漏桶原理:
水(请求)从上方倒入桶内,从水桶下面流出来(被处理),来不及流的水存在桶里面(缓冲),以固定的速度流出来,水桶满了就溢出来(丢弃)。核心算法 缓存请求,匀速处理,多余请求直接丢弃。
12.1、Nginx限速模块
Nginx官方版本限制IP的连接和并发分别有两个模块:
limit_req_zone 用来限制单位时间内的请求数。
Syntax: limit_req zone=name [burst=number] [nodelay];
Default: —
Context: http, server, location
limit_req_conn 用来限制同一时间连接数,即并发限制。
Syntax: limit_conn_zone key zone=name:size;
Default: —
Context: http
12.2、基于IP对请求数做限制
修改配置文件
[root@wb conf]# vim nginx.conf
http {
......
limit_req_zone $binary_remote_addr zone=xwx:10m rate=1r/s
server {
......
location / {
limit_req zone=xwx burst=5 nodelay;
......
}
}
}
limit_req_zone $binary_remote_addr zone=xwx:10m rate=1r/s
$binary_remote_addr 表示通过remote_addr标识来做限制,binary内存占用总量
zone=xwx:10m 表示生成一个10M的缓冲区,名字为xwx
rate=1r/s 访问频率 ,这里是一秒一次
limit_req zone=xwx burst=5 nodelay;
zone=xwx 配置缓冲区,应该与上面limit_req_zone name 一致
burst=5 访问频次
nodelay 如果设置,超过上面的访问凭此就直接返回503
启动
[root@wb conf]# ../sbin/nginx -t
nginx: the configuration file /opt/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /opt/nginx/conf/nginx.conf test is successful
[root@wb conf]# ../sbin/nginx -s stop
[root@wb conf]# ../sbin/nginx
验证
[root@wb sbin]# elinks http://192.168.0.129 --dump
test
[root@wb sbin]# elinks http://192.168.0.129 --dump
test
[root@wb sbin]# elinks http://192.168.0.129 --dump
test
[root@wb sbin]# elinks http://192.168.0.129 --dump
test
[root@wb sbin]# elinks http://192.168.0.129 --dump
503
12.3、基于IP对下载做限制
修改配置文件
[root@wb sbin]# vim ../conf/nginx.conf
http{
.....
limit_conn_zone $binary_remote_addr zone=down:10m;
server {
location / {
limit_conn down 1;
limit_rate 10k;
}
}
}
limit_conn_zone $binary_remote_addr zone=down:10m;
$binary_remote_addr 表示通过remote_addr标识来做限制,binary内存占用总量
zone=down:10m 表示生成一个10M的缓冲区,名字为down
limit_conn down 1; 同一时间能下载几个
limit_rate 10k; 下载速率
启动
[root@wb conf]# ../sbin/nginx -t
nginx: the configuration file /opt/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /opt/nginx/conf/nginx.conf test is successful
[root@wb conf]# ../sbin/nginx -s stop
[root@wb conf]# ../sbin/nginx
准备环境
[root@wb html]# dd if=/dev/zero of=bigfile bs=2M count=150
[root@wb html]# ll -h
-rw-r--r-- 1 root root 300M Nov 30 21:52 bigfile
测试浏览器测试
十三、URL重写
介绍:
所有的web服务软件都有这个URL重写的功能,尤其是网站架构发生改变,新老域名交替。
比方国内的京东 www.360buy.com ---> www.jd.com
nginx的rewrite模块是基于pcre库实现的,可以提高网站安全性,uri跳转。
原理:
用户浏览器发出请求,nginx接受到请求之后把新的url告诉用户浏览器,然后用户浏览器访问新的url。
rewrite是实现url重写的关键指令,根据正则表达式匹配到的内容,重定向到新的,结尾flag标记
rewrite语法格式:
rewrite <正则> <替换内容> flag标记
rewrite为关键字不能改变
正则匹配到要替换谁
调换成谁
rewrite支持的flag标记
flag标记
permanent 永久重定向
redirect 临时重定向
last 从头到尾重新再匹配一次
break 匹配完这条就不再往下匹配
set 定义变量,if 判断,return 返回指定值给用户,break 跳出终止
13.1、nginx特殊符号
~ 匹配
!~ 不匹配
~* 匹配不区分大小写
= 精确匹配
^ 从什么地方开始
$ 从什么地方结束
. 代表全部字符
* 代表一个或多个
13.2、set定义变量
例:访问117.51.154.71 就重写到 www.youku.com/1111
编写配置文件
[root@10-255-20-182 conf]# vim nginx.conf
server {
location / {
set $test 1111;
rewrite ^(.*)$ http://youku.com/$test;
}
}
启动并测试
[root@10-255-20-182 conf]# ../sbin/nginx -t
nginx: the configuration file /opt/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /opt/nginx/conf/nginx.conf test is successful
[root@10-255-20-182 conf]# ../sbin/nginx -s stop
[root@10-255-20-182 conf]# ../sbin/nginx
[root@10-255-20-182 conf]# elinks http://117.51.154.71 --dump
错误码:
1. https://youku.com/
2. https://t.youku.com/yep/page/pc/youkukefu?isNeedBaseImage=1
13.3、if判断、return返回指定值
例:用户浏览器如果是elinks 就返回404
if
编写配置文件
[root@10-255-20-182 conf]# vim nginx.conf
server{
location / {
if ($http_user_agent ~* 'elinks'){
return 404;
}
}
}
启动并验证
[root@10-255-20-182 conf]# ../sbin/nginx -t
nginx: the configuration file /opt/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /opt/nginx/conf/nginx.conf test is successful
[root@10-255-20-182 conf]# ../sbin/nginx -s stop
[root@10-255-20-182 conf]# ../sbin/nginx
[root@10-255-20-182 conf]# elinks http://117.51.154.71 --dump
404 Not Found
13.4、break终止后续指令
例:用户浏览器如果是elinks 就返回404,终止这个指令
break
编写配置文件
[root@10-255-20-182 conf]# vim nginx.conf
server{
location / {
if ($http_user_agent ~* 'elinks'){
break;
return 404;
}
}
}
启动并验证
[root@10-255-20-182 conf]# ../sbin/nginx -t
nginx: the configuration file /opt/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /opt/nginx/conf/nginx.conf test is successful
[root@10-255-20-182 conf]# ../sbin/nginx -s stop
[root@10-255-20-182 conf]# ../sbin/nginx
[root@10-255-20-182 conf]# elinks http://117.51.154.71 --dump
web2 is a html
13.5、last标记
例:如果是elinks浏览器,就将http://117.51.154.71/$uri 重写为 http://117.51.154.71/elinks/$uri
创建实验环境
[root@10-255-20-182 html]# mkdir elinks
[root@10-255-20-182 html]# cd elinks/
[root@10-255-20-182 elinks]# mkdir {a..c}
[root@10-255-20-182 elinks]# echo aaaa > a/index.html
[root@10-255-20-182 elinks]# echo bbbb > b/index.html
[root@10-255-20-182 elinks]# echo cccc > c/index.html
[root@10-255-20-182 elinks]# tree
.
├── a
│ └── index.html
├── b
│ └── index.html
└── c
└── index.html
编写配置文件
[root@10-255-20-182 conf]# vim nginx.conf
server {
location / {
if ($http_user_agent ~* 'elinks'){
rewrite ^(.*)$ /elinks/$1 last;
}
}
location /elinks {
root html;
index index.html index.htm;
}
}
启动并验证
[root@10-255-20-182 conf]# ../sbin/nginx -t
nginx: the configuration file /opt/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /opt/nginx/conf/nginx.conf test is successful
[root@10-255-20-182 conf]# ../sbin/nginx -s stop
[root@10-255-20-182 conf]# ../sbin/nginx
[root@10-255-20-182 conf]# elinks http://117.51.154.71/a --dump
aaaa
[root@10-255-20-182 conf]# elinks http://117.51.154.71/b --dump
bbbb
[root@10-255-20-182 conf]# elinks http://117.51.154.71/c --dump
cccc
[root@10-255-20-182 conf]# elinks http://117.51.154.71/d --dump
404 Not Found
关于$1的解释:
rewrite ^/images/(.*)_(\d+)x(\d+)\.(png|jpg|gif)$ /resizer/$1.$4?width=$2&height=$3? last;
对形如/images/bla_500x400.jpg的文件请求,重写到/resizer/bla.jpg?width=500&height=400地址,并会继续尝试匹配location。
十四、Nginx优化
14.1、为什么需要优化?
Nginx的所有参数都是基于最小硬件来配置的,跟我们真正的企业环境硬件不一致,需要我们认为改动参数配置,让资源利用更优,让用户体验更优。
14.2、大并发优化
nginx的工作模式是一个主进程加若干个工作进程。工作进程设置需要参考服务器的CPU核数,根据核数去优化该项配置
worker_processes 定义工作进程的数量。
worker_connections 定义每个工作进程可连接数。这个并发数要根据实际生产环境去决定。
[root@10-255-20-182 conf]# netstat -antpl|grep nginx | grep ESTABLISHED |wc -l 查看连接数
14.3、长连接优化
web服务器就是基于tcp协议,每次连接都必须三次握手,完事又要四次挥手。服务器会一直维护这种连接状态,消耗系统资源,理想状态是用户全部请求完成才断开。基于这种情况我们可以设置长连接,用户请求过来,下载完第一个 不断开,等待浏览器再次发出请求。弊端要设置一定时间,避免有人恶意开很多长连接消耗系统资源。默认为65秒,时间过久,建议改为5秒。
keepalive_timout 5
keepalive_requests 8192
设置在一个长连接上可以服务的最大请求数目。当达到最大请求数目并结束服务后,连接被关闭。
14.4、数据压缩优化
服务器响应数据给用户,数据越大响应时间越慢。需要对大文件进行压缩。
好处:
用户可以更快拿到数据,可以节省网络带宽,生产环境中必须开启此项
gzip on 开启压缩
gzip_proxied any 全部压缩
gzip_min_length 1k 小于等于1k的文件不压缩
gzip_comp_level 6 gzip压缩级别 1-9,级别越高压缩率越大,压缩时间越长,消耗CPU也越大
gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png; 需要压缩的类型
15.5、音视频文件客户端缓存
音视频文件无法压缩,建议直接把这些文件缓存到用户本地
expires 1h
location ~* \.(png|gif|jpg)$ {
expires 1h;
}
十五、负载均衡
15.1、何为高并发、负载均衡?
高并发:高(大量的),并发就是可以使用多个线程或者多个进程,同时处理(就是并发)不同的操作,就是每秒内有多少请求同时访问
负载均衡:将请求均匀的分摊到多个操作服务器上执行,负载均衡的关键在于 均匀,也是分布式系统架构设计中必须要考虑的因素之一
15.2、单点故障
传统的网站就是一台服务器,会接受来自五湖四海的请求,服务器会一直处于请求处理响应的状态,时间一长容易出现单点故障,单台服务器资源有限。解决单点故障的方法 添加备机器,但是考虑到主服务器已经被请求打挂了,备服务器也支撑不了多长时间。这个时候可以用到一个叫DNS轮询机制。来实现压力分摊,但是DNS是第三方的,无法判断业务服务器的好坏。这时候有个方式可以解决此类问题,就是集群的概念。
例:
一共10台服务器,放两台到最前面做分发器,负责接收请求,并且分发给后端业务服务器进行处理,处理完成分发服务器再响应给用户。还有八台放到最后面做业务服务器,负责处理请求,并返回给分发器,后端业务服务器然后没有响应分发器将被自动剔除。真实企业环境中,分发器只有一台再工作,另外一台做备份。
集群三要素
VIP vrrp协议分发器通讯
分发器 nginx去实现
业务服务器 nginx去实现
15.3、集群
介绍:
集群其实就是虚拟主机加反向代理加nginx分发模块
分发模块 ngx_http_upstream_module 基于七层分发,又称为应用层分发。
集群三要素:
1、vip(虚拟地址) vrrp
2、分发器
3、业务服务器
15.4、负载均衡配置
15.4.1、轮询分发
http{
upstream web{
server 192.168.0.120;
server 192.168.0.121;
server 192.168.0.122;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://web;
}
}
}
按照时间请求先后顺序,分配给后端业务服务器,所有请求都被代理到服务器组web
15.4.2、权重分发
http{
upstream web{
server 192.168.0.120 weight=3;
server 192.168.0.121 weight=2;
server 192.168.0.122;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://web;
}
}
}
谁的权重越大,分发的请求越多。
15.4.3、IP-hash分发
http{
upstream web{
ip_hash;
server 192.168.0.120;
server 192.168.0.121;
server 192.168.0.122;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://web;
}
}
}
能保证一个用户的请求全部给到一个业务服务器,保持session一致性
15.5、nginx业务服务器状态
down 表示后端业务服务器不参与处理请求
backup 表示后端业务服务器请求忙的时候处理,不忙的时候不参与
weight 代表权重,权重越大,处理请求越高
upstream web{
server 192.168.0.120 down;
server 192.168.0.121;
upstream web{
server 192.168.0.120 backup;
server 192.168.0.121;
15.6、负载均衡实例
15.6.1、基于域名分发
http{
upstream web1{
server 192.168.0.120;
server 192.168.0.121;
}
upstream web2{
server 192.168.0.122;
server 192.168.0.123;
}
server {
listen 80;
server_name www.abc.com;
location / {
proxy_pass http://web1;
}
}
server {
listen 80;
server_name www.def.com;
location / {
proxy_pass http://web2;
}
}
}
15.6.2、基于开发语言分发
http{
upstream html{
server 192.168.0.120;
server 192.168.0.121;
}
upstream php{
server 192.168.0.122;
server 192.168.0.123;
}
server {
listen 80;
server_name www.abc.com;
location ~*\.php${
proxy_pass http://php;
}
location ~*\.html${
proxy_pass http://html;
}
}
}
!!!要准备测试环境
1.把php组的业务服务器nginx停止,安装httpd,php。
yum install -y httpd php
2.启动httpd
systemctl start httpd
3.写索引页
echo "<?php phpinfo();?>" > /var/www/html/index.php
15.6.3、基于浏览器分发
http{
upstream elinks{
server 192.168.0.120;
server 192.168.0.121;
}
upstream chrome{
server 192.168.0.122;
server 192.168.0.123;
}
server {
listen 80;
server_name www.abc.com;
location /{
if ($http_user_agent ~* elinks){
proxy_pass http://elinks;
}
if ($http_user_agent ~* chrome){
proxy_pass http://chrome;
}
}
}
}
十六、高可用集群
16.1、分发器单点故障
后端的业务服务器如果故障,前端分发器会自动剔除,前端的分发器故障怎么办?
需要一个软件进行管理分发器,一台挂了,备份立马顶上去,两台机器用vrrp协议通信。
keepalived 字面意思 保持活着,keepalived检测到故障自动剔除,备份机器顶上去,恢复再回来。
16.2、keepalived简要介绍
Keepalived 是一种高性能的服务器高可用或热备解决方案, Keepalived 可以用来防止服务器单点故障的发生,通过配合 Nginx 可以实现 web 前端服务的高可用。
Keepalived 以 VRRP 协议为实现基础,用 VRRP 协议来实现高可用性(HA)。 VRRP(Virtual RouterRedundancy Protocol)协议是用于实现路由器冗余的协议, VRRP 协议将两台或多台路由器设备虚拟成一个设备,对外提供虚拟路由器 IP(一个或多个),而在路由器组内部,如果实际拥有这个对外 IP 的路由器如果工作正常的话就是 MASTER,或者是通过算法选举产生, MASTER 实现针对虚拟路由器 IP 的各种网络功能,如 ARP 请求, ICMP,以及数据的转发等;其他设备不拥有该虚拟 IP,状态是 BACKUP,除了接收 MASTER 的VRRP 状态通告信息外,不执行对外的网络功能。当主机失效时, BACKUP 将接管原先 MASTER 的网络功能。VRRP 协议使用多播数据来传输 VRRP 数据, VRRP 数据使用特殊的虚拟源 MAC 地址发送数据而不是自身网卡的 MAC 地址, VRRP 运行时只有 MASTER 路由器定时发送 VRRP 通告信息,表示 MASTER 工作正常以及虚拟路由器 IP(组), BACKUP 只接收 VRRP 数据,不发送数据,如果一定时间内没有接收到 MASTER 的通告信息,各 BACKUP 将宣告自己成为 MASTER,发送通告信息,重新进行 MASTER 选举状态。
------来源百度
16.3、安装并配置主备节点
[root@10-255-20-182 ~]# yum install keepalived -y
MASTER节点配置文件
# vim /etc/keepalived/keepalived.conf
global_defs {
## keepalived
router_id wb ## 标识本节点的字条串
}
## keepalived 会定时执行脚本并对脚本执行的结果进行分析,动态调整 vrrp_instance 的优先级。如果脚本执行结果为 0,并且 weight 配置的值大于 0,则优先级相应的增加。如果脚本执行结果非 0,并且 weight配置的值小于 0,则优先级相应的减少。其他情况,维持原本配置的优先级,即配置文件中 priority 对应的值。
vrrp_script chk_nginx {
script "/etc/keepalived/nginx_check.sh" ## 检测 nginx 状态的脚本路径
interval 2 ## 检测时间间隔
}
## 定义虚拟路由, VI_1 为虚拟路由的标示符,自己定义名称
vrrp_instance VI_1 {
state MASTER ## 主节点为 MASTER, 对应的备份节点为 BACKUP
interface eth0 ## 绑定虚拟 IP 的网络接口,与本机 IP 地址所在的网络接口相同, 我的是 eth0
virtual_router_id 33 ## 虚拟路由的 ID 号, 两个节点设置必须一样, 可选 IP 最后一段使用, 相同的 VRID 为一个组,他将决定多播的 MAC 地址
mcast_src_ip 192.168.0.133 ## 本机 IP 地址
priority 100 ## 节点优先级, 值范围 0-254, MASTER 要比 BACKUP 高
nopreempt ## 优先级高的设置 nopreempt 解决异常恢复后再次抢占的问题
advert_int 1 ## 组播信息发送间隔,两个节点设置必须一样, 默认 1s
## 设置验证信息,两个节点必须一致
authentication {
auth_type PASS
auth_pass 1111 ## 真实生产,按需求对应该过来
}
## 将 track_script 块加入 instance 配置块
track_script {
chk_nginx ## 执行 Nginx 监控的服务
} #
# 虚拟 IP 池, 两个节点设置必须一样
virtual_ipaddress {
192.168.0.188 ## 虚拟 ip,可以定义多个
}
}
BACKUP配置文件
# vim /etc/keepalived/keepalived.conf
global_defs {
router_id liuyazhuang134
}
vrrp_script chk_nginx {
script "/etc/keepalived/nginx_check.sh"
interval 2
weight -20
}
vrrp_instance VI_1 {
state BACKUP
interface eth1
virtual_router_id 33
mcast_src_ip 192.168.0.134
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
track_script {
chk_nginx
}
virtual_ipaddress {
192.168.0.188
}
}
16.4、Nginx状态检测脚本
[root@www ~]# vim nginx_pid.sh
#/bin/bash
nginx=`ss -antup | grep nginx | wc -l`
if [ $nginx -ne 1 ];then
/opt/nginx/sbin/nginx
sleep 2
if [ `ss -antup | grep nginx | wc -l` -ne 1 ];then
systemctl stop keepali
fi
[root@www ~]# chmod +x nginx_pid.sh
!!! 一定要测试
启动keepalived
[root@www ~]# systemctl start keepalived
16.5、高可用测试
1.浏览器输入keepalived 虚拟ip 进行访问
2.杀死主keepalived进程,查看虚拟ip是否飘逸到备
[root@www ~]# systemcatl stop keepalived
3.在备keepalived 服务器 查看ip
[root@www ~]# ip a