
Go
文章平均质量分 62
ezreal_pan
这个世界总有人是第一,那个人为什么不能是我?
有很多原因造成我不是第一,但是,不能阻挡我朝着成为第一的目标努力!
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
评论父子级关系的高效删除方案:避免递归
本文提出了一种基于路径存储的高效多级评论删除方案。通过在创建评论时记录完整的评论链路路径(如"1,2,3,4"),取代传统递归删除方式。当删除某条评论时,只需使用LIKE条件匹配该路径前缀即可批量标记删除(软删除)目标评论及其所有子评论。该方案显著提升了删除效率,避免了递归查询的性能损耗,同时采用软删除机制保证数据完整性。方案实现包括创建时生成路径、删除时批量更新等核心逻辑,适用于层级较深或数据量大的评论系统场景,兼具性能和可维护性优势。原创 2025-08-15 08:48:38 · 258 阅读 · 0 评论 -
营业数据多维度统计系统设计:解决跨期去重与精准分析难题
摘要:为解决多维度统计分析中的性能瓶颈和跨期数据去重问题,本文提出基于MySQL的预计算方案。采用星型/雪花模型构建数据体系,通过ETL四层架构(ODS→DWD→DWS→ADS)实现数据分层加工。方案创新性使用bitmap技术处理跨期去重,存储用户ID集合并通过位运算实现高效聚合。针对客单价、留存率等核心指标设计专门计算逻辑,建立会员消费时间序列中间表支持跨周期分析。性能测试显示,bitmap并集计算平均耗时469ms,内存消耗30MB,满足实时查询需求。该方案在保证查询效率的同时,解决了传统预计算方法面临原创 2025-07-17 14:46:16 · 1142 阅读 · 0 评论 -
巧用 Golang 函数特性实现单元测试中的数据库操作 Mock
本文介绍了一种基于Golang函数特性的Mock方案,用于解决单元测试中数据库依赖问题。通过将数据库操作封装为函数变量,在测试时重新赋值这些变量来模拟数据库行为,实现测试与数据库的解耦。该方法利用Golang函数作为"一等公民"的特性,无需引入复杂框架即可实现简洁高效的Mock功能。示例代码展示了如何模拟数据库查询结果和并发场景测试。该方案优势包括:消除数据库依赖、简化测试数据准备、提升测试效率、便于模拟特殊场景,同时保持代码简洁性,特别适合业务逻辑复杂、数据库操作频繁的项目场景。原创 2025-07-17 14:41:13 · 513 阅读 · 0 评论 -
golang条件编译:Build constraints
Go语言构建约束机制详解 Go语言通过构建约束(Build Constraints)实现跨平台编译控制,主要方式包括: 显式约束:使用//go:build注释行,支持逻辑运算符组合条件 隐式约束:通过文件名后缀(_GOOS_GOARCH)自动实现 案例演示了Windows和Linux平台的不同代码实现,其中: main.go调用SayHello() sayhello_linux.go和sayhello_windows.go分别实现平台特定逻辑 需注意gorun命令的两种使用方式差异: gorun main.原创 2025-07-09 11:24:46 · 1008 阅读 · 0 评论 -
多维度缓存一致性挑战:Cache-Aside模式下的解决方案精要
针对多维度缓存场景下缓存删除遗漏的问题,提出了四种解决方案:1)集中式缓存键管理器统一管理实体缓存键;2)缓存标签机制通过标签批量删除关联键;3)事件驱动解耦业务与缓存清理;4)测试与监控机制兜底保障。核心思路是将多维度缓存关联关系从分散转为集中管理,建议根据场景特点选择方案:键管理器适合简单场景,标签机制灵活性高,事件驱动适合分布式系统,测试监控作为通用兜底方案。这些方案可有效解决缓存不一致问题,降低开发维护成本。原创 2025-07-08 11:43:26 · 996 阅读 · 0 评论 -
深度排查 benchstat 无输出问题:编码格式引发的 “隐形故障”
本文分析了Golang benchstat工具无输出的问题。通过源码分析发现benchstat严格依赖UTF-8编码解析基准测试文件,当文件采用GBK等非UTF-8编码时,会触发utf8.RuneError导致解析终止。验证测试表明,将文件转换为UTF-8无BOM编码后问题解决。建议规范基准测试文件的生成流程,确保统一使用UTF-8编码保存,以避免此类"隐形约束"导致的工具异常。原创 2025-07-04 08:32:44 · 483 阅读 · 0 评论 -
使用Process Monitor定位benchstat工具执行过程
摘要:在Windows11系统Go1.21.0环境下使用benchstat工具比较基准测试结果时遇到问题。通过ProcessMonitor工具捕获分析,确认benchstat已成功读取目标文件(20_runs_bench.txt)。使用官方示例文件(D:\Go\pkg\mod\golang.org\x\perf@v0.0.0-20250605212013-b481878a17be\benchproc\testdata)测试成功,证明工具本身运行正常。原创 2025-07-02 16:47:28 · 434 阅读 · 0 评论 -
Benchmarking in Go
本文对比了Golang中JSON和Protobuf在序列化/反序列化性能上的差异。通过基准测试(Benchmark)方法,作者设置了包含20个字段的复杂消息结构,分别测试了两种协议的序列化速度、反序列化速度和数据大小。测试结果显示Protobuf在各方面均优于JSON:序列化速度快约1.5倍,反序列化速度快约2倍,生成的数据体积更小(480B vs 904B)。文章详细介绍了基准测试的实施方法,包括测试数据准备、测试命令参数(-benchmem,-count)以及推荐使用benchstat工具进行结果分析。原创 2025-07-02 15:23:53 · 763 阅读 · 0 评论 -
could not import google.golang.org/protobuf/proto
在Go项目测试中导入protobuf包时遇到"could not import google.golang.org/protobuf/proto"错误。临时解决方案是通过go mod vendor命令将依赖复制到本地的vendor目录,使编译器优先使用本地依赖而非模块缓存。虽然该方案能暂时解决问题,但用户仍困惑于根本原因未解决,寻求遇到过类似问题的开发者帮助。疑问焦点在于为何常规依赖管理方式会持续报错,而vendor模式却能正常工作。原创 2025-06-27 16:42:34 · 255 阅读 · 0 评论 -
缓存和数据库一致性问题
直接更新缓存方案虽能减少缓存穿透风险并确保数据一致性,但仍存在主从延迟和并发一致性问题。更优方案是采用Cache-Aside模式(更新数据库后删除缓存),配合SingleFlight解决缓存穿透,并通过延迟双删或Binlog监听应对主从延迟。该模式在并发场景下数据不一致概率极低,建议封装缓存组件隐藏底层实现,仅暴露数据库操作接口。原创 2025-06-27 11:18:01 · 1132 阅读 · 0 评论 -
基于开闭原则优化数据库查询语句拼接方法
这两种方案都遵循了开闭原则,使得代码在添加新的查询条件时更加灵活,同时减少了修改现有代码的风险。策略模式适合条件逻辑复杂、需要多维度扩展或复用的场景,通过接口化设计提升代码规范性。函数切片则以更轻量的方式实现条件解耦,适合快速开发或条件相对固定的场景。无论选择哪种方案,核心目标都是将查询条件的 “修改” 操作转化为 “扩展” 操作 —— 新增条件时无需触碰原有逻辑,从架构层面降低人为失误导致的风险。原创 2025-04-29 11:52:54 · 508 阅读 · 0 评论 -
优化 Go 语言函数传参设计,提升代码可读性与可维护性
控制参数数量:尽量将参数数量保持在 3 - 5 个以内。若参数过多,优先考虑使用结构体封装必需参数,或采用选项模式处理可选参数。规范命名:参数名应具有明确的描述性,能够准确传达参数的含义,避免使用含义模糊的名称。确定参数顺序:在 Go 语言中,通常将作为函数的第一个参数。常用于控制请求的生命周期,传递请求范围内的数据,将其前置有助于统一代码风格,提升可读性。选择传递方式:根据实际需求选择合适的参数传递方式。若函数需要修改传入的参数值,应使用指针传递;原创 2025-04-27 11:05:11 · 356 阅读 · 0 评论 -
golang不使用锁的情况下,对slice执行并发写操作,是否会有并发问题呢?
golang的slice不是线程安全的对象,那么,是否只要slice类型的对象在多线程中就需要加锁呢?原创 2025-03-26 13:55:04 · 1255 阅读 · 0 评论 -
写Excel文件是内存暴涨的罪魁祸首
通过对比,我们可以明显的发现两者消耗的资源差距非常大,所以,最终我们采用写Csv文件的方案。原创 2025-03-26 13:52:44 · 288 阅读 · 0 评论 -
recover无法捕获的panic场景
由于recover只能在defer函数中才能生效,所以,recover无法捕获panic的场景主要有如下的一些场景。原创 2025-03-11 11:45:53 · 480 阅读 · 0 评论 -
golang panic原理
stack结构体类型,包含lo(低地址)和hi(高地址)两个uintptr字段,描述 Goroutine 的栈内存区间[lo, hi)。初始栈大小为 2KB,可动态扩容至 1GB。m指向当前运行此 Goroutine 的内核线程(M)。调度器通过 M 将 Goroutine 映射到操作系统线程。原创 2025-02-19 16:39:24 · 405 阅读 · 0 评论 -
golang panic信息捕获
我们的日志接入阿里云sls平台,但是,日志是以json的格式存储在阿里云sls平台上,程序中产生的error,info等日志都可以实现以json的格式打印。但是,golang程序中产生的panic信息本身不是以json的格式输出,这就导致panic信息在阿里云sls平台上不方便检索。基于上述痛点,我们期望捕获程序的panic信息,并且以json的格式打印,如此,我们就可以方便的实现在阿里云sls平台上检索的目的。通过defer和recover()机制捕获panic信息。。原创 2025-02-19 16:39:32 · 635 阅读 · 0 评论 -
接口鉴权方案
接口生成签名分两个逻辑,首先,对原始数据,过期时间,随机字符串组成的字符串明文进行加密,对这个密文进行加签,最后,把密文和签名编码生成最终的签名,在发送http请求时带上这个最终生成的签名。这个方案的设计思路主要是为了确保数据在传输过程中的保密性和完整性。secret通过这种设计,可以确保数据在传输过程中既不会被窃听(通过加密),也不会被篡改(通过签名验证)。同时,时间戳和随机字符串的使用也防止了重放攻击。原创 2025-01-16 09:22:25 · 422 阅读 · 0 评论 -
kafka-go:性能测试
在这篇文章中,由于kafka消息堆积引起的一些探索,上篇文章中遗留的问题,已经解决了消息堆积的问题,是通过打印日志的地方开启协程的方式解决了,但是,造成这个问题背后的原因还是值得探索探索。在实际测试过程中,通过pprof工具发现,这个地方context的会导致内存增长,且似乎没有下降的趋势,看着像是内存泄漏。这个问题很是令人困惑。这个问题,留待后续继续探索。今天,我们主要围绕着kafka-go这个组件探索展开。原创 2025-01-16 09:21:55 · 664 阅读 · 0 评论 -
kafka消费堆积问题探索
我们的商城项目用PHP写的,原本写日志方案用的是PHP的方案,但是,这个方案导致资源消耗一直降不下来,使用了20个CPU。后面考虑使用通过kafka的方案写日志,商城中把产生的日志丢到kafka中,在以go写的项目中消费kafka中的日志,并打印到控制台,最后,统一使用阿里sls抓取日志。我们kafka的分区有12个,go程序部署在k8s集群中,开启了弹性扩缩容,最多开启了8个pod进行消费,每秒产生的日志数量高峰在1500条左右,在这种情况下,依然产生了消息的堆积。原创 2025-01-11 11:40:17 · 1236 阅读 · 0 评论 -
golang:微服务架构下的日志追踪系统(二)
在使用Gin框架进行服务开发时,我们遇到了一个日志记录的问题。由于Gin的上下文()实现了接口,在调用日志记录器的InfoWarnError等方法时,直接传递Gin的上下文通常不会导致编译错误。会导致我们在《》一文中定义的日志统计维度信息无法正确串联。为了解决这一问题,我们之前的解决方案是让业务方在使用日志记录器时,将Gin的上下文手动转换为。但这种方案带来了一个明显的弊端:它依赖于开发人员的主动转换,而开发人员往往会忘记进行这一步操作,直接传递Gin的上下文,从而导致日志并未按照预期格式打印。原创 2025-01-02 14:15:45 · 494 阅读 · 0 评论 -
golang:微服务架构下的日志追踪系统
为了把一个请求中所有的日志串联起来,我在日志中增加一个traceId的信息。》在这篇文章中,提供了第一个版本的解决方案。这个解决方案主要是解决单体服务架构下的日志串联问题。随着,我们分布式应用的发展,我们面临着需要一个能串联跨服务调用链路的日志系统。因此,我们在第一个版本上做了优化处理。主要是增加了日志的统计维度。原创 2025-01-02 13:51:35 · 1241 阅读 · 0 评论 -
ShardingSphere-Proxy分表场景:go测试案例
接续上篇文章《原创 2024-12-31 16:22:02 · 512 阅读 · 0 评论 -
ShardingSphere-Proxy 连接实战:从 Golang 原生 SQL 到 GORM 的应用
在这篇文章《》中,我们介绍了如何通过 Navicat 连接 ShardingSphere-Proxy。实际上,ShardingSphere-Proxy 兼容标准的 SQL 和原生数据库协议,因此你可以使用任何 MySQL 客户端与其进行连接,包括 Golang 的原生 SQL 库和流行的 ORM 框架 GORM。接下来,我们将展示如何使用 Golang 原生 SQL 和 GORM 连接并操作 ShardingSphere-Proxy。原创 2024-12-18 16:43:59 · 1053 阅读 · 0 评论 -
vitess使用:基于源码运行vtctldclient工具
记录了基于官方文档起的一个vitess的server。由于设置分库分表的规则,需要使用vtctldclient这个工具,这个工具的摸索费了诸多周折,《》这篇文章记录了,想通过docker的方式运行这个工具,但是,这一步尝试以失败告终,目前尚不明白失败的原因,待后续有时间再做探索。最后,通过源码的方式运行这个工具。由于,我是在windows下运行这个工具。需要把这一段代码注释掉,这一段代码应该是和统计相关,和业务不相关,并不影响我们的测试。这个错误的解决需要import这两个包,主要是初始化用的。原创 2024-11-26 17:20:45 · 494 阅读 · 0 评论 -
golang版本管理工具:scoop使用
Scoop根据官方文档安装。第一步:打开PowerShell。(注意不要使用管理员方式打开,否则在执行安装Scoop的过程中,会报错。第二步:切到C盘根目录下。第四步:安装Scoop。原创 2024-11-26 16:23:15 · 786 阅读 · 0 评论 -
context canceled错误
我们项目中使用web框架是gin框架,数据库orm使用的是gorm的框架。最近项目中,偶尔会报一些context canceled的错误,这个错误很容易理解,当context取消时,并且监听了上下文的Done信号,并且以error的方式抛出,就会报这样的错误。关于context的这个作用机制,我在《》这篇文章中有写过,有兴趣的可以移步过去看一下。原创 2024-10-29 17:37:59 · 1913 阅读 · 0 评论 -
golang如何import fork下来的代码?
由于这个分表的组件,对于单表多分表策略支持的不是很好,如果有这样的需求,需要初始化不同的DB实例,这种用法甚是不方便。因此,有了改造这个组件的想法,改造的思路见如下两篇文章:《》、《于是乎,我就fork了这个版本,按照上述想法改造了一下这个组件。改造后项目地址:现在的问题是,fork下来的包,如何引用呢?因为module还是和原项目一样,都是gorm.io/sharding。所以,理论上import的写法都是一样的。问题是:如此一来,到底使用了哪个包呢?原创 2024-10-29 14:01:30 · 844 阅读 · 0 评论 -
gorm.io/sharding改造:赋能单表,灵活支持多分表策略(下)
通过改造组件,我们实现了根据表名+分表键获取对应分表策略的逻辑。这一改造使得组件能够支持单表多个分表策略,更加灵活和强大。目前,我们已经简单测试了查询和插入场景,更复杂的场景和并发情况还需进一步测试和优化。通过这一改造,我们为业务逻辑的执行提供了更加精准和高效的分表策略定位。原创 2024-10-24 18:19:51 · 986 阅读 · 0 评论 -
gorm.io/sharding改造:赋能单表,灵活支持多分表策略(上)
通过对组件的改造,我们成功地实现了单表支持多个分表逻辑的功能。这一改进不仅提高了组件的灵活性,也使其能够更好地满足实际业务场景中的需求。然而,这篇文章尚未触及一个至关重要的议题:在增删改查的实际业务操作中,分表组件究竟如何精准地定位到对应的分表策略,以确保业务逻辑的顺利执行?这一环节对于分表技术的实际应用至关重要。关于组件在这一关键领域的改造与升级,鉴于其复杂性和重要性,我将在接下来的文章中展开详尽的阐述。在此次深入剖析中,我们将一起探索。原创 2024-10-24 16:48:46 · 1044 阅读 · 0 评论 -
跨域问题曲折探索背后的一个小小的插曲:header is present on the requested resource错误
发现是跨域的中间件并没有使用导致的这个错误原创 2024-10-23 15:35:24 · 1042 阅读 · 0 评论 -
平凡的跨域问题,竟暗藏波澜:一场意想不到的曲折探索
最终,运维把在k8s的Ingress-Nginx中设置的跨域去掉,问题得以解决,进一步印证了我们的结论的正确性。兜兜转转,到最后发现,我们一开始的解决方案就是正确的,此外,Access-Control-Expose-Headers这个头的设置也不是必须的。先介绍一下我的验证方法,在本地环境修改完代码后,我会在本地启动应用,随后,在浏览器的控制台中编写调用接口的逻辑,以测试是否存在跨域问题。本文的核心,并非直接提供解决方案,而是聚焦于遇到问题时,我们如何一步步深入思考,精准定位到问题的本质。原创 2024-10-23 14:40:10 · 694 阅读 · 0 评论 -
golang中的上下文
在Go语言中,使用context包来管理跨API和进程间的请求生命周期是常见的做法。特别是在涉及到并发编程时,如启动协程(goroutine)来处理异步任务,正确地传递和监听context变得尤为重要。比如,在gin框架中,发起一个http请求,把context传递到协程中,当http请求结束时就会执行上下文取消逻辑,从而导致异步协程退出。我们通过一个示例模拟在gin框架(或任何类似的Web框架)中可能遇到的一个问题:在HTTP请求处理过程中启动协程,并传递context以控制协程的生命周期。原创 2024-10-15 15:05:47 · 857 阅读 · 1 评论 -
gorm.io/sharding:改造,当查询条件中不包含分表键时,从自定义方法中获取对应的表进行查询
这篇文章是一种特殊的情形——当查询条件中不包含分表键时,从自定义方法中获取对应的表进行查询。实际项目中并不建议这种用法。当然,这里只是提供一种思路。这篇文章也是这个系列中的第三篇文章。前两篇文章《》、《》有兴趣的看官可以移步过去看看。原创 2024-09-24 17:51:53 · 643 阅读 · 0 评论 -
gorm.io/sharding使用中遗留问题探究:Error 1062 (23000): Duplicate entry ‘2‘ for key ‘orders_2025.PRIMARY
实际上因为支持自定义方法,也没有必要去修改源码中的问题,只是用于探索一下其实现原理。原创 2024-09-24 11:16:25 · 636 阅读 · 0 评论 -
基于gorm.io/sharding分表中间件使用案例
项目中需要用到mysql的分表场景,调研了一些常用的分库分表中间件,比如,mycat,小米的Gaea,这两个中间件太重了,学习成本较大,另外mycat不是go写的。我们需要一个轻量级的go版本的分表中间件。所以,把目光放在了如下这个开源组件上。原创 2024-09-23 16:39:25 · 2242 阅读 · 0 评论 -
swagger报错:ParseComment error in file xxx.go :cannot find type definition: response.RR
先给出解决方案,没有兴趣了解具体的原因,以及swag的源码的可以直接看第一部分即可。命令行中增加一个参数:pdl。参数用于控制是否解析外部依赖文件夹,以及解析的级别。原创 2024-09-19 15:01:38 · 1618 阅读 · 0 评论 -
开源项目timingwheel
开源的时间轮使用以及源码阅读原创 2024-09-10 15:16:44 · 869 阅读 · 0 评论 -
基于约束大于规范的想法,封装缓存组件
架构?何谓架构?好像并没有一个准确的概念。以前我觉得架构就是搭出一套完美的框架,可以让其他开发人员减少不必要的代码开发量;可以完美地实现高内聚低耦合的准则;可以尽可能地实现用最少的硬件资源,实现最高的程序效率......事实上,架构也并非只是追求这些。因为,程序是人写出来的,所以,似乎架构更多的需要考虑人这个因素。我们发现,即便我们在程序设计之初定了诸多规范,到了实际开发过程中,由于种种原因,规范并没有按照我们预想的情况落实。这个时候,我的心里突然有一个声音:约束大于规范冒了出来。原创 2024-09-03 15:58:25 · 1214 阅读 · 0 评论 -
基于kafka-go写的生产者和消费者
这一篇文章,主要是基于kafka-go写的生产者和消费者的代码。我自定义了一个kafka消息体,消息体中,有一个actionType的概念。为什么要有这么一个定义呢,主要是考虑到kafka的topic的颗粒度不能太细,太细会导致kafka的性能下降,所以,我们的消费需要基于actionType进行细分,以提升消费的并发能力,这里指的是从业务的角度来提升消费能力,而不是通过kafka自身的调整。原创 2024-08-14 15:05:13 · 675 阅读 · 0 评论