学习 golang 中,写了个 golang http client 练练手

cizixs 发表了文章 • 0 个评论 • 512 次浏览 • 2016-11-17 11:05 • 来自相关话题

项目地址: https://github.com/cizixs/gohttp

最近在学习 golang ,用 net/http 写一个 http ... 查看全部

项目地址: https://github.com/cizixs/gohttp


最近在学习 golang ,用 net/http 写一个 http 客户端的时候,发现有事事情写起来很复杂。就想着自己封装一个更易用的库,正好也练练手。


目前的功能已经包括:



  • 支持所有的 HTTP method

  • 可以设置 HTTP Header

  • 能够直接添加 query string

  • 动态拼接 url path

  • 发送 form 和 json 数据

  • 从 response 中读取对应格式的数据: string , bytes , json

  • 允许设置请求 timeout 时间

  • 允许手动设置代理

  • 支持简单地用户密码认证


后面也计划了挺多功能,希望慢慢实现。


代码比较简单,也都添加了注释。想学习 golang 的同学可以看看,欢迎试用。如果有想入门 golang http 编程的,也可以考虑后面补充几篇博客讲讲这块内容。


如果在使用过程中遇到什么问题,直接在 github 上创建 issue 就行,我会及时跟进和回复的。

练手项目,实现一个web框架

golang 发表了文章 • 4 个评论 • 966 次浏览 • 2016-11-14 20:01 • 来自相关话题

github.com/zjj2wry/virgin,楼主也刚搞go半年多,写业务无聊了,所以想研究怎么实现一个简单的web框架,学习学习~~

github.com/zjj2wry/virgin,楼主也刚搞go半年多,写业务无聊了,所以想研究怎么实现一个简单的web框架,学习学习~~

golang和adb

themoonstone 发表了文章 • 1 个评论 • 579 次浏览 • 2016-11-13 16:48 • 来自相关话题

golang也能和安卓结合啦、分享一个基于golang和adb的安卓应用:

软件包adbbot提供Android应用程序自动化的基本功能。 这个包基于Golang标准包和Android Debug Bridge(adb)的执行文件。话不多说... 查看全部

golang也能和安卓结合啦、分享一个基于golang和adb的安卓应用:


软件包adbbot提供Android应用程序自动化的基本功能。 这个包基于Golang标准包和Android Debug Bridge(adb)的执行文件。话不多说、直接看看实例:


package main

import (
"flag"
"log"
"runtime"
"time"

"./adbbot"
)

var verbosity = flag.Int("v", 2, "verbosity")
var ADB = flag.String("adb", "adb", "adb exec path")
var DEV = flag.String("dev", "", "select device")

var APP = flag.String("app", "com.android.vending", "app package name")
var TMPL = flag.String("tmpl", "tmpl.png", "app package name")

func main() {

log.SetFlags(log.Ldate|log.Ltime)
flag.Parse()
runtime.GOMAXPROCS(runtime.NumCPU())

adbbot.Verbosity = *verbosity
bot := adbbot.NewBot(*DEV, *ADB)

Vlogln(2, "[adb]", "wait-for-device")
_, err := bot.Run("wait-for-device")
if err != nil {
Vlogln(1, "adb err", err)
}

// press Home key
bot.KeyHome()

// start APP
bot.StartApp(*APP)

// create matching region between Point <100,635> and <9999,9999>
//reg := bot.NewRectAbs(100, 635, 9999, 9999)

// or All the screen (slow)
reg := bot.NewRectAll()

// create matching template
tmpl, err := bot.NewTmpl(*TMPL, reg)
if err != nil {
Vlogln(2, "load template image err", err)
} else {

// try to find target
// 10 times with 1000ms delay between each search
x, y, val := bot.FindExistReg(tmpl, 10, 1000)
if x == -1 && y == -1 {
Vlogln(2, "template not found", x, y, val)
} else {
Vlogln(2, "template found at", x, y, val)
}

}

infoname := time.Now().Format("20060102_150405")
err = bot.SaveScreen(infoname + ".png")
if err != nil {
Vlogln(2, "SaveScreen err", err)
} else {
Vlogln(2, "SaveScreen as file ", infoname + ".png")
}

// force-stop APP
bot.KillApp(*APP)

}

func Vlogln(level int, v ...interface{}) {
if level <= *verbosity {
log.Println(v...)
}
}

代码量不是很大、也比较容易理解、有兴趣的同学可以深入研究一下


原文链接:https://github.com/cs8425/go-adbbot

owl - Go语言开发的分布式监控系统

吴迎松 发表了文章 • 1 个评论 • 1015 次浏览 • 2016-11-11 18:43 • 来自相关话题

OWL是TalkingData公司推出的一款基于Go语言开发的分布式监控系统,源码已在github开源

github: https://github.... 查看全部

OWL是TalkingData公司推出的一款基于Go语言开发的分布式监控系统,源码已在github开源


github: https://github.com/TalkingData/owl


Features



  • 多机房中心支持

  • 多维的数据模型,由metric、value、dt、tags组合的时间序列数据,类opentsdb

  • 支持多种报警算法,报警策略支持多条件组合、克隆

  • 灵活的插件机制,支持任意语言编写,支持传参

  • 丰富的报警渠道,邮件、微信、短信

  • 原始数据永久存储

  • 自带web管理界面以及强大的自定义图表功能


演示环境


http://54.223.127.87/


demo/demo


QQ交流群


492850035

开源第二弹!数人云Mesos调度器Swan来啦

数人云 发表了文章 • 0 个评论 • 410 次浏览 • 2016-11-10 16:08 • 来自相关话题

数人云容器管理面板Crane开源之后,小数... 查看全部


数人云容器管理面板Crane开源之后,小数有一个好消息告诉大家,数人云Mesos调度器Swan也加入了开源的大家庭!从此Crane不再寂寞,和Swan相亲相爱。开源的脚步从不停歇,下一个会是谁呢?



Swan,为天鹅,优雅的代名词。


刚刚诞生于数人云工程师的手中的Swan,尚处于开源项目的早期,还是一只跌跌撞撞的丑小鸭,未能完全展现天鹅优雅的模样。比它早出生两个月的哥哥Crane已经在开源社区的帮助下成长许多,小数相信在大家的关怀下,Swan也会很快成长为一只真正的天鹅^ v ^


Swan基于Mesos Restful API编写的应用调度框架,可以帮助用户轻松发布应用,实现应用的滚动更新,并根据用户指定的策略做应用的健康检测和故障转移。


未来,数人云Swan团队还将努力实现调度策略、高可用服务发现、网络管理、编排,以及任务抢占等功能。


主要功能



  • 应用发布:发布应用支持应用实例名称固定,便于监控和做服务发现。

  • 应用扩缩:支持手动扩缩,扩缩过程中保持实例ID连续。

  • 滚动更新:可以指定更新的实例数目分步更新,也可以全量更新。滚动更新策略可配。

  • 版本回滚:支持更新过程中手动回滚,任意一个实例更新失败后自动回滚。

  • 版本管理:支持应用多版本管理。

  • 健康检查:支持实例级别的健康检测,可配置健康检测策略。

  • 自动容错:可配置自动容错策略,根据策略自动恢复失败的实例。

  • 优雅终止:扩缩和滚动更新过程中,支持优雅终止实例。


不多说啦,快跟随小数的步伐来一看究竟吧!
Fork me on GitHub!
https://github.com/Dataman-Cloud/swan


数人云现有企业版产品数人云操作系统和多个开源项目。数人云操作系统针对企业客户,帮助传统企业实现IT业务转型,更好地应对业务变化;开源项目容器管理面板Crane针对开发者,强调简单易用,Mesos调度器Swan用于Mesos环境应用管理。

自动生成代替interface的线程安全map

ggaaooppeenngg 发表了文章 • 0 个评论 • 694 次浏览 • 2016-11-09 16:55 • 来自相关话题

https://github.com/ggaaooppeenngg/safemap

项目当中经常要使用线程安全的map,但是实际... 查看全部

https://github.com/ggaaooppeenngg/safemap


项目当中经常要使用线程安全的map,但是实际编码的时候会因为失误引入一些非线程安全的代码。
把这些东西封装成一个包是一个比较好的方式。


这个工具的主要的特点是能够根据类型自动生成线程安全的map,做了一些简单的测试如果用interface类型转换的代价和用自动生成的固定类型的代价可能差距大概是20ns/op(40ns/op-20ns/op)的一个差距,当然这个差距并不是很致命的一个问题,至少用代码生成可以对性能有一个提升,可能引起的问题是项目中类似的map过多,生成的map的代码可能会很多,所以综合考量的话,在一个包里只有一两个map是要保证线程的安全的话,其实是很适合的,也比较方便管理,不管是在build的时候生成还是把生成的代码放入版本控制当中。当然也有很多自动生成的库可以用,但是为了减少依赖并没有使用。


使用方式可以结合go generate使用,比如在代码中嵌入。


//go:generate safemap -k string -v string -n namespace

在项目中会生成namespace_safemap.go文件,类型为type namespaceSafemap map[string]string,对应的GetSet方法是线程安全的。


目前正在做的是一个类似的实现思路的cache,https://github.com/ggaaooppeenngg/cachemap

Yun-Brute:一个简单而且好用的百度云私密分享链接密码暴力破解器

SuperFashi 发表了文章 • 1 个评论 • 736 次浏览 • 2016-11-08 18:29 • 来自相关话题

博客地址 | Github查看全部

博客地址 | Github




Yun-Brute


rcard


一个简单而且好用的百度云私密分享链接密码暴力破解器。


示例


Example-GIF


试着在你的电脑/服务器上跑跑这个链接!


编译


首先你得 go get -u 我在这个项目里用的两个包:



  • gopkg.in/alecthomas/kingpin.v2

  • gopkg.in/cheggaaa/pb.v1


然后 clone 这个项目来运行。


git clone https://github.com/hanbang-wang/Yun-Brute
go run brute.go

或者简单地使用这里的预编译版本。


用法


brute [<选项>] <链接>

选项:
-h, --help 查看帮助。
-p, --preset="0000" 开始破解的预设密码。
-t, --thread=1000 线程数。

参数:
<链接> 你想获取的百度云文件链接。

特点



  • 解析

    本程序自带两种百度云链接解析器。如果还有更多种的话,你可以自己添加解析函数,或者发个 PR 或者提个 issue 让我知道。

  • 中断处理

    如果你用 Ctrl-C 来中断程序,它将会输出目前的进度,让你可以晚点用 -p 选项继续破解。

  • 日志

    很可惜的是目前日志打印会和进度条打印混在一起,使用 2> /dev/null 来禁止输出日志,或者你可以尝试一下 1>&2

  • 代理

    这个程序自带4种获取代理的方式,并且有重复或失效代理纠正功能。当没有代理剩余的时候,线程将会自动挂起并等待新的代理进入。你也可以轻易地增加你自己的代理来源。


授权


这个小玩意用的是 MIT 授权,如需知更多信息请访问授权文件。

govpr--golang实现的gmm-ubm算法说话人识别引擎

ponpon_ 发表了文章 • 0 个评论 • 414 次浏览 • 2016-11-04 14:49 • 来自相关话题

简介

govpr是golang 实现的基于 GMM-UBM 说话人识别引擎(声纹识别),可用于语音验证,身份识别的场景. 目前暂时仅支持汉语数字的语音,语音格式为wav格式(比特率16000,16bits,单声道)

安装... 查看全部

简介


govpr是golang 实现的基于 GMM-UBM 说话人识别引擎(声纹识别),可用于语音验证,身份识别的场景.
目前暂时仅支持汉语数字的语音,语音格式为wav格式(比特率16000,16bits,单声道)


安装


go get github.com/liuxp0827/govpr


示例


如下是一个简单的示例. 可跳转至 example
查看详细的例子,示例中的语音为纯数字8位数字.语音验证后得到一个得分,可设置阈值来判断验证语音是否为注册训练者本人.


package main

import (
"github.com/liuxp0827/govpr"
"github.com/liuxp0827/govpr/log"
"github.com/liuxp0827/govpr/waveIO"
"io/ioutil"
)

type engine struct {
vprEngine *govpr.VPREngine
}

func NewEngine(sampleRate, delSilRange int, ubmFile, userModelFile string) *engine {
return &engine{
vprEngine: govpr.NewVPREngine(sampleRate, delSilRange, ubmFile, userModelFile),
}
}

func (this *engine) DestroyEngine() {
this.vprEngine = nil
}

func (this *engine) TrainSpeech(buffers [][]byte) error {

var err error
count := len(buffers)
for i := 0; i < count; i++ {
err = this.vprEngine.AddTrainBuffer(buffers[i])
if err != nil {
log.Error(err)
return err
}
}

defer this.vprEngine.ClearTrainBuffer()
defer this.vprEngine.ClearAllBuffer()

err = this.vprEngine.TrainModel()
if err != nil {
log.Error(err)
return err
}

return nil
}

func (this *engine) RecSpeech(buffer []byte) error {

err := this.vprEngine.AddVerifyBuffer(buffer)
defer this.vprEngine.ClearVerifyBuffer()
if err != nil {
log.Error(err)
return err
}

err = this.vprEngine.VerifyModel()
if err != nil {
log.Error(err)
return err
}

Score := this.vprEngine.GetScore()
log.Infof("vpr score: %f", Score)
return nil
}

func main() {
log.SetLevel(log.LevelDebug)

vprEngine := NewEngine(16000, 50, "../ubm/ubm", "model/test.dat")
trainlist := []string{
"wav/train/01_32468975.wav",
"wav/train/02_58769423.wav",
"wav/train/03_59682734.wav",
"wav/train/04_64958273.wav",
"wav/train/05_65432978.wav",
}

trainBuffer := make([][]byte, 0)

for _, file := range trainlist {
buf, err := loadWaveData(file)
if err != nil {
log.Error(err)
return
}
trainBuffer = append(trainBuffer, buf)
}

verifyBuffer, err := waveIO.WaveLoad("wav/verify/34986527.wav")
if err != nil {
log.Error(err)
return
}

vprEngine.TrainSpeech(trainBuffer)
vprEngine.RecSpeech(verifyBuffer)
}

func loadWaveData(file string) ([]byte, error) {
data, err := ioutil.ReadFile(file)
if err != nil {
return nil, err
}
// remove .wav header info 44 bits
data = data[44:]
return data, nil
}

动手造轮 | 一款Bash 脚本 +HTTP 请求工具 +JSON 解析工具组成的测试小工具

数人云 发表了文章 • 2 个评论 • 660 次浏览 • 2016-11-03 12:23 • 来自相关话题

数人云开源一款容器管理工具Crane,Crane开发过程中,为了保证API的健壮性和稳定性, 数人云开发团... 查看全部


数人云开源一款容器管理工具Crane,Crane开发过程中,为了保证API的健壮性和稳定性, 数人云开发团队自制了一套适合Crane API测试的小工具。它也适用于其他接口测试,小数发现很多朋友对它感兴趣,就勤劳地搬运过来,希望能为大家提供一个参考和思路。



针对Crane团队只向外输出API的特点, 选择测试工具是秉着以下原则的:



  • 第一, 功能不要太复杂,学习曲线不能太陡, 功能够用就行;

  • 第二, 可编程要好, 最好不要有界面,程序员友好。


于是一款简单的Bash脚本+HTTP 请求工具+JSON解析工具组成的测试小工具雏形出现了。


下面给大家展现这款工具的构成


Bash脚本: 测试工具的粘合剂, 不是Java也不是Python, 用Bash简单易用,功能强大。
Httpie: 一款类似curl的http工具, 不过比curl简单的多, 尤其是想发个JSON请求时候, 更简单。
jq: jq是一款命令行解析JSON文本的工具, 支持非常多的语法解析构造重组JSON文本。


下面依次给大家介绍一下httpie和jq的基本用法


1. 例子说明如何使用httpie


httpie在terminal下的命令是http, 先来几个简单的例子给演示一下用法。


http get http://httpbin.org/get header:header-content



其中, http是命令, get是请求method, http://httpbin.org 是请求地址, httpbin是一个http的测试服务; 用冒号相连的参数代表着HTTP请求头, 用等号连接为请求body中的JSON键和值。 httpie默认的请求为json请求, 所以不用过多指明,header已经加上了Content-Type:application/json。


http post http://httpbin.org/post header:header-content json-key=json-value



http支持很多命令行选项, 介绍一个有意思的是 --check-status, check-status是把http response的非200值设置成进程的exit code, 比如:



如上所示, 请求一个不存在的地址时候进程退出符号变成了4。 我们将大量使用这个feature来判断返回值。


2. 例子说明如何使用jq


下面我们用几个例子介绍一下jq的用法。



上图演示如何提取一个json的key。



如何提取一个嵌套的key。



提取数组中的元素。


篇幅关系我们不过多展示jq的高级功能, 除了基本的解析和构造以外,jq支持大量的filter, 如有兴趣可参考https://stedolan.github.io/jq/ ... tions


3. Crane测试工具的几个场景


场景一: 我期望测试API的HTTP测试的返回状态比如200, 404, 500


首先bash造了几个基本的函数来输出错误, 和判断状态



使用方法



场景二: 登录过程测试



更多的测试例子可参考https://github.com/Dataman-Clo ... _test


至此,一款可用的测试工具出炉了, 虽然简单,不过功能恰到好处,非常适合我们的场景, 再也不怕API出错发现不了了。 聪明的同事们把这工具配到了jenkins和单元测试一起执行, 出错了还能得到邮件通知, 酷极了。

FakeGit:一个自欺欺人的好玩意

SuperFashi 发表了文章 • 0 个评论 • 636 次浏览 • 2016-11-01 21:21 • 来自相关话题

这个项目一开始使用Python实现,发在了V2论坛上,后来接触了Golang以后就把这个用新语言重写了一遍。

查看全部

这个项目一开始使用Python实现,发在了V2论坛上,后来接触了Golang以后就把这个用新语言重写了一遍。


Github 页面 | 博客页面 | 原 Python 版本




rcard


FakeGit 是一个自欺欺人的好玩意,它会修改你的本地 git 配置文件,让 git 以为你是另外一个提交者。


你可以将其用于你自己的项目,当然也可以用于任何你具有写权限的 git 仓库。


示例


FakeGit Demo


举个栗子,jQuery 之父和 PHP 之父在我的项目里提交了一些好玩的玩意。当然,我对两位充满敬意且无意冒犯。


这些都是真实的提交,并且会被 Github 和基本上所有 git 代码托管网站识别成其用户,只要这个用户存在。


安装


go get -u github.com/hanbang-wang/FakeGit-Go/cmd/fakegit

用法


fakegit <command> [--user] [--help|-h]

FakeGit 会把所有的参数传递给原 git 命令行程序,除了以下的:


change       永远更改你的本地身份
recover 快速删除本地 git 配置文件内的 user 关键字
--help, -h 一个简单的帮助

FakeGit 会拦截--user和紧接着的一个参数,就是提交者的信息。


身份格式


如果你要钦定某个人,使用姓名 <邮箱> 这样的格式,比如:


--user 'John Doe <johndoe@example.com>'

或者你不想填写邮箱地址,留空即可:


--user 'No Email <>'

我同时也给 Github 用户做了个身份查询,填写用户名即可:


--user 'example'

例子


fakegit commit -a -m "A example." --user "SuperFashi"

程序将会使用 Github API 查询使用相应 id SuperFashi的用户,也就是我,查询我的提交历史和提交记录中的邮箱,生成一个类似于SuperFashi <admin@superfashi.com>的格式,用这个信息来进行提交。


但是我还是推荐指定用户信息:


fakegit commit -a -m "A example." --user "SuperFashi <admin@superfashi.com>"

当然你也可以用 FakeGit 执行任何 git 有的命令:


fakegit push --user "whateveryoulike <>"
# 和 `git push` 一样

因为只有 commit 命令会使用 user 关键字,所以都一样。


附加


fakegit change会永久更改你的本地身份,所以必须跟着--user,否则会抛出个错误。


fakegit recover是一个快速重置你本地 git 配置文件的小工具,预防你后悔或者想在突然退出程序后恢复。


授权 & 一些东西


这个小项目用的是 Unlicense ,去 LICENSE 了解更多。但是你应该详细阅读一下下面的东西:


这个项目和其他人的身份有关,所以最后有可能成为个身份盗贼,或者发生损害他人名誉权等这类犯法的事情。


我不承担任何责任,同时我希望各位只用其来开一些无伤大雅的玩笑,或者用来做教育或学术研究。

Hprose 2.0 for Golang 用户手册

andot 发表了文章 • 3 个评论 • 634 次浏览 • 2016-10-31 20:58 • 来自相关话题

HPROSE 是 High Performance Remote Object Service Engine 的缩写,翻译成中文就是“高性能远程对象服务引擎”。

它是一个先进的轻量级的跨语言跨平台面向对象的高性能远程动态通讯中间件。它不仅简... 查看全部

HPROSE 是 High Performance Remote Object Service Engine 的缩写,翻译成中文就是“高性能远程对象服务引擎”。


它是一个先进的轻量级的跨语言跨平台面向对象的高性能远程动态通讯中间件。它不仅简单易用,而且功能强大。你只需要稍许的时间去学习,就能用它轻松构建跨语言跨平台的分布式应用系统了。


Hprose for Golang 用户手册



  1. 安装与使用

  2. Hprose 序列化

  3. Hprose 客户端

  4. Hprose 服务器

  5. Hprose 过滤器

  6. Hprose 服务器事件

  7. Hprose 中间件

  8. 推送服务


附录


A. 2.0 新特征


B. 性能测试

实时分布式消息系统NSQ

soul008 发表了文章 • 3 个评论 • 783 次浏览 • 2016-10-28 14:26 • 来自相关话题

最近,我写了一个实时分布式消息系统的演讲稿。鉴于技术的共享原则,发给大家以供参考和讨论。

查看全部

最近,我写了一个实时分布式消息系统的演讲稿。鉴于技术的共享原则,发给大家以供参考和讨论。












SSH 服务器teleport

itfanr 发表了文章 • 0 个评论 • 537 次浏览 • 2016-10-25 12:34 • 来自相关话题

Teleport 1.2 版本发布了,Gravitational Teleport 是一个先进的 SSH 服务器,可通过 SSH 或者 HTTPS 远程访问 Linux 服务器。其目的是为了替代 sshd。

查看全部

Teleport 1.2 版本发布了,Gravitational Teleport 是一个先进的 SSH 服务器,可通过 SSH 或者 HTTPS 远程访问 Linux 服务器。其目的是为了替代 sshd。


https://github.com/gravitational/teleport

Apiware:一个轻松将net/http及fasthttp请求参数绑定到结构体的中间件

henrylee2cn 发表了文章 • 4 个评论 • 724 次浏览 • 2016-10-22 23:26 • 来自相关话题

Apiware 查看全部

Apiware GoDoc


Apiware binds the specified parameters of the Golang net/http and fasthttp requests to the structure and verifies the validity of the parameter values.


It is suggested that you can use the struct as the Handler of the web framework, and use the middleware to quickly bind the request parameters, saving a lot of parameter type conversion and validity verification. At the same time through the struct tag, create swagger json configuration file, easy to create api document services.


Apiware将Go语言net/httpfasthttp请求的指定参数绑定到结构体,并验证参数值的合法性。
建议您可以使用结构体作为web框架的Handler,并用该中间件快速绑定请求参数,节省了大量参数类型转换与有效性验证的工作。同时还可以通过该结构体标签,创建swagger的json配置文件,轻松创建api文档服务。


Demo 示例


package main

import (
"encoding/json"
"github.com/henrylee2cn/apiware"
// "mime/multipart"
"net/http"
"strings"
)

type TestApiware struct {
Id int `param:"in(path),required,desc(ID),range(1:2)"`
Num float32 `param:"in(query),name(n),range(0.1:10.19)"`
Title string `param:"in(query),nonzero"`
Paragraph []string `param:"in(query),name(p),len(1:10)" regexp:"(^[\\w]*$)"`
Cookie http.Cookie `param:"in(cookie),name(apiwareid)"`
CookieString string `param:"in(cookie),name(apiwareid)"`
// Picture multipart.FileHeader `param:"in(formData),name(pic),maxmb(30)"`
}

var myApiware = apiware.New(pathDecodeFunc, nil, nil)

var pattern = "/test/:id"

func pathDecodeFunc(urlPath, pattern string) apiware.KV {
idx := map[int]string{}
for k, v := range strings.Split(pattern, "/") {
if !strings.HasPrefix(v, ":") {
continue
}
idx[k] = v[1:]
}
pathParams := make(map[string]string, len(idx))
for k, v := range strings.Split(urlPath, "/") {
name, ok := idx[k]
if !ok {
continue
}
pathParams[name] = v
}
return apiware.Map(pathParams)
}

func testHandler(resp http.ResponseWriter, req *http.Request) {
// set cookies
http.SetCookie(resp, &http.Cookie{
Name: "apiwareid",
Value: "http_henrylee2cn",
})

// bind params
params := new(TestApiware)
err := myApiware.Bind(params, req, pattern)
b, _ := json.MarshalIndent(params, "", " ")
if err != nil {
resp.WriteHeader(http.StatusBadRequest)
resp.Write(append([]byte(err.Error()+"\n"), b...))
} else {
resp.WriteHeader(http.StatusOK)
resp.Write(b)
}
}

func main() {
// Check whether `testHandler` meet the requirements of apiware, and register it
err := myApiware.Register(new(TestApiware))
if err != nil {
panic(err)
}

// server
http.HandleFunc("/test/0", testHandler)
http.HandleFunc("/test/1", testHandler)
http.HandleFunc("/test/1.1", testHandler)
http.HandleFunc("/test/2", testHandler)
http.HandleFunc("/test/3", testHandler)
http.ListenAndServe(":8080", nil)
}

Struct&Tag 结构体及其标签























































































































tag key required value desc
param in only one path (position of param) if required is unsetted, auto set it. e.g. url: "http://www.abc.com/a/{path}"
param in only one query (position of param) e.g. url: "http://www.abc.com/a?b={query}"
param in only one formData (position of param) e.g. "request body: a=123&b={formData}"
param in only one body (position of param) request body can be any content
param in only one header (position of param) request header info
param in only one cookie (position of param) request cookie info, support: http.Cookie,fasthttp.Cookie,string,[]byte
param name no (e.g. "id") specify request param`s name
param required no required request param is required
param desc no (e.g. "id") request param description
param len no (e.g. 3:6, 3) length range of param's value
param range no (e.g. 0:10) numerical range of param's value
param nonzero no nonzero param`s value can not be zero
param maxmb no (e.g. 32) when request Content-Type is multipart/form-data, the max memory for body.(multi-param, whichever is greater)
regexp no (e.g. "^\w+$") param value can not be null
err no (e.g. "incorrect password format") customize the prompt for validation error

NOTES:



  • the binding object must be a struct pointer

  • the binding struct's field can not be a pointer

  • regexp or param tag is only usable when param:"type(xxx)" is exist

  • if the param tag is not exist, anonymous field will be parsed

  • when the param's position(in) is formData and the field's type is multipart.FileHeader, the param receives file uploaded

  • if param's position(in) is cookie, field's type must be http.Cookie

  • param tags in(formData) and in(body) can not exist at the same time

  • there should not be more than one in(body) param tag


Field Types 结构体字段类型














































































base slice special
string []string [][]byte
byte []byte [][]uint8
uint8 []uint8 multipart.FileHeader (only for formData param)
bool []bool http.Cookie (only for net/http's cookie param)
int []int fasthttp.Cookie (only for fasthttp's cookie param)
int8 []int8 struct (struct type only for body param or as an anonymous field to extend params)
int16 []int16
int32 []int32
int64 []int64
uint8 []uint8
uint16 []uint16
uint32 []uint32
uint64 []uint64
float32 []float32
float64 []float64

Source code


https://github.com/henrylee2cn/apiware

Gear: 一个 Go web framework 的设计思考和讨论

zensh 发表了文章 • 3 个评论 • 1248 次浏览 • 2016-10-22 16:57 • 来自相关话题

Gear 框架设计考量

Gear 是由 Teambition查看全部

Gear 框架设计考量


Gear 是由 Teambition 开发的一个轻量级的、专注于可组合扩展和高性能的 Go 语言 Web 服务框架。


Gear 框架在设计与实现的过程中充分参考了 Go 语言下多款知名 Web 框架,也参考了 Node.js 下的知名 Web 框架,汲取各方优秀因素,结合我们的开发实践,精心打磨而成。Gear 框架主要有如下特点:



  1. 基于中间件模式的业务处理控制流程。中间件模式使功能模块开发标准化、解耦、易于组合和集成到应用

  2. 框架级的错误和异常自动处理机制。开发者无需再担心业务逻辑中的每一个错误,只需在中间件返回错误,交给框架自动处理,也支持自定义处理逻辑

  3. 集成了便捷的读写 HTTP Request/Response 对象的方法,使得 Web 应用开发更加高效

  4. 高效而强大的路由处理器,能定义出各种路由规则满足业务逻辑需求

  5. 丰富的中间件生态,如 CORS, CSRF, Secure, Logging, Favicon, Session, Rate limiter, Tracing等

  6. 完整的 HTTP/2.0 支持

  7. 超轻量级,框架只实现核心的、共性的需求,可选需求均通过外部中间件或库来满足,确保应用实现的灵活自由,不被框架绑定束缚


目前 Gear 已经发布 v1.0.0


《Gear 框架设计考量》


2017-03-05 更新




2016-10-22


起因


因公司技术转型需要(见招聘贴 https://gocn.io/question/36 ),我最近一个月都在学习 Go 语言,研究 Go 语言下各种 Web 框架,主要有以下三个印象:



  1. Go 语言原生的 net/http 效率很低,第三方实现的 fasthttp 效率极高,是原生 10 倍以上,封神榜上排名第二。

  2. Go 的 Web 框架非常多,但知名度高的框架基本上是基于 fasthttp,除了 Asta谢 的 Beego

  3. Web 框架不但多,很多看起来也相似,但各自都有自己的功能插件和生态,API也非常繁杂。这大概是强类型引发的问题,很难像 Node.js 生态圈那样共用他人的开源模块。


我在 Node.js 生态圈中做了一个 Web 框架:https://github.com/toajs/toa ,我把它搬到了 Go 生态,这就是 Gear: https://github.com/teambition/gear


Gear 特性和目标



  1. 充分利用 Go 语言原生接口,一方面原生实现总是在不断进步优化;另一方面通用性更好,这点对于强类型来说很重要,尽量解耦类型依赖。

  2. 轻量级,框架本身只提供开发完整 Web 服务需要的核心功能,其它功能均通过中间件扩展。

  3. 充分发挥和扩展 Go 建议使用的 context.Context 能力。


关于性能


看过了太多的 benchmark,我以为 net/http 真弱鸡,但其实不然,在我的 14寸 rMBP 的测试结果如下:


Gear 48307 vs Iris 70310


Gear with "net/http": 48307


> wrk 'http://localhost:3333/?foo[bar]=baz' -d 10 -c 100 -t 4

Running 10s test @ http://localhost:3333/?foo[bar]=baz
4 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 2.30ms 2.53ms 59.54ms 94.28%
Req/Sec 12.15k 1.56k 20.98k 81.75%
484231 requests in 10.02s, 63.27MB read
Requests/sec: 48307.40
Transfer/sec: 6.31MB

Iris with "fasthttp": 70310


> wrk 'http://localhost:3333/?foo[bar]=baz' -d 10 -c 100 -t 4

Running 10s test @ http://localhost:3333/?foo[bar]=baz
4 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 1.37ms 648.31us 15.60ms 89.48%
Req/Sec 17.75k 2.32k 39.65k 84.83%
710317 requests in 10.10s, 102.29MB read
Requests/sec: 70310.19
Transfer/sec: 10.13MB

目前 Gear 还只刚成型,没有开始优化,另外据说 Go 1.8 的 net/http 有很大优化,两项相加赶上 Iris 完全可能。