• [技术干货] 12月技术干货合集
    12月技术干货合集分享:1、MySQL实现双机双向热备份的详细教程—转载cid:link_62、MySQL参数innodb_force_recovery详解—转载cid:link_73、Mysql中RelayLog中继日志的使用—转载cid:link_84、MySql 预处理(Preprocessor)的使用小结—转载cid:link_95、 MySQL错误1005(errno: 150)的原因分析与解决方案—转载cid:link_06、MySQL慢查询优化从30秒到300毫秒的完整过程—转载cid:link_17、MySQL回滚binlog日志的实现示例—转载cid:link_28、MySql 游标和触发器概念及使用详解—转载cid:link_109、 nginx+lua+redis实现限流的示例代码—转载cid:link_310、Nginx 访问控制的多种方法—转载cid:link_411、Nginx服务器部署详细代码实例—转载cid:link_1112、nginx跨域访问配置的几种方法实现—转载cid:link_513、在服务器上获取Linux目录大小的三种实用方法—转载cid:link_1214、 Linux中实现文件复制与迁移的命令详解—转载https://bbs.huaweicloud.com/forum/thread-0235200649718185081-1-1.html
  • [技术干货] nginx+lua+redis实现限流的示例代码—转载
    概述nginx、lua访问redis的三种方式HttpRedis模块指令少,功能单一,适合简单缓存。只支持get,select命令。HttpRedis2Module模块功能强大,比较灵活lua-resty-redis库OpenResty提供的API。适合复杂业务,节省内存。以上3个模块OpenResty都有集成OpenResty: 基于nginx开源版本的一个扩展版本。集成了大量的精良的lua库。所以接下来我们就使用OpenResty来实现相应的功能OpenResty的安装12345678# 安装wget 如果没有的话yum install wget# 下载资源库 这样yum就可以直接安装了# 得到 openresty.repocd /etc/yum.repos.d/wget https://openresty.org/package/centos/openresty.repo# 安装openresty 安装目录:/usr/local/openrestyyum install openresty编写nginx配置12cd /usr/local/openresty/nginx/confvim nginx-lua.confopenresty 提供了几种方式来配置lua脚本需要先了解一下content_by_lua 'ngx.say("hello my openrestry")' : 可以直接在配置文件中写入单行的lua脚本的字符串。content_by_lua_block :可以在nginx配置文件中配置 多行的 lua脚本代码块1234content_by_lua_block {    ngx.say("hello");    ngx.say("block");}content_by_lua_file /usr/local/openresty/nginx/lua/lua-test.lua: 可以配置lua脚本的文件路径log_by_lua_file /usr/local/openresty/nginx/lua/lua-log-test.lua : 可以配置lua脚本的日志文件12345678910111213141516171819202122# nginx-lua.confworker_processes 1;error_log logs/error.log debug;events {    worker_connections 1024;} http {    include mime.types;    default_type application/octet-stream;    sendfile on;    # 连接的超时时间    keepalive_timeout 65;    server {        listen 8080;        location / {            default_type text/html;            # 此处可以写lua脚本的文件路径            content_by_lua_file /usr/local/openresty/nginx/lua/ip_limit_log.lua;        }    }}12-- ip_limit_access.luangx.say("ip limit lua");先编写一个简单的脚本测试 看看是否配置成功。重启nginx并加载指定配置123456789# 查看nginx是否启动ps -ef | grep nginx# 停止nginx/usr/local/openresty/nginx/sbin/nginx -s stop# 启动nginx  -p指定工作目录  -c 指定配置文件/usr/local/openresty/nginx/sbin/nginx -p /usr/local/openresty/nginx/ -c /usr/local/openresty/nginx/conf/nginx-lua.conf# 使用curl访问地址 测试成功[root@localhost nginx]# curl http://localhostip limit luanginx_lua_redis限流通过以上测试,nginx配置lua脚本已经通过接下来就可以开始实现限流功能了。编写nginx配置编写配置ngin-ip-limit.conf12345678910111213141516171819202122# ngin-ip-limit.confworker_processes 1;error_log logs/error.log debug;events {    worker_connections 1024;}http {    include mime.types;    default_type application/octet-stream;    server {        listen 80;        localtion / {            default_type text/html;            # 配置lua脚本文件路径            access_by_lua_file /usr/local/openresty/nginx/lua/ip_limit_access.lua;            # 配置lua日志脚本路径            log_by_lua_file /usr/local/openresty/nginx/lua/ip_limit_log.lua;            # 需要准备一个被代理的服务            proxy_pass http://localhost:8080/;        }    }}编写lua日志脚本123-- ip_limit_log.lualocal ip = ngx.var.remote_addr;ngx.log(ngx.INFO, "request ip is:"..ip);编写lua限流脚本需求:系统每秒限流2个请求,如果超过阈值(每秒2个请求),则系统限制10秒内,不能被访问123456789101112131415161718192021222324-- ip_limit_access.luangx.log(ngx.INFO, "ip limit log"); local redis = require "resty.redis";local red = redis:new(); -- 连接redisred:connect("127.0.0.1",6379); -- 判断是否限流limit = red:get("limit");if limit == '1' then  return ngx.exit(503);end-- 次数加1inc = red:incr("testLimit");if inc <= 2 then  -- 设置过期时间 1秒  red:expire("testLimit",1);else  -- 超过阈值 limit设置成1 并设置过期时间10秒  red:set("limit",1);  red:expire("limit", 10);end 测试当快速方法时会报503错误。10秒后恢复正常访问。
  • [技术干货] Nginx 访问控制的多种方法—转载
    一、IP 白名单与黑名单1. 允许/拒绝指定IP12345location /admin/ {    allow 192.168.1.100;   # 仅允许该IP访问    allow 10.0.0.0/24;     # 或允许整个网段    deny all;              # 其他全部拒绝}2. 全局黑名单12345678910111213http {    geo $block_ip {        default 0;        1.2.3.4 1;        5.6.7.0/24 1;    }    server {        if ($block_ip) {            return 403;        }        ...    }}geo模块适合大规模黑名单。二、基于路径、方法、参数的访问控制1. 路径限制123location /private/ {    deny all;}2. 方法限制12345location /api/ {    if ($request_method !~ ^(GET|POST)$) {        return 405;    }}3. 参数限制12345location /api/ {    if ($arg_token = "") {        return 403;    }}三、HTTP 基本认证(Basic Auth)1. 启用账号密码访问控制1234location /secure/ {    auth_basic "Restricted";    auth_basic_user_file /etc/nginx/.htpasswd;}.htpasswd 文件可用 htpasswd 工具生成。四、Referer/UA 防盗链与防刷1. 防盗链(Referer控制)123456location /static/ {    valid_referers none blocked *.example.com;    if ($invalid_referer) {        return 403;    }}2. 防刷(UA控制)123if ($http_user_agent ~* "curl|bot|spider") {    return 403;}五、客户端证书校验(mTLS)12345678server {    listen 443 ssl;    ssl_certificate /etc/nginx/ssl/server.crt;    ssl_certificate_key /etc/nginx/ssl/server.key;    ssl_client_certificate /etc/nginx/ssl/ca.crt;    ssl_verify_client on;    ...}适用于金融、政企等高安全场景。六、限速限流(流量控制)1. 单IP限速1234limit_req_zone $binary_remote_addr zone=req_limit:10m rate=5r/s;location /api/ {    limit_req zone=req_limit burst=10 nodelay;}2. 连接数限制12limit_conn_zone $binary_remote_addr zone=conn_limit:10m;limit_conn conn_limit 10;七、地理位置访问控制(GeoIP)需安装第三方模块(如 ngx_http_geoip_module),可按国家/地区控制访问:12345678910geoip_country /usr/share/GeoIP/GeoIP.dat;map $geoip_country_code $allowed_country {    default 0;    CN 1; # 仅允许中国}server {    if ($allowed_country = 0) {        return 403;    }}八、API 安全与精细控制1. 精细化路径/参数/方法控制123456789location /api/admin/ {    allow 127.0.0.1;    deny all;}location ~* /api/(delete|update)/ {    if ($request_method != "POST") {        return 405;    }}2. 配合 OpenResty/Lua 动态访问控制可以根据业务逻辑、数据库、Redis等动态判断是否允许访问。九、企业级访问控制建议重要接口建议多重保护(IP+密码+限流+Referer)敏感路径建议只对内网或特定用户开放日志记录所有被拒绝的访问,便于审计和溯源定期更新黑名单、白名单,防止失效结合 WAF、API 网关、堡垒机等安全产品提升防护等级十、访问控制常见问题排查控制未生效?检查 location 优先级、正则匹配顺序。误封正常用户?检查 IP/Referer/UA 规则,避免误伤。限流后接口不可用?合理设置 burst,允许偶发高峰。黑名单太大影响性能?用 geo、map 或 Lua 动态判断,避免配置膨胀。十一、完整访问控制配置示例1234567891011121314151617181920212223242526272829303132http {    geo $block_ip {        default 0;        1.2.3.4 1;        5.6.7.0/24 1;    }    limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;    server {        listen 80;        server_name www.example.com;          if ($block_ip) { return 403; }          location /admin/ {            allow 192.168.1.100;            deny all;            auth_basic "Admin";            auth_basic_user_file /etc/nginx/.htpasswd;        }          location /static/ {            valid_referers none blocked *.example.com;            if ($invalid_referer) { return 403; }        }          location /api/ {            limit_req zone=req_limit burst=20 nodelay;            if ($request_method !~ ^(GET|POST)$) { return 405; }            if ($arg_token = "") { return 403; }        }    }}十二、多级访问控制策略1. 服务全局、Server级、Location级控制http块:全局黑名单/限流/Geoserver块:站点级白名单/认证location块:路径级精细控制示例:1234567891011121314http {    geo $block_ip { ... }    limit_req_zone $binary_remote_addr zone=req_limit:10m rate=20r/s;    server {        if ($block_ip) { return 403; }        location /admin/ {            allow 10.0.0.0/8;            deny all;        }        location /api/ {            limit_req zone=req_limit burst=10 nodelay;        }    }}建议高优先级规则(如黑名单)放在上层,局部规则覆盖全局。十三、基于Header的访问限制1. 按Header内容限制访问常用于API签名、Token、特定应用接入。12345location /api/secure/ {    if ($http_x_token != "your-secret-token") {        return 403;    }}2. 按Referer、Origin防止CSRF123if ($http_origin !~* ^https://trusted\.example\.com$) {    return 403;}十四、按时间段控制访问适用于限时活动、夜间维护、灰度发布等。123456789map $time_iso8601 $block_time {    default 0;    ~T02:..:.. 1;  # 02点整点到02:59:59 拒绝}server {    if ($block_time) {        return 403;    }}也可用 Lua/定时脚本实现更复杂的时间控制。十五、灰度/AB测试的访问控制1. 按用户ID、Cookie、IP分流123456789map $cookie_abtest $upstream_group {    default "old";    "A" "new";}server {    location / {        proxy_pass http://$upstream_group;    }}可结合 Lua 实现更灵活的灰度策略。十六、动态黑白名单(与外部系统结合)1. 结合 Redis/MySQL 实现动态名单用 OpenResty/Lua 读取 Redis/MySQL,将名单实时更新到共享内存,支持热更新。适合大规模名单、频繁变更场景。示例:123456789access_by_lua_block {    local redis = require "resty.redis"    local red = redis:new()    red:connect("127.0.0.1", 6379)    local is_blocked = red:get("ip:" .. ngx.var.remote_addr)    if is_blocked == "1" then        ngx.exit(403)    end}十七、日志、告警与审计1. 记录被拒绝访问的请求12log_format rejectlog '$remote_addr $request $status $http_user_agent $time_local';access_log /var/log/nginx/reject.log rejectlog if=$access_denied;$access_denied 可用 map/Lua 动态赋值。2. 集成告警结合 ELK、Prometheus、Zabbix,监控 403/405 等异常请求,自动触发告警。十八、自动化管理与集中策略1. 配置集中管理采用 include 引入统一黑白名单、认证配置,便于多站点维护。12include /etc/nginx/whitelist.conf;include /etc/nginx/blacklist.conf;2. 自动化工具配合 Ansible/SaltStack/Puppet 实现名单、限流、认证等策略的自动分发和热更新。十九、与WAF/堡垒机/认证系统集成1. WAF防护可用 Nginx+OpenResty/Lua-resty-waf 或接入云WAF,实现SQL注入、XSS等攻击防护。2. 堡垒机/认证系统重要接口后端部署堡垒机或认证代理,前端Nginx只允许堡垒机IP访问。3. 第三方认证(OAuth2、JWT等)可用 Lua 动态解析JWT、OAuth2 Token,按业务规则控制访问。二十、常见安全场景实战1. 管理后台只允许公司IP+二次认证123456location /admin/ {    allow 10.0.0.0/8;    deny all;    auth_basic "Admin Only";    auth_basic_user_file /etc/nginx/.htpasswd;}2. API接口防刷+签名校验12345limit_req_zone $binary_remote_addr zone=api_limit:10m rate=5r/s;location /api/ {    limit_req zone=api_limit burst=20 nodelay;    if ($http_x_sign = "") { return 403; }}3. 静态资源防盗链+限速12345location /static/ {    valid_referers none blocked *.example.com;    if ($invalid_referer) { return 403; }    limit_rate 100k;}二十一、访问控制优化建议分层分级设计,重要资源多重防护动态名单、限流、认证与自动化结合,提升响应和运维效率日志与监控全覆盖,异常及时告警定期安全审计和回溯,防止策略失效或被绕过
  • [技术干货] Nginx服务器部署详细代码实例—转载
    Nginx 服务器Nginx是一个‌高性能、高并发、轻量级‌的开源 ‌Web 服务器‌软件;Nginx 高性能和高并发的核心就在于其‌事件驱动和‌异步非阻塞I/O模型;Nginx 通信可分为4个阶段:主进程启动:启动 Nginx 时,首先运行的是‌主进程;主要负责读取并验证配置文件,‌创建和管理子进程‌,绑定端口等;主进程本身不处理客户端连接或请求;创建工作进程:主进程会创建一或多个‌工作进程‌,工作进程的数量通常会根据 CPU 核心数自动设置;工作进程是真正处理客户端连接和请求的实体;所有工作进程独立且平等,都运行在‌单线程‌中;工作进程的核心是使用一个‌事件驱动循环;事件驱动循环:每个工作进程内部都有一个持续的循环,称为事件循环;该模型允许一个‌单线程的工作进程同时管理数万个并发连接;连接处理:当Nginx监听的端口出现新TCP请求时,主进程本身监听了这些端口,但它‌不会‌处理连接;内核会将这个新建立的连接‌交给其中一个工作进程,该工作进程开始在这个连接上处理 HTTP 请求/响应或其他协议;Nginx 使用‌共享内存区域‌来实现工作进程间的数据共享,主进程负责创建这些共享内存区域;12345678[root@server ~]# yum -y install nginx | tail -n 1Complete![root@server ~]# systemctl enable nginx --nowCreated symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service.[root@server ~]# firewall-cmd --add-service=http --permanentsuccess[root@server ~]# firewall-cmd --reloadsuccess在浏览器地址栏输入Nginx服务器的IP地址或域名,如http://10.1.8.10;浏览器会发送HTTP请求到Nginx,Nginx处理请求并返回HTML内容;默认返回/usr/share/nginx/html/index.html使用该方法连接Nginx需配置监听80端口(HTTP)或443端口(HTTPS);Nginx的主配置文件为/etc/nginx/nginx.conf;/etc/nginx/目录下包含了所有nginx的配置文件;/etc/nginx/nginx.conf包含全局配置域、网络连接配置域和HTTP配置域;其中HTTP配置域内的server块是虚拟主机配置;123456789101112131415161718192021222324252627282930313233343536373839404142434445464748# 全局配置域user nginx;worker_processes auto;error_log /var/log/nginx/error.log;pid /run/nginx.pid;# 网络连接配置域events {    worker_connections 1024;}# HTTP配置域http {    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            on;    tcp_nopush          on;    tcp_nodelay         on;    keepalive_timeout   65;    types_hash_max_size 4096;     include             /etc/nginx/mime.types;    default_type        application/octet-stream;    # 虚拟主机配置    server {        listen       80;        listen       [::]:80;        server_name  www.gc.cloud;        root         /usr/share/nginx/html;         # Load configuration files for the default server block.        include /etc/nginx/default.d/*.conf;         error_page 404 /404.html;        location = /404.html {        }         error_page 500 502 503 504 /50x.html;        location = /50x.html {        }    } # 测试配置文件[root@server ~]# nginx -tnginx: the configuration file /etc/nginx/nginx.conf syntax is oknginx: configuration file /etc/nginx/nginx.conf test is successfulserver块中主要参数作用如下:listen 80;:监听80端口;下方的 listen [::]:80; 是监听IPv6端口;server_name:域名;root:网站根目录;index:默认首页文件;location:location块;决定了‌如何处理不同的客户端请求路径‌;1234# location块语法location [匹配模式] [匹配路径] {    [配置指令]}location包含5种路径匹配模式:location = /path:精确匹配;location ^~ /path:前缀匹配(优先于正则);location ~ .php$:正则匹配(区分大小写);location ~* .(jpg|png)$:正则匹配(不区分大小写);location /:通用匹配;location块内常用指令作用root设置文件根目录alias路径别名try_files尝试多个文件路径proxy_pass反向代理到后端index设置默认索引文件rewriteURL 重写add_header添加 HTTP 响应头deny / allow访问控制SSL/TLS 配置SSL/TLS是加密通信的安全协议,在客户端和服务器之间建立‌加密通道;证书是服务器的数字身份证‌;Nginx是SSL/TLS的‌执行者;证书生成流程如下:12345678910[root@server ~]# openssl genrsa -out www.key 2048Generating RSA private key, 2048 bit long modulus....+++....+++e is 65537 (0x10001)[root@server ~]# openssl req -new -key www.key -out www.csr -subj "/C=CN/ST=JS/L=NJ/O=LM/OU=DEVOPS/CN=www.gc.cloud/emailAddress=gc@gc.cloud"[root@server ~]# openssl x509 -req -days 3650 -in www.csr -signkey www.key -out www.crtSignature oksubject=/C=CN/ST=JS/L=NJ/O=LM/OU=DEVOPS/CN=www.gc.cloud/emailAddress=gc@gc.cloudGetting Private keyopenssl genrsa -out www.key 2048‌生成一个2048位的RSA私钥文件(www.key),用于SSL/TLS加密通信的基础密钥;openssl req -new -key www.key -out www.csr -subj "/C=CN/ST=JS/L=NJ/O=LM/OU=DEVOPS/CN=www.gc.cloud/emailAddress=gc@gc.cloud"‌用于创建证书签名请求文件(www.csr);subj参数定义了证书主体信息,其中CN参数必须与域名一致;openssl x509 -req -days 3650 -in www.csr -signkey www.key -out www.crt使用私钥(www.key)对CSR签名,生成有效期为3650天的自签名证书;站点配置文件一般需要独立创建,以便于管理;一般位于/etc/nginx/sites-available/目录下;首先配置证书相关参数:ssl_certificate:证书路径;ssl_certificate_key:私钥路径;之后还需在站点配置文件中配置启用HTTP重定向到HTTPS:12345678910111213141516server {    listen       443 ssl http2;    listen       [::]:443 ssl http2;    server_name  www.gc.cloud;    root         /usr/share/nginx/html;     ssl_certificate /www.crt;    ssl_certificate_key /www.key;} server {    listen       80;    server_name  www.gc.cloud;    root         /usr/share/nginx/html;    return 301 https://$host$request_uri; # 重定向到HTTPS}443是HTTPS的默认端口,专门用于加密数据传输,而80端口用于明文HTTP;ssl参数用于启用SSL/TLS加密模块,使Nginx能处理加密请求;若省略ssl,即使监听443端口,Nginx也‌不会启用加密‌;配置完成后重启服务即可;动态脚本Nginx本身只能处理‌静态资源‌(HTML/CSS/图片),而PHP能给Nginx带来‌动态内容处理能力;PHP是为Web而生的服务器端脚本语言;通过与Nginx进行协同工作,能让静态网站变成可交互的智能应用;12345# 安装php与其扩展包[root@server ~]# yum install -y php php-fpm | tail -n 1Complete![root@server ~]# yum install -y php-gd php-common php-pear php-mbstring php-mcrypt | tail -n 1Complete!之后在站点配置文件中配置支持php;1234567location ~ \.php$ {        try_files $uri =404;        fastcgi_pass unix:/run/php/php8.1-fpm.sock;        fastcgi_index index.php;        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;        include fastcgi_params;    }fastcgi_pass:指定PHP-FPM监听的地址和端口;上述写法适用于同一服务器环境,也可使用fastcgi_pass 127.0.0.1:9000; 配置支持跨服务器部署,但需保证在php-fpm.conf配置PHP-FPM监听该端口;try_files:按顺序检查文件/目录;当访问的文件不存在时返回配置的文件地址,通常和fastcgi_index协同工作;fastcgi_index:指定默认的PHP入口文件;‌优先级低于try_files;fastcgi_param SCRIPT_FILENAME:指定PHP脚本的完整路径;$document_root为网站根目录,$fastcgi_script_name为请求的PHP文件路径;include fastcgi_params:包含预定义的FastCGI参数;配置完成后就可以使用了;反向代理反向代理用于隐藏真实服务器;它接收用户请求,再转交给后端真实服务器,使用户不直接和真实服务器进行交互;Nginx可以在站点配置文件中配置实现反向代理;1234567location / {        proxy_pass http://localhost:3000;        proxy_set_header Host $host;        proxy_set_header X-Real-IP $remote_addr;        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;        proxy_set_header X-Forwarded-Proto $scheme;    }通过语法检查并重启服务‌后就可以使用了;
  • [技术干货] nginx跨域访问配置的几种方法实现—转载
    一、基本跨域配置在 nginx 的 location 块中添加以下内容:12345678910111213141516location /api/ {    add_header 'Access-Control-Allow-Origin' '*' always;    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;    add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept, Authorization' always;      # 处理预检请求(OPTIONS)    if ($request_method = 'OPTIONS') {        add_header 'Access-Control-Max-Age' 1728000;        add_header 'Content-Type' 'text/plain charset=UTF-8';        add_header 'Content-Length' 0;        return 204;    }      # 其他反向代理/静态资源配置...    proxy_pass http://backend-server;}说明:Access-Control-Allow-Origin:允许哪些域访问,* 表示所有域。Access-Control-Allow-Methods:允许的 HTTP 方法。Access-Control-Allow-Headers:允许的请求头。OPTIONS 方法用于处理 CORS 预检请求,返回 204 No Content。二、只允许指定域名跨域如果只允许某个域(如 https://www.example.com)跨域:1add_header 'Access-Control-Allow-Origin' 'https://www.example.com' always;三、完整示例假设你有一个前端(端口 8080)和后端(端口 8000),nginx 代理 /api/ 到后端:123456789101112131415161718server {    listen 80;    server_name your.domain.com;      location /api/ {        proxy_pass http://127.0.0.1:8000;        add_header 'Access-Control-Allow-Origin' '*' always;        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;        add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept, Authorization' always;          if ($request_method = 'OPTIONS') {            add_header 'Access-Control-Max-Age' 1728000;            add_header 'Content-Type' 'text/plain charset=UTF-8';            add_header 'Content-Length' 0;            return 204;        }    }}四、配置后重载 nginx每次修改配置后,记得重载 nginx:1nginx -s reload五、注意事项如果后端也设置了 CORS,可能会有冲突,建议只在一个地方设置。如果需要携带 cookie,Access-Control-Allow-Origin 不能为 *,必须指定具体域名,并加上 Access-Control-Allow-Credentials: true。六、支持携带 Cookie 的跨域配置如果你需要前端跨域请求时携带 cookie(如登录态),CORS 需要特殊配置:Access-Control-Allow-Origin 不能为 *,必须指定具体的域名。需要加上 Access-Control-Allow-Credentials: true。示例:123456789101112131415location /api/ {    proxy_pass http://127.0.0.1:8000;      add_header 'Access-Control-Allow-Origin' 'https://www.example.com' always;    add_header 'Access-Control-Allow-Credentials' 'true' always;    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;    add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept, Authorization' always;      if ($request_method = 'OPTIONS') {        add_header 'Access-Control-Max-Age' 1728000;        add_header 'Content-Type' 'text/plain charset=UTF-8';        add_header 'Content-Length' 0;        return 204;    }}前端请求时需要设置:1234fetch('https://api.example.com/api/', {  credentials: 'include', // 允许携带 cookie  // 其他参数})七、根据请求头动态设置允许的 Origin有时你希望根据请求头 Origin 动态设置允许的域名,可以用 nginx 的变量:12345678910111213141516171819location /api/ {    proxy_pass http://127.0.0.1:8000;      if ($http_origin ~* "^https://(www\.example\.com|other\.domain\.com)$") {        add_header 'Access-Control-Allow-Origin' "$http_origin" always;        add_header 'Access-Control-Allow-Credentials' 'true' always;    }      add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;    add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept, Authorization' always;      # 处理预检请求    if ($request_method = 'OPTIONS') {        add_header 'Access-Control-Max-Age' 1728000;        add_header 'Content-Type' 'text/plain charset=UTF-8';        add_header 'Content-Length' 0;        return 204;    }}八、常见问题排查add_header 不生效?确认 always 关键字已加上。确认没有被其他配置覆盖。确认 location 块没有被其他 server/location 块覆盖。OPTIONS 请求未返回 204?检查 if 语句是否正确。检查是否被后端拦截。前端报错:CORS header ‘Access-Control-Allow-Origin’ missing?检查响应头是否包含该字段。用浏览器开发者工具 Network 检查响应头。携带 cookie 时跨域失败?确认 Access-Control-Allow-Origin 不是 *,而是具体域名。确认 Access-Control-Allow-Credentials: true 已设置。前端 fetch/axios 需配置 credentials。九、nginx 跨域配置模板(推荐)可以将以下内容作为通用模板:12345678910111213141516171819202122232425location /api/ {    proxy_pass http://backend-server;      # 支持跨域    set $cors '';    if ($http_origin ~* '^https://(www\.example\.com|other\.domain\.com)$') {        set $cors 'true';    }      if ($cors = 'true') {        add_header 'Access-Control-Allow-Origin' "$http_origin" always;        add_header 'Access-Control-Allow-Credentials' 'true' always;    }      add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;    add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept, Authorization' always;      # 预检处理    if ($request_method = 'OPTIONS') {        add_header 'Access-Control-Max-Age' 1728000;        add_header 'Content-Type' 'text/plain charset=UTF-8';        add_header 'Content-Length' 0;        return 204;    }}十、针对不同路径/接口做跨域控制有时你只希望对部分接口(如 /api/)开放跨域,对其他接口(如 /admin/)不开放,可以这样配置:12345678910111213141516171819202122232425server {    listen 80;    server_name your.domain.com;      # 只对 /api/ 开放跨域    location /api/ {        proxy_pass http://backend-api;        add_header 'Access-Control-Allow-Origin' '*' always;        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;        add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept, Authorization' always;          if ($request_method = 'OPTIONS') {            add_header 'Access-Control-Max-Age' 1728000;            add_header 'Content-Type' 'text/plain charset=UTF-8';            add_header 'Content-Length' 0;            return 204;        }    }      # /admin/ 不开放跨域    location /admin/ {        proxy_pass http://backend-admin;        # 不添加跨域相关 header    }}十一、静态资源跨域(如图片、字体、JS/CSS)如果你希望静态资源(如图片、字体文件等)可以被其他域引用,需为静态资源 location 添加 CORS 响应头:123456location /static/ {    root /var/www/html;    add_header 'Access-Control-Allow-Origin' '*' always;    add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS' always;    add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept' always;}注意:如果你希望字体文件可被第三方引用,必须加上 Access-Control-Allow-Origin,否则会有跨域问题。十二、根据请求方法细分 CORS 策略有时你希望 GET/POST/PUT/DELETE 允许跨域,而 PATCH 不允许,可以这样写:12345678910111213141516location /api/ {    proxy_pass http://backend-server;      if ($request_method ~* "GET|POST|PUT|DELETE|OPTIONS") {        add_header 'Access-Control-Allow-Origin' '*' always;        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;        add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept, Authorization' always;    }      if ($request_method = 'OPTIONS') {        add_header 'Access-Control-Max-Age' 1728000;        add_header 'Content-Type' 'text/plain charset=UTF-8';        add_header 'Content-Length' 0;        return 204;    }}十三、反向代理多后端的跨域配置如果 nginx 代理多个后端(如 /api1/、/api2/),每个后端都需要跨域:1234567891011location /api1/ {    proxy_pass http://backend1;    add_header 'Access-Control-Allow-Origin' '*' always;    # ...同上}  location /api2/ {    proxy_pass http://backend2;    add_header 'Access-Control-Allow-Origin' '*' always;    # ...同上}十四、nginx 1.7.5 及以上版本的 always 参数确保你用的 nginx 版本支持 always 参数,否则有些 header 在 4xx/5xx 状态下不会返回。十五、安全建议生产环境不要使用 *,要指定具体域名。不建议在 / 根路径全局添加 CORS,容易引发安全隐患。如需支持多域名跨域,推荐用变量和正则动态判断。如果接口涉及敏感数据,务必开启认证和 HTTPS。十六、调试技巧用 Chrome/Firefox 开发者工具的 Network 面板查看 Response Headers,确认 CORS 头是否正确返回。使用 curl -i 命令直接发起跨域请求,检查响应头。检查 nginx 日志(access.log 和 error.log)排查问题。十七、完整多场景配置模板123456789101112131415161718192021222324252627282930313233343536373839server {    listen 80;    server_name your.domain.com;      # 静态资源    location /static/ {        root /var/www/html;        add_header 'Access-Control-Allow-Origin' '*' always;    }      # API1 跨域    location /api1/ {        proxy_pass http://backend1;        add_header 'Access-Control-Allow-Origin' 'https://www.a.com' always;        add_header 'Access-Control-Allow-Credentials' 'true' always;        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;        add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept, Authorization' always;        if ($request_method = 'OPTIONS') {            add_header 'Access-Control-Max-Age' 1728000;            add_header 'Content-Type' 'text/plain charset=UTF-8';            add_header 'Content-Length' 0;            return 204;        }    }      # API2 跨域    location /api2/ {        proxy_pass http://backend2;        add_header 'Access-Control-Allow-Origin' 'https://www.b.com' always;        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;        add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept, Authorization' always;        if ($request_method = 'OPTIONS') {            add_header 'Access-Control-Max-Age' 1728000;            add_header 'Content-Type' 'text/plain charset=UTF-8';            add_header 'Content-Length' 0;            return 204;        }    }}
  • [行业前沿] 从 Nginx 到云原生服务网格的演进
     在微服务架构普及的今天,单体应用被拆分为数十甚至上百个独立服务,每个服务暴露自己的 API。这种解耦带来了开发敏捷性,却也引入了新的复杂性:如何统一管理入口流量、保障安全、实现可观测性并简化客户端调用? API 网关(API Gateway)应运而生,作为系统的“前门”,承担起路由、认证、限流、日志等横切关注点。然而,随着云原生、Service Mesh 和 Serverless 的兴起,API 网关的角色正在发生深刻变化。一、API 网关的核心职责一个成熟的 API 网关通常需提供以下能力:请求路由(Routing)根据路径、Host、Header 等将请求转发至对应后端服务。认证与鉴权(Authentication & Authorization)验证 JWT、OAuth Token、API Key,并校验权限。限流与熔断(Rate Limiting & Circuit Breaking)防止突发流量压垮后端,保障系统稳定性。协议转换(Protocol Translation)如将 gRPC 转为 REST,或将 WebSocket 代理至后端。可观测性(Observability)记录访问日志、生成指标(QPS、延迟)、集成分布式追踪。安全防护(Security)防御 DDoS、注入攻击、爬虫等,支持 WAF(Web Application Firewall)。开发者体验(Developer Experience)提供 API 文档(Swagger/OpenAPI)、测试沙箱、订阅管理。二、演进阶段一:基于 Nginx 的静态网关(2010–2016)早期团队常直接使用 Nginx 作为简易网关:server { listen 80; server_name api.example.com; location /users/ { proxy_pass http://user-service; } location /orders/ { proxy_pass http://order-service; } # 简单限流 limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;}优势:性能极高(C 编写,事件驱动)配置灵活,社区模块丰富(如 lua-nginx-module)局限:配置静态化:新增服务需手动改配置并 reload无动态控制面:无法通过 API 实时调整路由或策略缺乏原生认证/限流:需依赖 Lua 脚本(OpenResty)扩展三、演进阶段二:专用 API 网关崛起(2016–2020)为解决动态管理问题,专用网关产品涌现:1. Kong(基于 OpenResty)插件化架构:官方提供 100+ 插件(JWT、OAuth2、Prometheus)Admin API:可通过 HTTP API 动态管理路由数据库支持:PostgreSQL/Cassandra 存储配置企业版支持:Vitals(监控)、Dev Portal(开发者门户)2. Tyk开源 + 商业双模式内置 OAuth2 授权服务器支持 GraphQL 聚合3. Amazon API Gateway / Azure API Management托管服务,免运维深度集成云生态(Lambda、IAM、CloudWatch)架构特点:控制面 + 数据面分离控制面(Admin API + DB)管理配置,数据面(Nginx/OpenResty)处理流量动态重载:无需重启即可生效新策略⚠️ 痛点:插件性能损耗(Lua VM 开销)多语言插件开发困难与 Kubernetes 原生集成弱四、演进阶段三:云原生网关(2020–至今)Kubernetes 成为主流部署平台后,网关需深度适配声明式 API 和服务发现。1. Ingress Controller ≠ API 网关?Ingress(如 Nginx Ingress)仅提供 L7 路由,缺乏认证、限流等高级功能API 网关需在此基础上增强2. 云原生网关代表Ambassador (Emissary-ingress)基于 Envoy Proxy使用 Kubernetes CRD(如 Mapping)定义路由原生支持 gRPC、WebSocket、OIDCGloo Gateway支持多协议(REST/gRPC/WebSocket)可聚合多个后端为单一 GraphQL 端点与 Istio 兼容Apache APISIX高性能(基于 etcd + Nginx)动态路由毫秒级生效支持 Serverless(对接 AWS Lambda、OpenFunction)核心优势:GitOps 友好:配置即 YAML,纳入版本控制自动服务发现:监听 K8s Endpoints,动态更新 upstream多租户隔离:按 Namespace 或 Label 分组管理 API 网关的演进,映射了整个后端架构的变迁:从静态配置到动态治理,从单体代理到云原生控制面,从单纯路由到全生命周期 API 管理。今天的 API 网关,早已不是简单的“反向代理”,而是连接外部世界与内部服务的智能枢纽。在微服务、Serverless 与服务网格并存的混合架构中,理解网关的定位与能力边界,是构建高可用、安全、可扩展系统的关键一步。未来,随着协议多样化和边缘计算兴起,API 网关将继续进化,成为数字世界的“通用翻译官”与“智能守门人”。
  • [技术干货] Nginx 中的Rewrite 使用示例详解 — 转载
    1. 概述Nginx 的 rewrite 模块是处理 HTTP 请求过程中的一个重要功能,它允许基于 Perl 兼容正则表达式(PCRE)对用户请求的 URI 进行重写,并返回 30x 重定向跳转或按条件执行相关配置。这个模块提供了灵活的 URL 重写和重定向功能,可以用于实现友好 URL、301/302 重定向、条件重写等。2. Rewrite 指令2.1 指令语法Nginx 中的 URL 重写主要依赖于 rewrite 指令,其基本语法如下:1rewrite <regex> <replacement> [flag];regex:用于匹配 URI 的正则表达式。replacement:将匹配到的 URI 替换成的新 URI。flag(可选):控制重写的行为,常见的标志有:last:表示重新搜索新的 location 块(即继续匹配新的规则)。break:停止当前 location 块中的规则匹配,执行后续指令。redirect:执行临时 重定向(302)。permanent:执行永久重定向(301)。2.2 Flag 标记说明last:重写请求并继续搜索 location 匹配。break:重写请求并停止搜索 location 匹配。redirect:返回 302 临时重定向。permanent:返回 301 永久重定向。3. Rewrite 与 Locationrewrite 指令可以在 server 或 location 块中配置。location 块只对域名后除去传递参数的字符串起作用,而 rewrite 可以对域名或参数字符串进行匹配和重写。3.1 Location 分类普通 location:匹配特定路径。正则 location:使用正则表达式匹配路径。优先级:Nginx 会优先匹配带有正则表达式的 location,然后是最长非正则 location。3.2 Rewrite 和 Location 比较rewrite 用于重写请求 URI。location 用于定义请求的处理方式。4. Rewrite 实际场景4.1 基于域名的跳转将旧域名的访问重定向到新域名,同时保持参数不变。12345678910111213# 定义一个 server 块,用于处理进来的 HTTP 请求server {    # 监听 80 端口,即 HTTP 默认端口    listen 80;    # 指定该 server 块响应的域名,这里是 olddomain.com    server_name olddomain.com;    # 定义 location 块,匹配所有 URI(/ 表示根路径)    location / {        # 使用 rewrite 指令将所有请求从 olddomain.com 重定向到 newdomain.com        # 并保持原有的请求路径和查询参数不变        rewrite ^/(.*)$ http://newdomain.com/$1 permanent;    }}这段配置的作用是将所有访问 olddomain.com 的请求通过 Nginx 重定向到 newdomain.com,并且保持请求的路径不变。permanent 标志表示这是一个永久重定向(301 状态码),告诉搜索引擎和浏览器该资源已经被永久移动到新的位置。4.2 基于客户端 IP 访问跳转只允许特定 IP 访问,其他 IP 重定向到维护页面。12345678910111213141516# 定义一个 server 块,用于处理进来的 HTTP 请求server {    # 监听 80 端口,即 HTTP 默认端口    listen 80;    # 指定该 server 块响应的域名,这里是 example.com    server_name example.com;    # 定义 location 块,匹配所有 URI(/ 表示根路径)    location / {        # 使用 if 指令进行条件判断,$remote_addr 是客户端的 IP 地址        if ($remote_addr != '192.168.1.100') {            # 如果客户端 IP 地址不是 '192.168.1.100',则返回 302 状态码            # 并将请求重定向到 /maintenance.html,表示网站正在维护中            return 302 /maintenance.html;        }    }}这段配置的作用是限制对 example.com 的访问,只允许 IP 地址为 192.168.1.100 的客户端访问所有资源,其他所有 IP 地址的访问都会被重定向到 /maintenance.html 页面,通常用于网站维护期间。这里使用的是临时重定向(302 状态码),意味着浏览器会显示新的 URL(即 /maintenance.html),但搜索引擎和缓存可能会保留原始请求的 URL。4.3 基于参数匹配的跳转根据请求参数进行跳转。12345678910111213141516# 定义一个 server 块,用于处理进来的 HTTP 请求server {    # 监听 80 端口,即 HTTP 默认端口    listen 80;    # 指定该 server 块响应的域名,这里是 example.com    server_name example.com;    # 定义 location 块,匹配所有 URI(/ 表示根路径)    location / {        # 使用 rewrite 指令进行 URL 重写        # 正则表达式 ^/(.*)?param=value$ 匹配任何以 / 开头,后面跟着任意字符        # 并且以 ?param=value 结尾的请求 URI        rewrite ^/(.*)?param=value$ /new-path/$1 last;        # last 标志表示重写完成后,继续搜索匹配的 location 块        # 这里的 $1 是正则表达式中括号内匹配到的部分,即任意字符的部分    }}这段配置的作用是将所有匹配特定模式的请求重写到一个新的路径。具体来说,它会查找所有以 / 开头,后面跟着任意内容,并且以 ?param=value 结尾的请求,并将这些请求重写到 /new-path/ 开头的路径下,同时保留原始请求中的路径部分(不包括查询参数)。last 标志意味着在重写后,Nginx 将继续检查其他 location 块以找到最合适的匹配项。4.4 基于目录下所有 PHP 文件跳转将特定目录下的所有 PHP 文件请求重写到新路径。12345678910111213141516# 定义一个 server 块,用于处理进来的 HTTP 请求server {    # 监听 80 端口,即 HTTP 默认端口    listen 80;    # 指定该 server 块响应的域名,这里是 example.com    server_name example.com;    # 定义一个 location 块,使用 ~ 表示这是一个正则表达式匹配    # 正则表达式 .php$ 匹配以 .php 结尾的请求 URI    location ~ .php$ {        # 使用 rewrite 指令进行 URL 重写        # 正则表达式 ^/(.*).php$ 匹配任何以 / 开头,后面跟着任意字符,以 .php 结尾的请求 URI        rewrite ^/(.*).php$ /new-path/$1.php last;        # last 标志表示重写完成后,继续搜索匹配的 location 块        # 这里的 $1 是正则表达式中括号内匹配到的部分,即除去 .php 后缀的文件名部分    }}这段配置的作用是将所有请求 URI 以 .php 结尾的请求重写到 /new-path/ 下的相同文件名。例如,请求 /example.com/about.php 会被重写为 /example.com/new-path/about.php。last 标志意味着在重写后,Nginx 将继续检查其他 location 块以找到最合适的匹配项,而不是立即停止处理当前 location 块。4.5 基于最普通 URL 请求的跳转将普通 URL 请求重写到新路径。12345678910111213141516# 定义一个 server 块,用于处理进来的 HTTP 请求server {    # 监听 80 端口,即 HTTP 默认端口    listen 80;    # 指定该 server 块响应的域名,这里是 example.com    server_name example.com;    # 定义 location 块,匹配所有 URI(/ 表示根路径)    location / {        # 使用 rewrite 指令进行 URL 重写        # 正则表达式 ^/(.*)$ 匹配任何以 / 开头,后面跟着任意字符的请求 URI        rewrite ^/(.*)$ /new-path/$1 permanent;        # permanent 标志表示这是一个永久重定向(301 状态码)        # 告诉浏览器和搜索引擎该资源已经被永久移动到新的位置        # $1 是正则表达式中括号内匹配到的部分,即除去第一个斜杠后的整个请求路径    }}这段配置的作用是将所有访问 example.com 的请求重定向到 /new-path/ 下的相同路径。例如,请求 /example.com/about 会被永久重定向到 /example.com/new-path/about。permanent 标志意味着这是一个永久重定向,浏览器会更新收藏夹中的 URL,搜索引擎也会更新其索引。5. Rewrite 执行顺序rewrite 指令的执行顺序如下:执行 server 块里面的 rewrite 指令。执行 location 匹配。执行选定 location 中的 rewrite 指令。6. Rewrite 与 If 指令if 指令用于条件判断,可以与 rewrite 结合使用,但需要注意 if 是邪恶的,因为它可能导致 Nginx 配置变得复杂和难以维护。推荐使用 rewrite 来实现条件重写。7. Rewrite 正则表达式Nginx 的 rewrite 模块支持 PCRE 正则表达式,以下是一些常用的正则表达式元字符:.:匹配任意单个字符。^:匹配字符串的开始。$:匹配字符串的结束。*:匹配前面的元素 0 次或多次。+:匹配前面的元素 1 次或多次。?:匹配前面的元素 0 次或 1 次。[]:匹配括号内的任意一个字符。|:逻辑或操作符。8. Rewrite 指令的脚本指令rewrite 模块提供了类似脚本语言的指令,可以在 HTTP 请求处理过程中对 URI 进行更灵活的操作控制。9. Rewrite 配置示例以下是一些 rewrite 配置的示例:9.1 301/302 重定向1234567891011121314151617# 定义一个 server 块,用于处理 HTTP 请求server {    # 监听 80 端口,这是 HTTP 协议的默认端口    listen 80;    # 指定 server 块服务的域名,这里是 olddomain.com    server_name olddomain.com;    # 定义 location 块,用于匹配所有请求的 URI(/ 表示根路径)    location / {        # 使用 rewrite 指令进行 URL 重写        # 正则表达式 ^/(.*)$ 匹配所有以 / 开头的请求 URI        rewrite ^/(.*)$ http://newdomain.com/$1 permanent;        # 将匹配到的请求重写到 newdomain.com 的相同路径        # $1 表示正则表达式中括号内匹配到的部分,即除了根斜杠外的路径部分        # permanent 标志表示这是一个永久重定向(301 状态码)        # 告诉浏览器和搜索引擎该资源已经被永久移动到新域名    }}这段配置的作用是将所有访问 olddomain.com 的请求永久重定向到 newdomain.com 的相同路径。例如,如果用户访问 olddomain.com/about,他们将被重定向到 newdomain.com/about。这个重定向是永久的,意味着搜索引擎和浏览器会更新相应的链接,并且用户浏览器的地址栏也会显示新的 URL。9.2 非 www 域名重定向到 www 域名1234567891011121314151617181920212223# 第一个 server 块,用于处理对 example.com 的非 www 前缀域名的请求server {    # 监听 80 端口,这是 HTTP 协议的默认端口    listen 80;    # 指定 server 块服务的域名,这里是 example.com(没有 www 前缀)    server_name example.com;    # 对于所有请求,返回一个 301 永久重定向响应    # 这会将用户从 http://example.com 重定向到 http://www.example.com,并保留原始请求的 URI    return 301 http://www.example.com$request_uri;}# 第二个 server 块,用于处理对 www.example.com 的请求server {    # 监听 80 端口,这是 HTTP 协议的默认端口    listen 80;    # 指定 server 块服务的域名,这里是 www.example.com(带有 www 前缀)    server_name www.example.com;    # 定义 location 块,用于匹配所有请求的 URI(/ 表示根路径)    location / {        # 这里可以放置处理 www.example.com 域名请求的配置        # 例如,可以配置 proxy_pass 来代理请求,或者 root 指令来指定文件根目录等        # 正常站点配置    }}这段配置的作用是将所有对 example.com(没有 www 前缀)的 HTTP 请求永久重定向到 www.example.com(带有 www 前缀)。第一个 server 块监听 example.com 并返回一个 301 状态码,将请求重定向到 www.example.com,同时保留请求的 URI。第二个 server 块则处理对 www.example.com 的请求,可以在这里进行进一步的配置,比如设置代理、静态文件服务等。关于您提到的网址 http://www.example.com$request_uri,由于网络原因,解析并没有成功。这可能是由于链接格式不正确或者网络连接问题。请检查网页链接的合法性,并在确保网络连接正常的情况下适当重试。如果问题依旧存在,可能需要进一步的网络诊断或联系网站管理员。如果您有其他问题或需要帮助,请随时告知。9.3 URL 正则重写:简化 URL 结构123456789101112131415# 定义一个 server 块,用于处理进来的 HTTP 请求server {    # 监听 80 端口,即 HTTP 默认端口    listen 80;    # 指定该 server 块响应的域名,这里是 example.com    server_name example.com;    # 定义一个 location 块,匹配请求 URI 路径以 /category/id/ 开头的请求    location /category/id/ {        # 使用 rewrite 指令进行 URL 重写        # 正则表达式 ^/category/id/(d+)$ 匹配以 /category/id/ 开头,接着是数字的请求 URI        rewrite ^/category/id/(d+)$ /category/$1 last;        # last 标志表示重写完成后,继续搜索匹配的 location 块        # $1 是正则表达式中括号内匹配到的部分,即 URI 中的数字部分    }} 这段配置的作用是将所有匹配 /category/id/ 路径并且后面跟着数字的请求重写到 /category/ 路径下。例如,请求 /category/id/123 会被重写为 /category/123。last 标志意味着在重写后,Nginx 将继续检查其他 location 块以找到最合适的匹配项。这样做可以允许 Nginx 在重写请求后,根据新的 URI 再次检查是否有更具体的 location 匹配,从而应用更具体的配置。10. 结论Nginx 的 rewrite 模块提供了强大的 URL 重写和重定向功能,可以用于实现各种复杂的 URL 处理需求。通过合理配置 rewrite 指令,可以提高网站的可用性、改善 SEO、实现域名迁移等。本手册详细介绍了 rewrite 的命令、语法、含义、环境和示例,希望能够帮助用户更好地理解和使用 Nginx 的 rewrite 功能。
  • [技术干货] 理解 Nginx 中的 location 配置
     Nginx 是一款高性能的 Web 服务器和反向代理服务器,其配置灵活、性能卓越,被广泛应用于现代 Web 架构中。在 Nginx 的配置文件中,location 指令是实现请求路由的核心机制之一。正确理解和使用 location,对于构建高效、安全、可维护的服务至关重要。一、location 基本语法location 指令用于定义如何处理特定 URI(统一资源标识符)的请求。其基本语法如下:location [modifier] pattern { # 配置指令}其中:modifier 是可选的修饰符,用于指定匹配方式;pattern 是要匹配的 URI 路径或正则表达式;{} 内是具体的配置指令,如 proxy_pass、root、rewrite 等。二、location 的五种匹配类型Nginx 支持以下五种主要的 location 匹配类型,每种有不同的优先级和用途:1. 精确匹配(=)location = /index.html { ...}特点:完全匹配 URI,不进行任何前缀或正则扩展。优先级最高。适用于高频访问且路径固定的资源(如首页),能提升性能。示例:当请求为 /index.html 时匹配,但 /index.html?a=1 也会匹配(Nginx 在匹配时忽略查询字符串)。2. 前缀匹配(无修饰符)location /images/ { ...}特点:匹配以指定字符串开头的 URI。属于“普通前缀匹配”,优先级低于 = 和 ^~。可被正则匹配覆盖(除非使用 ^~)。3. 最长前缀匹配(^~)location ^~ /static/ { ...}特点:也是前缀匹配,但一旦匹配成功,不再检查正则 location。优先级高于普通前缀匹配,但低于 =。适用于静态资源目录,避免不必要的正则计算。4. 正则匹配(~ 和 ~*)location ~ \.php$ { ...}location ~* \.(jpg|jpeg|png)$ { ...}~:区分大小写的正则匹配;~*:不区分大小写的正则匹配。按配置文件中出现的顺序依次匹配,一旦匹配成功即停止。优先级高于普通前缀匹配,但低于 = 和 ^~。5. 通用匹配(/)location / { ...}匹配所有请求,通常作为兜底规则。优先级最低。三、location 匹配优先级总结Nginx 处理请求时,location 的匹配顺序如下:精确匹配(=)最长前缀匹配(^~)正则匹配(~ / ~*) —— 按配置顺序普通前缀匹配 —— 选择最长匹配的规则通用匹配(/) 注意:普通前缀匹配虽然先被扫描,但只有在没有更高优先级规则匹配时才会生效。Nginx 会先找出所有前缀匹配中最长的一个,然后判断是否有 ^~ 或 =,如果没有,则继续尝试正则匹配。四、示例示例 1:静态资源与动态请求分离server { listen 80; server_name example.com; # 精确匹配首页 location = / { root /var/www/html; index index.html; } # 静态资源,使用 ^~ 避免正则检查 location ^~ /static/ { alias /var/www/static/; expires 30d; } # PHP 动态请求 location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name; } # 兜底规则 location / { try_files $uri $uri/ /index.html; }}示例 2:API 路由代理location /api/v1/ { proxy_pass http://backend_server; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr;}注意:proxy_pass 结尾是否带 / 会影响 URI 重写行为。proxy_pass http://backend/; → /api/v1/user → 后端收到 /userproxy_pass http://backend; → /api/v1/user → 后端收到 /api/v1/user 掌握 Nginx 的 location 匹配机制,是构建高性能 Web 服务的基础。理解其优先级规则、合理使用修饰符、结合实际业务场景设计路由逻辑,不仅能提升系统性能,还能增强安全性和可维护性。 
  • [技术干货] Lua 脚本语言深度解析
    在众多编程语言中,Lua(发音为 /ˈluːə/,意为“月亮”)以其轻量、高效、可嵌入性强的特性,在游戏开发、嵌入式系统、Web 服务器扩展、脚本自动化等领域占据着不可替代的地位。它被广泛应用于 《魔兽世界》、《愤怒的小鸟》、Redis、Nginx (OpenResty) 等知名项目中。 什么是 Lua?Lua 是一种用标准 C 语言编写的开源、轻量级、可扩展的脚本语言,由巴西里约热内卢天主教大学(PUC-Rio)的 Roberto Ierusalimschy 等人于 1993 年开发。核心设计理念:轻量:整个解释器核心仅几百 KB,适合嵌入资源受限的设备。高效:执行速度快,接近 Python、JavaScript 等主流脚本语言。可嵌入:设计初衷就是作为“胶水语言”,无缝集成到 C/C++ 等宿主程序中。可扩展:通过 C 扩展模块,轻松调用底层功能。定位:Lua 不是用于构建大型独立应用的“主语言”,而是作为嵌入式脚本语言,为宿主程序提供灵活的逻辑扩展能力。Lua 的核心特性特性说明轻量级解释器体积小(~200KB),内存占用低速度快基于寄存器的虚拟机,执行效率高动态类型变量无需声明类型,运行时确定自动内存管理内置垃圾回收(GC)机制过程式 + 函数式支持函数式编程(函数是一等公民)协程(Coroutine)轻量级线程,支持协作式多任务无内置复杂类型仅提供 表(table) 作为唯一数据结构,但功能强大Lua 基础语法速览1. 变量与数据类型Lua 有 8 种基本类型:nil, boolean, number, string, function, thread, table, userdata。-- 变量声明(无需类型)name = "Alice" -- stringage = 25 -- numberis_active = true -- booleanscore = nil -- nil-- 动态类型x = 10x = "hello" -- 合法,类型在运行时改变2. 表(Table)—— Lua 的“瑞士军刀”table 是 Lua 中唯一的数据结构,可实现数组、字典、对象、模块等多种功能。-- 作为数组(索引从 1 开始!)fruits = {"apple", "banana", "orange"}print(fruits[1]) --> "apple"-- 作为字典(键值对)person = { name = "Bob", age = 30, city = "Shanghai"}print(person["name"]) --> "Bob"print(person.age) --> 30-- 混合使用mixed = {10, "hello", x = 1, y = 2}print(mixed[1]) --> 10print(mixed.x) --> 13. 控制结构-- if 语句if age > 18 then print("Adult")elseif age > 13 then print("Teen")else print("Child")end-- for 循环for i = 1, 5 do print(i)end-- while 循环local i = 1while i <= 3 do print(i) i = i + 1end4. 函数(Function)函数是“一等公民”,可赋值给变量、作为参数传递。-- 定义函数function greet(name) return "Hello, " .. name .. "!"end-- 调用print(greet("Alice")) --> "Hello, Alice!"-- 函数作为变量local sayHi = function(name) return "Hi, " .. nameend-- 闭包(Closure)function makeCounter() local count = 0 return function() count = count + 1 return count endendcounter = makeCounter()print(counter()) --> 1print(counter()) --> 2Lua 的核心优势:可嵌入性Lua 的最大价值在于它可以被轻松嵌入到 C/C++ 程序中,通过 Lua C API 实现双向调用。典型嵌入流程:宿主程序(C/C++) 调用 Lua 脚本。Lua 脚本 调用宿主程序暴露的 C 函数。数据交换:通过 Lua 栈(Stack)传递参数和返回值。C 代码调用 Lua 示例:#include <lua.h>#include <lualib.h>#include <lauxlib.h>int main() { lua_State *L = luaL_newstate(); // 创建 Lua 状态机 luaL_openlibs(L); // 加载标准库 // 执行 Lua 脚本 if (luaL_dofile(L, "script.lua") != 0) { fprintf(stderr, "Error: %s\n", lua_tostring(L, -1)); } lua_close(L); return 0;}Lua 调用 C 函数:C 代码注册函数后,Lua 脚本可直接调用:-- Lua 脚本中result = my_c_function(42, "hello")Lua 的典型应用场景1. 游戏开发《魔兽世界》:UI 界面和插件系统使用 Lua。《愤怒的小鸟》:游戏逻辑由 Lua 驱动。Cocos2d-x:跨平台游戏引擎,支持 Lua 脚本开发。✅ 优势:热更新、快速迭代、非程序员(策划、美术)也能参与逻辑编写。2. Web 服务器扩展OpenResty:基于 Nginx 和 Lua 的高性能 Web 平台。在 Nginx 中直接运行 Lua 脚本,实现 API 网关、限流、鉴权、缓存等。性能远超传统 PHP/Python 后端。location /api { content_by_lua_block { local redis = require("resty.redis") local red = redis:new() red:connect("127.0.0.1", 6379) local data = red:get("user:123") ngx.say(data) }}3. 数据库脚本Redis:使用 Lua 脚本实现原子性操作(EVAL 命令)。多条命令打包执行,避免网络开销。保证操作的原子性。-- Redis Lua 脚本:原子性递增并返回local current = redis.call("GET", KEYS[1])if current then current = tonumber(current) + 1 redis.call("SET", KEYS[1], current) return currentelse return nilend4. 嵌入式系统与 IoT资源受限设备(如路由器、智能家居)中,Lua 用于配置脚本、业务逻辑扩展。NodeMCU:基于 ESP8266 的 IoT 固件,支持 Lua 编程。5. 配置与自动化脚本作为配置文件语言(比 JSON 更灵活)。自动化工具脚本(如 Wireshark 的插件)。  Lua 虽然小众,但其在特定领域的不可替代性使其历久弥新。它证明了“少即是多”的设计哲学——一个简单的 table 和强大的 C API,足以支撑起无数复杂系统的灵活扩展。
  • [技术干货] 高性能 Web 服务器与反向代理实战
    Nginx(发音为 "engine-x")已成为高并发、高性能 Web 服务的代名词。作为全球最受欢迎的 Web 服务器之一,Nginx 不仅被 Google、Facebook、Netflix、淘宝、京东等大型互联网公司广泛采用,更是微服务、负载均衡、API 网关等现代架构的核心组件。 一、什么是 Nginx?Nginx 是一个开源的 高性能 HTTP 服务器和反向代理服务器,同时也是一个 IMAP/POP3/SMTP 邮件代理服务器。它由俄罗斯程序员 Igor Sysoev 于 2004 年发布,最初为解决 C10K 问题(单机支持 1 万并发连接)而设计。核心特点:特性说明高性能异步非阻塞事件驱动架构,资源消耗低,支持高并发高可靠性进程模型稳定,即使高负载下也不会崩溃热部署支持不停机更新配置、升级版本模块化设计功能通过模块扩展,灵活可定制反向代理与负载均衡支持多种负载均衡算法静态资源服务高效处理 HTML、CSS、JS、图片等静态文件二、Nginx 架构原理:为什么这么快?1. 事件驱动 + 异步非阻塞与传统 Apache 的 多进程/多线程模型(每个连接占用一个进程/线程)不同,Nginx 采用 事件驱动的异步非阻塞 I/O 模型。Master 进程:管理进程,不处理请求。Worker 进程:每个 Worker 采用单线程 + 事件循环(Event Loop)处理成千上万个并发连接。I/O 多路复用:使用 epoll(Linux)、kqueue(BSD)等机制,一个进程可监听多个 socket。✅ 优势:内存占用少,上下文切换开销小,轻松应对数万并发连接。三、Nginx 的核心应用场景1. 静态 Web 服务器Nginx 是服务静态资源的绝佳选择,性能远超应用服务器(如 Tomcat)。server { listen 80; server_name www.example.com; location / { root /var/www/html; # 静态文件目录 index index.html; } # 缓存静态资源 location ~* \.(jpg|jpeg|png|css|js)$ { expires 1y; add_header Cache-Control "public, immutable"; }}2. 反向代理(Reverse Proxy)Nginx 作为“门面”,接收客户端请求,转发给后端应用服务器(如 Java、Python、Node.js),并返回响应。server { listen 80; server_name api.example.com; location / { proxy_pass http://127.0.0.1:8080; # 转发到本地 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; }}✅ 优势:隐藏后端服务器真实 IP统一入口,便于管理提升安全性3. 负载均衡(Load Balancing)Nginx 可将请求分发到多个后端服务器,实现横向扩展与高可用。配置示例:upstream backend { # 负载均衡算法 least_conn; # 最少连接 # round-robin; # 轮询(默认) # ip_hash; # IP 哈希(会话保持) # hash $request_uri; # 一致性哈希 server 192.168.1.10:8080 weight=3; # 权重 3 server 192.168.1.11:8080; server 192.168.1.12:8080 backup; # 备用服务器}server { listen 80; location / { proxy_pass http://backend; }}4. SSL/TLS 加密(HTTPS)Nginx 可作为 SSL 终端,处理 HTTPS 请求并解密后转发给后端 HTTP 服务。server { listen 443 ssl http2; server_name www.example.com; ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/private.key; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512; location / { proxy_pass http://backend; }}✅ 推荐:使用 Let's Encrypt 免费证书 + Certbot 自动续期。5. 缓存加速Nginx 支持反向代理缓存,减少后端压力,提升响应速度。# 定义缓存区proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;server { location / { proxy_cache my_cache; proxy_pass http://backend; proxy_cache_valid 200 302 10m; # 缓存 10 分钟 add_header X-Cache-Status $upstream_cache_status; }}缓存命中时,X-Cache-Status 返回 HIT,否则为 MISS。6. URL 重写与重定向# 301 永久重定向rewrite ^/old-page$ /new-page permanent;# 条件重写if ($http_user_agent ~* "bot|spider") { rewrite ^/.*$ /robots.txt break;}# 伪静态rewrite ^/article/(\d+)\.html$ /article.php?id=$1 last;四、常用配置指令详解指令作用listen监听端口和 IPserver_name匹配域名location定义 URL 路由规则root / alias文件路径映射proxy_pass反向代理目标upstream定义后端服务器组try_files尝试多个文件路径(常用于 SPA 路由)gzip启用 Gzip 压缩SPA 应用路由支持(如 Vue、React)location / { root /var/www/app; try_files $uri $uri/ /index.html;}确保前端路由刷新不 404。五、性能优化建议1. Worker 进程优化worker_processes auto; # 通常设置为 CPU 核心数worker_connections 1024; # 每个 Worker 最大连接数worker_rlimit_nofile 65535; # 提升文件描述符限制2. 开启 Gzip 压缩gzip on;gzip_types text/plain text/css application/json application/javascript text/xml application/xml;3. 启用 HTTP/2listen 443 ssl http2;减少延迟,提升加载速度。4. 静态资源缓存location ~* \.(css|js|jpg|png|gif)$ { expires 1y; add_header Cache-Control "public, immutable";}六、安全加固1. 隐藏 Nginx 版本号server_tokens off;2. 防止点击劫持add_header X-Frame-Options SAMEORIGIN;3. 防止 XSS 攻击add_header X-Content-Type-Options nosniff;add_header Content-Security-Policy "default-src 'self'";4. 限制请求频率limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;location /api/ { limit_req zone=api burst=20 nodelay;} 
  • [技术干货] 拌合楼软件开发(29)Nginx反向代理限制境外访问 -转载
    前言:        首先作者知道自己肯定是拉了很多屎在项目代码里面,项目初期想怎么写,怎么简单写就怎么来写,也没搞啥设计模式,就是vs 创建的.net core 项目模板,想着要做前后端分离的时候,已经成了一堆屎山代码,就算一些可能某个客户用不到的功能,我都不想去删除。这样的代码难免有漏洞,好在拌合楼的客户群提决定了他不会有大并发访问,超多用户等等问题要做考虑。 最近日志发现服务器有被扫描的情况,看IP都是写境外的IP,想想还是要采取一些技术防护手段。因为项目都是国内的,所以理论上不会有境外的访问,那么直接把境外的IP给禁止掉,就可以提高一点的安全性。实现的方案:        一、防火墙配置禁止境外IP访问        如果使用深信服、华为等企业级的防火墙在前端防护,那可以配置访问策略直接做限制,只允许境内的IP访问。但是由于作者服务器使用的是阿里云的服务,找了很久都没有看到阿里云在哪里可以设置不允许境外访问。后来发现nginix可以做IP限制,所以最终采取此种方案。        二、Nginx做反向代理限制境外IP不能访问        因为没有采用IIS来跑.net core 程序,直接用的linux来跑,本身就要用nginx来做反向代理后端的.net 程序。所以这个方案是比较适合作者的需求的。实现的路径:        一、Ngnix编译添加ngx_http_geoip2_module        1.  安装 geoip2 扩展依赖         yum install libmaxminddb-devel -yAI写代码        2.  查看自己安装的nginx编译的参数        [root@##### ~]# nginx -Vnginx version: nginx/1.24.0built by gcc 10.2.1 20200825 (#### 10.2.1-3.8 2.32) (GCC) built with OpenSSL 1.1.1q  5 Jul 2022TLS SNI support enabledconfigure arguments: --user=www --group=www --prefix=/www/server/nginx --add-module=/www/server/nginx/src/ngx_devel_kit --add-module=/www/server/nginx/src/lua_nginx_module --add-module=/www/server/nginx/src/ngx_cache_purge --with-openssl=/www/server/nginx/src/openssl --with-pcre=pcre-8.43 --with-http_v2_module --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_stub_status_module --with-http_ssl_module --with-http_image_filter_module --with-http_gzip_static_module --with-http_gunzip_module --with-ipv6 --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-http_auth_request_module --add-module=/www/server/nginx/src/ngx_http_substitutions_filter_module-master --with-ld-opt=-Wl,-E --with-cc-opt=-Wno-error --with-http_dav_module --add-module=/www/server/nginx/src/nginx-dav-ext-moduleAI写代码        3. 下载geoip模块        作者这里是使用宝塔面板直接安装的nginx,进入到nginx源码目录 /www/server/nginx/src 下,下载ngx_http_geoip2_module。        git clone https://github.com/leev/ngx_http_geoip2_module.gitAI写代码        4. 编译添加模块               重新编译nginx,会报错没有Luajit,如下图         可以yum来安装luajit        yum intall luajit luajit-develAI写代码        但是安装了还是会报这个错,需要设置下系统变量,修改/etc/profile 在最后一行增加export LUAJIT_LIB=/usr/local/libexport LUAJIT_INC=/usr/local/include/luajit-2.1AI写代码        LUAJIT_INC的值按照实际安装的版本做修改。source /etc/profileAI写代码       让变量生效后,然后再运行configure ./configure --user=www --group=www --prefix=/www/server/nginx --add-module=/www/server/nginx/src/ngx_devel_kit  --add-module=/www/server/nginx/src/ngx_cache_purge --add-module=/www/server/nginx/src/nginx-sticky-module-ng-1.3.0 --with-openssl=/www/server/nginx/src/openssl --with-pcre=pcre-8.43 --with-http_v2_module --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_stub_status_module --with-http_ssl_module --with-http_image_filter_module --with-http_gzip_static_module --with-http_gunzip_module  --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-http_auth_request_module --add-module=/www/server/nginx/src/ngx_http_substitutions_filter_module-master --with-ld-opt=-Wl,-E --with-cc-opt=-Wno-error --with-ld-opt=-ljemalloc --with-http_dav_module --add-module=/www/server/nginx/src/nginx-dav-ext-module --with-http_v3_module  --add-module=/www/server/nginx/src/ngx_http_geoip2_modulemakemake installAI写代码bash        完成后在运行 nginx -V 就可以看到module加载有geoip2        二、下载IP地址文件     模块安装成功后,还要在 Nginx 里指定数据库,在安装运行库时默认安装了两个,位于 /usr/share/GeoIP/ 目录下,一个只有 IPv4,一个包含 IPv4 和 IPv6 ,可以登录www.maxmind.com 网址,创建账户 下载最新的库文件。        作者找了好久都没有找到这个网站的注册入口地址,找不到那么就问问AI,可以通过点击这个链接来注册: https://www.maxmind.com/en/geolite2/signup  境外的公司,信息随便填,注意邮箱要填写正确,后面要用来收邮件设置密码和接收验证码。 国内的qq邮箱有可能会收不到,可以用微软的live邮箱了,每次登录都会要接收邮件验证码才可以登录。登录到后台,可以下载到免费的数据,因为只需要国家的,我们下载国家的即可。               注意如果你想下载城市的数据,会出现如下提示,大概率是对IP访问认为是中国的都做了限制,作者还挂代理,也同样下载不了,估计是关联了账户,修改了注册时候的国家,发现也还是出现这个问题。        试了其他方法,包括重新注册账号,且换了谷歌游览器的无痕模式,挂VPN访问,结果注册时候就提示,不知道他怎么知道我挂了VPN。由于只需要到国家的数据,其他数据不影响,作者也就没去纠结了。        解压缩包,我们需要的就是 GeoLite2-Country.mmdb 这个数据文件。        三、上传数据到模块指定文件夹        编译geoip模块的时候会自动有国家和城市的IP数据,但这个数据很老了。目录在/usr/share/GeoIP 下,图中是因为作者把文件做了备份,从时间上可以看出两个数据的文件是2018年的。         四、修改Nginx的配置文件        作者在这里踩了个坑,使用宝塔配置http和server配置是分开的。需要在nginx的配置文件http块中修改增加如下配置                geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {        auto_reload 5m;        $geoip2_data_country_code country iso_code;        }        map $geoip2_data_country_code $allowed_country {        default no;        CN yes;        }AI写代码bash        然后再到站点的server里面去配置,如果不是允许的国家,那么全部返回404   if ($allowed_country = no) {        return 404;        }AI写代码bash        重启就OK了————————————————                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。                        原文链接:https://blog.csdn.net/waxyy002/article/details/153265307
  • [技术干货] 【合集】10月技术干货汇总
    Nginx、 Redis、MySQL、Linux、centos相关技术干货汇总:1、Nginx平滑升级核心原理与location配置案例详解 — 转载cid:link_52、 Linux下ping时出现unknown host问题的解决方法 — 转载cid:link_03、CentOS 7安装TigerVNC Server的流程 — 转载cid:link_14、 CentOS7安装nodejs18和yarn操作实践 — 转载cid:link_65、在CentOS 7上安装Node.js 18.20.4全过程 — 转载cid:link_76、 nginx状态码的使用及说明 — 转载cid:link_87、 Linux云服务器手动配置DNS的方法步骤 — 转载cid:link_98、Nginx搭建前端本地预览环境的完整步骤教学 — 转载cid:link_29、 Nginx实现前端重定向的三种方法介绍 — 转载cid:link_1010、 Linux本地部署DeepSeek的详细流程 — 转载cid:link_311、MySQL中OR条件查询引发索引失效的场景及解决方案 — 转载cid:link_412、SQL 中 CASE WHEN 及 SELECT CASE WHEN 的用法详解 — 转载cid:link_1113、 云服务器安装mysql后如何设置示例详解 — 转载cid:link_1214、一文详解如何基于mysql dump进行全量备份还原 — 转载cid:link_1315、Redis 基本数据类型和使用详解 — 转载https://bbs.huaweicloud.com/forum/thread-0208195355535039239-1-1.html
  • [技术干货] Nginx平滑升级核心原理与location配置案例详解 — 转载
    Nginx平滑升级与location配置案例详解一、Nginx平滑升级Nginx平滑升级指在不中断服务的前提下,为Nginx添加新模块或更新版本,保障业务持续运行。以下是基于“为Nginx 1.24.0添加echo-nginx-module模块”的完整平滑升级流程,包含详细操作步骤、命令解释及注意事项。(一)平滑升级核心原理平滑升级的关键在于保留原配置与进程信息,通过重新编译包含新模块的Nginx程序,替换旧程序后重启服务,避免因服务中断导致的业务损失。核心逻辑为:获取原编译参数→添加新模块重新编译→备份旧程序→替换并重启。(二)详细操作步骤1. 部署基础Nginx环境(前提准备)若已部署Nginx可跳过此步,新环境需先完成Nginx安装(此处默认已安装Nginx 1.24.0,且运行正常)。2. 获取原有Nginx编译参数Nginx的编译参数决定了其功能模块(如SSL、静态压缩等),升级时需完整保留原参数,否则新程序会丢失原有功能。操作命令:1[root@nginx ~]# nginx -V  # 大写V,可显示编译参数;小写v仅显示版本执行结果(含关键编译参数,需完整记录):12345678910111213141516nginx version: nginx/1.24.0built by gcc 8.5.0 24210514 (Red Hat 8.5.0-4) (GCC) built with OpenSSL 1.1.1k  FIPS 25 Mar 2421TLS SNI support enabledconfigure arguments: --prefix=/usr/local/nginx \  # 安装目录                     --user=nginx \  # 运行用户                     --group=nginx \  # 运行用户组                     --with-debug \  # 启用调试模式                     --with-http_ssl_module \  # 启用SSL模块(HTTPS必备)                     --with-http_realip_module \  # 启用真实IP获取模块                     --with-http_image_filter_module \  # 启用图片处理模块                     --with-http_gunzip_module \  # 启用Gunzip解压模块                     --with-http_gzip_static_module \  # 启用静态文件Gzip压缩模块                     --with-http_stub_status_module \  # 启用Nginx状态监控模块                     --http-log-path=/var/log/nginx/access.log \  # 访问日志路径                     --error-log-path=/var/log/nginx/error.log  # 错误日志路径3. 下载新模块(echo-nginx-module)echo-nginx-module是OpenResty社区开发的Nginx模块,用于在响应中直接输出指定内容(如文本、变量等),常用于调试或简单接口返回。操作步骤:本地下载模块源码:访问echo-nginx-module GitHub地址,点击“Code”→“Download ZIP”,获取压缩包(如echo-nginx-module-master.zip)。上传至Nginx服务器:通过FTP、SCP等工具,将压缩包上传到Nginx服务器的/root目录(或其他自定义目录,需记住路径)。4. 重新编译Nginx(含新模块)编译前需确保服务器已安装编译依赖(如gcc、unzip、pcre-devel、openssl-devel等),若缺少依赖会导致编译失败。操作步骤:(1)安装编译依赖工具1234# 安装unzip(用于解压模块压缩包)[root@nginx ~]# yum -y install unzip# 安装Nginx编译必备依赖(若已安装可跳过)[root@nginx ~]# yum -y install gcc pcre-devel openssl-devel zlib-devel(2)解压模块与Nginx源码包解压新模块包:1[root@nginx ~]# unzip echo-nginx-module-master.zip  # 解压后生成目录echo-nginx-module-master解压Nginx源码包:平滑升级需基于原版本的源码进行编译,需确保服务器存在Nginx 1.24.0的源码包(若已删除,需重新从下载nginx-1.24.0.tar.gz并上传):1[root@nginx ~]# tar -zxf nginx-1.24.0.tar.gz  # 解压后生成目录nginx-1.24.0(3)配置编译参数(含新模块)进入Nginx源码目录,执行./configure命令,完整保留原编译参数,并通过--add-module指定新模块的解压路径:123456789101112131415[root@nginx ~]# cd nginx-1.24.0/  # 进入源码目录[root@nginx nginx-1.24.0]# ./configure \--prefix=/usr/local/nginx \  # 原参数:安装目录--user=nginx \  # 原参数:运行用户--group=nginx \  # 原参数:运行用户组--with-debug \  # 原参数:调试模式--with-http_ssl_module \  # 原参数:SSL模块--with-http_realip_module \  # 原参数:真实IP模块--with-http_image_filter_module \  # 原参数:图片处理模块--with-http_gunzip_module \  # 原参数:Gunzip模块--with-http_gzip_static_module \  # 原参数:静态Gzip模块--with-http_stub_status_module \  # 原参数:状态监控模块--http-log-path=/var/log/nginx/access.log \  # 原参数:访问日志--error-log-path=/var/log/nginx/error.log \  # 原参数:错误日志--add-module=../echo-nginx-module-master  # 新增:新模块的解压路径(相对源码目录)关键说明:--add-module的路径需准确(此处../echo-nginx-module-master表示“上一级目录下的echo-nginx-module-master”,因源码目录在/root/nginx-1.24.0,模块目录在/root),路径错误会导致模块加载失败。(4)编译生成新Nginx程序执行make命令编译(不可执行make install,否则会覆盖原安装目录,导致配置文件丢失):12# 执行编译(过程约1-3分钟,依赖服务器性能)[root@nginx nginx-1.24.0]# make(5)验证编译结果编译完成后,新的Nginx程序会生成在源码目录的objs子目录下,需确认程序存在:12# 查看objs目录内容[root@nginx nginx-1.24.0]# ls objs/预期结果:目录中需包含nginx可执行文件(即新编译的Nginx程序),其他文件如addon(模块相关)、src(源码编译文件)等为正常编译产物。5. 备份旧程序、替换并重启服务此步骤需严格按顺序执行,避免因操作失误导致服务中断或程序损坏。(1)对比新旧程序的编译参数(验证新模块是否加载)查看旧程序参数(原Nginx):123456[root@nginx nginx-1.24.0]# nginx -V  # 无--add-module参数nginx version: nginx/1.24.0built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)built with OpenSSL 1.0.2k-fips  26 Jan 2017TLS SNI support enabledconfigure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-debug --with-http_ssl_module --with-http_realip_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log查看新程序参数(编译后的程序):12[root@nginx nginx-1.24.0]# objs/nginx -V  # 需包含--add-module=../echo-nginx-module-masternginx version: nginx/1.24.0built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)built with OpenSSL 1.0.2k-fips 26 Jan 2017TLS SNI support enabledconfigure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-debug --with-http_ssl_module --with-http_realip_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --add-module=…/echo-nginx-module-master1234567**关键验证**:新程序的`configure arguments`末尾需出现新模块的路径,确认模块已成功集成。##### (2)停止原Nginx服务```bash# 优雅停止服务(发送停止信号,等待现有连接处理完成后退出)[root@nginx nginx-1.24.0]# nginx -s stop# 验证服务是否已停止(无80端口监听即表示停止成功)[root@nginx nginx-1.24.0]# ss -anlt | grep 80(3)备份旧程序将原Nginx程序(/usr/local/nginx/sbin/nginx)备份到安全目录(如/opt),便于升级失败后回滚:123[root@nginx nginx-1.24.0]# cp /usr/local/nginx/sbin/nginx /opt/nginx_old_$(date +%Y%m%d)# 验证备份结果(查看/opt目录下是否有备份文件)[root@nginx nginx-1.24.0]# ls /opt/(4)替换旧程序为新程序将objs目录下的新程序覆盖到原安装路径:123[root@nginx nginx-1.24.0]# cp objs/nginx /usr/local/nginx/sbin/# 系统会提示“是否覆盖”,输入y确认cp:是否覆盖'/usr/local/nginx/sbin/nginx'? y(5)启动新Nginx服务并验证1234# 启动新服务[root@nginx nginx-1.24.0]# /usr/local/nginx/sbin/nginx# 验证服务状态(80端口监听表示启动成功)[root@nginx nginx-1.24.0]# ss -anlt | grep 80预期结果:输出类似LISTEN 0 128 0.0.0.0:80 0.0.0.0:*,表示Nginx已正常启动。(6)最终验证新模块是否生效查看Nginx版本与参数,确认新模块已加载:1[root@nginx ~]# nginx -V预期结果:参数中包含--add-module=../echo-nginx-module-master,表示平滑升级完成。6. 测试echo模块功能通过配置location使用echo模块,验证其是否正常工作。(1)修改Nginx配置文件1[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf在server块中添加如下location配置(用于匹配根路径/的请求):12345678server {    listen       80;    server_name  localhost;    # 新增:使用echo模块输出文本“ycy”    location / {        echo "ycy";  # echo模块的核心指令,直接输出指定内容    }}(2)检查配置文件语法正确性修改配置后需先检查语法,避免因错误导致服务启动失败:1[root@nginx ~]# nginx -t预期结果:输出nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok和nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful,表示语法正确。(3)重载Nginx配置(无需重启服务)1[root@nginx ~]# nginx -s reload(4)验证echo模块功能浏览器访问:直接在浏览器输入Nginx服务器IP(如192.168.100.10),会触发文件下载(因echo模块输出的文本无Content-Type头,浏览器默认当作文件处理,属于正常现象)。命令行访问(推荐,更准确):在本地Windows或其他Linux机器上执行curl命令:123# Windows cmd中执行(需确保本地能ping通服务器IP)[root@ycy3 html]# curl http://192.168.100.10ycy12345678910111213  **预期结果**:输出`ycy`,表示echo模块已正常生效,平滑升级成功。## 二、Nginx location配置案例`location`是Nginx的核心配置指令,用于根据客户端请求的**URI(统一资源标识符,如`/abc`、`/image/1.jpg`)** 匹配不同的配置块,实现访问控制、内容转发、页面返回等功能。以下详细说明`location`的语法、修饰符、匹配规则及实操案例。### (一)location核心概念#### 1. 功能定位`location`属于`server`块的子配置,每个`server`可包含多个`location`,Nginx会根据请求的URI匹配对应的`location`,并执行该块中的配置(如`echo`输出、`proxy_pass`转发、`deny`拒绝访问等)。#### 2. 基本语法```nginxlocation [修饰符] pattern {    # 配置指令(如echo、proxy_pass、root等)    指令1;    指令2;}修饰符:可选,用于定义匹配规则(如精确匹配、正则匹配等),决定匹配优先级。pattern:匹配模式,即URI的匹配规则(如/abc、~^/image/.*\.jpg$等)。配置块:匹配成功后执行的指令集合。(二)location修饰符详解不同修饰符对应不同的匹配规则和优先级,是location配置的核心。以下为常用修饰符的对比:修饰符匹配规则优先级适用场景示例=精确匹配:URI必须与pattern完全一致(包括字符、长度、路径分隔符/)最高匹配固定URI(如首页/、接口/api/login)location = /abc { ... }(仅匹配/abc,不匹配/abc/或/abc/123)~正则表达式匹配:区分大小写,pattern为正则表达式中高(按配置顺序)需区分大小写的URI匹配(如/ABC和/abc不同处理)location ~ /abc$ { ... }(匹配以/abc结尾的URI,如/test/abc,不匹配/test/ABC)^~前缀匹配:URI以pattern开头即匹配,匹配成功后停止后续搜索(不支持正则)中(高于~/~*,低于=)匹配某一类前缀URI(如/static/下的所有静态资源)location ^~ /static/ { ... }(匹配/static/css、/static/js/1.js等,且不再检查后续正则匹配)~*正则表达式匹配:不区分大小写,pattern为正则表达式中高(按配置顺序)无需区分大小写的URI匹配(如静态资源/image和/IMAGE同处理)location ~* /abc$ { ... }(匹配/abc、/ABC、/aBc等)无修饰符前缀匹配:URI以pattern开头即匹配,但匹配成功后仍会继续搜索正则匹配(不支持正则)最低通用前缀匹配(如/abc匹配/abc、/abc/123等)location /abc { ... }(匹配/abc、/abc/、/abc/dsa等)@命名location:仅用于内部请求(如try_files、error_page跳转),客户端无法直接访问仅内部使用内部跳转(如404页面、502错误页面)location @error_404 { return 404 "Page Not Found"; }(三)location匹配顺序与优先级Nginx处理location匹配时,严格遵循以下优先级(从高到低),一旦匹配成功且满足“停止搜索”条件,即不再检查后续规则:=精确匹配:优先检查所有带=的location,若URI完全匹配,直接执行该配置块,停止后续搜索。^~前缀匹配:检查带^~的location,若URI以pattern开头,直接执行该配置块,停止后续搜索(包括正则匹配)。正则匹配(~/~*):按location在配置文件中的定义顺序检查正则匹配(~和~*优先级相同,谁在前先匹配谁),若匹配成功,执行该配置块,停止后续搜索。无修饰符前缀匹配:最后检查无修饰符的location,匹配URI前缀最长的location(若多个无修饰符location的pattern均为URI前缀,选择最长的那个),执行该配置块。(四)实操案例(基于echo模块验证)以下案例均基于“已安装echo模块”的Nginx环境,通过echo输出文本验证匹配结果,所有案例的server块基础配置如下(仅修改location部分):12345server {    listen       80;    server_name  localhost;  # 服务器IP为192.168.100.10    # 以下为不同案例的location配置}案例1:无修饰符的前缀匹配配置内容:123location /abc {    echo "cy";  # 匹配成功后输出“cy”}匹配规则:URI以/abc开头即匹配,不区分后续路径。测试结果(通过curl命令验证):123456789101112131415161718# 测试1:URI=/abc → 匹配成功[root@ycy3 ~]#curl 192.168.100.10/abccy# 测试2:URI=/abc/ → 匹配成功(以/abc开头)[root@ycy3 ~]#curl 192.168.100.10/abc/cy# 测试3:URI=/abc/dsa → 匹配成功(以/abc开头)[root@ycy3 ~]#curl 192.168.100.10/abc/dsacy# 测试4:URI=/ab → 不匹配(不以/abc开头)[root@ycy3 ~]#curl 192.168.100.10/ab<html><head><title>404 Not Found</title></head><body><center><h1>404 Not Found</h1></center><hr><center>nginx/1.24.0</center></body></html>案例2:=精确匹配(匹配固定URI)子案例2.1:pattern为/abc(无末尾/)配置内容:123location = /abc {    echo "ycy";  # 仅匹配/abc时输出}匹配规则:URI必须与/abc完全一致,多一个/或多字符均不匹配。测试结果:123456789101112# 测试1:URI=/abc → 完全匹配,输出“ycy”[root@ycy3 ~]#curl 192.168.100.10/abcycy# 测试2:URI=/abc/ → 末尾多“/”,不匹配,返回404[root@ycy3 ~]#curl 192.168.100.10/abc/<html><head><title>404 Not Found</title></head><body><center><h1>404 Not Found</h1></center><hr><center>nginx/1.24.0</center></body></html>子案例2.2:pattern为/abc/(有末尾/)配置内容:123location = /abc/ {    echo "ycy";  # 仅匹配/abc/时输出}测试结果:123456789101112# 测试1:URI=/abc/ → 完全匹配,输出“ycy”[root@ycy3 ~]#curl 192.168.100.10/abc/ycy# 测试2:URI=/abc → 末尾少“/”,不匹配,返回404[root@ycy3 ~]#curl 192.168.100.10/abc<html><head><title>404 Not Found</title></head><body><center><h1>404 Not Found</h1></center><hr><center>nginx/1.24.0</center></body></html>关键结论:=修饰符对/敏感,配置时需严格匹配实际请求的URI格式(如客户端请求是/abc还是/abc/)。案例3:~正则匹配(区分大小写)配置内容:123location ~ /abc$ {  # 正则表达式:匹配以“/abc”结尾的URI($表示结尾)    echo "ycy";}匹配规则:URI必须以/abc结尾,且区分大小写(/ABC、/aBc不匹配)。测试结果:123456789101112131415161718192021222324# 测试1:URI=/abc → 以/abc结尾,匹配成功,输出“ycy”[root@ycy3 ~]#curl 192.168.100.10/abcycy# 测试2:URI=/test/abc → 以/abc结尾,匹配成功,输出“ycy”[root@ycy3 ~]#curl 192.168.100.10/test/abcycy# 测试3:URI=/abc/ → 以/abc/结尾(非/abc),不匹配,返回404[root@ycy3 ~]#curl 192.168.100.10/abc/<html><head><title>404 Not Found</title></head><body><center><h1>404 Not Found</h1></center><hr><center>nginx/1.24.0</center></body></html># 测试4:URI=/ABC → 大小写不匹配,不匹配,返回404[root@ycy3 ~]#curl 192.168.100.10/ABC<html><head><title>404 Not Found</title></head><body><center><h1>404 Not Found</h1></center><hr><center>nginx/1.24.0</center></body></html>案例4:=与~的优先级对比配置内容(=和~同时存在,=在前):12345678# 正则匹配:以/abc结尾的URIlocation ~ /abc$ {    echo "ycy";}# 精确匹配:仅/abclocation = /abc {    echo "cy";}匹配规则:根据优先级,=精确匹配高于~正则匹配,因此/abc会优先匹配=的location。测试结果:123456# 测试:URI=/abc → 优先匹配=的location,输出“cy”(而非正则的“ycy”)[root@ycy3 ~]#curl 192.168.100.10/abccy# 测试:URI=/test/abc → 不匹配=的location,匹配~的正则,输出“ycy”[root@ycy3 ~]#curl 192.168.100.10/test/abcycy关键结论:无论=和~在配置文件中的顺序如何,=的优先级始终最高,优先匹配。案例5:~*正则匹配(不区分大小写)配置内容:123location ~* /abc$ {  # 正则表达式:以/abc结尾,不区分大小写    echo "ycy";}匹配规则:URI以/abc结尾,且不区分大小写(/ABC、/aBc均匹配)。测试结果:123456789# 测试1:URI=/abc → 匹配成功,输出“ycy”[root@ycy3 ~]#curl 192.168.100.10/abcycy# 测试2:URI=/ABC → 大小写不同,但~*不区分,匹配成功,输出“ycy”[root@ycy3 ~]#curl 192.168.100.10/ABCycy# 测试3:URI=/aBc → 混合大小写,匹配成功,输出“ycy”[root@ycy3 ~]#curl 192.168.100.10/aBcycy(五)location匹配优先级总结(从高到低)12345678910111213#依次输出测试优先级location = /abc {            echo "ycy1";        }        location ~ /abc {            echo "ycy2";        }       location ~*/abc {            echo "ycy3";        }        location ^~ /abc {            echo "ycy4";        }为便于记忆,将location的匹配优先级整理为以下顺序,实际配置时需严格遵循:=精确匹配:完全匹配URI,优先级最高,匹配后立即执行,停止后续搜索。^~前缀匹配:URI以pattern开头,匹配后停止后续搜索(包括正则匹配)。~/~*正则匹配:按配置文件中location的定义顺序匹配,先定义的优先,匹配后停止搜索(~和~*优先级相同,仅区分大小写)。无修饰符前缀匹配:URI以pattern开头,匹配最长前缀的location,优先级最低。配置建议:固定URI(如/、/api/login)用=精确匹配,提高匹配效率。静态资源目录(如/static/、/image/)用^~前缀匹配,避免被正则匹配干扰。需区分大小写的URI(如API接口/User/Info)用~正则匹配。无需区分大小写的URI(如静态资源/css、/CSS)用~*正则匹配。通用前缀URI(如/blog/下的所有文章)用无修饰符匹配,作为兜底规则。
  • [技术干货] nginx状态码的使用及说明 — 转载
    常见200:服务器成功返回网页403:服务器拒绝请求。404:请求的网页不存在499:客户端主动断开了连接。500:服务器遇到错误,无法完成请求。502:服务器作为网关或代理,从上游服务器收到无效响应。503 - 服务不可用504:服务器作为网关或代理,但是没有及时从上游服务器收到请求。这些状态码被分为五大类100-199 用于指定客户端应相应的某些动作。200-299 用于表示请求成功。300-399 用于已经移动的文件并且常被包含在定位头信息中指定新的地址信息。400-499 用于指出客户端的错误。 (自己电脑这边的问题)500-599 用于支持服务器错误。 (对方的问题)二百的200 (成功) 服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页。201 (已创建) 请求成功并且服务器创建了新的资源。202 (已接受) 服务器已接受请求,但尚未处理。203 (非授权信息) 服务器已成功处理了请求,但返回的信息可能来自另一来源。204 (无内容) 服务器成功处理了请求,但没有返回任何内容。205 (重置内容) 服务器成功处理了请求,但没有返回任何内容。206 (部分内容) 服务器成功处理了部分 GET 请求。三百的300 (多种选择) 针对请求,服务器可执行多种操作。 服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择。301 (永久移动) 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。302 (临时移动) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。303 (查看其他位置) 请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。304 (未修改) 自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。305 (使用代理) 请求者只能使用代理访问请求的网页。 如果服务器返回此响应,还表示请求者应使用代理。307 (临时重定向) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。四百的400 (错误请求) 服务器不理解请求的语法。401 (未授权) 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。403 (禁止) 服务器拒绝请求。404 (未找到) 服务器找不到请求的网页。405 (方法禁用) 禁用请求中指定的方法。406 (不接受) 无法使用请求的内容特性响应请求的网页。407 (需要代理授权) 此状态代码与 401(未授权)类似,但指定请求者应当授权使用代理。408 (请求超时) 服务器等候请求时发生超时。409 (冲突) 服务器在完成请求时发生冲突。 服务器必须在响应中包含有关冲突的信息。410 (已删除) 如果请求的资源已永久删除,服务器就会返回此响应。411 (需要有效长度) 服务器不接受不含有效内容长度标头字段的请求。412 (未满足前提条件) 服务器未满足请求者在请求中设置的其中一个前提条件。413 (请求实体过大) 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。414 (请求的 URI 过长) 请求的 URI(通常为网址)过长,服务器无法处理。415 (不支持的媒体类型) 请求的格式不受请求页面的支持。416 (请求范围不符合要求) 如果页面无法提供请求的范围,则服务器会返回此状态代码。417 (未满足期望值) 服务器未满足"期望"请求标头字段的要求。五百的500 (服务器内部错误) 服务器遇到错误,无法完成请求。501 (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。502 (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。504 (网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。505 (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。其他1xx - 信息提示“100”:Continue“101”:witchingProtocols2xx - 成功“200”:OK“201”:Created“202”:Accepted“203”:Non-AuthoritativeInformation“204”:NoContent“205”:ResetContent“206”:PartialContent3xx - 重定向“300”:MultipleChoices“301”:MovedPermanently“302”:Found“303”:SeeOther“304”:NotModified“305”:UseProxy“307”:TemporaryRedirect4xx - 客户端错误“400”:BadRequest“401”:Unauthorized“402”:PaymentRequired“403”:Forbidden“404”:NotFound“405”:MethodNotAllowed“406”:NotAcceptable“407”:ProxyAuthenticationRequired“408”:RequestTime-out“409”:Conflict“410”:Gone“411”:LengthRequired“412”:PreconditionFailed“413”:RequestEntityTooLarge“414”:Request-URITooLarge“415”:UnsupportedMediaType“416”:Requestedrangenotsatisfiable“417”:ExpectationFailed5xx - 服务器错误“500”:InternalServerError“501”:NotImplemented“502”:BadGateway“503”:ServiceUnavailable“504”:GatewayTime-out“505”:HTTPVersionnotsupported100Continue初始的请求已经接受,客户应当继续发送请求的其余部分。(HTTP 1.1新)101Switching Protocols服务器将遵从客户的请求转换到另外一种协议(HTTP 1.1新)200OK一切正常,对GET和POST请求的应答文档跟在后面。201Created服务器已经创建了文档,Location头给出了它的URL。202Accepted已经接受请求,但处理尚未完成。203Non-Authoritative Information文档已经正常地返回,但一些应答头可能不正确,因为使用的是文档的拷贝(HTTP 1.1新)。204No Content没有新文档,浏览器应该继续显示原来的文档。如果用户定期地刷新页面,而Servlet可以确定用户文档足够新,这个状态代码是很有用的。205Reset Content没有新的内容,但浏览器应该重置它所显示的内容。用来强制浏览器清除表单输入内容(HTTP 1.1新)。206Partial Content客户发送了一个带有Range头的GET请求,服务器完成了它(HTTP 1.1新)。300Multiple Choices客户请求的文档可以在多个位置找到,这些位置已经在返回的文档内列出。如果服务器要提出优先选择,则应该在Location应答头指明。301Moved Permanently客户请求的文档在其他地方,新的URL在Location头中给出,浏览器应该自动地访问新的URL。302Found类似于301,但新的URL应该被视为临时性的替代,而不是永久性的。注意,在HTTP1.0中对应的状态信息是“Moved Temporatily”。出现该状态代码时,浏览器能够自动访问新的URL,因此它是一个很有用的状态代码。注意这个状态代码有时候可以和301替换使用。例如,如果浏览器错误地请求http://host/~user(缺少了后面的斜杠),有的服务器返回301,有的则返回302。严格地说,我们只能假定只有当原来的请求是GET时浏览器才会自动重定向。请参见307。303See Other类似于301/302,不同之处在于,如果原来的请求是POST,Location头指定的重定向目标文档应该通过GET提取(HTTP 1.1新)。304Not Modified客户端有缓冲的文档并发出了一个条件性的请求(一般是提供If-Modified-Since头表示客户只想比指定日期更新的文档)。服务器告诉客户,原来缓冲的文档还可以继续使用。305Use Proxy客户请求的文档应该通过Location头所指明的代理服务器提取(HTTP 1.1新)。307Temporary Redirect和302 (Found)相同。许多浏览器会错误地响应302应答进行重定向,即使原来的请求是POST,即使它实际上只能在POST请求的应答是303时才能重定向。由于这个原因,HTTP 1.1新增了307,以便更加清除地区分几个状态代码:当出现303应答时,浏览器可以跟随重定向的GET和POST请求;如果是307应答,则浏览器只能跟随对GET请求的重定向。(HTTP 1.1新)400Bad Request请求出现语法错误。401Unauthorized客户试图未经授权访问受密码保护的页面。应答中会包含一个WWW-Authenticate头,浏览器据此显示用户名字/密码对话框,然后在填写合适的Authorization头后再次发出请求。403Forbidden资源不可用。服务器理解客户的请求,但拒绝处理它。通常由于服务器上文件或目录的权限设置导致。404Not Found无法找到指定位置的资源。这也是一个常用的应答。405Method Not Allowed请求方法(GET、POST、HEAD、DELETE、PUT、TRACE等)对指定的资源不适用。(HTTP 1.1新)406Not Acceptable指定的资源已经找到,但它的MIME类型和客户在Accpet头中所指定的不兼容(HTTP 1.1新)。407Proxy Authentication Required类似于401,表示客户必须先经过代理服务器的授权。(HTTP 1.1新)408Request Timeout在服务器许可的等待时间内,客户一直没有发出任何请求。客户可以在以后重复同一请求。(HTTP 1.1新)409Conflict通常和PUT请求有关。由于请求和资源的当前状态相冲突,因此请求不能成功。(HTTP 1.1新)410Gone所请求的文档已经不再可用,而且服务器不知道应该重定向到哪一个地址。它和404的不同在于,返回407表示文档永久地离开了指定的位置,而404表示由于未知的原因文档不可用。(HTTP 1.1新)411Length Required服务器不能处理请求,除非客户发送一个Content-Length头。(HTTP 1.1新)412Precondition Failed请求头中指定的一些前提条件失败(HTTP 1.1新)。413Request Entity Too Large目标文档的大小超过服务器当前愿意处理的大小。如果服务器认为自己能够稍后再处理该请求,则应该提供一个Retry-After头(HTTP 1.1新)。414Request URI Too LongURI太长(HTTP 1.1新)。416Requested Range Not Satisfiable服务器不能满足客户在请求中指定的Range头。(HTTP 1.1新)500Internal Server Error服务器遇到了意料不到的情况,不能完成客户的请求。501Not Implemented服务器不支持实现请求所需要的功能。例如,客户发出了一个服务器不支持的PUT请求。502Bad Gateway服务器作为网关或者代理时,为了完成请求访问下一个服务器,但该服务器返回了非法的应答。503Service Unavailable服务器由于维护或者负载过重未能应答。例如,Servlet可能在数据库连接池已满的情况下返回503。服务器返回503时可以提供一个Retry-After头。504Gateway Timeout由作为代理或网关的服务器使用,表示不能及时地从远程服务器获得应答。(HTTP 1.1新)505HTTP Version Not Supported服务器不支持请求中所指明的HTTP版本。(HTTP 1.1新)
  • [技术干货] Nginx搭建前端本地预览环境的完整步骤教学 — 转载
    项目目录结构.├── logs              # 存放 Nginx 访问日志和错误日志│   ├── access.log│   └── error.log├── nginx.conf        # Nginx 配置文件├── nginx.sh          # Nginx 启动/停止/重载脚本├── package.json      # npm 脚本配置└── utils.sh          # (可选)工具脚本这样整理后,前端项目和本地 Nginx 部署逻辑绑定在一起,不需要频繁写长命令。核心配置文件:nginx.conf1234567891011121314151617181920212223242526272829303132333435363738394041worker_processes 1;       # 启动的 worker 数量 events {    worker_connections 1024;  # 每个 worker 最大连接数} http {    include /opt/homebrew/etc/nginx/mime.types;   # 识别常见文件类型    default_type application/octet-stream;     sendfile on;              # 高效传输文件    keepalive_timeout 65;     # 长连接超时时间     # 日志文件路径    access_log /Users/luoluqi/Desktop/ngnix-server/logs/access.log;    error_log  /Users/luoluqi/Desktop/ngnix-server/logs/error.log warn;     server {        listen 8080;                               # 监听端口        server_name localhost;                     # 本地访问域名         root /Users/luoluqi/Desktop/blockify-ui/docs-dist; # 前端打包目录        index index.html;         # 单页面应用路由处理        location / {            try_files $uri $uri/ /index.html;        }         # 静态资源缓存        location ~* .(js|css|png|jpg|jpeg|gif|svg|ico|woff2?|ttf|eot)$ {            expires 30d;            add_header Cache-Control "public";        }         # 禁止访问隐藏文件        location ~ /. {            deny all;        }    }}配置要点:root:指定前端打包产物目录。try_files:保证 SPA 项目在刷新时不会 404,而是回退到 index.html。静态资源缓存:让 JS/CSS 等资源缓存 30 天,更接近生产环境。隐藏文件保护:禁止访问 .git、.env 等敏感文件。脚本化操作:nginx.sh12345678910111213141516171819202122#!/bin/bashBASE_DIR=$(cd "$(dirname "$0")"; pwd)NGINX_CONF="$BASE_DIR/nginx.conf" case "$1" in  start)    echo "Starting Nginx..."    nginx -c "$NGINX_CONF"    ;;  reload)    echo "Reloading Nginx configuration..."    nginx -s reload    ;;  stop)    echo "Stopping Nginx..."    nginx -s stop    ;;  *)    echo "Usage: ./nginx.sh {start|reload|stop}"    exit 1    ;;esac这样就不用每次手动敲 nginx -c 或 nginx -s reload,直接 ./nginx.sh start 即可。npm 脚本集成在 package.json 里增加:12345"scripts": {  "nginx:start": "./nginx.sh start",  "nginx:reload": "./nginx.sh reload",  "nginx:stop": "./nginx.sh stop"}这样就可以用熟悉的 npm 命令来操作:123npm run nginx:startnpm run nginx:reloadnpm run nginx:stop总结:对前端的意义快速验证打包产物:不用每次都等后端部署。模拟生产环境:测试缓存策略、路由、错误日志。更专业的本地调试:和移动端、后端联调时避免跨域或开发环境差异。一键化操作:脚本化 + npm 集成,让前端工程师也能轻松用上 Nginx。建议:在团队中可以把这套配置放到前端仓库里(例如 nginx/ 文件夹),大家拉代码后就能直接启动,减少环境差异。