支持高并发 (静态请求)
高性能反向代理功能(负载均衡服务器)
安装非常简单、bug很少、可在线平滑升级
模块丰富(功能丰富)
yum安装(本地源,base源,epel扩展源)
方案一、使用官方源:
注意:本地yum源没有nginx的安装包,需要其他的扩展源
#安装epel yum源 (需要开启官方Base源)
yum install epel-release -y
会发现多了两个yum源文件:
epel.repo epel-testing.repo (epel扩展源:包含nginx)
#安装nginx
yum -y install nginx
#启动nginx
systemctl start nginx
#防火墙放行
firewall-cmd --add-service=http --per
firewall-cmd --reload
#主配置文件:/etc/nginx/nginx.conf
源码安装
1.停止原有web服务卸载yum安装的nginx
2.准备源码安装依赖的环境
yum install -y gcc pcre-devel zlib-devel
注意:本地yum源版本过低,使用官方yum源:CentOS-Base.repo
3.创建程序运行用户和组
useradd -M -s /sbin/nologin nginx
4. 下载源码包
wget http://nginx.org/download/nginx-1.19.7.tar.gz
5.解包
tar -axf nginx-1.19.7.tar.gz
6.配置
cd ~/nginx-1.19.7
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx
注释: --prefix=/usr/local/nginx #指定安装目录
--user=nginx --group=nginx #指定程序运行的用户和组
7.编译安装
make && make install
8.启动服务
/usr/local/nginx/sbin/nginx
netstat -tunlp | grep nginx
firewall-cmd --zone=public --add-port=80/tcp --permanent
firewall-cmd --reload
9.客户机测试访问
10.环境优化
环境变量:PATH (命令的默认搜索路径)
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
简化命令的路径
vim /etc/profile.d/nginx.sh
export PATH="/usr/local/nginx/sbin:$PATH"
source /etc/profile #立即生效
以后启动只需要执行:nginx 或 nginx -c /usr/local/nginx/conf/nginx.conf
## 设置:开机自启动
echo "/usr/local/nginx/sbin/nginx" >> /etc/rc.d/rc.local (开机会执行的脚本)
chmod +x /etc/rc.d/rc.local
1.启动
nginx 或 nginx -c /usr/local/nginx/conf/nginx.conf
2.快速关闭
pkill -9 nginx
或者 nginx -s stop
3.重载
nginx -s reload
4.优雅的关闭
nginx -s quit
1.进入之前编译安装的目录,清除旧数据
make clean
2.重新配置,添加你需要的模块(功能)
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx
–with…
(重新配置会涉及到更多依赖包,根据报错去安装)
3.编译安装
make && make install
4 .平滑升级
make upgrade
5.查看
nginx -V
#日志切割(防止单个文件过大,可以及时删除旧日志,节省磁盘空间)
cat log.sh
#!/bin/bash
dir=/usr/local/nginx
mv $dir/logs/access.log $dir/logs/date +%F
.access.log
mv $dir/logs/error.log $dir/logs/date +%F
.error.log
$dir/sbin/nginx -s reopen
find $dir/logs/ -iname “*log” -atime +3 -exec rm -rf {} ;
编辑周期性计划任务定期执行该脚本:
crontab -e
59 23 * * * /bin/bash /root/log.sh
修改时间测试:
date -s “2021-11-24 23:58:50”
nginx主配置文件主要有以下几大块
1、全局块:配置影响nginx全局的指令。一般有运行nginx服务器的用户组,nginx进程pid存放路径,日志存放路径,配置文件引入,允许生成worker process数等。
2、events块:配置影响nginx服务器或与用户的网络连接。有每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。
3、http块:可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,单连接请求数等。
4、server块:配置虚拟主机的相关参数,一个http中可以有多个server。
5、location块:配置请求的路由,以及各种页面的处理情况。
[root@clone1 nginx]# vim /usr/local/nginx/conf/nginx.conf #user nobody;
worker_processes 1;///worker进程轻易不要调,否则会出问题,,这里的worker进程数调成了多少,对应的nginx就会生成多少worker进程。#最优值取决于许多因素,包括(但不限于)CPU核的数量、存储数据的硬盘数量及负载模式。#不能确定的时候,将其设置为可用的CPU核心数将是一个好的开始(设置为“auto”将尝试自动检测它) #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;
///每个进程最大的连接数,可以适当调高一点,最大值是65535
,nginx最终的并发连接数是这里的每个进程连接数乘以上面的worker进程数目
}
http {
(这种方式可以自定义发布目录) include mime.types;
default_type application/octet-stream;server_tokens off;#隐藏软件版本号
\#定义访问日志格式 # '$status $body_bytes_sent "$http_referer" ' # '"$http_user_agent" "$http_x_forwarded_for"'; #access_log logs/access.log main;
sendfile on;#开启高效文件传输模式 #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65;#连接超时时间 #gzip on; server {
listen 80; #监听端口
server_name localhost; \#虚拟主机名称
\#charset koi8-r; //字符集设置
\#access_log logs/host.access.log main; //定义日志。编译安装的日志
location / {
#资源路径
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;
}
\# proxy the PHP scripts to Apache listening on 127.0.0.1:80
\#
\#location ~ \.php$ {
\# proxy_pass http://127.0.0.1;
\#}
\# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
\#
\#location ~ \.php$ {
\# root html;
\# fastcgi_pass 127.0.0.1:9000;
\# fastcgi_index index.php;
\# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
\# include fastcgi_params;
\#}
\# deny access to .htaccess files, if Apache's document root
\# concurs with nginx's one
\#
\#location ~ /\.ht {
\# deny all;
\#}
}
\# another virtual host using mix of IP-, name-, and port-based configuration
\#
\#server {
\# listen 8000;
\# listen somename:8080;
\# server_name somename alias another.alias;
\# location / {
\# root html;
\# index index.html index.htm;
\# }
\#}
\# HTTPS server
\#
\#server {
\# listen 443 ssl;
\# server_name localhost;
\# ssl_certificate cert.pem;
\# ssl_certificate_key cert.key;
\# 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;
\# }
\#}
}
自己定义日志:在日志部分写入
log_format cust '$remote_addr : $time_local : $http_user_agent';
access_log logs/access.log cust; #cust:自定义的日志名称
测试自定义日志: # curl 192.168.1.254
#cat access.log
访问的Ip:访问的时间:访问的客户端的类型
$remote_addr 记录客户端的ip
$remote_user 记录远程客户端的名字
$time_local 记录访问时间
$request 记录请求的URL或HTTP协议
$status 记录请求状态
$body_bytes_sent 记录发送给客户端的文件的内容的大小
$http_referer 记录从哪个页面链接访问过来的
$http_user_agent 记录客户端浏览器的信息
$http_x_forwarded_for 记录客户端的ip
$hosts 记录客户端访问的域名
## ★ 如何:重开日志,从而执行<切割日志>
## (1) mv重命名:原<日志文件>,添加<当前系统日期>
find /usr/local/nginx/logs/ -iname "*.log" -exec mv {
} {
}.`date '+%F'` \;
ll /usr/local/nginx/logs/
## 结果输出:
## -rw-r--r--. 1 nginx root 0 7月 15 10:01 access.log.2020-07-15 <---- 这就是:备份的<日志文件>
## -rw-r--r--. 1 nginx root 131 7月 15 10:09 error.log.2020-07-15 <---- 这就是:备份的<日志文件>
## -rw-r--r--. 1 root root 5 7月 15 10:07 nginx.pid
## (2) 重开日志:产生<全新的日志文件>
nginx -s reopen 或者 kill -USR1 `cat /usr/local/nginx/logs/nginx.pid`
ll /usr/local/nginx/logs/
## 结果输出:
## -rw-r--r--. 1 nginx root 0 7月 15 10:30 access.log <---- 这就是:全新的<日志文件>
## -rw-r--r--. 1 nginx root 0 7月 15 10:01 access.log.2020-07-15 <---- 这就是:备份的<日志文件>
## -rw-r--r--. 1 nginx root 60 7月 15 10:30 error.log <---- 这就是:全新的<日志文件>
## -rw-r--r--. 1 nginx root 131 7月 15 10:09 error.log.2020-07-15 <---- 这就是:备份的<日志文件>
## -rw-r--r--. 1 root root 5 7月 15 10:07 nginx.pid
访问控制:
模块:ngx_http_auth_basic_module
有时我们会有这么一种需求,就是你的网站并不想提供一个公共的访问或者某些页面不希望公开,我们希望的是某些特定的客户端(限定IP)可以访问。那么我们可以在访问时要求进行身份认证,就如给你自己的家门加一把锁,以拒绝那些不速之客。我们在服务课程中学习过apache的访问控制,对于Nginx来说同样可以实现,并且整个过程和Apache 非常的相似。
基于用户的访问控制:
location / {
root /105/html;
index index.html index.htm;
auth_basic "haha"; //提示符:随便写
auth_basic_user_file /usr/local/nginx/.passwd.db; //认证文件
}
[root@web html]# htpasswd -c /usr/local/nginx/.passwd.db user1 ---- 用户,不用提前创建
New password:
Re-type new password:
Adding password for user user1
-c:创建新文件的时候用,在创建不用加了。
.passwd.db:实际工作中这个文件是隐藏文件
基于IP的访问控制:
server {
listen 80;
server_name example.com;
location / {
root html;
index index.html index.htm;
deny 192.168.1.1;
allow 192.168.1.0;
allow 10.1.1.0;
deny all;
#从上到下的顺序,类似iptables。匹配到了便跳出。如上的例子先禁止了192.16.1.1,接下来允许了2个网段,最后未匹配的IP全部禁止访问.被deny的将返回403状态码。
allow 允许 //ip或者网段
deny 拒绝 //ip或者网段
已经被匹配的ip或者网段,后面不再被匹配。
如果服务器与客户端是同网段,直接添加ip地址或者网段就可以了。
如果是不同网段就设置服务器ip地址的网关允许访问服务器ip。
状态访问统计
模块:ngx_http_stub_status_module
在server中添加如下行
location ~ /status {
//这个目录就是给运维人员访问的,不用创建
stub_status on;
access_log off;
}
查看访问状态统计:
浏览器:http://192.168.1.129/status 刷新可得到如下变化结果
Active connections: 557 //当前nginx处理请求的数目(活跃的连接数)
处理的请求 成功的连接 收到的请求
server accepts handled requests
36573075 36573075 43806112
Reading: 3 Writing: 16 Waiting: 538
Active connections
对后端发起的当前活动连接数
server accepts handled requests
nginx总共处理了36573075个连接
成功创建36573075次握手,也就是成功的连接数connection 失败连接=(总连接数-成功连接数)(相等表示中间没有失败的),
总共处理了43806112个请求 (平均每次握手处理了1.2个数据请求)。
Reading
nginx读取到客户端的Header信息数。请求头
Writing
nginx返回给客户端的Header信息数。响应头
Waiting
开启keep-alive的情况下,这个值等于active - (reading + writing),意思就是Nginx说已经处理完正在等候下一次请求指令的驻留连接。 //可以看到nginx有多少的长连接。相当于空闲的。可以把超时时间改的短一点来减少长连接数。
要理解负载均衡,必须先搞清楚正向代理和反向代理。
注:
• 正向代理,代理的是用户。
• 反向代理,代理的是服务器
什么是负载均衡
当一台服务器的单位时间内的访问量越大时,服务器压力就越大,大到超过自身承受能力时,服务器就会崩溃。为了避免服务器崩溃,让用户有更好的体验,我们通过负载均衡的方式来分担服务器压力。
我们可以建立很多很多服务器,组成一个服务器集群,当用户访问网站时,先访问一个中间服务器,在让这个中间服务器在服务器集群中选择一个压力较小的服务器,然后将该访问请求引入该服务器。如此以来,用户的每次访问,都会保证服务器集群中的每个服务器压力趋于平衡,分担了服务器压力,避免了服务器崩溃的情况。
负载均衡是用反向代理的原理实现的。
负载均衡的几种常用方式
1、轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
upstream backserver {
server 192.168.1.114;
server 192.168.1.115;
}
2、weight (权重)
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的
情况。
upstream backserver {
server 192.168.1.114 weight=3;
server 192.168.1.115 weight=7;
}
权重越高,在被访问的概率越大,如上例,分别是30%,70%。
3、ip_hash
上述方式存在一个问题就是说,在负载均衡系统中,假如用户在某台服务器上登录了,那么该用户第二次请求的时候,因为我们是负载均衡系统,每次请求都会重新定位到服务器集群中的某一个,那么已经登录某一个服务器的用户再重新定位到另一个服务器,其登录信息将会丢失,这样显然是不妥的。
我们可以采用ip_hash指令解决这个问题,如果客户已经访问了某个服务器,当用户再次访问时,会将该请求通过哈希算法,自动定位到该服务器。
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
upstream backserver {
ip_hash;
server 192.168.1.114:88;
server 192.168.1.115:80;
}
4、fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
upstream backserver {
server server1;
server server2;
fair;
}
5、url_hash(第三方)
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。
upstream backserver {
server squid1:3128;
server squid2:3128;
hash $request_uri;
hash_method crc32;
}
每个设备的状态设置为:
1.down 表示当前的server暂时不参与负载
2.weight 默认为1.weight越大,负载的权重就越大。
3.max_fails:允许请求失败的次数默认为1.当超过最大次数时,返回proxy_next_upstream模块定义的错误
4.fail_timeout:max_fails次失败后,暂停的时间。
5.backup: 其它所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。
配置实例:
#user nobody;
worker_processes 4;
events {
# 最大并发数
worker_connections 1024;
}
http{
# 待选服务器列表
upstream uplooking {
# ip_hash指令,将同一用户引入同一服务器。
ip_hash;
server 192.168.1.129 fail_timeout=60s;
server 192.168.1.130;
server 192.168.1.131;
}
server{
# 监听端口
listen 80;
# 根目录下
location / {
# 选择哪个服务器列表
proxy_pass http://uplooking; uplooking是组名
}
用nginx做反向代理,有负载均衡:
负载均衡策略:
1.轮循
2.加权轮循
3.ip hash
[root@nginx conf]# vim /usr/local/lnmp/nginx/conf/nginx.conf
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
upstream uplook {
server 192.168.10.11:80;
server 192.168.10.12;
server 192.168.10.13;
}
server {
listen 80;
server_name www.nginx.com;
index index.html index.htm;
location / {
proxy_pass http://uplook;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
--------------------------------------------------------------------------------------------
如果真实WEB服务的性能不同,为了保证每个apache-server都能够满足最大的访问.
可以加入权重,权重值越高,分到的请求越多.
[root@nginx conf]# vim /usr/local/lnmp/nginx/conf/nginx.conf
upstream uplook {
server 192.168.10.11 weight=1 max_fails=2 fail_timeout=30s;
server 192.168.10.12 weight=2;
server 192.168.10.13 backup; #backup:备份,其他服务器宕机后启用
}
-------------------------------------------------------------------------------------------
为了保证在短时间内,同一个客户端的请求不被分配到其他的apache-server上?
[root@nginx conf]# vim nginx.conf
upstream uplook {
ip_hash;
server 172.16.0.10;
server 172.16.5.100;
server 172.16.16.100;
}
客户端测试:
一直得到同一个页面.
=========================================================
nginx+(apache|nginx) ,WEB服务器获取客户端真实IP
代理服务器:
location / {
#root html;
#index index.html index.htm;
proxy_pass http://webs;
proxy_set_header X-Real-ip $remote_addr; //将记录客户端的ip 传入 X-Real变量
}
WEB服务器:
apache:
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{X-Real-ip}i\" \"%{User-Agent}i\"" combined
nginx:
安装real-ip模块
location / {
root html;
index index.html index.htm;
set_real_ip_from 10.10.10.11;
real_ip_header X-Real-ip; //IP头部 通过 代理服务器 传入 X-Real变量的值
}
动:动态脚本请求;静:静态页面请求;分离:动态的请求和静态的请求在一台服务器分离出来,由nginx-web-server 处理静态页面请求,由 PHP 处理动态请求.
使用fastcgi:
CGI:通用网关接口,web-server和动态的脚本语言之间进行通信的接口.
fastCGI:高速的运行在web-server上的和动态的脚本语言之间进行通信的接口.
运行原理:
fastcgi在linux下是socket,为了调用CGI程序,还需要一个应用程序-wrapper,这个wrapper绑定在socket上.
(1)nginx将动态的HTTP请求交给 socket,通过 fastcgi接口,由wrapper接受请求,然后派生出一个线程,调用请求数据;
(2)wrapper将得到的数据通过 fastcgi接口通过 socket交给 nginx;
(3)nginx把数据交给客户端.
403错误: 访问被拒绝。有可能是因为权限
404错误:页面找不到
304错误:缓存
200 : ok
nginx的500,502,504错误解决方法
一、解决500错误:
1、500错误
指的是服务器内部错误,也就是服务器遇到意外情况,而无法履行请求。
2、500错误一般有几种情况:
(1)web脚本错误,如php语法错误,lua语法错误等。 //让开发的看看自己的代码日志
(2)访问量大的时候,由于系统资源限制,而不能打开过多的文件
3、一般分析思路:
(1)查看nginx error log ,查看php error log
(2)如果是too many open files,修改nginx的worker_rlimit_nofile参数,使用ulimit查看系统打开文件限制,修改/etc/security/limits.conf
(3)如果是脚本的问题,则需要修复脚本错误,并优化代码
(4)各种优化都做好,还是出现too many open files,那就要考虑做负载均衡,把流量分散到不同服务器上去了
二、解决502,504错误
1、使用nginx代理,而后端服务器发生故障;或者php-cgi进程数不够用;php执行时间长,或者是php-cgi进程死掉;已经执行fastCGI等使用情况都会导致502、504。
2、502 Bad Gateway 是指请求的php-fpm已经执行,但是由于某种原因而没有执行完毕,最终导致php-fpm进程终止。
一般来说,与php-fpm.conf的设置有关,也与php的执行程序性能有关,网站的访问量大,而php-cgi的进程数偏少。针对这种情况的502错误,只需增加php-cgi的进程数。
具体就是修改/usr/local/php/etc/php-fpm.conf文件,将其中的max_children值适当增加。
这个数据要依据你的VPS或独立服务器的配置进行设置。一般一个php-cgi进程占20M内存,你可以自己计算下,适量增多。
/usr/local/php/sbin/php-fpm restart 然后重启一下.
3、504 表示超时,也就是客户端所发出的请求没有到达网关,请求没有得到可以执行的php-fpm
三、解决503错误
503 Service Temporarily Unavailable错误
单个ip并发设置过小会导致503报错
查看Web服务器(nginx apache)的并发请求数及其TCP连接状态:
#netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
LAST_ACK 5 (正在等待处理的请求数)
SYN_RECV 30
ESTABLISHED 1597 (正常数据传输状态)
FIN_WAIT1 51
FIN_WAIT2 504
TIME_WAIT 1057 (处理完毕,等待超时结束的请求数)