少林码僧
专注elasticsearch搜索领域8年,有海量数据搜索功能架构经验
展开
-
gRPC详解
protoc是protobuf文件(.proto)的编译器,可以借助这个工具把 .proto 文件转译成各种编程语言对应的源码,包含数据类型定义、调用接口等。通过查看protoc的源码,可以知道,protoc在设计上把protobuf和不同的语言解耦了,底层用C++来实现protobuf结构的存储,然后通过插件的形式来生成不同语言的源码。可以把protoc解析.proto文件,转译成protobuf的原生数据结构在内存中保存;原创 2024-08-31 00:00:00 · 0 阅读 · 0 评论 -
详解Golang的Goroutine
Go协程(Goroutine)是与其他函数或方法同时运行的函数或方法。可以认为Go协程是轻量级的线程。与创建线程相比,创建Go协程的成本很小。因此在Go中同时运行上千个协程是很常见的。原创 2024-08-17 12:26:56 · 21 阅读 · 0 评论 -
详解Golang垃圾回收机制
今天我们来聊聊golang是如何进行垃圾回收的。我们知道,目前各语言进行垃圾回收的方法有很多,如引用计数、标记清除、分代回收、三色标记等,各种方式都有其特点,GO语言在发展过程中, 其GC算法也是不断改进的。原创 2024-08-17 12:25:15 · 30 阅读 · 0 评论 -
详解golang内存管理
要搞明白 Go 语言的内存管理,就必须先理解操作系统以及机器硬件是如何管理内存的。因为 Go 语言的内部机制是建立在这个基础之上的,它的设计,本质上就是尽可能的会发挥操作系统层面的优势,而避开导致低效情况。原创 2024-08-17 12:23:59 · 170 阅读 · 0 评论 -
golang使用乐观锁实现读写锁
这种实现使用了自旋锁和原子操作,在高并发场景下可能导致CPU空转(busy-waiting)。尽管它避免了使用sync.Mutex和channel,但自旋锁的性能可能在某些场景下不如基于条件变量的实现高效。readerCount:使用int32类型表示当前读者的数量,使用原子操作保证并发安全。writerFlag:使用int32类型表示写锁的状态,当值为1时表示有写者正在写。使用CompareAndSwapInt32尝试获取写锁,如果未能获取,则自旋等待。获取写锁后,等待所有正在进行的读操作完成。原创 2024-08-09 08:00:00 · 44 阅读 · 0 评论 -
golang sync.Cond实现读写锁
这个自定义读写锁是Golang中高级同步原语的一个实现示例,能够满足大部分并发场景的需求,并且易于扩展和优化。如果当前有写者在执行写操作,读者会等待写操作完成(通过readCond.Wait())。如果有读者或其他写者在操作,写者会等待(通过writeCond.Wait())。如果所有读者都完成了操作且有写者在等待,唤醒写者进行写操作。优先唤醒等待的写者,如果没有写者等待,则唤醒所有等待的读者。一旦写操作完成,读者数量递增,表示读操作已开始。一旦可以执行写操作,写者数量递增。写操作结束后,写者数量递减。原创 2024-08-09 08:00:00 · 48 阅读 · 0 评论 -
golang使用channel实现读写锁
为了优化性能,可以考虑引入更复杂的锁机制,如基于条件变量的锁。readerCount 和 writerCount 分别用于追踪当前正在进行的读操作和写操作的数量。如果有等待的读者,读操作将会被释放;如果没有读者但有写者在等待,下一个写者将会被通知。如果没有其他读者,且有写者在等待,那么写者将会被通知进行写操作。当有写操作正在进行时,所有新的读操作将会等待,直到写操作完成。每当一个新的读操作开始时,readerCount会递增。当有其他写者正在写或有读者在读时,新的写者会等待。原创 2024-08-08 22:13:33 · 163 阅读 · 0 评论 -
详解使用Goalng+Redis实现分布式锁
本文主要介绍了如何使用Go代码正确实现Redis分布式锁,对于加锁和解锁也分别给出了两个比较经典的错误示例。其实想要通过Redis实现分布式锁并不难,只要保证能满足可靠性里的四个条件。互联网虽然给我们带来了方便,只要有问题就可以google,然而网上的答案一定是对的吗?其实不然,所以我们更应该时刻保持着质疑精神,多想多验证。原创 2024-08-08 12:32:58 · 242 阅读 · 0 评论 -
golang实现切换元素互换的7种方式
golang实现两个切换元素互换的方式至少有7种原创 2024-08-04 08:55:20 · 313 阅读 · 0 评论 -
go(golang) time.After 内存泄露问题详解
在今天这篇文章中,我们介绍了标准库time的基本常规使用,同时针对 Go 小伙伴所提出的time.After方法的使用不当,所导致的内存泄露进行了重现和问题解析。其根因就在于 Go 语言时间堆的处理机制和常规forselecttime.After组合的下意识写法所导致的泄露。原创 2024-08-01 14:58:19 · 45 阅读 · 0 评论 -
Go 1.22新特性,for range的坑终于被填上了
美国时间2023年12月20日,Go官方宣布Go 1.22rc1发布,开启了为期2个多月的、常规的公测之旅,Go 1.22也在2024.2月份正式发布!除了在官网下载Go 1.22rc1版本进行新特性体验之外,我们还可以通过在线的Go Playground选择“Go dev branch”来体验(相比下载安装,在线版本体验会有一些局限):本文将和大家一起看看Go 1.22都会带来哪些新特性。原创 2024-08-01 10:45:04 · 131 阅读 · 0 评论 -
Go1.23新特性,time.After 终于不会内存泄漏了
今天给大家分享了一个花了将近 10 年,Go 才解决的计时器泄露问题。就是这个解决速度比较慢,很多人在真实的 Go 工程中都已经遇到过了。另外从新版本开始,大家在旧项目体验新特性是,要注意项目 go.mod 的 go 行版本或是 go toolchain 版本,避免由于版本过低而无法测试到真实的新特性效果。原创 2024-08-01 10:16:53 · 64 阅读 · 0 评论 -
Go模版渲染使用详解
包实现了数据驱动的模板,用于生成可防止代码注入的安全的HTML内容。它提供了和包相同的接口,Go语言中输出HTML的场景都应使用这个包。其中,定义模板文件时需要我们按照相关语法规则去编写,后文会详细介绍。我们按照Go模板语法定义一个hello.tmpl原创 2024-07-25 10:08:33 · 114 阅读 · 0 评论 -
Gin框架光速入门
Gin是一个用Go语言编写的web框架。它是一个类似于martini但拥有更好性能的API框架, 由于使用了httprouter,速度提高了近40倍。如果你是性能和高效的追求者, 你会爱上Gin。Go世界里最流行的Web框架,Github上有32K+star。基于httprouter开发的Web框架。中文文档齐全,简单易用的轻量级框架。定义一个不转义相应内容的safe},})原创 2024-07-25 09:29:21 · 116 阅读 · 0 评论 -
Goland添加注释模板
Goland中也提供了我们注释模板的定义,到setting中配置即可,首先我们定义创建新文件的时候,生成的类注释外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传找到Go File即可,然后输入下面的信息保存即可* @Author 陌溪下面我们通过 new,创建一个go file文件进行测试外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传可以看到,刚刚添加的文件,就有了测试信息了~原创 2024-07-24 17:49:01 · 73 阅读 · 0 评论 -
执行go get命令下载依赖失败的解决方法
最近在学习go连接mysql数据库这块,需要下载mysql的驱动包,使用的是下面的命令但是在执行的时候,总是出现如下的错误很显然上面的问题就是因为如果连接对应的下载服务器所引起的。原创 2024-07-24 12:38:22 · 38 阅读 · 0 评论 -
从源码角度详解Golang调度GMP
前面都是各种初始化操作,在这里开启了调度器的第一个调度循环。(这里启动的 M 就是 M0)下面来围绕 G、M、P 三个概念介绍 Goroutine 调度循环的运作流程。原创 2024-07-23 22:59:10 · 258 阅读 · 0 评论 -
GO内存分配详解
因此,可寻址字节取决于地址线的总量,对于64位地址线(x86–64 CPU),其可寻址字节为2的64次方个,但是大多数使用64位指针的体系结构实际上使用48位地址线(AMD64 )和42位地址线(英特尔),理论上支持256TB的物理RAM(Linux 在x86–64上每个进程支持128TB以及4级页表(page table)和Windows每个进程则支持192TB)但是,Go内存管理的总体思路是使用不同的内存结构为不同大小的对象使用不同的缓存级别内存来分配内存。扩大堆,通常会请求大量内存。原创 2024-07-23 22:48:31 · 317 阅读 · 0 评论 -
Go 程序是怎样跑起来的?
这次的话题太大了,困难重重。从编译原理到 go 启动时的流程,到 go 命令原理,每个话题单独抽出来都可以写很多。幸好有一些很不错的书和博客文章可以去参考。这篇文章就作为一个引子,你可以跟随参考资料里推荐的一些内容去发散。原创 2024-07-21 12:37:13 · 232 阅读 · 0 评论 -
ETCD介绍以及Go语言中使用ETCD详解
ETCD是一个分布式、可靠的key-value存储的分布式系统,用于存储分布式系统中的关键数据;当然,它不仅仅用于存储,还提供配置共享及服务发现;基于Go语言实现。原创 2024-07-21 12:41:16 · 187 阅读 · 0 评论 -
Go 内存模型
Go 内存模型指定了在一个 Goroutine 中读取变量时可以保证观察到在不同 Goroutine 中写入同一变量所产生的值的条件。翻译 2024-07-20 08:22:39 · 73 阅读 · 0 评论 -
GO Channel使用详解(各种场景下的最佳实践)
这节课,我借助代码示例,带你学习了 Channel 的应用场景和应用模式。这几种模式不是我们学习的终点,而是学习的起点。掌握了这几种模式之后,我们可以延伸出更多的模式。虽然 Channel 最初是基于 CSP 设计的用于 goroutine 之间的消息传递的一种数据类型,但是,除了消息传递这个功能之外,大家居然还演化出了各式各样的应用模式。原创 2024-07-20 08:01:49 · 791 阅读 · 5 评论 -
Go channel实现原理详解(源码解读)
chan 的值和状态有多种情况,而不同的操作(send、recv、close)又可能得到不同的结果,这是使用 chan 类型时经常让人困惑的地方。为了帮助你快速地了解不同状态下各种操作的结果,我总结了一个表格,你一定要特别关注下那些 panic 的情况,另外还要掌握那些会 block 的场景,它们是导致死锁或者 goroutine 泄露的罪魁祸首。还有一个值得注意的点是,只要一个 chan 还有未读的数据,即使把它 close 掉,你还是可以继续把这些未读的数据消费完,之后才是读取零值数据。思考题。原创 2024-07-20 07:55:21 · 248 阅读 · 0 评论 -
Go操作Redis详解
Redis是一个开源的内存数据库,Redis提供了多种不同类型的数据结构,很多业务场景下的问题都可以很自然地映射到这些数据结构上。除此之外,通过复制、持久化和客户端分片等特性,我们可以很方便地将Redis扩展成一个能够包含数百GB数据、每秒处理上百万次请求的系统。原创 2024-07-19 11:27:56 · 955 阅读 · 0 评论 -
NSQ介绍以及使用Go操作NSQ
NSQ是Go语言编写的一个开源的实时分布式内存消息队列,其性能十分优异。NSQ提倡分布式和分散的拓扑,没有单点故障,支持容错和高可用性,并提供可靠的消息交付保证NSQ支持横向扩展,没有任何集中式代理。NSQ易于配置和部署,并且内置了管理界面。原创 2024-07-19 11:17:49 · 54 阅读 · 0 评论 -
Kafka介绍及Go操作kafka详解
每个业务系统都有日志,当系统出现问题时,需要通过日志信息来定位和解决问题。当系统机器比较少时,登陆到服务器上查看即可满足当系统机器规模巨大,登陆到机器上查看几乎不现实(分布式的系统,一个系统部署在十几台机器上)LogAgent:日志收集客户端,用来收集服务器上的日志Kafka:高吞吐量的分布式队列(Linkin开发,Apache顶级开源项目)ElasticSearch:开源的搜索引擎,提供基于HTTP RESTful的web接口Kibana:开源的ES数据分析和可视化工具。原创 2024-07-19 10:29:57 · 541 阅读 · 0 评论 -
Go Context的使用详解
在 Go http包的Server中,每一个请求在都有一个对应的 goroutine 去处理。请求处理函数通常会启动额外的 goroutine 用来访问后端服务,比如数据库和RPC服务。用来处理一个请求的 goroutine 通常需要访问一些与请求特定的数据,比如终端用户的身份认证信息、验证相关的token、请求的截止时间。当一个请求被取消或超时时,所有用来处理该请求的 goroutine 都应该迅速退出,然后系统才能释放这些 goroutine 占用的资源。原创 2024-07-19 10:03:10 · 903 阅读 · 0 评论 -
一次超时导致的协程泄露
f1函数中使用协程池routinePool来执行异步任务,当f1函数超时后,会执行到f1的case原创 2024-07-17 18:26:43 · 1913 阅读 · 0 评论 -
Go 官方发布了 Go 1.20.3 和 Go 1.19.8
mime/multipart.Reader.ReadForm 限制了解析的多部分表单可以消耗的总内存。这会影响使用 mime/multipart.Reader.ReadForm 的程序,以及在 net/http 包中使用请求方法 FormFile、FormValue、ParseMultipartForm 和 PostFormValue 进行的表单解析。输入数据的某些异常模式可能会导致用于解析 HTTP 和 MIME 标头的通用函数分配比保存已解析标头所需的内存更多的内存。原创 2023-12-21 17:57:33 · 8866 阅读 · 0 评论 -
Go集成elasticsearch8极简demo,光速入门
编辑器添加goproxy。原创 2023-12-18 14:46:36 · 519 阅读 · 0 评论 -
mysql binlog_ignore_db参数的效果详解
我们知道 binlog 会记录数据库所有执行的 DDL 和 DML 语句(除了数据查询语句select、show等)。我们可以在mysql配置文件中关闭binlog注意默认情况下会记录所有库的操作,那么如果我们有另类需求,比如说只让某个库记录 binglog 或排除某个库记录 binlog ,需要怎么配置呢?原创 2023-12-15 06:39:39 · 793 阅读 · 0 评论 -
kafka的lag(kafka的消费堆积)为什么有时是负数?
Kafka Manager先从zookeeper获取LogSize,再从kafka __consumer_offsets topic读取Offset。由于这两步操作存在时间间隔,因此吞吐很大的topic或者当前集群负载很高的时候就会出现Offset > LogSize的情况。原创 2023-12-14 15:22:19 · 1082 阅读 · 0 评论 -
深入理解 Goroutines 和 Go Scheduler
本文将重点帮助您了解 Golang 中的 goroutines。Go 调度程序如何工作以在 Go 中实现最佳并发性能。我会尽力用简单的语言解释,这样你就可以理解了。我们将介绍什么是操作系统中的线程和进程,什么是并发,为什么实现并发很难,以及 goroutines 如何帮助我们实现并发。然后,我们将深入研究 Golang 的内部架构,即 Go Scheduler,它管理多个 goroutine 的调度,以便每个 goroutine 获得公平的机会,并且本质上不会阻塞。原创 2023-12-13 11:10:53 · 1011 阅读 · 2 评论 -
golang实现同步阻塞、同步非阻塞、异步非阻塞IO模型
然后,我们使用"net.Conn.Read"函数从客户端读取数据,并使用"processData"函数来处理客户端发送的数据。然后,我们使用"listener.Accept"函数接受客户端连接,并使用"handleConnection"函数来处理客户端连接。在"handleConnection"函数中,我们使用"net.Conn.Read"函数从客户端读取数据,并使用"processData"函数来处理客户端发送的数据。由于我们使用了同步阻塞IO函数来进行IO操作,所以程序会在执行IO操作时被阻塞。原创 2023-12-13 10:57:39 · 1090 阅读 · 0 评论 -
Golang 领域驱动设计(DDD)最佳实践
一个实体是一个唯一的东西,并且可以在相当长的一段时间内持续地变化。唯一的身份标识和可变性(mutability)特征将实体对象和值对象(ValueObject)区分开来。——《实现领域驱动设计》存储层(Repository)接口定义import ("context"原创 2023-12-13 10:31:40 · 1149 阅读 · 0 评论 -
深入理解Golang中的goroutine 池
工作线程池是一种并发模式,由一组负责并发执行任务的工作线程 goroutine 组成。这些员工从共享队列中获取任务,处理任务并返回结果。在处理大量可以并行执行的任务时,工作线程池特别有用,因为它们有助于控制并发运行的 goroutine 数量,并避免因过度创建 goroutine 而产生的开销。考虑一家繁忙的餐厅,厨房是工人的游泳池,厨师是工人的例行公事。餐厅的顾客代表必须完成的任务。顾客的订单必须由厨师在下单时处理。原创 2023-12-13 10:05:47 · 1037 阅读 · 0 评论 -
Goroutine协程调度时机总结
以下四种情形下,goroutine 可能会发生调度,但也并不一定会发生,只是说 Go scheduler 有机会进行调度。原创 2023-07-21 20:32:29 · 147 阅读 · 0 评论 -
Golang假共享(false sharing)详解
假共享是 SMP 系统上的一种常见性能问题。在SMP系统中,每个处理器均有一个高速缓存。当不同处理器上的线程修改驻留在同一高速缓存行(Cache Block,或Cache Line)中的变量时就会发生假共享。这种现象之所以被称为假共享,是因为每个线程并非真正共享相同变量的访问权。访问同一变量或真正共享要求编程式同步结构,以确保有序的数据访问。线程 0 和线程 1 会用到不同变量,它们在内存中彼此相邻,并驻留在同一高速缓存块(Cache Block,或Cache Line)。原创 2023-07-17 22:00:38 · 833 阅读 · 2 评论 -
通过GOROOT实现多个go版本的切换
打开goland在编辑器右上角对点击设置图标,在展开的设置列表中点击Go Settings...\。找到GOROOT点击右边的+号,选择从官网下载的Golang压缩包解压后的目录。原创 2023-02-13 18:53:15 · 1043 阅读 · 0 评论 -
Go channel实现原理及源码解读
我们开发中,chan 的值或者状态会有很多种情况,此时一定要注意使用方式,一些操作可能会出现 panic。原创 2023-02-10 22:39:49 · 492 阅读 · 0 评论