当前位置: 首页 > article >正文

Nginx Lua模块(OpenResty)实战:动态化、智能化你的Nginx,实现复杂Web逻辑 (2025)

更多服务器知识,尽在hostol.com

嘿,各位Nginx的“铁杆粉丝”和“配置大师”们!咱们都知道,Nginx以其超凡的性能、稳定性和丰富的模块化功能,在Web服务器、反向代理、负载均衡等领域独步青云,简直是服务器软件界的“常青树”和“万人迷”。但是,你有没有在某些时候觉得,Nginx那基于静态配置文件的“行事风格”,在处理一些需要更强动态性、更复杂判断逻辑的场景时,显得有点“力不从心”或者“束手束脚”?比如,你想根据用户IP的地理位置动态调整后端服务,或者想在Nginx层面实现一个超轻量级的API参数校验,又或者想在把请求打到后端应用前,先去Redis里查点儿数据做个预处理……这些用纯Nginx配置写起来可能九曲十八弯,甚至根本实现不了。

这时候,你就需要祭出Nginx的“隐藏大招”,堪称“核武器”级别的增强模块了——那就是**`ngx_http_lua_module`**,以及基于它构建的更为强大的Web平台**OpenResty**!它们能让你的Nginx瞬间“开窍”,学会“说”Lua这门轻巧又高效的脚本语言,从而在Nginx的各个处理阶段注入你自己的动态逻辑。今天,Hostol就带你一起揭开Nginx + Lua这对“黄金搭档”的神秘面纱,看看它们是如何让你的Nginx从一个“循规蹈矩的交通警察”变身为一个“能文能武、随机应变的特种兵王”的!


Lua 与 Nginx 的“跨界联姻”:当高性能Web服务器遇到轻量级脚本语言

1. `ngx_http_lua_module` 是何方神圣?

简单来说,ngx_http_lua_module是一个第三方Nginx模块(在OpenResty中是核心组件),它把LuaJIT(一个超快的Lua即时编译器)或者标准的Lua解释器直接嵌入到了Nginx的工作进程中。这意味着,你可以在Nginx的配置文件里,直接编写或调用外部的Lua脚本,让这些脚本在Nginx处理HTTP请求的各个阶段(比如接收请求头后、访问控制检查时、内容生成时、响应过滤时等)执行你的自定义逻辑。

2. OpenResty又是什么?——“Nginx + Lua全家桶”

如果你觉得单独编译Nginx并集成ngx_http_lua_module以及其他相关的Lua库(比如操作Redis、MySQL的库)太麻烦,那么OpenResty就是为你量身打造的“一站式解决方案”。OpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数 Nginx 的标准模块。你可以把它看作是一个“超级Nginx”,出厂就自带了Lua引擎和一大堆实用的“瑞士军刀”(比如lua-resty-core, lua-resty-redis, lua-resty-mysql, lua-resty-upload等等),让你能用Lua在Nginx里轻松实现各种复杂功能,而无需重新编译Nginx。

Hostol建议: 对于大多数想在Nginx中使用Lua的场景,直接使用OpenResty通常是最省心、最高效的选择。

3. 为啥要在Nginx里用Lua?它能带来哪些“魔法”?

你可能会问:“我直接把这些逻辑放在后端的PHP/Java/Python应用里不行吗?为啥非得在Nginx这层折腾?” 问得好!在Nginx层面用Lua处理,很多时候能带来意想不到的好处:

  • 超高性能与非阻塞I/O: Lua脚本在Nginx中是基于Nginx自身的事件驱动、非阻塞模型运行的(通过Lua的协程和Nginx提供的非阻塞API,如ngx.socket.tcp(), ngx.location.capture())。这意味着,当你的Lua脚本需要进行网络调用(比如访问Redis、数据库、或其他HTTP API)时,它不会阻塞当前的Nginx工作进程去处理其他请求,而是会“挂起”当前请求,让Nginx先去忙别的,等网络I/O操作完成后再回来继续处理。这种“一心多用”的能力,使得Nginx+Lua能够轻松应对极高的并发。
  • 减少到后端应用的请求,降低延迟: 对于一些可以在Nginx层面快速处理的逻辑(比如简单的API参数校验、用户身份认证、AB测试分流、根据特定条件修改请求头/响应头等),直接用Lua在Nginx内部解决,可以避免一次到后端应用服务器的网络往返,从而显著降低请求延迟。这就像在公司前台就能解决的小问题,就不用再麻烦总经理了。
  • 强大的灵活性与可扩展性: Lua本身是一门小巧、灵活、易于嵌入的脚本语言。通过它,你可以像“搭积木”一样,快速地给Nginx添加各种自定义功能,而无需编写复杂的C模块或重新编译Nginx。
  • 构建高性能API网关: 利用Nginx+Lua,可以轻松构建出功能强大的API网关,实现请求路由、认证鉴权、流量控制、日志记录、监控告警、服务编排等复杂功能。
  • 实现自定义WAF逻辑: 虽然有专业的WAF模块,但有时你可能需要一些非常定制化的、轻量级的Web应用防火墙规则,用Lua在Nginx里实现会非常灵活。

可以这么说,Nginx+Lua就像是给Nginx这台“F1赛车”又加装了一套“智能辅助驾驶系统”和“氮气加速”,让它不仅跑得快,还能在复杂的“赛道”上做出各种风骚的“漂移动作”!


“开箱上膛”:Nginx中嵌入Lua代码的几种姿势

要在Nginx里运行Lua代码,主要是在Nginx配置文件的特定“钩子点”(处理阶段)使用相应的指令。Nginx将HTTP请求的处理过程划分为了多个阶段,你可以在这些阶段通过Lua脚本介入,影响请求的处理流程。

常见的Lua指令和它们对应的处理阶段(只列举部分核心的):

  • 变量设置阶段:
    • set_by_lua_block { lua_code }
    • set_by_lua_file /path/to/script.lua;
    • 作用:执行Lua代码,并将返回结果(字符串)设置为一个Nginx变量的值。通常在请求处理早期,用于动态生成一些后续配置会用到的变量。
  • 重写/路由阶段 (Rewrite Phase):
    • rewrite_by_lua_block { lua_code }
    • rewrite_by_lua_file /path/to/script.lua;
    • 作用:在此阶段执行Lua代码,可以进行复杂的URL重写、内部跳转、或者根据条件修改请求参数等。
  • 访问控制阶段 (Access Phase):
    • access_by_lua_block { lua_code }
    • access_by_lua_file /path/to/script.lua;
    • 作用:执行访问控制逻辑。比如根据IP、请求头、API密钥等判断是否允许访问,如果Lua脚本执行了ngx.exit(ngx.HTTP_FORBIDDEN),则请求会被拒绝。
  • 内容生成阶段 (Content Phase):
    • content_by_lua_block { lua_code }
    • content_by_lua_file /path/to/script.lua;
    • 作用:直接由Lua脚本生成HTTP响应内容,并发送给客户端。这使得Nginx可以直接充当一个轻量级的应用服务器!比如用Lua直接输出JSON或HTML。
  • 响应头/响应体过滤阶段 (Header/Body Filter Phase):
    • header_filter_by_lua_block { lua_code } / header_filter_by_lua_file ...;
    • body_filter_by_lua_block { lua_code } / body_filter_by_lua_file ...;
    • 作用:分别用于在Nginx将响应头或响应体发送给客户端之前,用Lua脚本对其进行修改。比如动态添加/删除/修改响应头,或者对响应内容进行过滤替换。
  • 日志记录阶段 (Log Phase):
    • log_by_lua_block { lua_code }
    • log_by_lua_file /path/to/script.lua;
    • 作用:在请求处理完毕,即将写入访问日志之前执行。可以用来实现非常灵活和定制化的日志记录逻辑,比如把日志发送到远程分析系统,或者记录更丰富的上下文信息。

*_block { ... } 后面直接跟Lua代码块,适合简短的逻辑。*_file /path/to/script.lua; 则指定一个外部Lua脚本文件,适合更复杂的逻辑,也更利于代码的组织和复用。


实战演练:“Lua弹药”上膛,让Nginx“指哪打哪”!

光说不练假把式,咱们来看几个简单但实用的例子,感受一下Nginx+Lua的威力!

示例1:基于IP黑名单的动态访问控制 (access_by_lua_block)

假设我们想阻止某些“不受欢迎”的IP地址访问我们的网站。我们可以把黑名单IP存在Redis里(当然也可以用其他方式)。

# nginx.conf 的 http 块中 (或者 server 块,如果只想对特定server生效)
# 定义一个lua共享字典,用来做简单的IP缓存,避免频繁查Redis
lua_shared_dict ip_blacklist_cache 10m;server {listen 80;server_name example.com;location / {access_by_lua_block {local redis = require "resty.redis"local cache = ngx.shared.ip_blacklist_cachelocal client_ip = ngx.var.remote_addrlocal cache_key = "ip_blacklist:" .. client_ip-- 先查本地缓存local is_blocked_cached = cache:get(cache_key)if is_blocked_cached == "1" thenngx.log(ngx.WARN, "IP ", client_ip, " blocked by local cache.")return ngx.exit(ngx.HTTP_FORBIDDEN)elseif is_blocked_cached == "0" then-- 缓存说它是安全的,直接放行 (可选,取决于你的策略)return ngx.OK end-- 本地缓存没有,去查Redislocal red = redis:new()red:set_timeout(1000) -- 1秒超时local ok, err = red:connect("127.0.0.1", 6379)if not ok thenngx.log(ngx.ERR, "Failed to connect to Redis: ", err)return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) -- Redis连不上,可以考虑放行或直接报错end-- 假设黑名单IP在Redis的Set "ip_blacklist_set" 中local is_member, err = red:sismember("ip_blacklist_set", client_ip)red:close() -- 及时关闭连接if err thenngx.log(ngx.ERR, "Failed to query Redis: ", err)return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)endif is_member == 1 thenngx.log(ngx.WARN, "IP ", client_ip, " found in Redis blacklist, blocking.")cache:set(cache_key, "1", 3600) -- 缓存1小时这个IP是被封的return ngx.exit(ngx.HTTP_FORBIDDEN)elsecache:set(cache_key, "0", 300) -- 缓存5分钟这个IP是安全的-- ngx.OK (或者不写,默认就是OK,会继续处理请求)end}# 如果上面的Lua代码没有exit,请求会继续走到这里root /var/www/html;index index.html index.htm;}
}

这个例子展示了如何在access_by_lua_block中连接Redis(需要lua-resty-redis库,OpenResty自带),查询IP是否在黑名单中,并利用Nginx的共享内存字典(lua_shared_dict)做一层简单的本地缓存,减少对Redis的请求压力。是不是感觉Nginx瞬间变成了一个智能的“防火墙”?

示例2:用Lua直接输出JSON响应 (content_by_lua_block)

有时候你可能需要一个超轻量级的API接口,直接由Nginx返回一些动态信息,而不想再启动一个后端应用(比如PHP-FPM或Tomcat)。

location /api/hello {default_type 'application/json'; # 设置响应类型content_by_lua_block {local cjson = require "cjson" -- OpenResty自带的快速JSON库local response_data = {message = "Hello from Nginx powered by Lua!",timestamp = ngx.time(),server_name = ngx.var.server_name}ngx.say(cjson.encode(response_data))}
}

访问/api/hello,Nginx就会直接返回一段JSON,是不是超酷?

示例3:动态修改响应头 (header_filter_by_lua_block)

比如,你想给所有从特定后端应用返回的响应都加上一个自定义的X-Powered-By头,或者删掉一些敏感的后端服务器信息头。

location /app1/ {proxy_pass http://backend_app1_server;# ...其他proxy配置...header_filter_by_lua_block {ngx.header["X-Powered-By"] = "Nginx + Lua Magic"ngx.header["X-App-Version"] = nil -- 删除可能存在的X-App-Version头}
}

Nginx Lua API “小抄” (ngx.*家族):

在Lua脚本里,你可以通过ngx.这个全局对象来访问Nginx的各种功能和请求上下文信息:

  • ngx.var.NGINX_VARIABLE_NAME:访问Nginx变量(比如ngx.var.uri, ngx.var.arg_name, ngx.var.http_user_agent)。
  • ngx.req.* 系列函数:用于请求处理,如ngx.req.get_headers(), ngx.req.set_header(), ngx.req.get_method(), ngx.req.get_uri_args(), ngx.req.read_body(), ngx.req.set_uri()等。
  • ngx.resp.* 系列函数:用于响应处理,如ngx.resp.add_header(), ngx.resp.get_headers()
  • ngx.say("...") / ngx.print("..."):输出响应内容(主要在content_by_lua_*阶段使用)。
  • ngx.exit(HTTP_STATUS_CODE):中断当前请求处理,并以指定的HTTP状态码退出。
  • ngx.log(ngx.LEVEL, "message"):向Nginx的错误日志输出信息(ngx.ERR, ngx.WARN, ngx.INFO, ngx.DEBUG等)。
  • 非阻塞I/O的关键:ngx.socket.tcp(), ngx.location.capture(), ngx.sleep()(这个sleep是协作式的,不会阻塞Nginx worker)。
  • 共享内存字典:ngx.shared.DICT_NAME,用于在Nginx的各个worker进程间共享少量数据(需要先在http块用lua_shared_dict指令定义)。


调试你的“Lua魔法”:

  • 日志是最好的朋友: 大量使用ngx.log(ngx.ERR, "调试信息: ", 变量值),把你想看的信息打印到Nginx的错误日志里。记得把Nginx错误日志的级别(error_log /path/to/error.log warn;中的warn)调得足够低(比如notice, info甚至debug)才能看到你的Lua日志。
  • lua_code_cache on/off; 在开发调试阶段,可以在http块或server块设置lua_code_cache off;(默认为on)。这样每次请求Nginx都会重新加载Lua脚本文件,方便你修改脚本后立即看到效果,不用频繁reload Nginx。但生产环境务必改回lua_code_cache on;,否则性能会大打折扣!
  • 小步快跑,独立测试: 复杂的Lua逻辑,可以先在本地用标准的Lua解释器(或LuaJIT)写一些小的测试单元,确保逻辑正确,再嵌入到Nginx配置中。


性能考量与最佳实践:

  • LuaJIT很快,但不是万能药: 虽然LuaJIT性能卓越,但过于复杂或低效的Lua代码仍然可能成为瓶颈。尽量保持Lua逻辑的简洁和高效。
  • 警惕阻塞操作: 在Nginx的Lua脚本中,绝对要避免任何可能导致阻塞的同步操作(比如直接用Lua标准库进行文件IO或网络IO)。所有需要等待的操作,都应该使用Nginx Lua模块提供的非阻塞API(如ngx.socket.*, ngx.location.capture, ngx.pipe等),或者使用基于这些API封装好的lua-resty-*库。
  • 共享数据要小心: Nginx是多worker进程模型。如果你在lua_shared_dict中存取数据,要注意并发访问可能带来的问题(虽然它本身提供了一些原子操作)。对于复杂的状态共享,可能需要更专业的方案(如Redis)。
  • 代码复用: 把常用的Lua函数封装成模块(.lua文件),然后在你的Nginx配置中通过require "my_module"来调用,保持配置的整洁和代码的可维护性。


怎么样,是不是感觉Nginx的“技能树”又被点亮了一大片?通过ngx_http_lua_module(或者说OpenResty的强大生态),Nginx不再仅仅是一个高性能的Web服务器和反向代理,它摇身一变,成了一个功能极其强大、灵活可编程的Web应用平台、API网关、动态防火墙……几乎无所不能!它就像是给了你一把能“随心所欲修改游戏规则”的“GM权限密钥”。虽然上手可能需要一点时间和对Nginx处理流程的理解,但一旦你掌握了Nginx+Lua这对“王炸组合”,你会发现,以前很多需要依赖后端应用才能实现的复杂逻辑,现在在Nginx层面就能举重若轻地搞定,那种酣畅淋漓的感觉,绝对会让你大呼过瘾!Hostol希望这篇“核武器”入门指南,能为你打开新世界的大门,去探索Nginx更深邃、更强大的潜能吧!

相关文章:

Nginx Lua模块(OpenResty)实战:动态化、智能化你的Nginx,实现复杂Web逻辑 (2025)

更多服务器知识,尽在hostol.com 嘿,各位Nginx的“铁杆粉丝”和“配置大师”们!咱们都知道,Nginx以其超凡的性能、稳定性和丰富的模块化功能,在Web服务器、反向代理、负载均衡等领域独步青云,简直是服务器软…...

openssl 怎么生成吊销列表

mkdir test cd test # 根据 /usr/lib/ssl/openssl.cnf 配置文件中目录结构可知有个demoCA目录,目录下有各种文件。 mkdir ./demoCA ./demoCA/newcerts ./demoCA/private sudo chmod 777 -R ./demoCA/ echo 01 > ./demoCA/serial touch ./demoCA/index.txt # /usr…...

Go语言包的组织与导入 -《Go语言实战指南》

在 Go 语言中,包(Package) 是管理代码模块化、复用性与可维护性的核心单位。本章将讲解如何组织包结构、如何导入其他包、以及项目中的最佳实践。 一、什么是包? • 每个 .go 文件都属于某个包(通过 package 声明&…...

springboot-响应接收与ioc容器控制反转、Di依赖注入

1.想将服务器中的数据返回给客户端,需要在controller类上加注解:ResponseBody; 这个注解其实在前面已经使用过,RestController其实就包含两个注解: Controller ResponseBody 返回值如果是实体对象/集合,将会转换为j…...

CSP使用严格设置

文章目录 说明示例 说明 日期:2025年6月2日。 内容安全政策(MPS)是一个额外的安全层,有助于检测和缓解某些类型的攻击。包括(但不限于)跨站点脚本(XSS)和数据注入攻击。这些攻击用…...

Spring代理工厂类ProxyFactory作用以及实现原理

代理工厂类ProxyFactory AdvisedSupport(代理配置信息类)ProxyFactory(代理工厂类)小结测试 源码见:mini-spring 在 AOP(面向切面编程)中,Spring 支持两种常见的代理机制&#xff1a…...

SpringBoot使用MQTT协议简述

在 Spring Boot 中使用 MQTT 协议连接硬件设备&#xff0c;可以通过以下步骤实现。这里以 Eclipse Paho MQTT 客户端为例&#xff1a; 1. 添加 Maven 依赖 <dependencies><!-- Spring Boot Starter --><dependency><groupId>org.springframework.boo…...

【GraphQL】深入解析 Apollo Client:从架构到实践的一站式 GraphQL 解决方案

深入解析 Apollo Client&#xff1a;从架构到实践的一站式 GraphQL 解决方案 1. 引言 GraphQL 作为现代 API 开发的核心技术&#xff0c;其灵活性和高效性正在重塑数据交互模式。Apollo Client 作为 GraphQL 生态中最受欢迎的客户端库&#xff0c;凭借强大的缓存机制、框架集…...

集成电路制造设备防震基座选型指南:为稳定护航-江苏泊苏系统集成有限公司

集成电路制造设备防震基座选型指南&#xff1a;为稳定护航 在集成电路制造这一精密复杂的领域&#xff0c;每一个环节都如同精密仪器中的微小齿轮&#xff0c;一丝偏差都可能导致严重后果。制造设备的稳定运行更是重中之重&#xff0c;而防震基座作为守护设备稳定的第一道防线…...

华为OD机试真题——阿里巴巴找黄金宝箱(II)(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳实现

2025 A卷 100分 题型 本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式; 并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析; 本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分…...

Vue中 toRaw 和 markRaw 的使用

背景 针对一些特殊的需求&#xff0c;在项目里&#xff0c;需要将响应式数据变为普通原始类型数据&#xff0c;这种情况是有的 在 Vue 中&#xff0c;能够将普通数据类型的数据变为响应式数据&#xff0c;也能将响应式类型数据变为普通类型数据&#xff0c;用于提升数据的性能…...

探索DeepSeek提示词:关键策略与实用场景

在人工智能飞速发展的时代&#xff0c;DeepSeek作为一款备受关注的AI工具&#xff0c;其强大的功能为用户提供了高效便捷的服务。然而&#xff0c;要充分发挥DeepSeek的潜力&#xff0c;掌握提示词的使用策略至关重要。本文将深入探讨DeepSeek提示词的关键策略&#xff0c;并结…...

海底三维可视化平台

1. 摘要 本文作者为视觉分析构建了一个真实海底的“虚拟世界”。在3D环境中导入底部轮廓。在该模型中&#xff0c;通过地震反射获得的海床地层剖面被数字化为离散点&#xff0c;并用克里金算法进行插值&#xff0c;以在每个地层中产生均匀的网格。然后在每一层构建 Delaunay三…...

Elasticsearch 读写流程深度解析

在数据驱动的数字化浪潮中&#xff0c;Elasticsearch 凭借其毫秒级搜索响应与水平扩展能力&#xff0c;已成为现代数据架构的核心引擎。本文将深入剖析其读写流程的设计思想、实现细节与工程权衡&#xff0c;揭示这一分布式系统的精妙架构。 一、 架构基石&#xff1a;分布式设…...

AIoT赋能场馆数字化转型:智能管理新生态

在数字化浪潮席卷全球的当下&#xff0c;传统场馆管理模式已难以满足日益增长的高效运营与精细化服务需求。智慧场馆建设成为行业发展的必然趋势&#xff0c;而AIoT&#xff08;人工智能物联网&#xff09;技术的深度应用&#xff0c;为多系统集成提供了全新的解决方案&#xf…...

1、Pytorch介绍与安装

1、Pytorch介绍 PyTorch 是由 Facebook AI Research (FAIR) 团队开发并维护的一款开源深度学习框架&#xff0c;于 2016 年首次发布。它因其直观的设计、卓越的灵活性以及强大的动态计算图功能&#xff0c;迅速在学术界和工业界获得了广泛认可&#xff0c;成为当前深度学习研究…...

【从零开始学习QT】Qt 概述

目录 一、什么是 Qt 1.1 简介 1.2 Qt 的发展史 1.3 Qt 支持的平台 1.5 Qt 的优点 1.6 Qt 的应用场景 二、搭建 Qt 开发环境 2.1 Qt SDK 的下载 2.2 Qt SDK 的安装 2.3 验证 Qt SDK 安装是否成功 2.4 Qt 环境变量配置 三、认识 Qt Creator 3.1 Qt Creator 概览 3.…...

家庭路由器改装,搭建openwrt旁路由以及手机存储服务器,实现外网节点转发、内网穿透、远程存储、接入满血DeepSeek方案

大家好&#xff0c;也是好久没有发文了&#xff0c;最近在捣鼓一些比较有趣的东西&#xff0c;打算跟大家分享一下&#xff01; 先聊一下我的大致方案嘛&#xff0c;最近感觉家里路由器平时一直就只有无线广播供网的功能&#xff0c;感觉这么好的一下嵌入式设备产品不应该就干这…...

人工智能工程技术专业 和 其他信息技术专业 有哪些关联性?

人工智能工程技术专业与其他信息技术专业之间存在紧密的关联性&#xff0c;这些关联既体现在基础理论、技术体系上&#xff0c;也反映在行业应用和技术融合的趋势中。以下从多个维度解析它们的关联性&#xff1a; 一、基础学科与核心技术的共通性 数学与算法基础 关联专业&…...

基于本地模型+多级校验设计的高效缓存,有效节省token数量(有点鸡肋doge)。

前言 我是基于token有限而考虑的一个省钱方案&#xff0c;还能够快速返回结果&#xff0c;但是劣势也很明显&#xff0c;设计不好容易出问题&#xff0c;就如下面所介绍的语义飘逸和缓存污染&#xff0c;我认为在自己学习大模型的过程用来省钱非常可以&#xff0c;再加上学习过…...

逐步检索增强推理的跨知识库路由学习

摘要 多模态检索增强生成&#xff08;MRAG&#xff09;在多模态大语言模型&#xff08;MLLM&#xff09;中通过在生成过程中结合外部知识来减轻幻觉的发生&#xff0c;已经显示出了良好的前景。现有的MRAG方法通常采用静态检索流水线&#xff0c;该流水线从多个知识库&#xff…...

用Git管理你的服务器配置文件与自动化脚本:版本控制、变更追溯、团队协作与安全回滚的运维之道

更多服务器知识&#xff0c;尽在hostol.com 咱们在和服务器打交道的日子里&#xff0c;是不是经常要和各种各样的配置文件&#xff08;Nginx的、Apache的、PHP的、防火墙的……&#xff09;还有自己辛辛苦苦写下的自动化脚本打交道&#xff1f;那你有没有遇到过这样的“抓狂”…...

【数据库】关系数据库标准语言-SQL(金仓)下

4、数据查询 语法&#xff1a; SELECT [ALL | DISTINCT] <目标列表达式> [,<目标列表达式>] … FROM <表名或视图名>[, <表名或视图名> ] … [ WHERE <条件表达式> ] [ GROUP BY <列名1> [ HAVING <条件表达式> ] ] [ ORDER BY <…...

Vue3+SpringBoot全栈开发:从零实现增删改查与分页功能

前言 在现代化Web应用开发中&#xff0c;前后端分离架构已成为主流。本文将详细介绍如何使用Vue3作为前端框架&#xff0c;SpringBoot作为后端框架&#xff0c;实现一套完整的增删改查(CRUD)功能&#xff0c;包含分页查询、条件筛选等企业级特性。 技术栈介绍 前端&#xff1…...

小黑大语言模型应用探索:langchain智能体构造源码demo搭建1(初步流程)

导入工具包 rom langchain_core.tools import BaseTool from typing import Sequence, Optional, List from langchain_core.prompts import BasePromptTemplate import re from langchain_core.tools import tool from langchain_core.prompts.chat import (ChatPromptTempla…...

极客时间:用 FAISS、LangChain 和 Google Colab 模拟 LLM 的短期与长期记忆

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…...

leetcode hot100刷题日记——35.子集

解答&#xff1a; 方法一&#xff1a;选or不选的dfs&#xff08;输入视角&#xff09; 思路&#xff1a;[1,2,3]的全部子集可以看成是对数组的每一位数字做选择。 eg.空集就是一个数字都不选&#xff0c;[1,2]就是1&#xff0c;2选&#xff0c;3不选。 class Solution { pub…...

MybatisPlus(含自定义SQL、@RequiredArgsConstructor、静态工具类Db)

大家在日常开发中应该能发现&#xff0c;单表的CRUD功能代码重复度很高&#xff0c;也没有什么难度。而这部分代码量往往比较大&#xff0c;开发起来比较费时。 因此&#xff0c;目前企业中都会使用一些组件来简化或省略单表的CRUD开发工作。目前在国内使用较多的一个组件就是…...

React 组件异常捕获机制详解

1. 错误边界&#xff08;Error Boundaries&#xff09;基础 在React应用开发中&#xff0c;组件异常的有效捕获对于保证应用稳定性至关重要。React提供了一种称为"错误边界"的机制&#xff0c;专门用于捕获和处理组件树中的JavaScript错误。 错误边界是React的一种…...

手眼标定:九点标定、十二点标定、OpenCV 手眼标定

因为一直使用6轴协作机器人&#xff0c;且主要应用是三维视觉&#xff0c;平常的手眼标定基本都是基于OpenCV来计算的&#xff0c;听说有九点标定和十二点标定&#xff0c;顺便了解下。 目录 1.九点标定1.1 基本原理1.2 关于最小二乘法1.3 具体示例 2.十二点标定3.OpenCV 手眼标…...