4. Nginx 入门部署:安装、配置结构与静态资源代理
好,咱们进入 Nginx 实战的第一站。说实话,Nginx 这东西,你只要搞过线上服务,早晚得跟它打交道。我最早接触它的时候,还是用来解决 Apache 并发撑不住的问题。那时候 Nginx 刚火起来,配置起来感觉挺别扭——跟 Apache 的 .htaccess 思路完全不一样。但用顺手之后,你会发现它的设计其实非常优雅。
这一节,咱们把 Nginx 从安装到基本配置捋一遍。重点就三个:怎么装、配置长什么样、怎么用 Nginx 代理静态资源。
4.1 安装 Nginx:三种主流方式
安装这事儿,不同环境有不同玩法。我个人习惯在开发机用包管理器,线上机器用编译安装或者 Docker。下面列三种最常见的,你根据场景选。
| 安装方式 | 适用场景 | 命令 / 步骤 |
|---|---|---|
| apt / yum 包管理器 | Ubuntu / CentOS 快速安装 | sudo apt install nginx 或 sudo yum install nginx |
| 源码编译安装 | 需要自定义模块(如 HTTP/2、SSL) | ./configure → make → make install |
| Docker 容器 | 微服务 / 容器化部署 | docker run -d -p 80:80 nginx |
4.2 Nginx 配置结构:http、server、location
Nginx 的配置,说白了就是一棵树。根是 http,下面挂 server,server 下面挂 location。你想想看,这跟咱们写代码的命名空间、类、方法是不是有点像?
咱们先看一个最简配置,感受一下:
http {
include mime.types;
default_type application/octet-stream;
server {
listen 80;
server_name example.com;
location / {
root /var/www/html;
index index.html index.htm;
}
location /api/ {
proxy_pass http://127.0.0.1:8080;
}
}
}
这个结构,我拆开给你讲:
- http 块:全局配置,影响所有虚拟主机。比如超时时间、日志格式、gzip 开关,都放这里。
- server 块:一个虚拟主机。你可以配多个 server,监听不同端口或域名。我记得有一次帮客户排查问题,发现他配了三个 server 块,但 server_name 写重了,结果请求全跑到第一个去了。嗯,这种坑很常见。
- location 块:匹配 URI 路径。它支持前缀匹配、正则匹配、精确匹配。匹配优先级是个容易搞混的点,我后面会专门说。
4.3 location 匹配规则:别在这上面翻车
location 的匹配规则,我见过太多人搞错了。你记住这张表就行:
| 写法 | 匹配类型 | 优先级 | 示例 |
|---|---|---|---|
= /path |
精确匹配 | 最高 | = /login 只匹配 /login |
^~ /path/ |
前缀匹配(不检查正则) | 次高 | ^~ /static/ 匹配 /static/ 开头的所有路径 |
~ pattern |
正则匹配(区分大小写) | 第三 | ~ \.(jpg|png)$ |
~* pattern |
正则匹配(不区分大小写) | 第三 | ~* \.(jpg|png)$ |
/path |
普通前缀匹配 | 最低 | / 匹配所有 |
匹配流程是这样的:先检查精确匹配,有就直接返回。然后看前缀匹配,如果找到 ^~ 的,也直接返回。否则把所有正则匹配跑一遍,命中第一个就停。最后才用普通前缀匹配。
location /images/,又配了一个 location ~ \.(jpg|png)$。我以为前者会优先,结果正则先匹配了,导致 /images/ 下的请求全走了正则,缓存策略全乱了。后来我加了个 ^~ /images/ 才搞定。所以,如果你确定某个路径不需要正则,记得用 ^~ 锁死。
4.4 静态资源代理:最常用的场景
静态资源代理,说白了就是让 Nginx 直接返回文件,不经过后端应用。这能大幅减轻应用服务器的压力。我见过一个项目,图片全走 Tomcat 返回,结果 Tomcat 线程池经常被打满。后来把静态资源切到 Nginx,CPU 占用直接降了 60%。
一个典型的静态资源代理配置长这样:
server {
listen 80;
server_name static.example.com;
# 图片、CSS、JS 等静态资源
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg)$ {
root /data/static;
expires 30d;
add_header Cache-Control "public, immutable";
access_log off;
}
# 字体文件(跨域问题)
location ~* \.(woff|woff2|ttf|eot)$ {
root /data/static;
expires 365d;
add_header Access-Control-Allow-Origin "*";
}
# 其他请求
location / {
root /data/static;
try_files $uri $uri/ /index.html;
}
}
这里面有几个关键点:
- root 指令:指定文件在磁盘上的根目录。注意,它是把 URI 拼到 root 后面去找文件。比如请求
/img/logo.png,实际路径是/data/static/img/logo.png。 - expires:设置浏览器缓存时间。30d 就是 30 天。对于不常变的资源,设长一点,能省很多带宽。
- Cache-Control:
public表示允许中间缓存(比如 CDN)缓存;immutable告诉浏览器,这个文件永远不会变,连条件请求都不用发。 - access_log off:静态资源的访问日志一般关掉,不然日志文件会疯长。我见过一个案例,日志把磁盘写满了,服务直接挂掉。
alias 而不是 root,路径拼接逻辑会不一样。alias 会替换掉 location 匹配的部分。比如 location /static/ { alias /data/files/; },请求 /static/logo.png 实际找的是 /data/files/logo.png。很多人在这上面搞混,我建议你统一用 root,除非你明确知道需要 alias。
4.5 本章知识体系:一张图看懂
下面这张 SVG 图,把 Nginx 配置的核心结构、匹配流程和静态资源代理的要点串起来了。你多看几遍,心里就有谱了。
4.6 验证配置与常见问题
配置写完了,别急着重启。先检查语法:
# 检查配置文件语法
nginx -t
# 如果输出类似下面,说明没问题
# nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
# nginx: configuration file /etc/nginx/nginx.conf test is successful
# 重新加载配置(不中断服务)
nginx -s reload
我见过有人直接 systemctl restart nginx,结果配置有错,服务起不来,线上直接挂了。所以,nginx -t 这个习惯一定要养成。
setsebool -P httpd_can_network_connect 1 解决。