作者归档:mzh

如何压缩Golang 编译出的可执行文件大小

先给结论:可以减少到原来的29%

最近在写一个TLScat小工具
Github.com/mengzhuo/tlscat
源文件仅仅2KB不到,但是用 go build tlscat.go 编译出来的有4.6MB!

屏幕快照 2015-05-04 23.39.08

贴纸

后来发现这个Golang的1.5才会解决的问题 Issue #6853 all: binaries too big and
growing
可是,我就不信这个邪,于是搜索到了go
build的一些用法 go build -ldflags "-s -w" ‘-s’ 相当于strip掉符号表,
但是以后就没办法在gdb里查看行号和文件了。 ‘-w’ flag to the linker to omit the debug information
告知连接器放弃所有debug信息 这样一来就只有3MB了

贴纸

然后发现在Mac平台下,还有upx这样神一般的存在。

UPX achieves an excellent compression ratio and offers very fast
decompression.

简而言之,upx就是对可执行文件进行压缩,然后可以已极快的速度解压并运行

可以用brew快速安装upx brew install upx upx 可执行文件 屏幕快照 2015-05-0523.41.40

参加某开发比赛后记

前些日子参加了某云的开发大赛,结果出来了~ 屏幕快照 2015-05-04 16.19.27 仅仅拿了一个三等奖,略桑心。
参赛过程具体见《[如何一下午写3000行?记某云的Golang API
SDK生产过程](/%e5%a6%82%e4%bd%95%e4%b8%80%e4%b8%8b%e5%8d%88%e5%86%993000%e8%a1%8c%ef%bc%9f%e8%ae%b0%e6%9f%90%e4%ba%91%e7%9a
%84golang-api-sdk%e7%94%9f%e4%ba%a7%e8%bf%87%e7%a8%8b)》

不过伤心之余,我理性一把,看了看前4的分别都是啥: 特等奖是移动客户端的解决方案:mu
MU (Mobile UCloud) 是一个基于 UCloud API 的手机版管理工具……
成熟度已经和产品可以媲美了,也解决了在移动端大潮之下,官方对移动端支持几乎是空白的痛点,所以只需要签个协议就可以用的产品,拿奖不奇怪。
而三个一等奖里,有另一个产品: ESS_For_Ucloud
这货就相当于AWS里的ELB,同样是改改就能投入线上使用的产品。 解决了……呃……官方有LB,但是需要人工调整这样"不云"的尴尬。 第二个一等奖是:
Ucloud CLI命令行接口
回想我司的运维、SA们用来控制AWS的工具,不是web控制端,不是各种写好的SDK,而是AWS CLI,因为他们最熟悉的就是各种脚本。
这也正是比赛举办方所缺少的! 虽然命令覆盖得并不是很完善,但也算是补上了个自动化运维的坑。 最后一个一等奖是: Python
SDK

在我吐槽官方的SDK用了**params这样的动态语言特性时,聪明的人自然会想到,举办方自然希望修补官方的SDK也是比赛的侧重方向了嘛~

虽然,我粗浅地看下去,这个SDK也仅仅是修补了官方SDK调用时不严谨的尴尬,而且由于API这么多,自然覆盖得不全,但是也算抓住了举办方的心了。
公布之后在交流群里,不少人也吐槽自己UT覆盖率比得上面的都高,为啥只能拿二等甚至是三等。反过来想,真的算是程序员典型的思维了:自己做的程序、工具很"牛B",但是为啥没有人用,甚至是不受欢迎。
都是因为: 没有抓住痛点!没有抓住痛点!!没有抓住痛点!!! 所以,下次做东西的时候,得多问问自己:

需求是啥!?

如何一下午写3000行?记某云的Golang API SDK生产过程

近日参加了某云的SDK编写比赛,官方给的样例是个Python版,请求直接用**params这样方法构造请求体

暴走漫画-你他妈的在逗我

因为尼玛Golang是静态语言,我们严谨!没有可变参数!还没有默认值!!

所以我苦逼地写了一个多小时类似这样的代码:

func (c *Client) GetHostInstance(id string, option string, count int) {
// bla....
}

每个API一遍遍地重复,真是苦不堪言,啥时候是个头啊,人生苦短啊,早知道还用Python了…… 于是我去睡觉了,嗯 梦中Rob
Pike托梦
醒来,突然想到,几天前学习的Go
reflect库,可以反射出调用的type,这样我只要构造struct,然后遍历一下每一项,不就可以省了很多时间了么? 于是,我开始构造各种struct
type GetHostInstance struct{ id string option string count int }
从json库中直接拉了些代码来遍历NumField,顿时感觉自己棒棒的!! 但是,写了三个以后我突然发现API里有些参数是optional的!!!

20130422212028-23861660

幸好,Rob大大已经替我等想好了,那就是struct的TagField,于是我TM也构造了一个自己的解析器

type GetHostInstance struct{
id string `cloud:"optional"`
option string
count int }
// .....解析器部分代码
// .....获取tag tag := typ.Field(i).Tag.Get("cloud")

取出tag值之后,依靠检查struct这项是否为nil来确定是否传不传参数!
终于可变参数这么蛋疼的事情都让我解决了,紧接着,我又写了3个struct,累得不行了……年纪轻轻就体力不支了
但是我决定写完去,因为这么漂亮的解决方案不用来拿个马克杯做奖品怎么行?!
于是又写了3个API,我发现我就是在复制粘贴官方的API文档,于是我祭出我的复制粘帖大法+Vim宏
顿时快了很多,变成5分钟一个API,我看了看文档里……TM的一共50多个接口!! 5*50 = 250 分钟 = 4个多小时 =
我都可以拿来看《黑鹰坠落》+ 5集《GTA 5搞笑视频》了!!
于是我开始无聊地点着官方API文档,我突然发现,官方的API文档是用Sphinx写的,只是套了层自己的css而已 –>
因为我的请求体都只是struct,官方还把请求的类型都已经标注好了,这时耳边响起了:人生苦短,我用Python 的标语
我可以用python写个程序,将官方文档直接转成SDK 代码啊!!! 于是,说干就干!! 找了requests等库,人生顿时快乐了很多有没有~
大法 壮观地生成,连注释都有( ̄▽ ̄) 哈哈哈

生成器代码:https://gist.github.com/mengzhuo/f1b07decb69eea6e7dab

生成好的SDK:https://github.com/mengzhuo/ucloud-go-sdk

涠洲岛之旅

春节去了趟涠洲岛,今天才整理照片,发现除了发朋友圈,还是有些可以拿出来分享的。

涠洲岛火山岩海滩
火山岩海滩

涠洲岛 教堂 教堂

码头 码头

灯塔 灯塔

海滩日落 海滩日落

渔船船队 渔船船队

无名海滩 无名海滩

如何用ZeroMQ实现UDP组播Pub-Sub(基于Golang)

ZeroMQ有一对Pub/Sub socket 类型,但是网上的教程一般侧重于使用TCP版本的……
虽然TCP版本的也能组网,但是略显麻烦,今天我来给大家介绍一下基于PGM协议的ZeroMQ Pub/Sub模型 首先要编译安装OpenPGM brew install libpgm 接着是zmq brew install zmq --with-pgm 这样就准备好了环境了,
这里需要了解一下PGM网络的原理,很简单,如下图 Udp_encapsulated_ports
绿色的就是发送方,向目的组播地址239.192.0.1 端口3055(黑色粗线)发送数据,然后所有监听此端口的接收者(Receiver)都收到了。
就这么简单。 然后就是写代码咯:

soc = zmq.NewSocket(zmq.PUB)
soc.Connect("epgm://192.168.1.100;239.192.0.1:3055")
soc.SendMessage("Hi")

呃……192.168.1.100? 这个是pgm的特点,你需要指定发送组播包的网卡名,一般人记不住网卡名……所以用此网卡所持有的IP来标示。 p.s.

  1. PGM有个特点,就是发送方进行流量控制,zmq中使用的是setrate,切记在Connect之前使用
  2. zmq会整理包,所以再散的数据,都会组合成一个message发送出来(不愧是智能网络)
  3. 实际测试时……16Mbps的流量根本不是问题
  4. 需要debug PGM时export PGM_MIN_LOG_LEVEL=TRACE