发一个 Go 实现的 HTTP 代理服务器以及一些感想

248 views
Skip to first unread message

Chen Yufei

unread,
Feb 19, 2013, 10:45:45 AM2/19/13
to golang...@googlegroups.com
COW https://github.com/cyfdecyf/cow/

去年 8 月开始写这个 HTTP 代理的时候是作为 Go 的练手项目的,现在已经是我日常使用的一个工具了。

这个代理主要用处是辅助自动化翻墙。机制很简单,默认对 client 请求使用直接连接,遇到 connection reset 或者 dial/read timeout 就用翻墙代理重试请求。更多机制有兴趣的同学可以看下 github 上的 readme。

下面说下写这个代理过程中的一些感受吧。

一些使用 Go 的时候最让觉得舒服的地方:

- 标准库很好用
- 跨平台支持、交叉编译很方便
- 个人比较喜欢多值返回的方式来处理错误
- go tool 极大的方便了编译、测试等工作
- 静态链接方便二进制文件的发布

偶尔也会有发现一些不太令人满意的地方:

- 没有泛型有时是会有些不便,例如我想实现一个通用的 set,如果用 interface{} 作为 value 的类型则没有编译时类型检查
  - 关于这个问题 Russ Cox 说过他们考虑过,但是还没有找到合适的方式,期待某一天出现
- cgo 调用 blocked call 可能会需要创建新线程,目前不会限制创建线程的数量
  - 这个问题目前也在考虑解决中
  - 感谢 minux 让我明白了这个问题
  - 从这个问题里学到的是用带有 runtime 的语言,好好了解 runtime 还是必须的
- 有些标准库 (例如 strconv) 只处理 string 而不处理 []byte,所以不得不做转换而引入一些不必要的 copy
  - 在写 COW 的时候我特地从 strconv 里拷贝了 ParseInt 的代码来专门处理 []byte
  - 这个是有点 micro optimization 了,不过问题还是存在的,Brad Fitzpatrick 也创建过 issue
- net 包返回的错误难以判断具体是什么错误
  - 今天想到发这个贴就是因为又看到之前有人问如何判断 connection reset 错误的帖子
  - 像 use of closed network connection 这个错误除了用 Error() 然后判断字符串是否匹配以外貌似没有其他办法
  - connection reset, timeout, dns error 这些错误在 unix 和 windows 平台要用不同的方式去判断

总体来说,这些不太令人满意的地方都不是太大的问题,或者是已经在解决中。

写这个代理服务器的过程中慢慢体会到 Go is not meant to innovate programming theory. It’s meant to innovate programming practice. 这句话的含义。

越来越喜欢 Go,她已是我的最喜欢用的编程语言。

我欲乘风去

unread,
Feb 19, 2013, 4:41:53 PM2/19/13
to golang...@googlegroups.com
多谢分享实战经验

Tony

unread,
Feb 19, 2013, 9:09:24 PM2/19/13
to golang...@googlegroups.com
不错, 谢谢分享!

2013/2/20 我欲乘风去 <knif...@gmail.com>
多谢分享实战经验
--
--
官网: http://golang-china.org/
IRC: irc.freenode.net #golang-china
@golangchina
 
---
您收到此邮件是因为您订阅了 Google 网上论坛的“Golang-China”论坛。
要退订此论坛并停止接收此论坛的电子邮件,请发送电子邮件到 golang-china...@googlegroups.com
要查看更多选项,请访问 https://groups.google.com/groups/opt_out。
 
 

Reply all
Reply to author
Forward
0 new messages