写在之前
高可用:高可用(High availability,缩写为 HA),是指系统无中断地执行其功能的能力,代表系统的可用性程度。
一、nginx简介
Nginx 是一个很强大的高性能Web和反向代理服务,它具有很多非常优越的特性;
Nginx作为负载均衡服务:Nginx 既可以在内部直接支持 Rails 和 PHP 程序对外进行服务,也可以支持作为 HTTP代理服务对外进行服务。
支持 SSL 和 TLSSNI。
Nginx 是一个安装非常的简单、配置文件非常简洁(还能够支持perl语法)、Bug非常少的服务。Nginx 启动特别容易,并且几乎可以做到7*24不间断运行,即使运行数个月也不需要重新启动。你还能够不间断服务的情况下进行软件版本的升级。
二、nginx的安装
首先进行解压
tar zxf nginx-1.21.1.tar.gz
安装依赖性
yum install -y gcc pcre-devel openssl-devel
对源码进行编译,在这一部分,我们可以根据自己的需求进行编译
./configure --with-http_ssl_module --with-http_stub_status_module --prefix=/usr/local/nginx
然后我们进行make、make install 进行安装
源码编译三部曲:进行完解压之后,condigure;make;make install
这些进行完之后,我们的nginx已经安装成功,nginx的开启非常简单,直接nginx命令就可以开启,开启之后,我们可以通过查看80端口来检查是否开启,也可以ps进行查看进程
[root@server1 conf]# netstat -antlp | grep :80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 10134/nginx: master
10134 ? Ss 0:00 nginx: master process nginx
10170 ? R 0:00 [kworker/1:1]
10177 ? S 0:00 nginx: worker process
10178 ? S 0:00 nginx: worker process
以上两种方式都可以看到nginx已经开启
我们可以对其做一个软连接,方便我们使用
ln -s /usr/local/nginx/sbin/nginx /usr/local/bin/
三、利用nginx实现负载均衡
打开nginx的配置文件,添加用户、用户组
首先添加nginx用户
useradd -M -d /usr/local/nginx/ -s /sbin/nologin nginx
user nginx nginx;
worker_processes 2;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
我们可以将cpu与进程进行捆绑,也就是一个cpu对应一个进程,01 10 代表一个cpu开启时另一个关闭,以此类推,多个cpu也可以用这种方式来进行捆绑
user nginx nginx;
worker_processes 2;
worker_cpu_affinity 01 10;
我们在nginx.conf中添加负载均衡,可以给某台真实主机添加权重,比如给10主机配置权重为2,那么在需求分配的时候,10主机就会是3主机二倍的响应
http {
upstream westos {
server 192.168.110.10:8000 weight=2;
server 192.168.110.3:80;
}
include mime.types;
default_type application/octet-stream;
我们再给我们想要设置负载均衡的网站代理到我们设置的负载均衡上,这个时候我们再次访问这个网址,就会被认为访问代理的负载均衡器而按照权重分配给真实主机(首先要添加解析)
server {
listen 80;
server_name www.westos.org;
location / {
proxy_pass http://westos;
}
}
效果如下,1.1的响应是1.3的两倍,说明我们利用nginx实现了负载均衡
[root@server5 ~]# for i in {1..10}; do curl www.westos.org;done
server1.3
server1.1
server1.1
server1.3
server1.3
server1.1
server1.1
server1.3
server1.1
server1.1
如果我们此时停掉真实主机中的一台,再次测试会发现调度器自动将所有的需求分配给正常运行的真实主机,在这一点上nginx要更加合理
[root@server1 ~]# curl 192.168.110.3
server1.3
[root@server5 ~]# for i in {1..10}; do curl www.westos.org;done
server1.3
server1.3
server1.3
server1.3
server1.3
server1.3
server1.3
server1.3
server1.3
server1.3
那如果所有的真实主机都down了,再次测试就会报错、
[root@server5 ~]# curl www.westos.org
<html>
<head><title>502 Bad Gateway</title></head>
<body>
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.21.1</center>
</body>
</html>
这个时候我们就得添加备机,以防止出现这种情况,我们可以将本机设置为备机,那么在真实主机全部down的时候,再次测试,就不会出现502报错
http {
upstream westos {
server 192.168.110.10:8000 weight=2;
server 192.168.110.3:80;
server 127.0.0.1:80 backup;
}
[root@server5 ~]# curl www.westos.org
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
如果我们需要用到sticky算法,就需要进行升级,这个时候再次进行源码编译就不需要make install,因为已经不是第一次安装,这个算法是会将来自同一个地址的请求全部分配给同一台主机,以满足有些需求;
四、nginx的平滑升级
有些时候我们使用的nginx版本需要更新,但是我们又因为某些原因不能关闭nginx,所以就需要进行平滑升级,在开启nginx的同时,对其进行升级
首先tar新的版本
258 tar zxf nginx-1.21.6.tar.gz
259 cd nginx-1.21.6/
进入目录之后进行源码编译,但是不要进行make install ,因为我们是进行升级,升级完之后,发现现在的nginx只有900多k,比之前的5.9M大大减小
[root@server1 nginx-1.21.6]# ls
auto CHANGES CHANGES.ru conf configure contrib html LICENSE Makefile man objs README src
[root@server1 nginx-1.21.6]# cd objs/
[root@server1 objs]# du -h nginx
940K nginx
但是此时我们采用du -h查看nginx版本的时候发现还是原来的版本,并没有进行更新,所以这个时候我们要继续进行以下操作,首先我们以防万一,对原来的二进制nginx进行复制
[root@server1 sbin]# cp nginx nginx.old
[root@server1 sbin]# ls
nginx nginx.old
然后对原来的nginx进行覆盖,但是在覆盖的过程中会发现显示在忙,这个时候我们可以采取-f强制覆盖,加\的原因是忽略隐藏,直接执行现在的命令
[root@server1 ~]# cd nginx-1.21.6/
[root@server1 nginx-1.21.6]# ls
auto CHANGES CHANGES.ru conf configure contrib html LICENSE Makefile man objs README src
[root@server1 nginx-1.21.6]# cd objs/
[root@server1 objs]# cp nginx /usr/local/nginx/sbin/nginx
cp: overwrite ‘/usr/local/nginx/sbin/nginx’? yes
cp: cannot create regular file ‘/usr/local/nginx/sbin/nginx’: Text file busy
但是我们在覆盖之后再次查看依旧是原来的版本,这是因为这些都存在于内存中,内存中并未改变,所以我们需要使用kill -USR2 加进程号来开启新版本进程,并且用kill -WINCH 加进程号终止原来的worker进程
[root@server1 objs]# \cp -f nginx /usr/local/nginx/sbin/nginx
[root@server1 objs]# curl -I localhost
HTTP/1.1 200 OK
Server: nginx/1.21.1
Date: Thu, 29 Sep 2022 02:00:30 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Fri, 23 Sep 2022 23:13:57 GMT
Connection: keep-alive
ETag: "632e3db5-264"
Accept-Ranges: bytes
[root@server1 sbin]# ps ax | grep nginx
18566 ? Ss 0:00 nginx: master process /usr/local/nginx/sbin/nginx
18567 ? S 0:00 nginx: worker process
18568 ? S 0:00 nginx: worker process
22493 pts/0 R+ 0:00 grep --color=auto nginx
[root@server1 sbin]# kill -USR2 18566
[root@server1 sbin]# ps ax | grep nginx
18566 ? Ss 0:00 nginx: master process /usr/local/nginx/sbin/nginx
18567 ? S 0:00 nginx: worker process
18568 ? S 0:00 nginx: worker process
22495 ? S 0:00 nginx: master process /usr/local/nginx/sbin/nginx
22496 ? S 0:00 nginx: worker process
22497 ? S 0:00 nginx: worker process
22499 pts/0 R+ 0:00 grep --color=auto nginx
[root@server1 sbin]# kill -WINCH 18566
[root@server1 sbin]# ps ax | grep nginx
18566 ? Ss 0:00 nginx: master process /usr/local/nginx/sbin/nginx
22495 ? S 0:00 nginx: master process /usr/local/nginx/sbin/nginx
22496 ? S 0:00 nginx: worker process
22497 ? S 0:00 nginx: worker process
22503 pts/0 S+ 0:00 grep --color=auto nginx
[root@server1 sbin]# ps ax | grep nginx
18566 ? Ss 0:00 nginx: master process /usr/local/nginx/sbin/nginx
22495 ? S 0:00 nginx: master process /usr/local/nginx/sbin/nginx
22496 ? S 0:00 nginx: worker process
22497 ? S 0:00 nginx: worker process
22505 pts/0 S+ 0:00 grep --color=auto nginx
这个时候可以看见老进程中的worker进程已经全部终止,这个时候再去查看版本,就会发现已经更改
[root@server1 sbin]# curl -I localhost
HTTP/1.1 200 OK
Server: nginx/1.21.6
Date: Thu, 29 Sep 2022 02:05:27 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Fri, 23 Sep 2022 23:13:57 GMT
Connection: keep-alive
ETag: "632e3db5-264"
Accept-Ranges: bytes
如果在我们升级之后又需要用到老版本,那么就要进行回滚;我们首先将原来复制的nginx.old复制给nginx然后用kill -HUP唤醒原进程,并且采用kill -WINCH 来回收新进程中的worker进程,这个时候就完成了版本回滚
[root@server1 sbin]# \cp -f nginx.old nginx
[root@server1 sbin]# kill -HUP 18566
[root@server1 sbin]# curl -I localhost
HTTP/1.1 200 OK
Server: nginx/1.21.6
Date: Thu, 29 Sep 2022 10:31:13 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Fri, 23 Sep 2022 23:13:57 GMT
Connection: keep-alive
ETag: "632e3db5-264"
Accept-Ranges: bytes
[root@server1 sbin]# ps ax | grep nginx
18566 ? Ss 0:00 nginx: master process /usr/local/nginx/sbin/nginx
22495 ? S 0:00 nginx: master process /usr/local/nginx/sbin/nginx
22496 ? S 0:00 nginx: worker process
22497 ? S 0:00 nginx: worker process
22710 ? S 0:00 nginx: worker process
22711 ? S 0:00 nginx: worker process
22715 pts/0 R+ 0:00 grep --color=auto nginx
[root@server1 sbin]# kill -WINCH 22495
[root@server1 sbin]# curl -I localhost
HTTP/1.1 200 OK
Server: nginx/1.21.1
Date: Thu, 29 Sep 2022 10:31:43 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Fri, 23 Sep 2022 23:13:57 GMT
Connection: keep-alive
ETag: "632e3db5-264"
Accept-Ranges: bytes
五、nginx限流
我们有的时候需要nginx帮助我们对文件传输或者下载进行限流,这个时候我们可以采用以下方法来实现
比如我们在nginx.conf中添加以下内容,控制download中并发量为1
limit_conn_zone $binary_remote_addr zone=addr:10m;
location /download/ {
limit_conn addr 1;
}
在这时进行压力测试,-c10,结果会显示有部分错误
ab -c10 -n 10 http://192.168.110.2/download/R8.jpg
Concurrency Level: 10
Time taken for tests: 0.007 seconds
Complete requests: 10
Failed requests: 4
如果我们将并发改为1,就不会出现错误
[root@server5 sbin]# ab -c1 -n 10 http://192.168.110.2/download/R8.jpg
刚刚我们限制了并发连接数,现在我们可以限制请求速率,例如限制每秒一个
limit_conn_zone $binary_remote_addr zone=addr:10m;
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
location /download/ {
limit_conn addr 1;
limit_req zone=one;
}
进行压测会发现报错,因为我们要处理10个请求,但是限制了每秒一个而且并发为1
Time taken for tests: 0.010 seconds
Complete requests: 10
Failed requests: 5
我们再添加一个限制,就是让超出速率限制的请求进行排队,而burst的值就是排队的最大数量
location /download/ {
limit_conn addr 1;
limit_req zone=one burst=5;
}
Concurrency Level: 1
Time taken for tests: 5.017 seconds
也可以进行限制带宽
location /download/ {
limit_conn addr 1;
limit_req zone=one burst=5;
limit_rate 50k;
}
可以看见,限制带宽之后,处理十张照片花费的时间大大增多,我们可以根据需求来对带宽进行限制
Concurrency Level: 1
Time taken for tests: 60.615 seconds
Complete requests: 10
六、nginx配置管理
我们如果想要下载比较直观方便,可以进行以下设置
location /download/ {
limit_conn addr 1;
limit_req zone=one burst=5;
limit_rate 50k;
autoindex on;
}
可以看到,之前在访问的时候会直接出现图片,而现在会出现一个目录供我们选择,更加直观方便
日志轮循
写一个脚本,让日志做一个截断
#! /bin/bash
cd /usr/local/nginx/logs && mv access.log access_$(date +%F -d -1day).log
kill -USR1 `cat /usr/local/nginx/logs/nginx.pid`
crontab -e添加定时任务
00 00 * * * /opt/nginxlog.sh
进行测试后会发现,前一天的日志已经被截断,新的日志都放在了今天的新access.log下
[root@server1 logs]# ll
total 72
-rw-r--r-- 1 root root 42240 Sep 30 09:39 access_2022-09-29.log
-rw-r--r-- 1 nginx root 0 Sep 30 10:19 access.log
-rw-r--r-- 1 nginx root 24095 Sep 30 09:38 error.log
-rw-r--r-- 1 root root 6 Sep 30 00:58 nginx.pid
[root@server1 logs]# ll
total 84
-rw-r--r-- 1 root root 42240 Sep 30 09:39 access_2022-09-29.log
-rw-r--r-- 1 nginx root 10500 Sep 30 10:20 access.log
-rw-r--r-- 1 nginx root 24095 Sep 30 09:38 error.log
-rw-r--r-- 1 root root 6 Sep 30 00:58 nginx.pid
对于一些没有必要写入日志的内容我们可以=采用access_log off;来关闭日志写入
也可以对可见主机进行限制,比如允许本机访问而不允许其他主机访问
nginx重定向
对于没有开放的域名,我们可以对其设置重定向
server {
listen 80;
server_name localhost;
rewrite ^(.*) http://www.westos.org permanent;
也可以设置443重定向
server {
listen 443 ssl;
server_name www.westos.org;
ssl_certificate cert.pem;
ssl_certificate_key cert.pem;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
root html;
index index.html index.htm;
}
}
server {
listen 80;
server_name www.westos.org;
rewrite ^/(.*)$ https://www.westos.org/$1 permanent;
#location / {
# proxy_pass http://westos;
#}
}
}
这里再次进行测试会发现已经完成重定向
[root@server5 ~]# curl -I www.westos.org
HTTP/1.1 301 Moved Permanently
Server: nginx/1.21.1
Date: Fri, 30 Sep 2022 03:01:04 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: https://www.westos.org/
nginx防盗链
我们有的时候访问网站中的内容并不是通过原网站进行访问,这时候就会白白消耗资源,所以可以设置防盗链,如果是通过其他地址访问就会显示错误或者可以将其跳转至其他页面
location ~ \.(jpg|png)$ {
root html;
valid_referers none blocked www.westos.org;
if ($invalid_referer) {
return 403;
#rewrite ^/http://www2.westos.org/R8.jpg;
}
}