«

关于 nginx 的一些技术知识

时间:2026-3-29 23:58     作者:独元殇     分类: 开发相关


欢迎关注我的公众号,名叫「串串狗小刊」

技术人就得学的杂一点,看似在重视广度,而不是深度,实际上广度也是深度的一部分。君子不器,君子不像器具那样,作用仅仅限于某一方面。博学才能多才。

以前做反向代理,已经有了老牌 Apache 了,但这个 nginx 的出现,是解决【传统服务器在高并发连接下,性能不足问题】的。它的最初优势很明显,就是高并发下,内存占用小。随着不断更迭,它相较于 Apache 已经没有短板了。

配置

安装就不说了,首先是配置。配置文件就一个,一般在这里:

/etc/nginx/nginx.conf

然后它的结果大概是这样:

# Nginx 配置区域

events {
}

http {
    upstream backend {
    }
    server {
        location / {
        }
    }
}

stream {
    upstream backend {
    }
    server {
    }
}

其中:

  1. event 是全局配置区域,比如:“每一个进程最多同时接客 1024 个”
  2. upstream backend 是代理池区域,比如“你可以打包三个 Java 服务成一个组”
  3. server 里的 location ,我们用的比较多,是 URI 路由配置区域,也就是根据 URL 的路径(URI)决定去向。
  4. stream 是 流代理全局配置,是处理 TCP/UDP 协议的,比如你外网想访问内网的 MySQL(3306 端口)或 Redis,就在这里配置转发。

常用命令

一般有这几个:

nginx -s stop       关闭 Nginx
nginx -s quit       平稳关闭 Nginx (推荐,会等当前任务结束再关闭)
nginx -s reopen     重新打开日志文件。
nginx -c filename   为 Nginx 指定一个配置文件,来代替默认的。
nginx -s reload     改配置后,重新加载
nginx -t            仅仅测试配置文件。
nginx -T            仅将 Nginx 启动时所加载的所有配置、模块等信息全部显示出来。
nginx -V            显示 nginx 的版本等

然后是使用。

模块

其实,nginx 的本体是很小的,功能全靠一大堆插件来运行!

这是很精妙的设计。我一直认为 模块化 是万能的,比设计严肃严格的赘余的类型更能支撑起大软件。

在 nginx 里,模块通常分为三类:

  1. 核心模块
  2. HTTP 模块
  3. Stream 模块

其中核心模块一般就一个,就是上面我们的配置区域。

额 stream 有两个。

stream,是 ngx_stream_core_module 模块,提供 TCP/UDP 流量代理服务最基本的功能。

proxy_pass ,是 ngx_stream_proxy_module 模块,为 Stream 服务提供反向代理的功能。

比如:

stream {
    upstream mysql_cluster {
        server 192.168.1.10:3306;
        server 192.168.1.11:3306;
    }

    server {
        listen 3306; # 监听服务器的 3306
        proxy_pass mysql_cluster; # 直接转发 TCP 流
    }
}

这就是一个流量的搬运工了,这里的 3306 是数据库的常用端口,以数据库举例,其他服务也一样。

你内网有两个数据库(一般来说是实时同步的),然后你接受到客户端的请求后,分发给这些数据库,如果 192.168.1.10:3306 宕机了,你可以直接转给 192.168.1.11:3306 。好处就是,你的数据库是公网不公开的,是私密的,而且能防止宕机。

HTTP 模块

而 HTTP 模块比较多。

  1. ngx_http_core_module(HTTP 核心):如 listen、server_name、root、location
  2. ngx_http_proxy_module(反向代理):如 proxy_pass、proxy_set_header
  3. ngx_http_upstream_module(负载均衡):如 upstream、server(组内机器)、keepalive
  4. ngx_http_rewrite_module(路由重写):如 rewrite、return、if
  5. ngx_http_ssl_module(SSL 加密):如 ssl_certificate、ssl_session_timeout
  6. ngx_http_index_module(默认首页):如 index
  7. ngx_http_log_module(访问日志):如 access_log、log_format
  8. ngx_http_auth_basic_module(身份认证):如 auth_basic、auth_basic_user_file
  9. ngx_http_access_module(IP 访问控制):如 allow、deny
  10. ngx_http_geoip_module(地理位置):如 geoip_country、geoip_city
  11. ngx_http_limit_conn_module(并发限制):如 limit_conn、limit_conn_zone
  12. ngx_http_limit_req_module(请求速率限制):如 limit_req、limit_req_zone
  13. ngx_http_stub_status_module(状态统计):如 stub_status
  14. ngx_http_autoindex_module(目录列表):如 autoindex
  15. ngx_http_fastcgi_module(PHP 等脚本支持):如 fastcgi_pass、fastcgi_index

HTTP 模块举例

我们用 nginx ,一般是负载网站比较多。

① 路由匹配

http {
    server {
        listen 80;
        server_name  www.test.com;
        location / {
            root /var/www/html;
            index index.html;
        }
        location /test2 {
            root /var/www/html2;
            index index.html;
        }
    }
}

一个经典的路由匹配。

如果用户访问 www.test .com ,那么就加载 /var/www/html/index.html

如果用户访问 www.test .com/test2 ,那么就加载 /var/www/html2/index.html

② 不同域名,不同端口的路由分发

http {
    server {
    listen 80;
        server_name  www.test.com;
        location / {
            root /var/www/html;
            index index.html;
        }
    }
    server {
        listen 8080;
        server_name  www.test2.com;
        location / {
            root /var/www/html2;
            index index.html;
        }
    }
}

如果用户访问 www.test .com ,那么就加载 /var/www/html/index.html

如果用户访问 www.test2 .com:8080 ,那么就加载 /var/www/html2/index.html

③ HTTPS (SSL)

http {
    #......
    server {
    listen 443 ssl;
        server_name  www.test.com;
        ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
        ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
        location / {
            root /var/www/html;
            index index.html;
        }
    }
    server {
        listen 80;
        server_name .test.com; 
        location / {
            return 301 https://www.test.com$request_uri;
        }
    }
}

证书通过 make-ssl-snake 命令去制作会更方便(本地实验)。生产环境使用 Certbot (Let's Encrypt) 自动续期。

这其实是一个重定向。ssl 的端口是 443。

也就是说,加上 https:// ,其实就是访问 443 端口,而不是 80 。

如果用户访问 http://www.test .com:80 ,那么就强制重定向到 https://www.test .com:443 (当然,是 443 拿着证书解密后的数据)

③ 文件服务器(一般用在内网)

http {
    autoindex on;# 显示目录
    autoindex_exact_size on;# 显示文件大小
    autoindex_localtime on;# 显示文件时间

    server {
        listen 80;
        root /var/www;
    }
}

④ 反向代理(很常用)

http {
    server {
    listen 80;
        server_name  www.test.com;
        location / {
            proxy_set_header Host $host;
            proxy_pass http://www.test2.com;
        }
    }
}

可以实现这样的效果:用户以为在访问 test.com,其实 Nginx 偷偷去请求 test2.com 拿回内容,用户全程蒙在鼓里。

⑤ 负载均衡(客流量大的互联网公司比较常用)

http {
    upstream load_balance_server {
    server 192.168.1.11:80   weight=1;
    server 192.168.1.12:80   weight=2;
    server 192.168.1.13:80   weight=3;
}
    server {
    listen 80;
        server_name  www.test.com;
        location / {
            proxy_pass http://load_balance_server;
        }
    }
}

weigth参数表示权值,权值越高被分配到的几率越大。

客户访问 http://www.test .com 然后服务器,按照 11、12、13 号服务器按 1:2:3 的比例分摊流量。

⑥ SSH 代理转发

stream {
    upstream tcp_proxy {
        hash $remote_addr consistent;  # 远程地址做个hash
        server 1.1.1.1:22;
    }
    server {
        listen 2222;
        proxy_pass tcp_proxy;
    }
}

客户访问这个服务器的 2222 端口,然后 服务器 为客户做个 hash 标注,之后客户只要你的上网 IP 不变,Nginx 永远把你甩给同一台机器。这在管理多台服务器、防止 SSH 认证频繁失效时非常有用。

注意,22 端口是 SSH 端口,用 2222 做中转,提升了安全性。

Nginx 的 Stream 功能平时用的较少,但他实际上和 HAProxy 的功能类似,都是为了实现 TCP/UDP 四层的流量代理转发功能。

标签: 原创 nginx