• [行业前沿] 从 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/ 文件夹),大家拉代码后就能直接启动,减少环境差异。
  • [技术干货] Nginx实现前端重定向的三种方法介绍 — 转载
    方法 1:使用 rewrite 指令123456789101112server {    listen 80;    server_name 127.0.0.1;     # 方法1.1:在server级别重写    rewrite ^/test-chat/orig_docs/(.*)$ /orig_docs/$1 permanent;     # 或者方法1.2:在location中重写    location /test-chat/orig_docs/ {        rewrite ^/test-chat/orig_docs/(.*)$ /orig_docs/$1 permanent;    }}方法 2:使用 location 代理12345678910111213141516171819202122232425server {    listen 80;    server_name 127.0.0.1;     location /test-chat/orig_docs/ {        # 移除test-chat前缀        rewrite ^/test-chat(/orig_docs/.*)$ $1 break;         # 代理到实际服务        proxy_pass http://your_backend_server;        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;    }     location /orig_docs/ {        # 处理原始/orig_docs请求        proxy_pass http://your_backend_server;        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;    }}方法 3:精确的路径重写12345678server {    listen 80;    server_name 127.0.0.1;     location ~ ^/test-chat/orig_docs/(.+)$ {        return 301 /orig_docs/$1;    }}完整的 nginx 配置示例123456789101112131415161718192021222324252627282930313233server {    listen 80;    server_name 127.0.0.1;     # 访问日志    access_log /var/log/nginx/access.log;    error_log /var/log/nginx/error.log;     # 重写规则:移除test-chat前缀    rewrite ^/test-chat/orig_docs/(.*)$ /orig_docs/$1 permanent;     # 处理/orig_docs请求    location /orig_docs/ {        # 这里配置您的后端服务        proxy_pass http://backend_server;        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;         # 可选:设置超时时间        proxy_connect_timeout 30s;        proxy_send_timeout 30s;        proxy_read_timeout 30s;    }     # 其他location配置...    location / {        # 默认处理        root /usr/share/nginx/html;        index index.html;    }}配置说明permanent (301 重定向):浏览器会记住重定向,适合永久性 URL 变更redirect (302 重定向):临时重定向,每次都会请求原 URLbreak:在 server 内部重写,不对外部重定向测试配置12345# 检查nginx配置语法nginx -t # 重新加载配置nginx -s reload
  • [技术干货] Nginx 配置详解-转载
    Nginx 是一款高性能的 Web 服务器、反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在互联网领域应用广泛。其配置文件采用模块化结构,通过配置文件可以灵活实现负载均衡、动静分离、虚拟主机等功能。一、配置文件基础结构Nginx 的主配置文件通常位于/etc/nginx/nginx.conf,其他配置文件可通过include指令包含进来:# 全局块:配置影响nginx全局的指令,通常是和nginx服务运行相关的参数user  nginx;           # 运行用户worker_processes  1;   # 工作进程数,通常设置为CPU核心数 # 错误日志配置error_log  /var/log/nginx/error.log warn;pid        /var/run/nginx.pid; # events块:影响nginx服务器与用户的网络连接events {    worker_connections  1024;  # 每个工作进程的最大连接数} # http块:配置代理、缓存、日志定义等绝大多数功能和第三方模块的配置http {    include       /etc/nginx/mime.types;  # 文件扩展名与类型映射表    default_type  application/octet-stream;  # 默认文件类型        # 日志格式定义    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;    keepalive_timeout  65;        # 虚拟主机配置    include /etc/nginx/conf.d/*.conf;}AI生成项目二、配置块详解Nginx 配置块详解-CSDN博客 三、虚拟主机配置 (server 块)虚拟主机是 Nginx 最常用的功能之一,可以在一台服务器上运行多个网站:# 基于域名的虚拟主机配置server {    listen       80;                # 监听端口    server_name  example.com;       # 域名        # 访问日志    access_log  /var/log/nginx/example.access.log;        # 默认请求处理    location / {        root   /var/www/example;    # 网站根目录        index  index.html index.htm;  # 默认首页文件    }        # 错误页面配置    error_page   500 502 503 504  /50x.html;    location = /50x.html {        root   /usr/share/nginx/html;    }} # 另一个虚拟主机server {    listen       80;    server_name  blog.example.com;        location / {        proxy_pass http://127.0.0.1:8080;  # 反向代理到后端服务        proxy_set_header Host $host;        proxy_set_header X-Real-IP $remote_addr;    }}AI生成项目四、反向代理与负载均衡配置Nginx 最强大的功能之一就是反向代理和负载均衡:# 定义后端服务器集群upstream backend_servers {    # 轮询调度(默认)    server 192.168.1.100:8080 weight=5;  # 权重为5    server 192.168.1.101:8080 weight=3;  # 权重为3    server 192.168.1.102:8080 weight=2;  # 权重为2        # 会话保持(基于IP哈希)    # ip_hash;        # 健康检查    keepalive 32;} server {    listen 80;    server_name example.com;        location / {        proxy_pass http://backend_servers;  # 代理到后端集群                # 常用代理头设置        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;                # 超时设置        proxy_connect_timeout 30s;        proxy_send_timeout 60s;        proxy_read_timeout 60s;                # 缓冲区设置        proxy_buffer_size 32k;        proxy_buffering on;        proxy_buffers 4 128k;        proxy_busy_buffers_size 256k;        proxy_max_temp_file_size 256k;    }}AI生成项目五、动静分离配置将动态请求和静态请求分开处理,提高性能:server {    listen 80;    server_name example.com;        # 静态文件处理    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {        root /var/www/static;  # 静态文件目录        expires 7d;             # 缓存7天        access_log off;         # 关闭访问日志        add_header Cache-Control "public";    }        # 动态请求处理    location / {        proxy_pass http://backend_servers;        proxy_set_header Host $host;        proxy_set_header X-Real-IP $remote_addr;    }}AI生成项目六、HTTPS 配置配置 HTTPS 需要 SSL 证书:server {    listen 80;    server_name example.com;    return 301 https://$host$request_uri;  # 强制跳转HTTPS} server {    listen 443 ssl;    server_name example.com;        # SSL证书配置    ssl_certificate /path/to/cert.pem;       # 证书文件    ssl_certificate_key /path/to/key.pem;   # 私钥文件        # SSL会话缓存    ssl_session_cache shared:SSL:10m;    ssl_session_timeout 10m;        # SSL协议和加密算法    ssl_protocols TLSv1.2 TLSv1.3;    ssl_prefer_server_ciphers on;    ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384";        # 其他配置    location / {        root /var/www/example;        index index.html;    }}AI生成项目七、访问控制配置限制特定 IP 或用户访问:server {    listen 80;    server_name example.com;        # 基于IP的访问控制    location /admin {        deny 192.168.1.1;            # 拒绝单个IP        allow 192.168.1.0/24;       # 允许整个网段        allow 10.1.1.0/16;        deny all;                   # 拒绝其他所有    }        # 基于密码的访问控制    location /private {        auth_basic "Restricted Area";        auth_basic_user_file /etc/nginx/.htpasswd;    }}AI生成项目八、缓存配置配置 Nginx 缓存可以显著提高性能:http {    # 定义缓存区域    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;        server {        listen 80;        server_name example.com;                location / {            proxy_pass http://backend_servers;                        # 启用缓存            proxy_cache my_cache;            proxy_cache_valid 200 302 10m;  # 200和302状态码缓存10分钟            proxy_cache_valid 404 1m;        # 404状态码缓存1分钟                        # 设置缓存键            proxy_cache_key "$scheme$request_method$host$request_uri";                        # 缓存控制头            add_header X-Cache $upstream_cache_status;        }    }}AI生成项目九、Gzip 压缩配置启用 Gzip 可以减小传输数据量,提高加载速度:http {    # Gzip压缩配置    gzip on;    gzip_disable "msie6";  # 对IE6禁用        # 压缩级别和类型    gzip_vary on;    gzip_proxied any;    gzip_comp_level 6;    gzip_buffers 16 8k;    gzip_http_version 1.1;    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;}AI生成项目十、常见问题与优化1)配置加载:修改配置后无需重启服务nginx -s reloadAI生成项目2)检查配置语法:修改配置后检查语法是否正确nginx -tAI生成项目3)优化建议:worker_processes 设置为 CPU 核心数根据内存大小调整 worker_connections静态文件使用长缓存策略启用 HTTP/2 提高传输效率使用 sendfile 加速文件传输4)性能监控:location /nginx_status {    stub_status on;    access_log off;    allow 127.0.0.1;    deny all;}AI生成项目通过 stub_status 模块获取 Nginx 状态Nginx 的配置非常灵活,可以根据实际需求进行定制。以上只是一些常见的配置示例,实际使用时需要根据服务器性能、应用特点和访问量进行调整和优化。————————————————                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-NC-SA 版权协议,转载请附上原文出处链接和本声明。                        原文链接:https://blog.csdn.net/ygq13572549874/article/details/148423772
  • [技术干货] Nginx 报403 Forbidden错误常见原因和解决方案—转载
    当 Nginx 代理配置出现 403 Forbidden 错误时,通常是由于权限或配置问题导致。以下是常见原因和解决方案:常见原因及解决方法1.后端服务器拒绝访问原因:后端 HTTPS 服务配置了 IP 白名单或访问控制解决:检查后端服务器(如 Apache/Nginx)的访问限制规则将 Nginx 代理服务器的 IP 加入白名单在后端服务中关闭临时访问控制(测试用)2.Nginx 权限问题12# 在 server 块开头添加user www-data;  # 确保与系统用户一致检查:12ps aux | grep nginx  # 查看运行用户ls -ld /var/lib/nginx/  # 查看缓存目录权限修复:12chown -R www-data:www-data /var/lib/nginx/chmod -R 755 /var/cache/nginx3.缺少索引文件(目录访问)现象:访问 / 时出现 403解决:1234567location / {    # 添加默认索引    index index.html index.htm;         # 或显式禁止目录列表    autoindex off;}4.SELinux 限制(CentOS/RHEL)12345# 临时关闭(测试用)setenforce 0 # 永久解决semanage permissive -a httpd_t或添加策略:1setsebool -P httpd_can_network_connect 15.代理头信息缺失123456789location / {    proxy_pass https://backend;         # 必须添加以下头    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;}完整调试配置123456789101112131415161718192021222324252627282930server {    listen 80;    server_name proxy.example.com;         # 权限设置    user www-data;    access_log /var/log/nginx/proxy_access.log;    error_log /var/log/nginx/proxy_error.log debug;  # 开启调试日志     location / {        proxy_pass https://backend.example.com;                 # 关键头信息        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;                 # HTTPS 设置        proxy_ssl_server_name on;        proxy_ssl_protocols TLSv1.2 TLSv1.3;                 # 临时关闭证书验证(测试)        proxy_ssl_verify off;                 # 超时设置        proxy_connect_timeout 60s;        proxy_read_timeout 180s;    }}诊断步骤检查 Nginx 错误日志1tail -f /var/log/nginx/proxy_error.log查找 permission denied 或 access forbidden 相关条目测试直接访问后端1curl -vk https://backend.example.com -H "Host: proxy.example.com"确认后端服务是否可用检查文件权限1namei -l /var/lib/nginx/proxy/*临时简化配置移除所有非必需配置,仅保留 proxy_pass 和 proxy_set_header 测试测试代理连通性12# 在 Nginx 服务器上执行curl -x http://localhost:80 https://google.com常见错误日志分析*13 directory index of "/var/www/html/" is forbidden➜ 添加 index index.html; 或关闭 autoindex*102 connect() to [backend] failed (13: Permission denied)➜ SELinux 问题或防火墙阻挡upstream prematurely closed connection while reading response➜ 增加 proxy_read_timeout 值提示:生产环境调试后,记得恢复证书验证:12proxy_ssl_verify on;proxy_ssl_trusted_certificate /etc/ssl/certs/ca-bundle.crt;
  • [技术干货] 记一次nginx访问快捷方式指向的文件夹失败的排查解决过程
    起因是项目上有一个文件域名,dns解析到linux系统的服务器上,有一个nginx服务反向代理了一个位于nas挂载盘内的文件目录,现在有一个新需求是让客户还是通过这个域名作为访问入口,访问同样位于nas盘中和这个目录同级的另一个目录内的文件。比如通过nginx反向代理访问的nas盘下的目录路径为/mnt/picture/,访问的url为:https://picture.test.cn/cache/20260101/1749690185966.jpg和picture同级的目录路径为:/mnt/bak/,期望的访问url为:https://picture.test.cn/bak/20251024/1749690185966.jpg我第一时间想到的就是通过软连接的方式,将/mnt/bak目录软连接到/mnt/picture/bak目录:ln -s /mnt/bak/ /mnt/picture/baknginx的配置简略如下:server { listen 443; server_name picture.test.cn; ... location / { root /mnt/picture/; }}访问没有问题,当然还可以通过增加一个location,使用bak关键字代理/mnt/bak/目录。本地开发机器是windwos10,在一个盘符下创建了两个文件夹模拟了linux机器上的挂载盘目录进行开发测试,nginx的配置简略如下:server { listen 8066; server_name picture.test.cn; location / { root D:/tmp/mnt/picture/; }}两个目录分别是:D:/tmp/mnt/picture/、D:/tmp/mnt/bak我在D:/tmp/mnt/picture/下创建了一个D:/tmp/mnt/bak目录的快捷方式,快捷方式的名称叫bak,hosts文件中配置域名到本机的映射。访问http://picture.test.cn:8066/bak/20251024/1749690185966.jpg却提示我文件不存在:nginx的error日志如下:2026/10/24 09:41:16 [error] 16584#7532: *4 CreateFile() "D:/tmp/mnt/picture/bak/20251024/1749690185966.jpg" failed (3: The system cannot find the path specified), client: 127.0.0.1, server: picture.test.cn, request: "GET /bak/20251024/1749690185966.jpg HTTP/1.1", host: "picture.test.cn:8066"明明我可以在文件系统中点击快捷方式进入对应的文件夹,为啥nginx却不识别,问了下ai(不得不说现在ai确实是一个好帮手),其核心原因有这些:1.快捷方式本质是特殊文件Windows快捷方式(.lnk)是系统级符号链接文件,需由操作系统解析路径。但Nginx作为Web服务器,仅读取实际文件或目录内容,不会解析.lnk文件的目标路径。2.Nginx配置依赖物理路径Nginx的root或alias指令需指向真实目录(如D:\folder),若指向含快捷方式的目录,Nginx会将快捷方式视为普通文件而非目录入口,导致访问失败。3.路径安全限制Nginx默认禁止访问路径含符号链接的文件(安全策略),且Windows路径格式(反斜杠\、中文名等)易引发兼容性问题。ai提供了解决方案:1.NTFS 联结点(Junction Point)实现类似 Linux 软链接的效果文件系统需要是NTFS,以管理员身份运行CMD:mklink /J "D:\tmp\mnt\picture\bak" "D:\tmp\mnt\bak"2.修改Nginx配置启用路径解析nginx的location下增加如下配置:disable_symlinks off; # 允许解析符号链接其中disable_symlinks于nginx的1.1.15版本中增加,默认开启,需要在编译nginx时增加--with-file-aio参数。通过nginx -v和nginx -V确认项目上使用的nginx版本为1.22.0,服务器上的nginx也启用了--with-file-aio参数。为何Nginx在Linux支持软链接而Windows不支持快捷方式?ai给出了回答:Linux:Nginx 通过系统调用(如 open())访问文件时,内核自动解析软链接路径,服务无需额外处理。Windows:Nginx 直接读取文件系统,但 .lnk 是需解析的二进制文件,非标准目录入口,因此无法识别其指向的真实路径。按照ai给出的解决方案,我在本地windows机器上使用mklink创建了目录联结:mklink /J "D:\tmp\mnt\picture\bak" "D:\tmp\mnt\bak"再次访问http://picture.test.cn:8066/bak/20251024/1749690185966.jpg已经可以访问。我让ai详细说说mklinkmklink 是 Windows 系统(Vista 及以上版本)提供的命令行工具,用于创建文件或目录的链接,其功能类似于 Linux 中的 ln 命令,但实现机制和类型划分更为复杂。以下是其核心特性和使用场景的详细解析:1.mklink 的链接类型2.关键差异与注意事项权限要求符号链接(/D)和文件硬链接(/H)需管理员权限运行 CMD,目录联结(/J)则不需要。路径解析符号链接支持相对路径(如 ..\target),联结仅支持绝对路径。移动符号链接可能导致相对路径失效,而联结的绝对路径仍有效。跨分区限制硬链接不可跨分区,符号链接和联结可跨分区但需目标存在。可以看到通过快捷方式和mklink命令创建出来的文件是可以同名的,但是其类型不一样,一个是快捷方式,一个是文件夹ai还提到了nginx的disable_symlinks标签需要防止攻击者通过上传符号链接文件访问/etc/passwd 等系统文件,我在windows上测试添加这个标签发现,windows上的nginx并不支持这个标签,其核心限制原因如下:1.平台兼容性问题disable_symlinks 是 Nginx 针对类 Unix 系统(如 Linux)设计的特性,依赖文件系统符号链接权限检查机制,而Windows NTFS 文件系统的符号链接管理逻辑与此不兼容,导致该指令在 Windows 环境下无效或无法正确解析。尝试在 Windows 配置中使用时,nginx -t 会提示语法错误或未知指令(如 unknown directive "disable_symlinks")。2.版本无实质支持即使用户使用的是较新的 Nginx 1.22.0 或更高版本,其Windows 编译版仍未适配此功能。官方并未在 Windows 构建中启用相关依赖模块(如 --with-file-aio)。本地windwos机器只是用来开发测试,倒是不影响,生产服务器上需要严格做好目录权限的划分以及在上传文件的入口强校验文件的类型。转载自https://www.cnblogs.com/imadc/p/18938385
  • [技术干货] OpenResty 入门实战(1)--简介及安装
    本文介绍的 OpenResty 为开源版本 OpenResty,官网地址为:https://openresty.org/cn/,如需了解商业版本,可访问商业官网:https://openresty.com.cn/cn/;文中所使用到的软件版本:OpenResty 1.21.4.2、pcre 8.43、opnessl 1.1.1s、zlib 1.2.11、CentOS 7.9.2009。1、简介OpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。OpenResty® 通过汇聚各种设计精良的 Nginx 模块(主要由 OpenResty 团队自主开发),从而将 Nginx 有效地变成一个强大的通用 Web 应用平台。这样,Web 开发人员和系统工程师可以使用 Lua 脚本语言调动 Nginx 支持的各种 C 以及 Lua 模块,快速构造出足以胜任 10K 乃至 1000K 以上单机并发连接的高性能 Web 应用系统。OpenResty® 的目标是让你的 Web 服务直接跑在 Nginx 服务内部,充分利用 Nginx 的非阻塞 I/O 模型,不仅仅对 HTTP 客户端请求,甚至于对远程后端诸如 MySQL、PostgreSQL、Memcached 以及 Redis 等都进行一致的高性能响应。2、安装OpenResty 的安装与 Nginx 基本一致。2.1、下载源码OpenResty 源码:https://openresty.org/cn/download.htmlpcre 源码:http://www.pcre.org/openssl 源码:https://www.openssl.org/source/zlib 源码:http://www.zlib.net/下载后解压:tar zxvf openresty-1.21.4.2.tar.gzunzip pcre-8.43.ziptar zxvf openssl-1.1.1s.tar.gztar zxvf zlib-1.2.11.tar.gz2.2、编译安装cd openresty-1.21.4.2./configure --prefix=/home/mongo/soft/openresty-1.21.4.2 --with-luajit --with-pcre=/home/mongo/installfile/pcre-8.43 --with-http_ssl_module --with-openssl=/home/mongo/installfile/openssl-1.1.1s --with-zlib=/home/mongo/installfile/zlib-1.2.11 --with-mail --with-streammakemake install--with-luajit 表示使用默认的 luajit,也可以指定其他的 luajit 目录;其他参数说明可参考:Nginx 入门实战(1)--简介及安装。2.3、启动OpenResty 同 Nginx 一样默认配置了一个端口为 80 Http 服务器,使用普通用户启动需要修改该端口;编辑 conf/nginx.conf 文件:http { include mime.types; default_type application/octet-stream; ... server { listen 8080; ...执行启动命令:sbin/nginx启动后访问 8080 端口:2.4、停止及重启sbin/nginx -s stop #停止sbin/nginx -s reload #重启