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 是一种可复用资源。一个 goid10 的协程,可以在处理完一个任务后,重置状态,再处理另一个任务。任务是唯一性的,而 goid 总会重复。因此使用 goid 作为标识会引发混乱,实际使用中仍然需要其他标识作为参考。

而在一个任务对应多个协程的场景中,goid 更是徒劳无益。

 

标识与渠道相关,而不是与处理相关

正确的做法是使用编程的方式标识一个任务。这不仅契合 标识 本身的含义,也更加具有扩展性。

微服务架构越来越流行。比起设计一个庞大臃肿的系统,人们更倾向于把它拆分为多个小巧的系统,各司其职。这也符合 devOps 的发展方向。这种情况下,一个从系统入口就生成并透传的唯一标识是必须的。这是链路追踪的基础。

此外,对于分布式事务来说,一个事务也需要一个唯一标识。

最新文章

  1. MongoDB学习笔记~MongoDBRepository仓储的实现
  2. Leetcode: Serialize and Deserialize BST
  3. 我所了解的chrome
  4. Mac OX 隐藏文件夹,文件,应用,磁盘的2种方法 hide finder folder, file, application, volume in 2 ways
  5. [Sharepoint]备份 迁移 还原
  6. xamarin fivechess
  7. web前端开发框架搜集
  8. 集合中Set_List必须覆盖 hashCode()与 equals()
  9. Neo4j 第五篇:批量更新数据
  10. 如何开发自己的搜索帝国之Elasticsearch
  11. Javascript一句代码实现JS字符串去除重复字符
  12. MongoDB $type条件操作符
  13. linux下gtk+一个将字符串大写化的小示例
  14. php获取两个时间戳之间相隔多少天多少小时多少分多少秒
  15. HashMap与LinkedHashMap的区别
  16. python day05笔记总结
  17. js获取元素位置和style的兼容性写法
  18. Spring MVC基础知识整理➣国际化和异常处理
  19. Apache URL重写的配置 及其 apache500错误
  20. Objective-C语法之指针型参数

热门文章

  1. ASP.NET MVC 四种Controller向View传值方法
  2. JavaScript基础正则表达式的字面声明(012)
  3. 洛谷 P1347 【排序】
  4. CI CD概念
  5. Linux查看docker容器日志
  6. application.yml和application.properties文件的区别
  7. pdfjs优化,实现按需加载,节省流量和内存
  8. JavaScript之原型模式
  9. Github 新玩法 -- Profile ReadMe
  10. 百万级别数据Excel导出优化