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 的发展方向。这种情况下,一个从系统入口就生成并透传的唯一标识是必须的。这是链路追踪的基础。

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

为什么不应该使用goroutine id?的更多相关文章

  1. golang goroutine 介绍

    Goroutine 是用户态自己实现的线程,调度方式遇到IO/阻塞点方式就会让出cpu时间(其实也看编译器的实现,如果TA在代码里面插入一些yield,也是可以的. 反正现在不是抢占式的.) 不能设置 ...

  2. golang的并发不等于并行

    先 看下面一道面试题: func main() { runtime.GOMAXPROCS(1) wg := sync.WaitGroup{} wg.Add(20) for i := 0; i < ...

  3. <转>年终盘点!2017年超有价值的Golang文章

    马上就要进入2018年了,作为年终的盘点,本文列出了一些2017年的关于Go编程的一些文章,并加上简短的介绍. 文章排名不分先后, 文章也不一定完全按照日期来排列.我按照文章的大致内容分了类,便于查找 ...

  4. Go调试工具—— Delve

    参考https://github.com/go-delve/delve 安装 首先你必须有等于或高于1.8版本的Go,我的版本是: userdeMBP:go-learning user$ go ver ...

  5. go 面试题总结

    1.什么是goroutine,他与process, thread有什么区别? 2. 什么是channel,为什么它可以做到线程安全? 3. 了解读写锁吗,原理是什么样的,为什么可以做到? 4. 如何用 ...

  6. 06 Frequently Asked Questions (FAQ) 常见问题解答 (常见问题)

    Frequently Asked Questions (FAQ) Origins 起源 What is the purpose of the project? What is the history ...

  7. Go语言 7 并发编程

    文章由作者马志国在博客园的原创,若转载请于明显处标记出处:http://www.cnblogs.com/mazg/ Go学习群:415660935 今天我们学习Go语言编程的第七章,并发编程.语言级别 ...

  8. go——并发

    并发与并行的区别: 并发:逻辑上具备同时处理多个任务的能力. 并行:物理上在同一时刻执行多个并发任务.通常都会说程序是并发设计的,也就是说它允许多个任务同时执行,但实际上并不一定真在同一时刻发生.在单 ...

  9. golang ----并发 && 并行

    Go 语言的线程是并发机制,不是并行机制. 那么,什么是并发,什么是并行? 并发是不同的代码块交替执行,也就是交替可以做不同的事情. 并行是不同的代码块同时执行,也就是同时可以做不同的事情. 举个生活 ...

随机推荐

  1. junit搭建自动化测试框架(一)

    这里主要使用Junit搭建一个分层的自动化测试框架.这就是一个有业务逻辑的单元测试的思想.灵活性很大,对测试人员的代码能力要求较高. 以登录QQ邮箱为例,数据源使用了集合接口Map.借鉴了MVC的思想 ...

  2. web安全之跨站脚本漏洞(XSS)

    XSS(跨站脚本)概述以及pikachu上的实验操作 Cross-Site Scripting 简称为“CSS”,为避免与前端叠成样式表的缩写"CSS"冲突,故又称XSS. XSS ...

  3. pxc搭建mysql集群

    docker -y update yum install -y docker service docker satrt docker images 服务器:curl -sSL https://get. ...

  4. Electron: 如何以 Vue.js, Vuetify 开始应用

    Electron: 使用 JavaScript, HTML 和 CSS 等 Web 技术创建原生程序的框架 Vue.js: Web 前端用于构建用户界面的渐进式框架 Vuetify: Vue.js 的 ...

  5. PAT A1003 Emergency 题解

    PAT A1003 Emergency PAT A1003 Emergency 题目简述: 原题为英文题目,所以在这里简述一下题意: 给定n个点和m条无向路以及起点.终点 下面一行n个数,第i个数表示 ...

  6. Maven Jar包下载失败及解决方案

    我是阿福,公众号「阿福聊编程」作者,一个在后端技术路上摸盘滚打的程序员,在进阶的路上,共勉! 文章已收录在 JavaSharing 中,包含Java技术文章,面试指南,资源分享. 明显的下载失败 具体 ...

  7. JS数据类型判断的几种方法

    JS数据类型判断 JavaScript 中常见数据类型有Number.String.Boolean.Object.Array.Json.Function.Date.RegExp.Error.undef ...

  8. 【JMICRO】 微服务简介及异步RPC体验

    一,为什么写JMicro 印象中初次接触微服务大概是2011年,那会做Eclpise插件开发,网上查看好多关于OSGI的技术文章,发现Spring新出了一个叫Spring-boot的框架,那会没太上心 ...

  9. MCU 51-4 独立按键&编码按键

    独立按键: 按键的按下与释放是通过机械触点的闭合与断开来实现的,因机械触点的弹性作用,在闭合与断开的瞬间均有一个抖动的过程,抖动必须清除. 按键按下一次,数码管数值加1: #include<re ...

  10. shell专题(十一):企业真实面试题(重点)

    11.1 京东 问题1:使用Linux命令查询file1中空行所在的行号 答案: [atguigu@hadoop102 datas]$ awk '/^$/{print NR}' sed.txt 问题2 ...