Nginx服务器

什么是Nginx

Nginx ("engine x") 是一个高性能的 HTTP 和反向代理服务器,特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等

代理服务

正向代理

正向代理:如果把局域网的Intent想象成一个巨大的资源库,则局域网中的客户端要访问Intent,则需要通过代理服务器来访问,这种代理称为正向代理。需要在客户端(浏览器)配置代理服务器,通过代理服务器进行网络通信。

Nginx不仅可以反向代理,实现负载均衡。还能用作正向代理来进行上网等功能。

image-20210406140429607

反向代理

反向代理,其实客户端对代理是无感知的,因为客户端不需要配置就可以访问,我们只需要将请求发送到代理服务器器,由代理服务器去选择目标服务器获取数据后,再返回给客户端,此时反向代理服务器和目标服务器对外是一个服务器,暴露的是代理服务器地址,隐藏了真实服务器IP地址。

image-20210406140517251

负载均衡

客户端发送多个请求到服务器,服务器处理请求,有一些肯要与数据库进行交互,服务器处理完毕后,再将结果返回给客户端。

这种架构模式对于早期的系统相对单一并发请求相对较少的情况下是比较适合的,成本低,但是随着信息数量的不断增长,访问数量和数据量的飞速增长,以及系统业务的复杂度增加,这种架构会造成服务器响应客户端的请求日益缓慢,并发量特别大的时候,还容易造成服务器崩溃,很明显这是由于服务器性能的瓶颈造成的问题,那么如何解决这种情况呢?

我们首先想到的可能是服务器的配置,比如说提高CPU执行效率,加大内存等提高服务器物理性能来解决此问题,但是我们知道的是摩尔定律的日益失效,硬件性能提高已经不能满足日益提升的需求了,最明显的一个例子,双十一一天的访问量就破亿万次,那么上面的系统架构是无法完成这样的服务需求的,那么该怎么办呢?

上面的分析我们去掉了增加服务器的物理配置来解决问题的方法,也就是说纵向解决问题的方法行不通,那么横向增加服务器的数量呢?这时候服务器集群的概念产生了,单个服务器解决不了,我们增加服务器数量,将原先的请求集中到单个服务器上的情况改为将请求分发到多个服务器上,将负载分发到不同的服务器,也就是我们所说的负载均衡。

image-20210406140601979

动静分离

为了加快网站的解析速度,可以把动态页面和静态页面由不同的服务器来解析,加快解析速度,降低原来单个服务器的压力。

image-20210325101332273

安装Nginx服务器

使用远程工具连接到Linux操作系统,推荐工具FinalShell

方法一、yum源安装

有很多yum源可供我们使用,比如,我个人通常会使用阿里的epel源,或者使用nginx官方的yum源,此处以nginx官网的yum源为例,访问如下官网链接可以查看官方yum源的配置过程 http://nginx.org/en/linux_packages.html

从上述链接中可以找到主线版和稳定版的yum源

# 安装相关依赖
# 安装PCRE gcc 和 autoconf、 libtool
yum install -y gcc gcc-c++ autoconf libtool
# 安装PCRE pcre 和 openssl、 Zlib
yum install -y pcre pcre-devel 
yum install -y openssl openssl-devel
yum install -y zlib zlib-devel

# 安装 Nginx
# 下载指定版本的安装包到服务器当前文件夹,根据当前时间选择稳定的版本 ,下载地址: http://nginx.org/en/download.html
wget -c https://nginx.org/download/nginx-1.16.0.tar.gz 
# 解压并进入nginx目录
tar -zxvf nginx-1.14.0.tar.gz
cd nginx-1.14.0 
# 使用nginx的默认配置
./configure 
# 编译安装
make && make install 

# 查找安装路径
whereis nginx
# 查找到目录进入sbin文件夹,可以看到有一个可执行文件nginx,直接./执行就OK了
./nginx
# 关闭命令
./nginx -s stop
# 重新加载命令
./nginx -s reload

# 启动防火墙
systemctl start firewalld
# 禁用防火墙
systemctl stop firewalld
# 查看开放的端口号
firewall-cmd --list-all
# 设定火墙策略,添加 http 服务到策略中
firewall-cmd --add-service=http --permanent
# 设置开放的端口号
firewall-cmd --add-port=80/tcp --permanent
# 关闭端口号
firewall-cmd --zone=public --remove-port=80/tcp --permanent 
# 重启防火墙
firewall-cmd --reload
# 查看监听的端口
netstat -lnpt

方法二、手动安装

进入Nginx官网,下载 http://nginx.org/en/download.htmlNginx 安装包和依赖安装包

安装包名称 备注
pcre PCR是一个Perl库,包括 perl 兼容的正则表达式库。nginx 的 http 模块使用 pcre 来解析正则表达式,所以需要在 linux 上安装 pcre 库,pcre-devel 是使用 pcre 开发的一个二次开发库。nginx也需要此库。
openssl openssl是一个开放源代码的软件库包,应用程序可以使用这个包来进行安全通信,避免窃听,同时确认另一端连接者的身份。
zlib zlib 库提供了很多种压缩和解压缩的方式, nginx 使用 zlib 对 http 包的内容进行 gzip ,所以需要在 Centos 上安装 zlib 库。
nginx nginx是一个高性能的 HTTP 和反向代理服务器
# 讲所需的安装包放入服务器文件夹中
cd 文件夹
# 解压软件安装包并进入目录
tar -zxvf 软件安装包.tar.gz
cd 软件安装包
# 使用nginx的默认配置
./configure 
# 编译安装
make && make install 
# 所有软件安装都是以上的操作方式

Nginx常用命令

# 查找安装路径
whereis nginx
which nginx

# 查找到目录进入sbin文件夹,可以看到有一个可执行文件nginx,直接./执行就OK了
./nginx start
# 重启
./nginx restart
# 快速停止或者关闭命令
./nginx -s stop
# 正常停止或者关闭命令
./nginx -s quit
# 重新加载命令
./nginx -s reload
# 检查Nginx配置文件是否正确
./nginx -t
# 实时查看错误日志更新
tail -f /var/log/nginx/error.log
# 实时查看日志更新
tail -f /var/log/nginx/access.log

# windows关闭nginx所有进程
taskkill /f /t /im nginx.exe

Nginx配置文件

1、nginx配置文件位置: */nginx/conf/nginx.conf

2、nginx配置文件的组成

# vi 打开配置文件
vi nginx.conf 

(1) nginx配置文件有三部分组成

worker_processes  1;

events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    server {
        listen       80;
        server_name  localhost;

        location / {
            root   html;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

第一部分 全局块

从配置文件开始到events块之间的内容,主要会设置一些影响Nginx服务器整体运行的配置命令,主要包括配置Nginx服务器的用户(组)、允许生成worker process 数,进程PID存放路径、日志存放路径和类型以及配置文件的引入等。

比如上面第一行:

worker_processes  1;

这是Nginx服务器并发处理服务的关键配置,worker_processess 值越大,可以支持的并发处理数量也越多,但是会受到硬件、软件设备的制约。

第二部分 events块

比如上面的配置:

events {
     worker_connections  1024;
}

events 块涉及的指令主要影响 Nginx 服务器与用户的网络连接 上述例子就表示每个 work process 支持的最大连接数为 1024.这部分的配置对 Nginx 的性能影响较大,在实际中应该灵活配置。

第三部分 http块

http {
    include mime.types;
    datault_type application/octer-stream;
    
    senfile		on;
    keepalive_timeout	65;
    
    server {
        listen	80;
        server_name localhost;
        
        location / {
            root   html;
            index  index.html index.htm;
        }
        
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

这算是 Nginx 服务器配置中最频繁的部分,代理、缓存和日志定义等绝大多数功能和第三方模块的配置都在这里。 需要注意的是:http 块也可以包括 http 全局块、server 块。

http 全局块

http 全局块配置的指令包括文件引入、MIME-TYPE 定义、日志自定义、连接超时时间、单链接请求数上限等。

http {
    include mime.types;
    datault_type application/octer-stream;
    
    senfile		on;
    keepalive_timeout	65;
}

server 块

这块和虚拟主机有密切关系,虚拟主机从用户角度看,和一台独立的硬件主机是完全一样的,该技术的产生是为了 节省互联网服务器硬件成本。

每个 http 块可以包括多个 server 块,而每个 server 块就相当于一个虚拟主机。

而每个 server 块也分为全局 server 块,以及可以同时包含多个 locaton 块。

server {
    # 监听端口号
    listen	80;
    # 监听主机名称
    server_name localhost;

    # 路径,路径中包含某个值的配置
    location / {
        root   html;
        index  index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }
}
全局server 块

最常见的配置是本虚拟机主机的监听配置和本虚拟主机的名称或 IP 配置

localhost块

一个 server 块可以配置多个 location 块。

这块的主要作用是基于 Nginx 服务器接收到的请求字符串(例如 server_name/uri-string),对虚拟主机名称 (也可以是 IP 别名)之外的字符串(例如 前面的 /uri-string)进行匹配,对特定的请求进行处理。地址定向、数据缓 存和应答控制等功能,还有许多第三方模块的配置也在这里进行。

配置实例

反向代理

location 指令说明

location [ = | ~ | ~* | ^~] uri {

}

1、= :用于不含正则表达式的 uri 前,要求请求字符串与 uri 严格匹配,如果匹配 成功,就停止继续向下搜索并立即处理该请求。 2、~:用于表示 uri 包含正则表达式,并且区分大小写。 3、~*:用于表示 uri 包含正则表达式,并且不区分大小写。 4、^~:用于不含正则表达式的 uri 前,要求 Nginx 服务器找到标识 uri 和请求字 符串匹配度最高的 location 后,立即使用此 location 处理请求,而不再使用 location 块中的正则 uri 和请求字符串做匹配。 注意:如果 uri 包含正则表达式,则必须要有 ~ 或者 ~* 标识。

案例1

# 1、实现效果,在浏览器地址栏中输入地址 localhost:8080,跳转到百度页面
# 2、具体实现

server {
        # 监听端口号
        listen  8080;
        # 监听主机名称
        server_name   localhost;
        # 站点根目录
        root  D:/Nginx/html;

        # 路径,路径中包含某个值的配置
        location / {
            index  index.html index.htm;
            # 配置代理地址
            proxy_pass https://www.baidu.com;
            autoindex  on;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }

案例2

# 1、实现效果,使用Nginx反向代理,根据访问的路径跳转到不同端口的服务中
# 2、具体实现
server {
    listen  8080;
    server_name   localhost;
    
    # 匹配到路径中包含/edu/它就代理到下方地址中
    location ~ /edu/ {
        # 配置代理地址
        proxy_pass http://localhost:8081;
    }
    location ~ /vod/ {
        # 配置代理地址
        proxy_pass http://localhost:8082;
    }

}

负载均衡

# 1、浏览器地址栏输入地址: http://localhost/edu/a.html,负载均衡效果,平均8080和8081端口中
# 2、具体实现

http{
    # 定义服务名称
    upstream myserver{
        ip_hash;
        # 配置需要负载的服务器
        server 115.25.52.63:8080;
        server 115.28.52.63:8180;
    }
    server{
        listen	80;
        server_name localhost;
        
        location / {
            # 配置负载服务名称
            proxy_pass http://myserver;
        }
    }
}

策略

1 、轮询(默认) 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,能自动剔除。

2 、weight weight 代表权,重默认为 1,权重越高被分配的客户端越多 指定轮询几率,weight 和访问比率成正比,用于后端服务器性能不均的情况。

upstream server_pool {
    server 192.168.5.21 weight = 10 ;
    server 192.168.5.22 weight = 10 ;
}

3 、ip_hash 每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 的问题。

upstream server_pool {
    ip_hash ;
    server 192.168.5.21:80 ;
    server 192.168.5.22:80 ;
}

4 、fair (第三方) 按后端服务器的响应时间来分配请求,响应时间短的优先分配。

upstream server_pool {
    server 192.168.5.21:80 ;
    server 192.168.5.22:80 ;
    fair ;
}

动静分离

server{
    listen	80;
    server_name localhost;

    location /www/ {
        root /data/;
        index index.html index.htm;
    }
    location /image/ {
        root /data/;
        # 列出文件列表
        autoindex on;
    }
}

nginx中斜杠(/)详解

nginx中斜杠(/)详解,配置location、proxy_pass时,加“/”与不加“/”的区别

日常在nginx配置时,是不是会对是否加斜杠充满疑惑?

配置location、proxy_pass时,加“/”与不加“/”的区别,我们通过实操去验证下。

通过nginx代理访问地址:http://127.0.0.1/v1/pt/apply/page

location、proxy_pass都不加斜杠

location /v1 {
    proxy_pass http://127.0.0.1:8899;
}

实际访问代理地址:http://127.0.0.1:8899/v1/pt/apply/page

location加斜杠,proxy_pass不加斜杠

location location /v1/ {
    proxy_pass http://127.0.0.1:8899;
}

实际访问代理地址:http://127.0.0.1:8899/v1/pt/apply/page

location不加斜杠,proxy_pass加斜杠

location /v1 {      
    proxy_pass http://127.0.0.1:8899/;
}

实际访问代理地址:http://127.0.0.1:8899//pt/apply/page

location、proxy_pass都加斜杠

location /v1/ {
    proxy_pass http://127.0.0.1:8899/;
}

实际访问代理地址:http://127.0.0.1:8899/pt/apply/page

location不加斜杠,proxy_pass加"v1"

location /v1 {
    proxy_pass http://127.0.0.1:8899/v1;
}

实际访问代理地址:http://127.0.0.1:8899/v1/pt/apply/page

location加斜杠,proxy_pass加"v1"

location /v1/ {
    proxy_pass http://127.0.0.1:8899/v1;
}

实际访问代理地址:http://127.0.0.1:8899/v1pt/apply/page

location不加斜杠,proxy_pass加"v1/"

location /v1 {
    proxy_pass http://127.0.0.1:8899/v1/;
}

实际访问代理地址:http://127.0.0.1:8899/v1/pt/apply/page

location加斜杠,proxy_pass加"v1/"

location /v1/ {
    proxy_pass http://127.0.0.1:8899/v1/;
}

实际访问代理地址:http://127.0.0.1:8899/v1/pt/apply/page

常用配置

worker_processes  1;

events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    server {
        listen       80;
        server_name  localhost;

        location / {
            root   html;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
    # 将配置文件安放到其他文件夹中
    include D:/Nginx/config/*.conf;
}
server {
            # 监听端口号
            listen  8080;
            # 监听主机名称
            server_name   localhost;
            # 站点根目录
            root  D:/Nginx/html/1.host8080;

            # 路径,路径中包含某个值的配置
            location / {
                index  index.html index.htm;
                # 展示文件目录
                autoindex  on;
            }

            location ^~ /api/ {
                # $host 与一条请求匹配的server name
                # proxy_set_header   Host             $host;
                # X-Real-IP 代表本地真实的IP $remote_addr 代表客户端IP
                proxy_set_header   X-Real-IP        $remote_addr;
                # X-Forwarded-For 记录代理信息  $proxy_add_x_forwarded_for 读取的代理信息
                # proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

                # 设置响应头,转发的时候模拟对方主机, m.huaruisales.com
                proxy_set_header Host m.huaruisales.com
                # 配置代理地址,如果proxy_pass 的URL以 / 结尾 ,那么请求转发的时候将不会带上匹配到的/api/
                proxy_pass https://m.huaruisales.com/platform/;
                # 设置转发后端cookie存放地址
                proxy_cookie_path  /platform/ /;
                # 带cookie转发
                proxy_pass_header Set-Cookie;
            }

            error_page   500 502 503 504  /50x.html;
            location = /50x.html {
                root   html;
            }
        }

配置静态资源跨域

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)${
    add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Methods' '*';
    add_header 'Access-Control-Allow-Credentials' "true"; 
    add_header 'Access-Control-Allow-Headers' 'Origin, X-Requested-With, Content-Type, Accept';
}

代理后台API接口

location /insure/ {
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header REMOTE-HOST $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    # 代理到模板地址
    proxy_pass https://m.huaruisales.com/insure/;
    # 设置转发后端cookie存放地址
    proxy_cookie_path  /insure /;
    # 带cookie转发
    proxy_pass_header Set-Cookie;
}

Vue/React History 模式

location / {
  try_files $uri $uri/ /index.html;
}

# 二级目录资源 https://xxxx.com/cms -> C:/static-server/cms
location /cms {
    root C:/static-server; # 项目部署资源所在磁盘目录
    index  index.html;
    try_files $uri $uri/ /cms/index.html; #history模式路由需增加这一行配置
}

Vue/React资源和Html文件缓存问题

# html文件
location ~ \.html$ {  
    # 禁用缓存  
    expires -1;  
    add_header Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";  
    add_header Pragma "no-cache"; 
}

# css/js文件
location ~ \.(js|css)?$ {
    expires 4h; 
    access_log off;
}

# 图片资源
location ~ \.(gif|jpg|jpeg|png|bmp|swf|flv|mp4|ico)$ {
    expires 4h;
    access_log off;
}

判断移动端切换目录

location / {
  root html/pc;
  # 判断移动端
  if ($http_user_agent ~* (mobile|nokia|iphone|ipad|android|samsung|htc|blackberry)) {
    root html/mobile;
  }
  index  index.html index.htm;
}

判断客户端浏览器语言

#中文
if ($http_accept_language ~* ^zh){
    rewrite ^/$ http://zh.aa.com/index.html?la=zh redirect;
}

#英文
if ($http_accept_language ~* ^en){
    rewrite ^/$ http://us.aa.com/index.html?la=us redirect;
}

cookie值不同切换服务器

方式一

# 负载服务器
upstream portal_server1  {
    server 172.20.2.18:7001 weight=1 max_fails=2 fail_timeout=10s;
}
upstream portal_server2  {
    server 172.20.2.236:7001 weight=1 max_fails=2 fail_timeout=10s;
}
upstream portal_server_default  {
    server 172.20.2.18:7001 weight=1 max_fails=2 fail_timeout=10s;
    server 172.20.2.236:7001 weight=1 max_fails=2 fail_timeout=10s;
}

# $COOKIE_[cookie键值对名称] [负载服务器名称]
map $COOKIE_isPjaxTest $portal_server {
    1 portal_server1;
    2 portal_server2;
    default portal_server_default;
}

# 正常服务代理
location ^~ /portal-oms {
        include proxy.conf;
        proxy_pass http://$portal_server$request_uri;
        access_log  logs/dlis-portal-oms.log  main;
}

# 匹配并截取代理前缀
location ^~ /claims/ {
        if ($request_uri ~ /claims/(.+)) {
            set $rightUrl $1;
        }
        include /etc/nginx/proxy.conf;
        proxy_pass http://$portal_server/$rightUrl;
        access_log  logs/dlis-portal-oms.log  main;
}

方式二

location ^~ /portal-oms {
        if ($http_cookie ~* "isPjaxTest=1"){
            set $group https://zhenyutsai.com;
        }
        if ($http_cookie ~* "isPjaxTest=2"){
            set $group https://m.zhenyutsai.com;
        }
        include proxy.conf;
        proxy_pass $group;
        access_log  logs/dlis-portal-oms.log  main;
}