为什么不应该使用goroutine id?
Goroutine id 的获取方式
之前做的项目中,会使用 goroutine-id(以下简称 goid) 作为日志中的一个标识参数。而 goroutine 的相关信息是不对外暴露的。想要获取 goid,除了直接修改 Golang 源码的骚操作,通常会使用两种方式:
- 一种是通过堆栈获取。
func Goid() int {
var buf [64]byte
n := runtime.Stack(buf[:], false)
goroutineId := strings.Fields(strings.TrimPrefix(string(buf[:n]), "goroutine "))[0]
id, err := strconv.Atoi(goroutineId)
if err != nil {
panic(fmt.Sprintf("cannot get goroutine id: %v", err))
}
return id
}
这种获取方式会牺牲一部分性能,好处是不用修改 Golang 的源码,不用关心 Go 语言版本,省去后期维护的麻烦。
- 另一种获取
goid的方式是建立goroutine的本地存储。相关库参考:
github.com/v2pro/plz。这种方式同样不入侵源码,更为高效,但是需要随Go语言的版本进行维护。
以上获取 goid 的方法在搜索引擎中可以很容易地获取到。但是,这是不是反而引发了 goid 的滥用呢?换句话说,goid 是否是一个伪需求呢?
为什么不应该使用goroutine id?
根据 Go 语言的官方设计,我们是无法对一个运行中的 goroutine 进行操作的。coder 对协程不具有管理权限,一旦使用 go 关键字开启了一个协程,只能任其运行。不像在其他语言中管理线程,Go 不需要一个线程的标识来记录对于线程的管理。
在大多数业务场景里,服务端启用一个协程处理一个任务(多数情况下是一个请求)。这种场景下,我们使用 goid 的目的,更多地在于标识一个任务。然而 goroutine 是一种可复用资源。一个 goid 为 10 的协程,可以在处理完一个任务后,重置状态,再处理另一个任务。任务是唯一性的,而 goid 总会重复。因此使用 goid 作为标识会引发混乱,实际使用中仍然需要其他标识作为参考。
而在一个任务对应多个协程的场景中,goid 更是徒劳无益。
标识与渠道相关,而不是与处理相关
正确的做法是使用编程的方式标识一个任务。这不仅契合 标识 本身的含义,也更加具有扩展性。
微服务架构越来越流行。比起设计一个庞大臃肿的系统,人们更倾向于把它拆分为多个小巧的系统,各司其职。这也符合 devOps 的发展方向。这种情况下,一个从系统入口就生成并透传的唯一标识是必须的。这是链路追踪的基础。
此外,对于分布式事务来说,一个事务也需要一个唯一标识。
为什么不应该使用goroutine id?的更多相关文章
- golang goroutine 介绍
Goroutine 是用户态自己实现的线程,调度方式遇到IO/阻塞点方式就会让出cpu时间(其实也看编译器的实现,如果TA在代码里面插入一些yield,也是可以的. 反正现在不是抢占式的.) 不能设置 ...
- golang的并发不等于并行
先 看下面一道面试题: func main() { runtime.GOMAXPROCS(1) wg := sync.WaitGroup{} wg.Add(20) for i := 0; i < ...
- <转>年终盘点!2017年超有价值的Golang文章
马上就要进入2018年了,作为年终的盘点,本文列出了一些2017年的关于Go编程的一些文章,并加上简短的介绍. 文章排名不分先后, 文章也不一定完全按照日期来排列.我按照文章的大致内容分了类,便于查找 ...
- Go调试工具—— Delve
参考https://github.com/go-delve/delve 安装 首先你必须有等于或高于1.8版本的Go,我的版本是: userdeMBP:go-learning user$ go ver ...
- go 面试题总结
1.什么是goroutine,他与process, thread有什么区别? 2. 什么是channel,为什么它可以做到线程安全? 3. 了解读写锁吗,原理是什么样的,为什么可以做到? 4. 如何用 ...
- 06 Frequently Asked Questions (FAQ) 常见问题解答 (常见问题)
Frequently Asked Questions (FAQ) Origins 起源 What is the purpose of the project? What is the history ...
- Go语言 7 并发编程
文章由作者马志国在博客园的原创,若转载请于明显处标记出处:http://www.cnblogs.com/mazg/ Go学习群:415660935 今天我们学习Go语言编程的第七章,并发编程.语言级别 ...
- go——并发
并发与并行的区别: 并发:逻辑上具备同时处理多个任务的能力. 并行:物理上在同一时刻执行多个并发任务.通常都会说程序是并发设计的,也就是说它允许多个任务同时执行,但实际上并不一定真在同一时刻发生.在单 ...
- golang ----并发 && 并行
Go 语言的线程是并发机制,不是并行机制. 那么,什么是并发,什么是并行? 并发是不同的代码块交替执行,也就是交替可以做不同的事情. 并行是不同的代码块同时执行,也就是同时可以做不同的事情. 举个生活 ...
随机推荐
- Springboot 集成 ElasticSearch 踩坑
这里只涉及到基础使用 导包 <dependency> <groupId>org.springframework.boot</groupId> <artifac ...
- dart快速入门教程 (3)
3.运算符 运算符本质上就是代表某运算规则的符号,例如: + ,这个符号,代表着数学运算里面的加法,按照加法法则进行运算即可,同理,学习运算符就是掌握这些规则而已 3.1.算术运算符 算术运算符主要包 ...
- js语法基础入门(5.2)
5.2.循环结构 当一段代码被重复调用多次的时候,可以用循环结构来实现,就像第一个实例中出现的场景一样,需要重复询问对方是否有空,这样就可以使用循环结构来搞定 5.2.1.for循环语句 //语法结构 ...
- Excel表格中第一个输入的零不显示怎么办?
Excel表格是办公的人经常要用到的软件,经常用它来统计和记录各种数据,但是有时候表格中第一个数字是零的时候,经常第一个零输入时不显示的,这个情况我们怎么解决呢?这里小编跟大家讲一下希望能帮助大家. ...
- spring bean post processor
相关文章 Spring 整体架构 编译Spring5.2.0源码 Spring-资源加载 Spring 容器的初始化 Spring-AliasRegistry Spring 获取单例流程(一) Spr ...
- 洛谷 P4822 [BJWC2012]冻结
之前没学分层图,所以先咕了一下hiahiahia. 学完分层图了回来水写题解了. 这道题要用分层图来解.分层图就是在我们决策的时候,再建k层图,一共k+1层,层与层之间是有向边(这个很重要的),权值为 ...
- CentOS7开机报错piix4_smbus ****host smbus controller not enabled
vi /etc/modprobe.d/blacklist.conf 输入:blacklist i2c_piix4 保存退出::wq 重启:reboot (完)
- AI 开发路漫漫,什么才是真正的极客精神?
摘要:AI开发看上去很美,实践起来却不是一件容易的事.一个聪明的开发者知道借助工具提升开发效率,一个智能的平台则会站在开发者的立场,为用户提供贴心服务. 前言 “理想很丰满,现实很骨感.”如果用一句话 ...
- PHPstorm快捷键的学习
1.Ctrl + 空格 当输入代码时,PHPstorm 会自动出现联想选项. 但是,如果在输入时联想时错过了选择,我们要想让他再一次出现联想,通常采用的方法是在先前的输入后面再输入字符,这时联想又会出 ...
- JAVA死锁排查-性能测试问题排查思路
死锁原因 Java发生死锁的根本原因是:在申请锁时发生了交叉闭环申请.即线程在获得了锁A并且没有释放的情况下去申请锁B,这时,另一个线程已经获得了锁B,在释放锁B之前又要先获得锁A,因此闭环发生,陷入 ...