Go语言中实现基于 event-loop 网络处理

我们知道, Go语言为并发编程提供了简洁的编程方式, 你可以以"同步"的编程风格来并发执行代码, 比如使用go关键字新开一个goroutine。 对于网络编程,Go标准库和运行时内部采用 epoll/kqueue/IoCompletionPort来实现基于 event-loop的网络异步处理,但是通过netpoll的方式对外提供同步的访问。具体代码可以参考 runtime/netpollnetinternal/poll

Package poll supports non-blocking I/O on file descriptors with polling.
This supports I/O operations that block only a goroutine, not a thread.
This is used by the net and os packages.
It uses a poller built into the runtime, with support from the
runtime scheduler.

当然,我们平常不会设计到这些封装的细节,正常使用net包就很方便的开发网络程序了, 但是,如果我们想自己实现基于epollevent-loop网络程序呢?

阅读全文

[译]Go TCP Socket的实现

原文: TCP Socket Implementation On Golang by Gian Giovani.

译者注: 作者并没有从源代码级别去分析Go socket的实现,而是利用strace工具来反推Go Socket的行为。这一方法可以扩展我们分析代码的手段。
源代码级别的分析可以看其实现: net poll,以及一些分析文章:The Go netpoller, The Go netpoller and timeout

Go语言是我写web程序的首选, 它隐藏了很多细节,但仍然不失灵活性。最新我用strace工具分析了一下一个http程序,纯属手贱但还是发现了一些有趣的事情。

下面是strace的结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
91.24 0.397615 336 1185 29 futex
4.13 0.018009 3 7115 clock_gettime
2.92 0.012735 19 654 epoll_wait
1.31 0.005701 6 911 write
0.20 0.000878 3 335 epoll_ctl
0.12 0.000525 1 915 457 read
0.02 0.000106 2 59 select
0.01 0.000059 0 170 close
0.01 0.000053 0 791 setsockopt
0.01 0.000035 0 158 getpeername
0.01 0.000034 0 170 socket
0.01 0.000029 0 160 getsockname
0.01 0.000026 0 159 getsockopt
0.00 0.000000 0 7 sched_yield
0.00 0.000000 0 166 166 connect
0.00 0.000000 0 3 1 accept4
------ ----------- ----------- --------- --------- ----------------
100.00 0.435805 12958 653 total

阅读全文

Go 1.10 的pprof的工具将直接支持火焰图

google/pprof是一个性能可视化和分析工具,由Google的工程师开发。虽然自称不是Google官方的工具,但是项目挂在google的team下,而且还在Google其它项目中得到应用,是非常好的一个性能剖析工具。

go tool pprof 复制了一份google/pprof的代码, 封装了一个golang的工具,用来分析Go pprof包产生的剖析数据,也就是最终数据的处理和分析还是通过gogole/pprof来实现的。

这样,你至少就用两种方式来分析Go程序的 pprof数据:

  1. go tool pprof : Go封装的pprof的工具
  2. pprof: 原始的pprof工具

阅读全文

Kafka的复制机制

最近在设计一个多分区多副本的消息系统,以前对kafka有一些了解,在阅读了阿里的RocketMQ、小米的Pegasus等分布式系统后,再仔细阅读的kafka的复制设计,整理出本篇文档,可以和其它系统做一个对比。

Kafka是一种高吞吐量的分布式发布订阅消息系统,有如下特性:

  1. 通过O(1)的磁盘数据结构提供消息的持久化,这种结构对于即使数以TB的消息存储也能够保持长时间的稳定性能。
  2. 高吞吐量:即使是非常普通的硬件Kafka也可以支持每秒数百万的消息。
  3. 支持通过Kafka服务器和消费机集群来分区消息。
  4. 支持流式处理。

7年过去了, kafka已经成为一个羽翼丰满的发布订阅平台、消息存储、流处理的工具。财富500强企业中有三分之一的公司使用了kafka平台。也就是在昨天(2017年11月1日),kafka发布了它的1.0.0版本。

本文主要参考了Jun Rao(饶军)的Intra-cluster Replication in Apache Kafka, Jun Rao毕业于清华大学,哥读到博士,后来在IBM、LinkedIn工作,在LinkedIn期间任Kafka组的技术leader。2014年Kafka一帮人成立了Confluent公司,推广Kafka的商业应用,Jun Rao是共同创始人。

阅读全文

如何整个替换git master分支?

最近需要将一个项目的master分支用另一个分支完全替换, 查找了相关资料,最后追溯到stackoverflow上的一个提问: How to replace master branch in git, entirely, from another branch?

网友给出了两种方案。

假设需要将seotweaks分支替换成master

1、

1
2
3
4
git checkout seotweaks
git merge -s ours master
git checkout master
git merge seotweaks

-s ours--strategy=ours的简写。

2、
如果上面的操作有问题, 还可以使用下面这个方法:

1
2
3
git branch -m master old-master
git branch -m seotweaks master
git push -f origin master

-m用来重命名分支。

This might remove commits in origin master

git cmd

[译] Kafka 存储的工作机制

翻译自 Kafka/Confluent 公司的工程师 Travis Jeffery 的文章: How Kafka’s Storage Internals Work

通过本文我会帮助你理解Kafka是如何存储它的数据的。
对于调优Kafka的性能以及了解broker配置实际是干什么的, 了解Kafka的存储很有用。 我受Kafka的简单性的启发, 用我所学开始实现一个Go的Kafka: jocko

那么, Kafka存储内部是如何工作的呢?

阅读全文

GOMAXPROCS需要设置吗?

自 Go 1.5开始, Go的GOMAXPROCS默认值已经设置为 CPU的核数, 这允许我们的Go程序充分使用机器的每一个CPU,最大程度的提高我们程序的并发性能, 而且,在大部分情况下, 我们并不会去设置这个参数。因为默认值已经足够好了, 以至于fasthttp的作者valyala提议禁止runtime.GOMAXPROCS设置这个数值, 对于所有的case, GOMAXPROCS默认值是否是最好的值呢?

badger的作者Manish Rai Jain就遇到了这样一个问题

阅读全文

Convert Shadowsocks into an HTTP proxy

备用,不解释

socks5 to http proxy

1、 首先安装 polipo, 设置parent proxy to Ss:

1
2
3
apt-get install polipo
service polipo stop
polipo socksParentProxy=localhost:1080 &

macosx运行

1
2
brew install polipo
polipo socksParentProxy=localhost:1080 &

设置全局http proxy:

1
2
3
http_proxy=http://localhost:8123 apt-get update
http_proxy=http://localhost:8123 curl www.google.com
http_proxy=http://localhost:8123 wget www.google.com

对于git:

1
2
3
4
5
git config --global http.proxy 127.0.0.1:8123
git clone https://github.com/xxx/xxx.git
git xxx
git xxx
git config --global --unset-all http.proxy

glide mirror

1
2
3
4
5
6
7
8
9
$ rm -rf ~/.glide
$ mkdir -p ~/.glide
$ glide mirror set https://golang.org/x/mobile https://github.com/golang/mobile --vcs git
$ glide mirror set https://golang.org/x/crypto https://github.com/golang/crypto --vcs git
$ glide mirror set https://golang.org/x/net https://github.com/golang/net --vcs git
$ glide mirror set https://golang.org/x/tools https://github.com/golang/tools --vcs git
$ glide mirror set https://golang.org/x/text https://github.com/golang/text --vcs git
$ glide mirror set https://golang.org/x/image https://github.com/golang/image --vcs git
$ glide mirror set https://golang.org/x/sys https://github.com/golang/sys --vcs git