• Nginx


    Nginx

    1. Nginx安装

    Windows环境安装Nginx

    Windows安装nginx,我们首先需要去官网下载对应的.exe或者.zip文件,然后解压运行即可。

    start nginx
    

    Linux(CentOS)环境安装Nginx

    1. 安装所需的依赖
    yum -y install gcc gcc-c++ make libtool zlib zlib-devel openssl openssl-devel pcre pcre-devel
    
    1. 下载nginx

    官网地址:https://nginx.org/en/download.html 下载tar.g安装包

    或者使用wget命令下载:

    wget -c https://nginx.org/download/nginx-1.18.0.tar.gz
    #如果不存在wget 使用yum install wget安装
    
    1. 解压压缩包,并以默认配置文件启动
    tar -zxvf nginx-1.18.0.tar.gz 
    cd nginx-1.18.0
    #使用默认配置
    ./configure
    #编译安装
    make
    make install
    #启动
    cd /usr/local/nginx/sbin/
    ./nginx #启动
    ./nginx -s stop #停止
    ./nginx -s quit #完全停止【建议使用!!!】
    ./nginx -s reload #重新加载配置文件
    ps aux|grep nginx #查看nginx进程
    
    1. 设置nginx开启自启动
    vi /etc/rc.local
    #增加一行
    /usr/local/nginx/sbin/nginx
    
    1. 重启
    #先停止
    ./nginx -s quit
    #再启动
    ./nginx
    

    Docker环境安装Nginx

    Nginx

    #拉取nginx镜像
    docker pull nginx
    #查看nginx镜像,并记录image前4位
    docker images nginx
    #测试nginx是否可用
    docker run -d --name nginx -p 80:80 【nginx镜像前四位】
    
    -d 指定容器以守护进程方式在后台运行
    –name 指定容器名称,此处我指定的是nginx
    -p 指定主机与容器内部的端口号映射关系,格式 -p [宿主机端口号][容器内部端口]
    

    通过docker ps查看nginx正常运行…

    在这里插入图片描述

    直接在web端访问:

    在这里插入图片描述

    此时,我们需要解决的即是配置文件挂载在容器外部【转移到宿主主机内部中】

    复制配置文件到宿主主机对应目录下:

    docker cp 容器id:/etc/nginx/nginx.conf /mydata/nginx/
    
    docker cp 容器id:/etc/nginx/conf.d /mydata/nginx/conf/
    docker cp 容器id:/usr/share/nginx/html/ /mydata/nginx/html/
    docker cp 容器id:/var/log/nginx/ /mydata/nginx/logs/
    
    这里我的容器id前缀为3d43
    docker cp 3d43:/etc/nginx/nginx.conf /mydata/nginx/
    docker cp 3d43:/etc/nginx/conf.d /mydata/nginx/conf/
    docker cp 3d43:/usr/share/nginx/html/ /mydata/nginx/
    docker cp 3d43:/var/log/nginx/ /mydata/nginx/logs/
    

    停止并移除容器:

    docker stop 3d43【容器id】
    docker rm 3d43
    

    最后再次以容器的文件作为挂载进行nginx的启动:

    docker run  --name nginx -m 200m -p 80:80 -p 443:443 \
    -v /mydata/nginx/nginx.conf:/etc/nginx/nginx.conf \
    -v /mydata/nginx/logs/:/var/log/nginx \
    -v /mydata/nginx/html/:/usr/share/nginx/html \
    -v /mydata/nginx/conf/conf.d:/etc/nginx/conf.d \
    -e TZ=Asia/Shanghai \
    --privileged=true -d nginx
    --restart=always
    
    # 注意
    上面同时开启了80和443端口,为了后续配置ssl需要开启443端口服务
    

    参数说明:

    参数说明
    -name  给你启动的容器起个名字,以后可以使用这个名字启动或者停止容器
    -p     映射端口,将docker宿主机的80端口和容器的80端口进行绑定
    -v    挂载文件用的,
    -m 200m 分配内存空间
    -e TZ=Asia/Shanghai  设置时区
    第一个-v 表示将你本地的nginx.conf覆盖你要起启动的容器的nginx.conf文件,
    第二个-v 表示将日志文件进行挂载,就是把nginx服务器的日志写到你docker宿主机的/home/docker-nginx/log/下面
    第三个-v 表示的和第一个-v意思一样的。
    -d 表示启动的是哪个镜像
    

    需要注意的是挂载在容器外部的/mydata/nginx下的nginx.conf/mydata/nginx/conf/conf.d下的default.conf配置文件

    2. Nginx快速入门

    Nginx (engine x) 是一款轻量级的 Web 服务器反向代理服务器及电子邮件(IMAP/POP3)代理服务器。

    反向代理

    反向代理(Reverse Proxy)方式是指以代理服务器来接受 internet 上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给 internet 上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。

    在这里插入图片描述

    nginx常见的命令:

    nginx -s stop       快速关闭Nginx,可能不保存相关信息,并迅速终止web服务。
    nginx -s quit       平稳关闭Nginx,保存相关信息,有安排的结束web服务。
    nginx -s reload     因改变了Nginx相关配置,需要重新加载配置而重载。
    nginx -s reopen     重新打开日志文件。
    nginx -c filename   启动,为Nginx 指定一个配置文件,来代替缺省的。
    nginx -t            不运行,而仅仅测试配置文件。nginx 将检查配置文件的语法的正确性,并尝试打开配置文件中所引用到的文件。
    nginx -v            显示 nginx 的版本。
    

    nginx.conf:

    nginx的使用在于nginx.conf配置文件的编写,其中conf/nginx.conf是nginx的全局配置文件:

    #运行用户配置,默认用户nginx
    user  nginx;
    #启动进程,通常设置成和cpu的核数相同
    worker_processes  auto;
    #全局错误日志的配置
    error_log  /var/log/nginx/error.log notice;
    #pid用于记录启动nginx的进程id
    pid        /var/run/nginx.pid;
    #工作模式及连接上限
    events {
        worker_connections  1024; #指定单个后台worker process进程的最大并发数为1024
    }
    #设定http服务器【一个conf文件只能存在一个http标签】,利用它来实现反向代理和负载均衡支持
    http {
        
        #设置支持的mime类型,保存在mime.types文件中
        include       /etc/nginx/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"';
    
        access_log  /var/log/nginx/access.log  main;
    		
        #sendfile指令指定nginx是否调用sendfile函数(zero copy 方式)来输出文件,对于普通应用必须为on
        sendfile        on;
        #tcp_nopush     on;
    		
        #连接超时时间设置
        keepalive_timeout  65;
      	#gzip压缩开关
        #gzip  on;
      	
        #引入其他子配置文件:一般将真正的配置写在/etc/nginx/conf.d路径下的配置文件中,全局配置文件保持不变
        include /etc/nginx/conf.d/*.conf;
    }
    

    进入/etc/nginx/conf.d,发现存在一个default.conf配置文件,则便是我们真正进行配置的地方:这里以一个简单的nginx配置为例:

    #配置负载均衡列表
    upstream tfblog_web_server {
      server www.tfblog.top:9090;
    }
    upstream tfblog_back_server {
      server www.tfblog.top:9091;
    }
    #http-server配置
    server {
        #监听80端口,80端口是知名端口号,用于HTTP协议
        listen       80;
        
        #指定访问地址:ip/域名【www.xxx.com】
        server_name  www.tfblog.top;
      
        #配置跨域访问 
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Max-Age 3600;
        add_header Access-Control-Allow-Credentials true;
        add_header Access-Control-Allow-Methods *;
        add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
        if ($request_method = OPTIONS){
          return 200;
        }
      
        #指定编码格式
        charset utf-8;
      
        #指定反向代理的路径,可以与upstream进行绑定,实现负载均衡;location后面设置映射的路径
        #指定默认/,指向前台的server
        location / {
            proxy_pass http://www.tfblog.top:8080/blog-web/;
        }
        location /web {
            proxy_pass http://www.tfblog.top:8080/blog-web/;
        }
        location = /api/web/ {
    		proxy_pass http://tfblog_web_server;
        }
      	location = /api/back/ {
        	#proxy_pass结尾不加/,则www.tfblog.top/api/back/xxx/xxx会被代理到http://tfblog_back_server/api/back/xxx/xxx
    		proxy_pass http://tfblog_back_server;
        } 
    }
    #https
    server {
        #监听443端口
        listen       443 ssl;
        #使用域名访问
        server_name  www.tfblog.top;
        #开启ssl
        ssl on;
        #配置ssl证书的位置(这里为http证书【crt/key】,一般ssl证书文件格式为【crt/pem】)
        ssl_certificate      /etc/ssl/certificate.crt; 
        ssl_certificate_key  /etc/ssl/private.key;
        #ssl配置参数,可以选择性配置
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;
        ssl_ciphers AESGCM:ALL:!DH:!EXPORT:!RC4:+HIGH:!MEDIUM:!LOW:!aNULL:!eNULL;  
        ssl_prefer_server_ciphers on;
        charset utf-8;
    
        location / {
          proxy_pass http://www.tfblog.top:8080/blog-web/;
        }
        location = /web {
          proxy_pass http://www.tfblog.top:8080/blog-web/;
        }
    }
    

    3. Nginx配置文件

    location

    语法规则:

    location [=||*|^~] /uri/ { … }

    • = 开头表示精确匹配
    • ^~ 开头表示uri以某个常规字符串开头,理解为匹配 url路径即可。nginx不对url做编码,因此请求为/static/20%/aa,可以被规则^~ /static/ /aa匹配到(注意是空格)。以xx开头
    • ~ 开头表示区分大小写的正则匹配 以xx结尾
    • ~* 开头表示不区分大小写的正则匹配 以xx结尾
    • !~!~*分别为区分大小写不匹配及不区分大小写不匹配的正则
    • / 通用匹配,任何请求都会匹配到

    这里列举几种常见的匹配规则:

    • 必选规则1
      • 直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理
      • 这里是直接转发给后端应用服务器了,也可以是一个静态首页
    location = / {
        proxy_pass http://域名:8080/index
    }
    
    • 必选规则2
      • 静态文件请求,存在两种配置模式,目录匹配或后缀匹配
    #第一种:以xxx开头
    location ^~ /static/ {                              
        root /webroot/static/;
    }
    #第二种:以xxx结尾
    location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {    
        root /webroot/res/;
    }
    
    • 通用规则
      • 用来转发动态请求到后端应用服务器,可以在前端页面增加路由转发,增加一个共同的前缀
      • 非静态文件请求就默认是动态请求,自己根据实际把握
    location / {
        proxy_pass http://域名:8080/
    }
    
    proxy_pass转发“/”带不带问题

    在配置location的时候,经常会进行路由转发,此时转发地址结尾带不带“/”会导致最后转发的url地址存在很大的不同,这里简单明了地梳理一番。同样我们以例子切入,更加形象:

    • proxy_pass不携带/
    listen  80;   
    server_name  locahost;
    location /api/ {   
        proxy_pass http://192.168.xx.xx:9090;
    }
    此时,/api会携带在proxy_pass的转发地址后面:
    http://locahost:80/api/    ==>   http://192.168.xx.xx:9090/api/
    http://locahost:80/api/a/b/c    ==>   http://192.168.xx.xx:9090/api/a/b/c
    
    • proxy_pass携带/
    listen  80;   
    server_name  locahost;
    location  /api/ {   
        proxy_pass http://192.168.xx.xx:9090/;
    }
    此时,/api就不会存在于proxy_pass的转发地址后面:
    http://locahost:80/api/    ==>   http://192.168.xx.xx:9090
    http://locahost:80/api/a/b/c    ==>   http://192.168.xx.xx:9090/a/b/c
    

    PS:现在是不是很清晰了…~

    Rewrite地址重写

    语法规则:

    rewrite regex replacement [flag]

    其中:

    • regex:表示使用正则表达式或者字符串来匹配相应的地址
    • replacement:表示重定向的地址
    • flag:标志位
    flag描 述
    last本条规则匹配完成后,停止匹配,将重写后的地址重新发起请求进行匹配,浏览器地址栏URL地址不变
    break本条规则匹配完成后,停止匹配,不再匹配后面的规则
    redirect返回302临时重定向,地址栏会显示跳转后的地址
    permanent返回301永久重定向,地址栏会显示跳转后的地址

    这里举一个例子,当我们配置https-ssl证书的时候,需要将原来http的请求转发到https:

    server {
      listen 80;
      server_name www.xxx.com
      rewrite ^(.*) https://$host$1 permanent;
    }
    

    当然这里我们也可以使用return 301的方式:

    server {
      listen 80;
      server_name www.xxx.com
      return 301 https://$server_name$request_uri;
    }
    

    upstream

    nginx另一个核心的功能点就是可以实现请求的负载均衡,这里可以使用location+upstream实现:

    #配置负载均衡列表
    upstream tfblog_web_server {
      server www.tfblog.top:9090;
      server www.tfblog.top:9092;
    }
    server {
      listen 80;
      server_name www.tfblog.top;
      
      location / {
        proxy_pass http://tfblog_web_server;
        proxy_set_header Host $proxy_host;
      }
    }
    

    上面便是一个简单的负载均衡配置,当请求http://www.tfblog.top:80时,此时会负载均衡到http://www.tfblog.top:9090和http://www.tfblog.top:9092这两个地址上。其中:

    • upstream后面的名称与proxy_pass后面的地址对应
    • upstream中的两个server地址就是两个服务器的地址
    • proxy_set_header:可以设置请求头,并将头信息传递到服务器端

    对于负载均衡来说,nginx提供了6中负载均衡算法,上面什么都没配置,只写了两个服务器地址,则使用的是默认的轮询算法,另外几种如下所示:

    • 轮询
    即上面配置的案例
    
    • 权重-weight:指定轮询的访问几率,用于后端服务器性能不均时调整访问比例
    upstream tfblog_web_server {
      server www.tfblog.top:9090 weight=4;
      server www.tfblog.top:9092 weight=6;
    }
    server {
      listen 80;
      server_name www.tfblog.top;
      
      location / {
        proxy_pass http://tfblog_web_server;
        proxy_set_header Host $proxy_host;
      }
    }
    
    • ip_hash:指定负载均衡器按照基于客户端IP的分配方式,这个方法确保了相同的客户端的请求一直发送到相同的服务器,可以解决session不能跨服务器的问题。
    upstream tfblog_web_server {
      ip_hash;
      server www.tfblog.top:9090;
      server www.tfblog.top:9092;
    }
    server {
      listen 80;
      server_name www.tfblog.top;
      
      location / {
        proxy_pass http://tfblog_web_server;
        proxy_set_header Host $proxy_host;
      }
    }
    
    • least_conn:把请求转发给连接数较少的后端服务器
    upstream tfblog_web_server {
      least_conn;
      server www.tfblog.top:9090;
      server www.tfblog.top:9092;
    }
    server {
      listen 80;
      server_name www.tfblog.top;
      
      location / {
        proxy_pass http://tfblog_web_server;
        proxy_set_header Host $proxy_host;
      }
    }
    
    • fair(第三方):按照服务器端的响应时间来分配请求,响应时间短的优先分配
    upstream tfblog_web_server {
      fair;
      server www.tfblog.top:9090;
      server www.tfblog.top:9092;
    }
    server {
      listen 80;
      server_name www.tfblog.top;
      
      location / {
        proxy_pass http://tfblog_web_server;
        proxy_set_header Host $proxy_host;
      }
    }
    
    • url_hash(第三方):该策略按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,需要配合缓存用
    upstream tfblog_web_server {
      hash $request_uri;
      server www.tfblog.top:9090;
      server www.tfblog.top:9092;
    }
    server {
      listen 80;
      server_name www.tfblog.top;
      
      location / {
        proxy_pass http://tfblog_web_server;
        proxy_set_header Host $proxy_host;
      }
    }
    

    if

    语法规则:

    if (condition) {

    ​ …

    }

    = ,!= 比较的一个变量和字符串

    ~, ~*与正则表达式匹配的变量

    -f ,!-f 检查一个文件是否存在

    -d, !-d 检查一个目录是否存在

    -e ,!-e 检查一个文件、目录、符号链接是否存在

    -x , !-x 检查一个文件是否可执行

    作用域:server,location

    举例说明:

    server {
      if ($request_method = OPTIONS){
              return 200;
      }
    }
    

    跨域配置

    #配置跨域访问 
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Max-Age 3600;
        add_header Access-Control-Allow-Credentials true;
        add_header Access-Control-Allow-Methods *;
        add_header Access-Control-Allow-Headers *;
    

    SSL配置

    server {
        #监听443端口
        listen       443 ssl;
        #使用域名访问
        server_name  www.xxx.com;
        #配置ssl证书的位置(这里为http证书【crt/key】,一般ssl证书文件格式为【crt/pem】)
        ssl_certificate      /etc/ssl/certificate.crt; 
        ssl_certificate_key  /etc/ssl/private.key;
        #ssl配置参数,可以选择性配置
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;
        ssl_ciphers AESGCM:ALL:!DH:!EXPORT:!RC4:+HIGH:!MEDIUM:!LOW:!aNULL:!eNULL;  
        ssl_prefer_server_ciphers on;
        charset utf-8;
    		
        location / {
    			  proxy_pass https://www.xxx.com:port;
        }
    }
    #http请求转发至https
    server {
      listen 80;
      server_name www.xxx.com
      rewrite ^(.*) https://$host$1 permanent;
    }
    

    未完待续,后续在项目中nginx实战,再补充更多的配置和牛逼的使用…

  • 相关阅读:
    golang GC
    【C++】类的声明 与 类的实现 分开 ① ( 类的声明 与 类的实现 常用用法 | Visual Studio 2019 中创建类的头文件和源文件 | 确保头文件包含一次 )
    消息中间件介绍
    【Feign】 基于 Feign 远程调用、 自定义配置、性能优化、实现 Feign 最佳实践
    现货黄金休市时间长不长?科普一下交易时间
    【浙大版《Python 程序设计》题目集(解)】第6章-6 求指定层的元素个数(40分)
    为啥是Spring Cloud Alibaba
    ListUtil java
    计算机毕业设计ssm软件学院社团管理系统l62lq系统+程序+源码+lw+远程部署
    LeetCode每日一题:1333. 餐厅过滤器(2023.9.27 C++)
  • 原文地址:https://blog.csdn.net/SmallPig_Code/article/details/127110706