goflow 是一个基于 Go 语言的高性能、可扩展、分布式的工作流框架,由 GitHub 用户 s8sg 开发。它允许开发者以编程方式将分布式工作流定义为任务的有向无环图(DAG),并通过多个工作节点(Worker)均匀分配负载来执行任务。 核心特性 1. DAG 构建与任务编排 goflow 允许用户以 DAG 的形式定义工作流,每个节点代表一个任务,边表示任务之间的依赖关系。这种结构使得任务的执行顺序清晰,便于管理复杂的工作流程。 2. 分布式执行与负载均衡 任务可以分布在多个 Worker 上执行,goflow 通过均匀分配负载的方式,确保各个 Worker 的工作量平衡,从而提高整体执行效率。 3. 可扩展的服务架构 goflow 提供了 FlowService 结构体,允许用户配置服务的端口、Redis 地址、OpenTrace 地址、Worker 并发数等参数,便于根据实际需求进行扩展和调整。 4. 内置监控与可观测性 框架支持集成 OpenTracing,提供对工作流执行过程的监控和追踪功能,帮助开发者及时发现和解决问题。 5. Redis 支持 goflow 使用 R.... 有更新! golang每日一库之goflow golang每日一库
今天介绍一个工作流库。 Fastflow 是一个由 ShiningRush 开发的基于 Go 语言的轻量级、高性能分布式工作流框架。 它旨在解决复杂任务流的调度与执行问题,特别适用于如离线任务、Kubernetes 集群管理、容器迁移等场景。 特点 基于 DAG 的工作流模型 Fastflow 使用有向无环图(DAG)定义任务之间的依赖关系。每个节点(Task)代表一个操作,只有其所有依赖任务成功完成后,才会被触发执行。 高性能与并发执行 借助 Go 的协程和 channel 技术,Fastflow 能在单个实例上并行处理数百到数万个任务,满足高并发需求。 可观测性 集成 Prometheus,Fastflow 提供任务执行的实时指标,如并发任务数、任务分发时间等,便于监控和调试。 水平扩展与负载均衡 支持多实例部署,通过 Leader 选举机制实现节点间的负载均衡,确保系统在高负载下的稳定性。 易用的 API 与扩展性 提供开箱即用的 API,支持通过编程或 YAML 定义工作流。用户可以自定义任务行为(Action),并根据上下文决定是否跳过任务。 轻量级集成 作为基础框架,Fas.... 有更新! golang每日一库之fastflow golang每日一库
go-workflow 是一个基于 Go 语言开发的超轻量级工作流引擎,设计灵感来源于 Java 的 Activiti,但进行了深度简化和解耦,特别适用于微服务架构下的流程控制需求。 特点 微服务架构友好:go-workflow 仅关注流程流转逻辑,完全解耦用户、组织等业务数据,便于与各类系统集成。 JSON 流程定义:采用 JSON 数组替代传统的 BPMN 模型,简化流程配置,灵感来源于钉钉 OA 系统。 轻量高效:相比 Activiti 更加精简,部署简单,运行效率高,适合中小型企业或对流程控制有定制需求的场景。 前后端分离:提供独立的前端流程设计器 go-workflow-UI,支持可视化流程配置。 表结构 go-workflow 使用多张表来管理流程定义、实例、任务等核心数据: procdef:流程定义表,存储流程名称、版本、JSON 配置等信息。 proc_inst:流程实例表,记录每次流程启动的实例信息,如当前节点、审批人等。 execution:执行流表,保存流程的执行路径,确保流程按预定顺序流转。 task:任务表,记录每个节点的任务详情,包括审批人、审批状态等。 i.... 有更新! golang每日一库之go-workflow golang每日一库
VictoriaMetrics/fastcache 是由 VictoriaMetrics 开发的一个高性能、线程安全的内存缓存库,旨在作为 Go 语言标准库 map 的高效替代方案,用于缓存键值对(key-value pairs)。 它在性能、并发处理能力和内存利用率方面表现优异,尤其适用于对性能要求较高的应用场景,如监控系统、代理服务、数据库中间件等。 它的缺点像它的优点一样明显。 它比 BigCache快! 先说优点 高性能、低延迟 使用内存池和分段锁,最大程度减少 GC 压力。 单个缓存实例可以并发处理多个读写操作。 内存管理高效 自动淘汰(eviction)策略:当缓存容量达到上限时,会自动丢弃旧的数据。 使用预分配大内存块的方式来减少碎片。 线程安全 适用于高并发场景。 轻量级 API 简洁,易于集成和使用。 再说缺点 fastcache 并不是持久化缓存。如果你需要跨进程/重启持久化数据,考虑其他方案(如 Redis、BoltDB)。如果你一定要持久化,其实么也可以。 不是 LRU/TTL 缓存,它只在空间用尽时自动清理旧数据。 不适合需要缓存超大 value(默认限制 6.... 有更新! golang每日一库之VictoriaMetrics/fastcache golang每日一库
go-redislock 是一个由 jefferyjob 开发的 Go 语言库,用于在分布式环境中实现基于 Redis 的高性能分布式锁。它提供了可靠的并发控制机制,确保多个节点在访问共享资源时的数据一致性和资源互斥。 核心特性 高性能:利用 Redis 的内存存储特性,实现快速的锁获取与释放。 超时机制:支持设置锁的过期时间,防止死锁。 可重入性:允许同一线程多次获取同一把锁。 自动续期:在长时间任务执行期间,自动延长锁的有效期。 手动续期:提供手动延长锁有效期的方法,满足特定需求。 灵活的锁释放方式:支持手动释放锁,确保资源的及时释放。 安装 使用以下命令安装 go-redislock: go get -u github.com/jefferyjob/go-redislock 示例 package main import ( "context" "fmt" redislock "github.com/jefferyjob/go-redislock" "github.com/redis/go-redis/v9" ) func main() { // 创建 Redis 客户端 red.... 有更新! golang每日一库之jefferyjob/go-redislock golang每日一库
bsm/redislock 是一个用于 在 Go 语言中实现基于 Redis 的分布式锁(distributed lock) 的开源库,由 bsm 组织开发和维护。 它实现了基于 Redis 的 SET NX PX 命令模式的分布式锁,兼容 Redlock 算法的核心思想,但更简单和轻量。 简介 基于 Redis 单实例实现分布式锁 遵循 Redis 官方推荐的 SET resource-name value NX PX max-lock-time 模式 简洁、高性能、线程安全 支持锁自动过期 支持锁续约(可选) 没有依赖复杂的 Redlock 多主节点算法,更适合大多数实际应用 安装方法 go get github.com/bsm/redislock 示例 import ( "context" "fmt" "log" "time" "github.com/bsm/redislock" "github.com/redis/go-redis/v9" ) func main() { // Connect to redis. client := redis.NewClient(&r.... 有更新! golang每日一库之bsm/redislock golang每日一库
redsync 是一个用 Go 编写的分布式互斥锁(Distributed Mutex)库,基于 Redis 实现。其主要目标是在分布式系统中为多个进程或服务之间提供互斥访问的机制,确保同一时间内只有一个客户端可以访问共享资源。 GitHub 项目地址:👉 https://github.com/go-redsync/redsync 核心功能 redsync 实现了 Redlock 算法(由 Redis 创始人 antirez 提出),该算法旨在在分布式环境中实现安全、健壮的锁。 基本原理 使用多个独立的 Redis 实例。 客户端尝试依次在多数 Redis 节点上设置一个带过期时间的锁。 如果大多数实例成功设置锁,并且总耗时小于锁的过期时间,则认为加锁成功。 释放锁时,会逐个删除这些实例上的锁。 安装 go get github.com/go-redsync/redsync/v4 示例 package main import ( "github.com/go-redsync/redsync/v4" "github.com/go-redsync/redsync/v4/redis/go.... golang每日一库之redsync golang每日一库
RussellLuo/slidingwindow 是一个用 Go 语言实现的滑动窗口速率限制器,灵感来源于 Kong API 网关的限流算法。该库支持本地和分布式限流,适用于需要精确控制请求速率的场景。 设计理念 该库通过维护两个窗口(当前窗口和前一个窗口)的请求计数,估算当前时间点的请求速率,从而实现滑动窗口限流。 例如,设定每分钟最多允许 100 次请求: 当前时间为第 75 秒,即当前窗口开始于第 60 秒。 当前窗口内记录了 12 次请求。 前一个窗口(第 0 秒到第 60 秒)内记录了 86 次请求。 则当前估算的请求数为: count = 86 * ((60 - 15) / 60) + 12 = 86 * 0.75 + 12 = 76.5 如果 count 超过设定的阈值(例如 100),则拒绝新的请求。 主要组件 1. Limiter Limiter 是速率限制的核心结构,负责判断是否允许新的请求。它通过维护两个窗口的计数来估算当前的请求速率。 主要方法: Allow():判断是否允许一个新的请求。 AllowN(now time.Time, n int64):判断是否.... 有更新! golang每日一库之RussellLuo/slidingwindow golang每日一库
在 Go(Golang)中,基于滑动窗口的 IP 限速器是一种精确且高效的限流策略,适用于需要细粒度流量控制的场景,如防止恶意攻击、限制 API 调用频率等。 滑动窗口限速算法简介 滑动窗口算法通过在每次请求时计算过去固定时间窗口内的请求数量,实现对请求速率的限制。 与固定窗口算法相比,滑动窗口算法能更平滑地限制流量,避免突发请求集中在窗口边界的问题。 Go 中的滑动窗口 IP 限速器实现 以下是几个在 Go 中实现滑动窗口 IP 限速器的开源项目: 1. RussellLuo/slidingwindow 该库实现了 Kong API 网关使用的可扩展滑动窗口限流算法,适用于分布式环境。 特点: 支持本地和分布式限流。 通过计算当前窗口和前一个窗口的请求数,估算当前的请求速率。 适用于需要高精度限流的场景。 示例: 假设每分钟允许 100 次请求,在第 75 秒时,当前窗口内有 12 次请求,前一个窗口内有 86 次请求,则当前估算的请求数为:(GitHub) count = 86 * ((60 - 15) / 60) + 12 = 86 * 0.75 + 12 = 76.5 如果 .... 滑动窗口ip限速器 golang基础
Intern 是一个用于 Go 语言的字符串驻留库。 它的核心思想是在程序中对重复出现的字符串只保留一份副本,从而节省内存并减少垃圾回收压力。在需要频繁处理大量相同字符串的场景下(例如解析 JSON 时大量重复的键名、日志标签、协议头字段等),使用该库可以显著降低内存占用。 需要注意的是,该库仅提供“尽力而为”(best-effort)的驻留机制,即库会尽量重用已有字符串,但驻留的字符串可能会在任何时候被回收和移除。 学习该库之前,你必须明白什么是字符串驻留,为什么需要字符串驻留,什么时候需要字符串驻留,以及实现字符串驻留的常用方法。 项目用途 Intern 库的设计目的就是简化字符串驻留的过程。 通常自己实现字符串驻留需要管理一个全局映射 (map[string]string) 并处理并发访问和生命周期,但这很容易出错。 Intern 包通过简单的 API 隐藏了这些复杂性:只需调用 intern.String(s) 或 intern.Bytes(b) 即可得到驻留后的字符串版本。文档说明该包“所有函数都支持并发调用”并且“驻留的字符串可以随时被移除”。 换言之,用户无需手动加锁或维.... golang每日一库之josharian/intern golang每日一库
Go 中的 errgroup 包详解 Golang 的扩展并发库 golang.org/x/sync/errgroup 提供了对多协程任务进行管理和错误处理的便利功能。 与基础的 sync.WaitGroup 相比,errgroup.Group 在等待所有任务完成的同时,还会自动捕获第一个非 nil 错误并返回。如果通过 WithContext 创建 Group,当任一子任务返回错误时,errgroup 会取消关联的 Context,从而通知其他协程提前退出。 简言之,errgroup 封装了错误传播、上下文取消和并发控制等功能,使并发编程更加简洁易用。 基本用法 使用 errgroup 时,首先需要创建一个 Group 实例。可以直接用零值初始化:var g errgroup.Group,或者调用 errgroup.WithContext(ctx) 同时获取一个基于 ctx 派生的新 Context。典型的用法是对每个并发任务调用 g.Go(func() error) 来启动 goroutine。Group.Go 方法内部会自动执行 WaitGroup.Add(1),并在函数返回时执.... 有更新! errgroup详解 golang标准库
do 是 Go 语言中一个轻量级的依赖注入(Dependency Injection, DI)容器,由 samber 开发。 它基于 Go 1.18+ 泛型实现,为 Go 提供了一个类型安全的 DI 方案。 do 库的设计理念是简化服务组件之间的依赖管理,取代手工创建依赖关系的繁琐工作,使不同组件之间松散耦合、更易测试与维护。 与反射型 DI 框架不同,do 在注册和解析依赖时不使用反射,因此性能开销很小。 功能简介 服务注册:使用 do.Provide 系列函数将服务构造函数注册到容器中(默认懒加载,即按需单例创建);也可以使用 ProvideTransient 注册每次调用都新建实例的工厂(瞬时模式);或使用 ProvideValue/ProvideNamedValue 注册已经创建好的实例(急加载)。注册时可指定名称或匿名服务(推荐匿名,由框架自动命名)。 依赖解析:通过 do.Invoke[T](injector) 或 do.MustInvoke[T](injector) 获取指定类型的服务实例。容器会自动根据函数签名的参数解析依赖,并以依赖图的方式按顺序实例化各服务(默认单例.... 有更新! golang每日一库之依赖注入库samber/do golang每日一库
在 Golang 中使用 float64 类型时,精度丢失主要发生在以下场景中。 根本原因是 IEEE 754 双精度浮点数标准的固有特性: 一、无法精确表示的十进制小数 原理:某些十进制小数(如 0.1、0.2)无法用有限的二进制浮点数精确表示,导致存储时被截断或四舍五入。 示例: var a float64 = 0.1 var b float64 = 0.2 fmt.Println(a + b) // 输出 0.30000000000000004 而非 0.3 • 原因:0.1 的二进制表示为无限循环小数 0.0001100110011...,而 float64 的尾数位仅 52 位,超出部分会被截断。 二、大整数或数值范围差异大的运算 原理:当数值超过 2^53(约 9e15)时,连续整数无法被准确表示,且大数和小数相加时可能发生“大数吃小数”现象。 示例: fmt.Println(float64(9007199254740993)) // 输出 9.007199254740992e15(精度丢失) fmt.Println(1e16 + 1.0 == 1e16) // 输出 t.... 有更新! 在 Golang 中使用 float64 可能导致精度丢失的情况 golang基础