- 博客(41)
- 收藏
- 关注
原创 问题复盘:Agent 每隔 30 秒上报,为什么 HTTP 连接越用越多?
本文通过一个定时心跳上报场景,揭示了HTTP/1.1中未读取并关闭响应体(Body)会导致连接无法复用,进而引发连接数持续增长、超时等问题。实验表明:仅关闭Body不能保证连接复用,必须完整读取至EOF后关闭,才能实现连接重用。即使请求成功返回200,若忽略正文处理,仍会占用连接资源,最终因连接池耗尽导致后续请求失败。核心结论:“不读不关”是隐藏的资源泄漏点,需确保响应体被完整读取并关闭。
2026-10-23 09:00:00
461
原创 明明写了 defer Close,为什么日志任务还是报 too many open files?
尽管使用了 defer f.Close(),但因关闭操作被推迟至外层函数返回才执行,导致大量文件在循环中持续打开,最终耗尽系统文件描述符(FD),引发“too many open files”错误。问题根源在于 defer 的执行时机晚于单个文件的使用周期。修复方法是将关闭逻辑移至每轮处理结束时立即执行,或拆分函数使 defer 与单个文件生命周期绑定,确保资源及时释放。
2026-10-22 16:00:00
693
原创 日志聚合接口已经超时,后台任务为什么还没结束?
日志聚合接口超时后,后台 goroutine 仍未退出,根源在于无缓冲 channel 的发送操作未受 context 取消影响。即使请求结束、上下文取消,若结果通道无接收方,worker 仍会阻塞在 out <- result 这一发送动作上,导致任务无法退出。本地验证表明,取消通知不自动唤醒阻塞的 channel 发送,必须显式处理取消逻辑。排查关键:区分“请求返回”与“任务真正结束”,通过堆栈分析定位到具体发送行,确认等待点而非仅依赖数量变化。最终发现,真正的泄漏点是未监听 context 的 cha
2026-10-22 09:00:00
168
原创 从 0 到 1 构建 GitHub 自动化测试 Case Reviewer Bot(二):小试牛刀-先跑一遍基础的功能
这一篇只验证本地服务和本地链路。不配置 GitHub webhook。不发布 PR 评论。不打开 LLM。这几个都放后面。先把本地服务跑稳,下一篇再让 GitHub 真的来调用它。服务能启动/health 能访问basic-smoke 能通过这三个确认完成后,再接 GitHub webhook 就更轻松简单了。
2026-08-26 10:00:00
308
原创 从 0 到 1 构建 GitHub 自动化测试 Case Reviewer Bot(一):实现一个测试代码Review 机器人
这里的 case 指自动化测试用例,不是业务需求里的 case。})case_namefile_pathframeworkraw_codeassertionssummary这些信息后面会进入 case memory,作为历史记忆。## 自动化测试用例 Review 结果本次变更检测到 2 个新增或修改的自动化测试用例。- 结论:新测试用例- 最高相似度:0%- 文件:`tests/test_login3.py`**新增用例意图**- 覆盖对象:`login3`- 场景:`-`
2026-08-26 09:00:00
461
原创 从零理解 AI Skill:不只是Markdown这么简单
Skill 这东西看起来没有 Agent 框架、MCP Server、向量数据库那么热闹。但我越用越觉得,它很接近 AI 工程化的基础设施。业务规则架构约定发布流程故障处理经验数据口径安全红线Review 偏好这些东西不会自动存在于模型里。你不写,Agent 就只能猜。Skill 的意义,就是把这些“以前靠人记住、靠口头传递、靠踩坑积累”的东西,变成 AI 可以读取、可以执行、可以迭代的能力资产。Prompt 是一次性交互。Skill 是长期协作方式。
2026-07-17 08:30:00
6151
1
原创 一次 ClickHouse 审计日志查询优化:从 P95 9.6s 到 420ms 左右
本文探讨了ClickHouse审计日志查询的优化方案。作者通过真实业务场景(脱敏处理)和本地实验数据(500万行)对比分析,发现原有查询存在读放大问题:列表查询常读取百万行数据,且带大字段detail_json导致高read_bytes。核心问题在于表设计(ORDER BY顺序不匹配租户查询模式)和查询混合(明细、统计、搜索等多类需求共用同一查询链路)。优化思路包括:重构表结构使主键匹配查询模式、分离不同类型查询职责、避免不必要的大字段读取。实验数据显示优化后read_rows和read_bytes显著下降
2026-07-14 23:37:33
5684
原创 PR Reviewer Bot 优化指导手册(自用)
把一个已经能跑通基础流程的 PR reviewer-bot,逐步优化成更可靠、更可解释、更适合团队内部长期试运行的版本。这份文档不追求一步到位做成平台,而是按“先准确、再稳定、再生产化”的顺序推进。
2026-07-14 10:58:22
5622
原创 Golang 实战 ELK 日志系统全流程教程(六):把 Logstash 加进日志链路
本文介绍了如何在Golang ELK日志系统中集成Logstash,构建更完整的日志处理链路。从Filebeat直连Elasticsearch的基础架构演进为Filebeat→Logstash→Elasticsearch的架构,重点讲解了Logstash作为日志加工层的核心作用。 文章提供了具体实现步骤: 在docker-compose中添加Logstash服务配置 修改Filebeat配置使其输出到Logstash而非直接写入ES 编写基础的Logstash管道配置(pipeline.conf)
2026-06-04 09:00:00
5661
原创 Golang 实战 ELK 日志系统全流程教程(五):Filebeat 采集 Go 日志并写入 Elasticsearch
本文是《Golang 实战 ELK 日志系统全流程教程》系列的第五篇,主要介绍如何使用 Filebeat 采集 Go 服务日志并写入 Elasticsearch。文章从日志采集链路的最简模式(Go→Filebeat→ES→Kibana)入手,详细讲解了 Filebeat 的核心功能、目录准备、Docker 部署配置、filebeat.yml 关键参数(特别是 ndjson 解析配置),以及如何验证日志采集是否成功。重点内容包括:Filebeat 的 registry 机制对日志位置记录的重要性、JSON 日
2026-06-02 09:00:00
15911
原创 Golang 实战 ELK 日志系统全流程教程(四):Go 项目日志字段设计和结构化输出
文章摘要 本文是Golang实战ELK日志系统系列教程的第四篇,重点讲解如何设计Go项目的日志字段并实现结构化输出。作者指出,在接入ELK之前,必须先规范应用日志的结构化输出,否则会导致后续日志分析困难。文章详细分析了传统文本日志的痛点(如字段名不统一、数值类型不明确等),并给出了理想的JSON日志示例,强调关键字段(如service_name、trace_id、cost_ms等)应稳定统一。作者推荐使用zap日志库实现结构化输出,并分享了一个封装logger包的最佳实践,包括时间格式、公共字段注入等细节。
2026-06-01 09:30:00
5634
原创 【Golang 实战 ELK 日志系统全流程教程(三):ElasticSearch和kibanna环境搭建】
本文介绍如何搭建Elasticsearch和Kibana环境来构建Go应用的日志系统。主要内容包括: 使用Docker Compose部署Elasticsearch 9.4.1和Kibana 9.4.1,确保版本一致 配置单节点Elasticsearch环境,关闭安全认证以简化本地开发 重点说明关键配置项:单节点模式、JVM内存限制、Kibana连接ES的服务名等常见误区 提供详细的环境验证步骤,包括ES健康检查、Kibana访问和日志查看 最后通过手动写入一条模拟的Go应用日志,确认整个链路可正常工作 文
2026-05-29 09:00:00
5681
原创 Python asyncio 模块学习总结:从“等着”到“切出去干点别的”
本文介绍了Python asyncio模块的核心概念和使用方法。asyncio适用于I/O密集型任务,通过协程和事件循环实现异步并发。文章通过示例展示了async/await的基本用法,解释了协程、Task和事件循环的工作原理,并介绍了gather()批量并发、Semaphore控制并发数等实用技巧。同时指出了同步阻塞代码在异步环境中的问题,以及如何正确使用await进行非阻塞等待。最后提及了超时处理的重要性,为开发者提供了从同步思维转向异步编程的实践指导。
2026-05-25 23:28:56
5800
原创 AI应用系统理解学习:向量搜索
本文介绍了向量搜索的基本原理及其在语义检索中的应用。向量搜索通过将文本转换为向量表示,能够捕捉语义相似性,克服传统关键词搜索的局限性。文章对比了稀疏向量(如TF-IDF)和稠密向量(如BERT)的特点,并解释了向量空间模型的工作原理。通过代码示例展示了文本向量化、相似度计算和结果排序的完整流程,最后使用PCA降维可视化文本向量在二维空间的分布,直观呈现语义相近文本的向量距离较近的特性。
2026-05-07 10:36:24
15784
原创 5分钟理解 RAG:从零开始构建你的第一个检索增强生成系统
RAG(检索增强生成)技术通过结合信息检索与大语言模型,有效解决传统LLM的知识过时、幻觉等问题。本文以130行代码实现极简RAG系统,核心流程包括:加载知识库文档、文本嵌入转换为向量、计算余弦相似度检索相关内容,最后基于检索结果生成答案。通过5分钟快速理解RAG原理,为后续深入学习奠定基础。
2026-03-18 09:00:00
5820
原创 AI时代,正在重演纺织工的故事
《AI时代的技术革命与程序员未来》通过工业革命中纺织业的历史变迁,揭示了技术变革对社会结构的重塑过程。文章指出,工业革命并非简单的技术升级,而是生产关系的系统性重构,这一规律正在AI时代重演。当前AI技术处于类似珍妮纺纱机的早期阶段,虽已显著提升编程效率,但尚未触及系统设计层。未来程序员将面临分层:执行层工作将被自动化取代,而系统架构、AI协作和复杂问题解决等高认知角色价值将提升。历史经验表明,技术革命最终带来的是职业结构而非就业总量的变化,关键在于主动适应新工具、重新定位自身在技术生态中的位置。
2026-03-18 09:00:00
5750
原创 极简 AI Agent Demo:一个文件,跑完 Thought → Act → Observation
摘要:基于CloudWeGo Eino框架的ReAct Agent天气查询系统 本文介绍了一个基于CloudWeGo Eino框架实现的ReAct模式AI Agent,用于智能天气查询服务。该系统通过Reason+Act交替执行的方式,解决了传统LLM直接应答在复杂业务场景中的局限性。Agent具备自动判断是否需要工具、多步推理完成任务的能力,能够处理不完整信息、依赖外部系统和多步决策等场景。文章详细阐述了三种不同的Tool封装方式(NewTool、InferTool和InvokableTool接口),并比
2026-01-26 08:30:00
17502
原创 gRPC Web 应用实战从入门到精通(四):构建支持自发现的 gRPC 微服务(基于 Consul)
摘要: 本文介绍了如何构建支持自发现的gRPC微服务,使用Consul实现服务注册、发现与负载均衡。通过Docker快速部署Consul,并演示如何将gRPC服务注册到Consul,同时实现健康检查。客户端通过动态获取服务实例列表,结合gRPC负载均衡策略,实现多实例请求分配。代码示例展示了服务端注册逻辑和健康检查配置,为微服务架构提供了可扩展的解决方案。
2026-01-19 09:47:00
6064
原创 【gRPC Web 应用实战从入门到精通(三):实现简单的负载均衡服务】
本文介绍了如何通过gRPC实现客户端负载均衡,结合HTTP网关代理gRPC服务。主要内容包括:1)解析gRPC-Go中的Builder接口,说明如何自定义服务发现与地址解析逻辑;2)实现包含3个实例的gRPC服务端;3)客户端通过自定义resolver.Builder注入多个服务地址,并使用round_robin策略实现轮询访问。通过Gin框架搭建HTTP网关,将HTTP请求转发到gRPC服务,演示了简单的服务治理能力。该方案可在无服务注册中心的情况下,实现服务的横向扩展和负载均衡。
2025-08-05 08:30:00
6607
原创 【Golang玩转本地大模型实战(四):基于Eino实现AI 编程搭档】
本文介绍了基于Golang和Eino框架开发本地大语言模型应用的实践。文章首先回顾了前文实现的AI聊天系统,包括模型部署、Web对话界面和上下文记忆功能。重点解析了Eino框架的核心组件ChatModel(封装大模型交互接口)和ChatTemplate(处理提示模板),通过代码示例展示了流式调用、多轮对话等功能的实现。最后通过"结对编程"项目实战,演示了如何利用Eino简化开发流程,快速构建智能对话系统。文章为开发者提供了使用Golang开发本地大模型应用的高效方案。
2025-07-29 08:30:00
7244
2
原创 【Go 实践学习】内存泄漏情景及pprof工具使用(下半篇)
本文介绍了Go语言中pprof工具的使用方法,以及如何通过实战排查内存泄漏问题。pprof是Go官方内置的性能分析工具,可对CPU、内存、Goroutine等进行采样分析。文章详细讲解了pprof的安装、基本使用、命令行工具操作和可视化Web界面查看分析结果。同时提供了多种内存泄漏场景的实战示例代码,包括切片泄漏、日志缓冲泄漏、协程泄漏等12种常见情况,并搭建了基于Gin框架的测试环境,方便观察和分析内存泄漏现象。最后介绍了如何通过/reset接口优雅重启服务进行测试验证。
2025-07-03 08:30:00
6962
4
原创 【Golang 实战 ELK 日志系统全流程教程(二):Zap 收集日志,并通过 Filebeat 发送】
本文介绍了一个基于微服务的日志采集系统实现方案。系统采用Gin框架构建Web服务,使用Zap日志库实现JSON格式日志记录,支持文件和终端双输出。主要功能包括:1) Gin服务路由配置与优雅退出机制;2) Zap日志中间件记录请求详情;3) 业务日志采集处理。系统通过Docker容器化部署,利用Filebeat实现日志采集转发,配置Harvester和Input组件进行日志文件监控。项目结构清晰,包含完整的Dockerfile和docker-compose编排文件。后续可扩展对接ELK或Kafka等日志分析
2025-06-27 08:30:00
6693
原创 【Golang 实战 ELK 日志系统全流程教程(一):ELK 是什么?为什么要用 ELK?】
在服务架构日益复杂、微服务化和分布式环境盛行的今天,一个可搜索、可视化、可扩展的日志分析系统已成为项目开发、运维监控、业务运营的关键基础设施。ELK 作为业界主流日志分析方案,以其强大的功能和良好的生态,成为众多企业的首选。本篇文章将介绍 ELK 的基本概念、核心组件的作用,以及它为何成为日志系统的首选方案。本篇博客简要介绍了 ELK 体系的架构、组件职责及整体工作流程。
2025-06-18 09:00:00
6414
原创 【Golang玩转本地大模型实战(三):实现上下文记忆,让对话更连贯】
在本系列的前两篇文章中,我们已经完成了一个基于Golang与Ollama[第一篇]:《Golang玩转本地大模型实战(一):ollama部署模型及流式调用》,介绍如何在本地部署大模型并实现 Golang 端的 API 调用;[第二篇]:《Golang玩转本地大模型实战(二):基于Golang + Web实现AI对话页面》,实现了前后端结合的实时聊天功能,支持 WebSocket 与 SSE。缺乏上下文记忆。每次对话模型都只能“盲目作答”,无法结合历史对话内容生成连贯回应。
2025-05-08 08:30:00
7881
4
原创 【Golang玩转本地大模型实战(二):基于Golang + Web实现AI对话页面】
在上一篇文章中,我们学习了如何通过 Ollama 在本地部署大模型,并使用 Golang 实现了流式与非流式的 API 调用。本篇将继续实战,目标是打造一个完整的 网页端 AI 对话系统。该系统基于前后端协作,通过 WebSocket 和 SSE(Server-Sent Events)两种流式传输协议,实现模型回复的实时展示效果。最终实现效果为:本次项目的基本流程如下:SSE(Server-Sent Events)是一种基于 HTTP 的单向推送协议,允许服务器持续向浏览器发送数据。文件下:这段代码的主要
2025-04-30 08:30:00
8804
6
原创 【Golang玩转本地大模型实战(一):ollma部署模型及流式调用】
近年来,AI技术迅猛发展,作为后端程序员,掌握基本的AI应用开发能力变得尤为重要。即使不深入研究模型底层原理,具备快速部署模型并在应用中调用的能力,也能极大地扩展自身技能边界。本系列文章将从AI模型的本地部署到后端调用接口,再到前端交互展示,以最简化的方式,带领大家完成一个完整的AI应用开发流程。使用Ollama部署本地模型,并通过Golang实现非流式和流式的API调用。Ollama是一个本地大模型部署工具,极其易用,非常适合快速上手体验AI应用开发。如何安装并使用Ollama快速部署本地大模型;
2025-04-28 08:30:00
7628
2
原创 【gRPC Web 应用实战从入门到精通(二):gRPC 协议与通信机制】
在上一章节【gRPC Web 应用实战从入门到精通(一):为什么选择 gRPC 及基础使用】中,我们已经通过Golang启动了一个简单的 gRPC 服务,初步体验了 gRPC 的使用流程。从使用体验上来看,gRPC 与传统 HTTP 服务相似,但整体启动过程更加复杂,对前置环境的要求也更高。知其然,更要知其所以然。本章中,我们将借助Wireshark抓包工具,直观地分析 gRPC 与 HTTP 服务在底层协议上的本质区别,并探究为什么在微服务架构中,gRPC 成为了越来越多团队的首选。
2025-04-27 12:45:54
6484
原创 【gRPC Web 应用实战从入门到精通(一):为什么选择 gRPC 及基础使用】
随着 Web 微服务架构的逐渐普及,企业对 Web 应用的性能和可扩展性提出了更高的要求。对于现代 Web 应用而言,具备灵活控制吞吐量和并发能力已成为基本需求。不同企业面临的业务体量和技术标准各不相同,因此,构建一个支持水平扩展的系统不仅能够满足多样化的性能需求,也能为开发者提供更清晰的模块划分与开发体验。微服务架构正是实现系统水平扩展的有效手段。然而,微服务之间的高效通信也是架构设计中不可忽视的重要一环。
2025-04-16 09:55:23
6866
原创 【gin】手动实现自己的参数验证器
在上一个文章中我们尝试使用golang中gin自带的binding验证方法,并介绍了一些常用的验证场景,如一些requiredlen等常见字段,详见文章【GIN】go-gin 中 validator 验证功能。但是这些基础的方法往往不够我们去使用,所以需要一些自定义更强的验证功能去验证,其实看到binding验证的源码,就可以发现手撸一个自定义的方式进行参数验证,其实并不是太难,可以通过结构体字段的 tag 实现类似 binding 的功能。阅读前置:golang 反射内容意思。
2024-12-16 09:45:00
6939
原创 【GIN】go-gin 中 validator 验证功能
在 Go 中使用 Gin 框架时,BindJSON 可以将 JSON 请求体中的数据绑定到结构体上,配合 binding 标签还可以进行验证。其主要是通过validator库实现在Gin的文件中可以看到validator方法是包中的。所以实际上,gin中binding 验证的方法是使用validator实现的这样可以快速的实现多种验证条件,而不需要额外的去写验证方法。Gin 支持多种验证规则,可以通过 binding 标签在结构体字段上定义。下面我们来看一下有哪些验证方法吧。使用。
2024-10-29 12:37:47
7140
原创 【SQL】 JOIN语句作用及Gorm使用案例
最近参与一个迭代项目的开发,代码走查的过程中,遇到了一个蠢了自己一脸的问题。它的场景是这样的:一个rule表和一个 rule_item表。rule表:存入rule_id和对应的内容rule_item:主要存入rule_id和item_id的关联表。大概知道两个表的作用,再来说一下要做的需求:给了一个item_id,需要根据这个item_id在关联表中反查到所有rule_id。并根据rule表用多个rule_id查到所有规则,取出用到之后的代码。
2024-10-17 11:28:52
6744
原创 Go 依赖注入库wire 基本使用
学习过Java 开发的同学,一定对依赖注入有所耳闻。依赖注入(Dependency Injection,简称 DI)是一种设计模式,通过将组件依赖项外部化,使代码更加模块化和易于测试。对于Wire的使用,可以使得开发人员不用在手写对应实例的创建,只需要规范化的编写对应的依赖代码,并通过wire gen 对应目录即可生成对应的实例创建代码。依赖注入是一种设计模式,用于将对象的依赖关系通过构造函数、方法或属性注入,而不是在对象内部创建依赖。这样可以提高代码的可测试性和灵活性。
2024-09-27 10:15:29
7169
1
原创 【Go 实践学习】内存泄漏情景及pprof工具使用(上半篇)
golang本身是拥有GC机制的,GC机制帮我们去处理掉那些我们程序之后不在使用的内存,以缓解程序在运行期间里,内存占用率不断上升,最终达到临界值而出现内存溢出(OOM)的问题。所谓内存泄漏直白来讲即:程序主观上不再想去使用的内存,但是客观上却又持续占有,而是GC系统无法通过三色算法去回收的问题。所以我们在开发中也并能完全的信任GC,而不去管程序中内存的使用。因此,保持一个良好的开发习惯是非常重要的。夫人,你也不想你的代码周末的时候突然在线上挂掉吧。
2024-09-03 09:51:46
7484
1
原创 Golang 版本控制工具:g 安装与使用
Golang的版本控制工具g是一个用来方便地管理和切换Go语言版本的工具。它让用户可以轻松地安装、卸载和切换不同版本的Go,从而更好地适应不同项目的需求。可以看作是golang自己的nvm了。g版本控制工具 releases下载同时支持windows、Linux、mac三个系统。
2024-08-30 09:36:30
10549
原创 golang 项目结构设计参考
作为一个新手,学习了golang中的http、net,也学习了gin、beego等web框架,也学习了zero-go这种脚手架。自己也在一些网站上学习了相关WEB后端开发的代码,跟着敲了一段时间,换到一个新的教程又发现两者的写法是完全不同。所以我需要一种稳定的、适用于各种大中小项目的项目排版模式,来保证开发、维护这几个过程中的代码是容易阅读的。所以结合了各个版本规范,以及一些社区和公司的规范,整理一个版本供大家参考。对于上面的说到的部分,我们在此继续做个总结,用tree命令做一个演示图,方便大家直接参考。
2024-08-26 09:44:40
8386
原创 【Go 互斥锁与读写锁深入浅出】
在Web后端业务或者一些需要高IO的场景中,一些共享资源往往会被系统快速的修改。比如在电商的多线程的场景下,对一个商品数量的修改,往往是由多个用户同时修改。这些用户可以看作不同的线程,在多核CPU下出现并行修改,在单核CPU下出现并发修改。在Go中最简单的例子即是一个公共资源的数,在多个协程中进行累加。通过waitgroup原子数可以实现协程在主线程中等待退出,具体代码实现如下import ("fmt""sync"count := 0// 协程数量n := 10wg.Add(n)
2024-07-18 20:36:39
6704
原创 【Redis 理论与实践学习】 一、Redis的数据结构:4.Set类型
Redis 的 Set 是 String 类型的无序集合。集合中任意成员是唯一的,即集合中不能出现重复的数据。无序性:集合中的元素没有特定的顺序。唯一性:集合中不允许重复的元素。元素数量限制:最多可以存储2^32-1个元素。增加元素:向集合中添加一个元素,如果元素已存在则忽略。删除元素:从集合中移除指定元素。检查元素是否存在:判断集合中是否存在某个元素。并集:返回多个集合的所有成员的并集。交集:返回多个集合的所有成员的交集。差集:返回指定集合和其他集合之间的差集。
2024-07-08 23:16:32
6940
原创 (Redis 理论与实践学习)一、Redis的数据结构:3.Hash类型
Redis中的Hash类型是一种键值对(Key-Value)的集合映射表,其特别适合用于存储对象,因此在各种场景的业务中都有着广泛应用。OK1) "name"3) "age"4) "20"在上述的命令中,我们成功的存储了一个对象,其key值为student,包含了name和age两个字段,最终存入到Redis中。在前面的学习中,我们介绍了String类型也可以用来存储对象(详情见此),那么两者在实际业务中存储对象的区别是什么样的呢?
2024-07-03 16:11:13
6808
原创 (Redis 理论与实践学习)一、Redis的数据结构:2.List类型
List类似是Redis中的一个基本数据类型,它支持按照插入顺序存储一组数据,适合处理需要有序集合和快速插入/删除操作的场景。不管是Redis内部使用,还是一些业务场景都有可能使用到它的特性。
2024-06-27 21:45:11
6020
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅