Nginx详解

x33g5p2x  于2021-12-12 转载在 其他  
字(12.2k)|赞(0)|评价(0)|浏览(202)

Nginx

一.nginx详解

1.优势

支持高并发 (静态请求)

高性能反向代理功能(负载均衡服务器)

安装非常简单、bug很少、可在线平滑升级

模块丰富(功能丰富)

2.安装

  1. 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. 源码安装
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

3.nginx服务管理

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

4.nginx升级或者添加模块

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”

5.nginx配置文件详解

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;
​    \#    }
​    \#}
}

6.自定义日志

自己定义日志:在日志部分写入
    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

7.访问控制

访问控制:
 模块: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。

8.状态访问

状态访问统计

模块: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有多少的长连接。相当于空闲的。可以把超时时间改的短一点来减少长连接数。

9.反向代理,负载均衡

要理解负载均衡,必须先搞清楚正向代理和反向代理。

注:
• 正向代理,代理的是用户。
• 反向代理,代理的是服务器

什么是负载均衡
当一台服务器的单位时间内的访问量越大时,服务器压力就越大,大到超过自身承受能力时,服务器就会崩溃。为了避免服务器崩溃,让用户有更好的体验,我们通过负载均衡的方式来分担服务器压力。
我们可以建立很多很多服务器,组成一个服务器集群,当用户访问网站时,先访问一个中间服务器,在让这个中间服务器在服务器集群中选择一个压力较小的服务器,然后将该访问请求引入该服务器。如此以来,用户的每次访问,都会保证服务器集群中的每个服务器压力趋于平衡,分担了服务器压力,避免了服务器崩溃的情况。
负载均衡是用反向代理的原理实现的。

负载均衡的几种常用方式
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变量的值  
        }

10.动静分离

动:动态脚本请求;静:静态页面请求;分离:动态的请求和静态的请求在一台服务器分离出来,由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把数据交给客户端.

二.相关问题

1.500,502,503,504错误

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报错

2.查看并发

查看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 (处理完毕,等待超时结束的请求数)

相关文章