再谈谈获取 goroutine id 的方法

去年年初的时候曾经写过一篇关于如何获取goroutine id的方法: 如何得到goroutine 的 id?, 当时调研了一些一些获取goid的方法。基本的方法有三种:

  1. 通过Stack信息解析出ID
  2. 通过汇编获取runtime·getg方法的调用结果
  3. 直接修改运行时的代码,export一个可以外部调用的GoID()方法

每个方式都有些问题, #1比较慢, #2因为是hack的方式(Go team并不想暴露go id的信息), 针对不同的Go版本中需要特殊的hack手段, #3需要定制Go运行时,不通用。当时的petermattis/goid提供了 #2 的方法, 但是只能在 go 1.3中才起作用,所以只能选择#1的方式获取go id。

最近一年来, petermattis更新了他的代码,逐步增加了对 Go 1.4、1.5、1.6、1.7、1.8、1.9的支持,同时也提供了#1的方法,在#2方法不起作用的时候作为备选,所以我们可以在当前的所有的版本中可以使用stable的获取go id的方法了。

阅读全文

Go 1.9 sync.Map揭秘

在Go 1.6之前, 内置的map类型是部分goroutine安全的,并发的读没有问题,并发的写可能有问题。自go 1.6之后, 并发地读写map会报错,这在一些知名的开源库中都存在这个问题,所以go 1.9之前的解决方案是额外绑定一个锁,封装成一个新的struct或者单独使用锁都可以。

本文带你深入到sync.Map的具体实现中,看看为了增加一个功能,代码是如何变的复杂的,以及作者在实现sync.Map的一些思想。

阅读全文

Mac OS X显示连接

Mac OSX中虽然带了 netstat工具,可是用起来不像Linux下那么爽, 一个是慢 (netstat -p tcp | grep $PORT),二是不能pid,所以stackoverflow上建议使用lsof工具。

所以你可以使用下面的命令:

1
2
3
lsof -n -i4TCP:$PORT | grep LISTEN # Verified on macOS Sierra
lsof -n -iTCP:$PORT | grep LISTEN
lsof -n -i:$PORT | grep LISTEN

为了不显示端口的俗称,你可以加P参数:

1
2
3
lsof -nP -i4TCP:$PORT | grep LISTEN # Verified on macOS Sierra
lsof -nP -iTCP:$PORT | grep LISTEN
lsof -nP -i:$PORT | grep LISTEN

如果不想grep Listen,可以加-sTCP:LISTEN

没有更多要说的了,谨记一下备用。

[译]参考资料: 地道的GO代码

原文: Idiomatic Go

什么样的代码才算最地道的Go代码? 这个问题经常被人问起,但是确不太好回答。部分原因在于我们还在摸索之中,抑或Go还是一个年轻的语言。随着语言和社区的逐渐成熟,老司机们才会对地道的Go代码达成共识。

请注意,地道的代码不是限制你的规则,而是代码指导。工作正常的代码比地道的代码更重要。因为所谓的地道,只是大家达成的一种共识,所以"不地道"的的代码不一定代表着错误。

既然没有确定的答案,我在本文中收集了相关的参考资料, 以飨读者。

阅读全文

在Nginx内部自动处理3XX跳转

利用Nginx很容易的配置反向代理和负载均衡的服务, 比如下面的配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
upstream backends {
server 10.0.0.10:8080;
server 10.0.0.11:8080;
server 10.0.0.12:8080;
}
server{
listen 8080;
location / {
proxy_pass http://backends;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

它将客户端的请求转发给后台的三个服务器。 负载均衡的算法又多种, 比如轮询、least_conn、ip_hash、weight等算法,本文重点不介绍这方面的内容,而是下面的需求。

后端服务器可能返回 3XX的redirect的response, Nginx会把这个请求直接返回给客户端。现在我们的需求是让Nginx自己处理这个跳转,而客户端无感知。

阅读全文

[译]像牛人一样改进你的Go代码

原文: Lint your #golang code like a mad man!, 作者: Arsham Shirvani

我使用下面的工具来改进我的代码,除了vendor文件夹。我的操作系统是GNU/Linux,但是稍微修改一下脚本应该也能运行在你的操作系统上。我使用glide来处理依赖(vendor),但你也可以使用你的包依赖管理工具来替换glide nv, 这个命令列出了所有的文件夹,除了vender (译者按: Go 1.9中可以直接使用./...,它会排除vendor文件夹)。有些情况下glide nv不适合,所以我使用了它的老式风格。

注意我使用$作为shell的提示符。

阅读全文

了解 Go 1.9 的类型别名

如你所知, 类型别名(type aliases) 最终还是加入到Go 1.9中, Go 1.9 beta2今天已经发布了, 正式版预计8月初发布, 是时候深入了解一下它的新特性了,本文介绍的就是它的重要的新特性之一: 类型别名。

当然,如果你想尝试这些新特性,需要安装Go 1.9的版本,目前是beta2版,可以在官方网站下载。

阅读全文

[转]Golang 中使用 JSON 的小技巧

taowenjson-iterator的作者。 序列化和反序列化需要处理JSON和struct的关系,其中会用到一些技巧。 原文 Golang 中使用 JSON 的小技巧是他的经验之谈,介绍了一些struct解析成json的技巧,以及 json-iterator 库的一些便利的处理。

有的时候上游传过来的字段是string类型的,但是我们却想用变成数字来使用。 本来用一个json:",string" 就可以支持了,如果不知道golang的这些小技巧,就要大费周章了。

参考文章:http://attilaolah.eu/2014/09/10/json-and-struct-composition-in-go/

阅读全文