关于 nginx 的一些技术知识
时间:2026-3-29 23:58 作者:独元殇 分类: 开发相关
技术人就得学的杂一点,看似在重视广度,而不是深度,实际上广度也是深度的一部分。君子不器,君子不像器具那样,作用仅仅限于某一方面。博学才能多才。
以前做反向代理,已经有了老牌 Apache 了,但这个 nginx 的出现,是解决【传统服务器在高并发连接下,性能不足问题】的。它的最初优势很明显,就是高并发下,内存占用小。随着不断更迭,它相较于 Apache 已经没有短板了。
配置
安装就不说了,首先是配置。配置文件就一个,一般在这里:
/etc/nginx/nginx.conf
然后它的结果大概是这样:
# Nginx 配置区域
events {
}
http {
upstream backend {
}
server {
location / {
}
}
}
stream {
upstream backend {
}
server {
}
}
其中:
- event 是全局配置区域,比如:“每一个进程最多同时接客 1024 个”
- upstream backend 是代理池区域,比如“你可以打包三个 Java 服务成一个组”
- server 里的 location ,我们用的比较多,是 URI 路由配置区域,也就是根据 URL 的路径(URI)决定去向。
- 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 里,模块通常分为三类:
- 核心模块
- HTTP 模块
- 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 模块比较多。
- ngx_http_core_module(HTTP 核心):如 listen、server_name、root、location
- ngx_http_proxy_module(反向代理):如 proxy_pass、proxy_set_header
- ngx_http_upstream_module(负载均衡):如 upstream、server(组内机器)、keepalive
- ngx_http_rewrite_module(路由重写):如 rewrite、return、if
- ngx_http_ssl_module(SSL 加密):如 ssl_certificate、ssl_session_timeout
- ngx_http_index_module(默认首页):如 index
- ngx_http_log_module(访问日志):如 access_log、log_format
- ngx_http_auth_basic_module(身份认证):如 auth_basic、auth_basic_user_file
- ngx_http_access_module(IP 访问控制):如 allow、deny
- ngx_http_geoip_module(地理位置):如 geoip_country、geoip_city
- ngx_http_limit_conn_module(并发限制):如 limit_conn、limit_conn_zone
- ngx_http_limit_req_module(请求速率限制):如 limit_req、limit_req_zone
- ngx_http_stub_status_module(状态统计):如 stub_status
- ngx_http_autoindex_module(目录列表):如 autoindex
- 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 四层的流量代理转发功能。