什么是Nginx

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

其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用nginx的网站有:百度、京东、新浪、网易、腾讯、淘宝等。
Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:PaM6nep)开发的,第一个公开版本0.1.0发布于2004年10月4日。
官网: nginx news

下载安装

Tip
  • Nginx是C语言编写的需要环境gcc环境
  • 可以使用Docker一键安装(使用Docker安装的话一定要注意容器内网络的映射)

安装过程:
1、安装依赖包yum -y install gcc pcre-devel zlib-devel openssl openssl-devel
2、下载Nginx安装包wget https: //nginx.org/download/nginx-1.16.1.tar·gz
3、解压tar -zxvf nginx-1.16.1.tar.gz
4、cd nginx-1.16.1
5、./configure --prefix=/usr/local/nginx——设置Nginx安装到/usr/local/nginx
6、make && make install——先编译再安装

目录结构

  • conf/nginx.confnginx:配置文件
  • html:存放静态文件(html、CSS、Js等)
  • logs:日志目录,存放日志文件
  • sbin/nginx:二进制文件,用于启动、停止Nginx服务
    image-20230120123902272

配置文件结构

Nginx配置文件(conf/nginx.conf)整体分为三部分:

  • 全局块:和Nginx运行相关的全局配置
  • events块:和网络连接相关的配置
  • http块:代理、缓存、日志记录、虚拟主机配置
    • http全局块
    • Server块
      • Server全局块
      • location块

注意:http块中可以配置多个Server块,每个Server块中可以配置多个location块。

image-20230120133050434

部署静态资源

Nginx可以作为静态web服务器来部署静态资源。静态资源指在服务端真实存在并且能够直接展示的一些文件,比如常见的html页面、css文件、js文件、图片、视频等资源。
相对于Tomcat,Nginx处理静态资源的能力更加高效,所以在生产环境下,一般都会将静态资源部署到Nginx中。 将静态资源部署到Nginx非常简单,只需要将文件复制到Nginx安装目录下的html目录中即可。

image-20230120135017649

负载均衡

什么是负载均衡

早期的网站流量和业务功能都比较简单,单台服务器就可以满足基本需求,但是随着互联网的发展,业务流量越来越大并且业务逻辑也越来越复杂,单台服务器的性能及单点故障问题就凸显出来了,因此需要多台服务器组成应用集群,进行性能的水平扩展以及避免单点故障出现。

  • 应用集群:将同一应用部署到多台机器上,组成应用集群,接收负载均衡器分发的请求,进行业务处理并返回响应数据
  • 负载均衡器:将用户请求根据对应的负载均衡算法分发到应用集群中的一台服务器进行处理

image-20230120145847107

配置负载均衡策略

使用upstream指令定义一组服务器

反向代理使用这一组服务器

image-20230120150014752

默认选用的负载均衡策略是轮询

image-20230120150251598

举一个根据权重进行负载均衡策略配置的例子

image-20230120150349551

博客部署案例

配置文件参考如下:

  • 指定log文件
  • 80和443端口监听
  • 错误页面重定向
  • 域名、路径服务重定向
  • SSL证书配置
  • 方向代理请求头、请求参数设置

user nginx;
worker_processes 1;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;


events {
    worker_connections 1024;
}

http {

    include mime.types;
    default_type application/octet-stream;
    sendfile on;
    keepalive_timeout 65;

    client_max_body_size 50m;
    client_body_buffer_size 10m;
    client_header_timeout 1m;
    client_body_timeout 1m;

    gzip on;
    gzip_min_length 1k;
    gzip_buffers 4 16k;
    gzip_comp_level 4;
    gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
    gzip_vary on;
    # server {
    #     listen 80 default_server;
    #     server_name _; # 默认服务器块的server_name设置为下划线

    #     # 这里可以添加默认的处理逻辑,例如返回一个自定义的错误页面
    #     location / {
    #         root /usr/share/nginx/html/blog;
    #         index index.html index.htm;
    #         try_files $uri $uri/ /index.html;
    #     }
    # }
    # halo博客
    server {
        #   listen 80;
        #   listen [::]:80;
        listen 443 ssl;
        server_name cytl.ink;
        client_max_body_size 1024m;
        ssl_certificate /etc/nginx/certs/cert.pem;
        ssl_certificate_key /etc/nginx/certs/privkey.pem;
        # 如果您的SSL证书链中包含中间证书,而这些中间证书不是由广泛接受的根证书颁发机构(Root Certificate Authority)签发的,使用ssl_trusted_certificate来指定中间证书
        ssl_trusted_certificate /etc/nginx/certs/chain.pem;
        ssl_session_timeout 5m;
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        location / {
            proxy_pass http://XXX:8090;
            proxy_set_header HOST $host;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
    server {
        listen 443 ssl;
        server_name www.cytl.ink;

        ssl_certificate /etc/nginx/certs/cert.pem;
        ssl_certificate_key /etc/nginx/certs/privkey.pem;
        # 如果您的SSL证书链中包含中间证书,而这些中间证书不是由广泛接受的根证书颁发机构(Root Certificate Authority)签发的,使用ssl_trusted_certificate来指定中间证书
        ssl_trusted_certificate /etc/nginx/certs/chain.pem;
        ssl_session_timeout 5m;
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;

        location / {
            root /usr/share/nginx/html/blog;
            index index.html index.htm;
            try_files $uri $uri/ /index.html;
        }

        # location ~ ^/redirect/(.*) {
        #     proxy_pass $1;
        #     proxy_set_header Host $host;
        #     proxy_set_header X-Real-IP $remote_addr;
        #     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        # }

        location ^~ /api/ {
            proxy_pass http://XXX:8080/;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

    }

    server {
        listen 443 ssl;
        server_name admin.cytl.ink;

        ssl_certificate /etc/nginx/certs/cert.pem;
        ssl_certificate_key /etc/nginx/certs/privkey.pem;
        # 如果您的SSL证书链中包含中间证书,而这些中间证书不是由广泛接受的根证书颁发机构(Root Certificate Authority)签发的,使用ssl_trusted_certificate来指定中间证书
        ssl_trusted_certificate /etc/nginx/certs/chain.pem;
        ssl_session_timeout 5m;
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;

        location / {
            root /usr/share/nginx/html/admin;
            index index.html index.htm;
            try_files $uri $uri/ /index.html;
        }

        location ^~ /api/ {
            proxy_pass http://XXX:8080/;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

    }

    server {
        listen 443 ssl;
        server_name talk.cytl.ink;

        ssl_certificate /etc/nginx/certs/cert.pem;
        ssl_certificate_key /etc/nginx/certs/privkey.pem;
        # 如果您的SSL证书链中包含中间证书,而这些中间证书不是由广泛接受的根证书颁发机构(Root Certificate Authority)签发的,使用ssl_trusted_certificate来指定中间证书
        ssl_trusted_certificate /etc/nginx/certs/chain.pem;

        location /websocket {
            proxy_pass http://XXX:8080;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "Upgrade";
            proxy_set_header X-Real-IP $remote_addr;
        }

    }


    server {
        listen 443 ssl;

        add_header 'Access-Control-Allow-Origin' 'https://www.cytl.ink';
        add_header 'Access-Control-Allow-Methods' *;
        server_name file.cytl.ink;
        ssl_certificate /etc/nginx/certs/cert.pem;
        ssl_certificate_key /etc/nginx/certs/privkey.pem;
        # 如果您的SSL证书链中包含中间证书,而这些中间证书不是由广泛接受的根证书颁发机构(Root Certificate Authority)签发的,使用ssl_trusted_certificate来指定中间证书
        ssl_trusted_certificate /etc/nginx/certs/chain.pem;
        ssl_session_timeout 5m;
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;

        location / {
            root /usr/local/upload;
        }

    }

    server {
        listen 80;
        server_name www.cytl.ink;
        # 当有HTTP请求到达file.cytl.ink域名时,应该将该请求重定向到相同的URI路径下的HTTPS地址,从而实现了HTTP到HTTPS的重定向。
        rewrite ^(.*)$	https://$host$1	permanent;

    }

    server {
        listen 80;
        server_name admin.cytl.ink;

        rewrite ^(.*)$	https://$host$1	permanent;

    }

    server {
        listen 80;
        server_name file.cytl.ink;

        rewrite ^(.*)$	https://$host$1	permanent;

    }

    server {
        listen 80;
        listen [::]:80;
        server_name cytl.ink;
        rewrite ^(.*)$	https://$host$1	permanent;
    }
}

补充:压缩和限流技巧

Note

摘抄自:Nginx的这些妙用,你肯定有不知道的! | mall学习教程 (macrozheng.com)

如果我们租用了一个带宽很低的服务器,网站访问速度会很慢,这时我们可以通过让nginx开启GZIP压缩来提高网站的访问速度。这里我们以mall的前端项目为例来演示下它的提速效果。

  • 首先我们对nginx进行限速操作,限制每个连接的访问速度为128K来建立一个比较慢的访问场景;

  • 修改nginx.conf配置文件,进行限速操作:

    server {
        listen       80;
        server_name  mall.macrozheng.com;
        
        limit_rate 128k; #限制网速为128K
    
        location / {
            root   /usr/share/nginx/html/mall;
            index  index.html index.htm;
        }
    
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    
    }
    
  • 对mall的前端项目mall.macrozheng.com进行访问,我们可以发现网站中有个js文件比较大,需要加载12s:
    img

  • nginx返回请求头信息如下:
    img

  • 修改/mydata/nginx/conf目录下的nginx.conf配置文件,开启GZIP压缩;

    http {
        gzip on; #开启gzip
        gzip_disable "msie6"; #IE6不使用gzip
        gzip_vary on; #设置为on会在Header里增加 "Vary: Accept-Encoding"
        gzip_proxied any; #代理结果数据的压缩
        gzip_comp_level 6; #gzip压缩比(1~9),越小压缩效果越差,但是越大处理越慢,所以一般取中间值
        gzip_buffers 16 8k; #获取多少内存用于缓存压缩结果
        gzip_http_version 1.1; #识别http协议的版本
        gzip_min_length 1k; #设置允许压缩的页面最小字节数,超过1k的文件会被压缩
        gzip_types application/javascript text/css; #对特定的MIME类型生效,js和css文件会被压缩
    
        include /etc/nginx/conf.d/*.conf;
    }
    
  • 再次对mall的前端项目mall.macrozheng.com进行访问,我们可以发现js文件已经被压缩,加载时间缩短到3.88s,提速3倍左右:
    img

  • nginx返回请求头中添加了Content-Encoding: gzip的信息:
    img