据说跟 C 比只差 10% 了,简单写了个 http server 输出个字符串,AB 测了下,-KC 100 -N 10000,双核老 I3 笔记本,4G 内存,MINT 64 位,飚到近 50000 每秒,用仿 SINATRA 的 beego 框架,prod 环境下用模板输出个字符串,也能飚到 26000,拿来 JAVA 的仿 SINATRA 框架 PLAY 输出同样字符串,每秒 8000 多。
都不是一个重量级了。。。。。
测的太 hello world 了 你可以模板里加些拼接看看
还有就是 beego 很多地方都在偷工减料... 例如 cookie session 里根本就没签名,作者好像没理解 CSRF 在里面用了固定字符串...
(我测过 C 比 go 快 10 倍左右...)
这个的确,Golang 内建的 html/template 性能比较差,你测试的时候输出太少是没有意义的。以我的经验,render 较多内容时,common lisp 竟不比 Go 差多少。
另外,你可以看看我这个用 go 写的网站 http://occnet.net
我对 Google 的东西有点没信心了。Android 偶尔自动重启,Chrome 偶尔崩溃一下,还没 Firefox 稳定。
https://github.com/astaxie/beego/blob/master/session/session.go 都是服务器端 session, 没找到签名 session 啊
关于 csrf https://github.com/astaxie/beego/blob/master/controller.go#L307 token 的生成方法是 sha1(key + ip : nanotime) : nanotime 对吧?不直接用随机字符串的话 总是存在可预测的隐患的。
c 和 go 的对比代码是两年前的... https://github.com/luikore/performance_evaluation/tree/master/chello 现在 go 比那时快很多了,但别忘了现在 clang 都能开 -O4
了
#17 楼 @luikore 第一,session 不是保存在服务器端那保存在哪里啊?session 和 cookie 的区别你了解吗? 第二、token 的这个产生方式我不觉得存在可预测的隐患,你有什么更好的建议吗?
第三,你别拿两年前的对比出来唬人啊,看得我都惊呆了,现在你可以再用 clang 和 Go 对比一下,这个是别人的对比情况:http://my.oschina.net/chai2010/blog/130859
#24 楼 @rasefon BenchmarksGame 不是为了测试不同语言的最优性能,而且为了测试不同语言最自然状态下编写程序的性能。比如,binary-trees 测试就是禁止自己定制专有的缓冲池的,而 C 语言的版本则可以随意使用 各种优化手段 (基于 apr 和缓冲池和 openmp 的并行优化).所以出现了如上的结果,你看看 Go 自带的测试用例的测试结果,相差就是在 10% 之内:
$GOROOT/test/bench/shootout/timing.sh
fasta -n 25000000
gcc -m64 -O2 fasta.c 0.86u 0.00s 0.87r
gc fasta 0.85u 0.00s 0.86r
gc_B fasta 0.83u 0.00s 0.83r
reverse-complement < output-of-fasta-25000000
gcc -m64 -O2 reverse-complement.c 0.45u 0.05s 0.50r
gc reverse-complement 0.60u 0.05s 0.65r
gc_B reverse-complement 0.55u 0.04s 0.59r
nbody -n 50000000
gcc -m64 -O2 nbody.c -lm 5.51u 0.00s 5.52r
gc nbody 7.16u 0.00s 7.18r
gc_B nbody 7.12u 0.00s 7.14r
binary-tree 15 # too slow to use 20
gcc -m64 -O2 binary-tree.c -lm 0.31u 0.00s 0.31r
gc binary-tree 1.08u 0.00s 1.07r
gc binary-tree-freelist 0.15u 0.00s 0.15r
fannkuch 12
gcc -m64 -O2 fannkuch.c 26.45u 0.00s 26.54r
gc fannkuch 35.99u 0.00s 36.08r
gc fannkuch-parallel 73.40u 0.00s 18.58r
gc_B fannkuch 25.18u 0.00s 25.25r
regex-dna 100000
gcc -m64 -O2 regex-dna.c -lpcre 0.25u 0.00s 0.26r
gc regex-dna 1.65u 0.00s 1.66r
gc regex-dna-parallel 1.72u 0.01s 0.67r
gc_B regex-dna 1.64u 0.00s 1.65r
spectral-norm 5500
gcc -m64 -O2 spectral-norm.c -lm 9.63u 0.00s 9.66r
gc spectral-norm 9.63u 0.00s 9.66r
gc_B spectral-norm 9.63u 0.00s 9.66r
k-nucleotide 1000000
gcc -O2 k-nucleotide.c -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -lglib-2.0 2.62u 0.00s 2.63r
gc k-nucleotide 2.69u 0.01s 2.71r
gc k-nucleotide-parallel 3.02u 0.00s 0.97r
gc_B k-nucleotide 2.66u 0.01s 2.68r
mandelbrot 16000
gcc -m64 -O2 mandelbrot.c 20.95u 0.00s 21.01r
gc mandelbrot 23.73u 0.00s 23.79r
gc_B mandelbrot 23.72u 0.00s 23.79r
meteor 2098
gcc -m64 -O2 meteor-contest.c 0.05u 0.00s 0.05r
gc meteor-contest 0.06u 0.00s 0.07r
gc_B meteor-contest 0.06u 0.00s 0.06r
pidigits 10000
gcc -m64 -O2 pidigits.c -lgmp 0.77u 0.00s 0.77r
gc pidigits 1.45u 0.01s 1.44r
gc_B pidigits 1.45u 0.01s 1.43r
threadring 50000000
gcc -m64 -O2 threadring.c -lpthread 12.05u 261.20s 216.36r
gc threadring 6.61u 0.00s 6.63r
chameneos 6000000
gcc -m64 -O2 chameneosredux.c -lpthread 4.04u 21.08s 4.20r
gc chameneosredux 4.97u 0.00s 4.99r
#14 楼 @hooopo 你指的是https://github.com/astaxie/beego/pull/215/files#L1L34 这样的方法吧,这个目前还在考虑中,如何更好的加入进来。第二我不觉得通过 sha1 加密就是用了牛刀了。
楼上各位,Go 其实除了性能之外,还有很多别的优势,我在这个里面总结了一些,很多人也补充了一些,希望对大家了解 Go 有帮助:http://www.zhihu.com/question/21409296
#34 楼 @bhuztez 所以我上面说了啊,你确信 CSRF 是放 session 里面的?你没理解 beego 的实现方式啊。然后你在看看http://en.wikipedia.org/wiki/Cross-site_request_forgery#Prevention 如何防御 csrf
#49 楼 @hooopo 看看我对于 session 和 cookie 的理解:https://github.com/astaxie/build-web-application-with-golang/blob/master/ebook/06.1.md
还有 csrf 的核心手段是不可预测原则没错,IP 变化的请求拦截当然是基于不同的 IP 伪造请求拦截,我觉得这个设计没有任何问题啊。随机算法比较容易破解,为什么采用 sha1 主要是防止破解,md5 就可以反破解
首先移动设备基本上应用走的是 API 请求方式,就不存在 xsrf 开启的问题,一般都是认证的方式。顺带说一下 API 开发也是目前 Go 做的最好的,用 Go 来写 API 太爽了。
如果是移动设备来操作 web 的话,那变了只能说页面你必须重新刷新了
session,简而言之就是在服务器上保存用户操作的历史信息
你的问题就是硬要给 session 加一个在服务器上
这样的定语。
因此 cookie 存在着一定的安全隐患,例如本地 cookie 中保存的用户名密码被破译,或 cookie 被其他网站收集(例如:1. appA 主动设置域 B cookie,让域 B cookie 获取;2. XSS,在 appA 上通过 javascript 获取 document.cookie,并传递给自己的 appB)。
A 域设置 B 域 cookie 是不可能的,浏览器会有同源策略,如果这样也可以 web 就乱套了。
对于 XSS,有 HTTP Only cookie 和一楼所说的客户端 session 签名和加密策略防止重要 cookie 被篡改/窃取。
#21 楼 @astaxie 准确点说,是这个框架没有签名 cookie 支持,如果用了这个框架,cookie 就应该只用来存 session identifier 和存与用户身份不相干的信息。使用时如果不知道这一点就很危险。另外就是你的 sessionid 不支持 secure (https only) 的设定,利用 dns 污染进行 session hijack 也是可能的,不适合用来做电子商务收钱等安全性要求比较高的网站。
#29 楼 @astaxie 如果服务器跑在 nginx 后面,通过 tcp 连接信息得来的 ip 都是同样的,如果用户用了代理,看到的 remote ip 都是同样的。按照你的计算方式,相同 ip, 同一时间的请求,就会存在 csrf token 撞车的情况。然后攻击者使用某个流行的 proxy 去访问你的网站来获取一个 token, 那么通过这个 proxy 的用户都有比较大的机会和攻击者的 token 撞车,攻击者在他的伪造表单里自动更新这个 token 坐等鱼上钩。你最后就只能寄希望在 nanotime 上了...
解决很简单,增加一段随机字符串即可。
最后,因为你没有防止篡改 cookie 的手段,你的 csrf 不该放 cookie 而应该存在 session store 里 (你的情况就是 文件/数据库/redis/内存了), 或者继续把 csrf 放 cookie 里,把签名附上也可以。
要挑刺是还可以给你提很多 issue 的 (flash 写成 falsh 就不提了...) ...
#61 楼 @luikore 第一点:https://github.com/astaxie/beego/blob/master/session/session.go#L67 自己看到底有没有 http only
第二点:nanotime 我随机我觉得已经比你所谓的随机字符串好很多了
第三点:看看什么是签名https://github.com/astaxie/beego/blob/master/controller.go#L312
最后欢迎各种挑刺
那啥 CSRF token 放在 cookie 里面有啥问题么?话说 AngularJs 就要求服务端设置一个 csrf cookie(实际上除了放 cookie 根本没别的地方可以放啊,服务端整个页面都是静态模板,渲染是在客户端进行的)……另外为啥 API 就不需要 CSRF?
拿 secure cookie 当 session 在 ruby、php、python、node 甚至 go(gorilla) 都很常见
ruby、php、python、node 的主流模板默认对变量 auto escaping 已经是老黄历了
消息不对称很可怕
#77 楼 @astaxie
#78 楼 我还是说清楚点... gcc 编译器 -O2
的优化程度一般般,你可以试试 -O3
, 如果是 clang 还可以 -O4
. -Og
的意思是加入了调试符号,作用是让编译出来的 C 程序跑得更慢点。
C / ObjC / C++ 程序员基本不会上 Go 这条船的:没有动态加载能力,没有 macro, 没有 generic type, 没有 typed exception, 不支持手动内存管理,欠缺抽象能力,没有消息 dispatch 能力,不支持函数式的 idiom, 代码里面大量 if (err != nil)
, 编译器做不了跨 obj file 分析,运行时能力太弱,GC 太挫,缺少丰富的 literal 语法... Go 代码其实是很底层的,直接 1:1 映射到 assembler, 比起 C 的唯一优势是有字符串...
golang 的好处不在性能,在并发模型、库、工具链这些。 其实我认为 web 开发这类拼接下字符串的工作,用 golang 感觉和用 C 差不多,本身就没啥语法糖,对于重复性的体力劳动不像 ruby 那样能搞出各种 DSL 来提高表达效率。
#61 楼 @luikore 继续驳斥你各种观点:准确点说, 是这个框架没有签名 cookie 支持, 如果用了这个框架, cookie 就应该只用来存 session identifier 和存与用户身份不相干的信息. 使用时如果不知道这一点就很危险.
这一点的危险在哪里?为什么不能存类似 csrf 签名加密的 cookie,你目前的 cookie 存都是怎么做的,签名 cookie 我自己签名过了存不可以嘛?
另外就是你的 sessionid 不支持 secure (https only) 的设定, 利用 dns 污染进行 session hijack 也是可能的, 不适合用来做电子商务收钱等安全性要求比较高的网站.
这个功能可以加,而且不是那么难的事情,你不用说的好像很严重的 bug 问题。
如果服务器跑在 nginx 后面, 通过 tcp 连接信息得来的 ip 都是同样的, 如果用户用了代理, 看到的 remote ip 都是同样的.
你不了解 nginx 吧
按照你的计算方式, 相同 ip, 同一时间的请求, 就会存在 csrf token 撞车的情况. 然后攻击者使用某个流行的 proxy 去访问你的网站来获取一个 token, 那么通过这个 proxy 的用户都有比较大的机会和攻击者的 token 撞车, 攻击者在他的伪造表单里自动更新这个 token 坐等鱼上钩. 你最后就只能寄希望在 nanotime 上了.
双重的 unixNano 能冲突的概率几乎没有,但是你们说的通过 IP 来做 token 认证确实可以改进的更好,例如 uuid 之类的,这一块后期我可以改进
最后, 因为你没有防止篡改 cookie 的手段, 你的 csrf 不该放 cookie 而应该存在 session store 里 (你的情况就是 文件/数据库/redis/内存了), 或者继续把 csrf 放 cookie 里, 把签名附上也可以.
目前的 cookie 是已经签名加密的,用户篡改的话能通过认证嘛?csrf 不一定非得放 session 就是安全的。
#109 楼 @bhuztez https://github.com/astaxie/beego/pull/215/files 但是我觉得这个放的位置需要改进,还有一些实现的方式
昨天本来去采购书籍,本来想买 go 的书来着...结果看了几页受不了了有点不符合我之前的逻辑,于是只好先弄了几本 nodejs 的书回去...lz 推荐几本 go 的书呗?
#17 楼 @luikore #42 楼 @gihnius #40 楼 @reus #37 楼 @rasefon #15 楼 @bhuztez
谢谢各位的讨论,针对大家提出的一些意见,我努力改进了一下目前 beego 的 csrf 的做法
csrf 在表单中存的是一个随机字符串,cookie 采用了 GetSecureCookie 的方式,如下所示:
func (c *Controller) XsrfToken() string {
if c._xsrf_token == "" {
token, ok := c.GetSecureCookie(XSRFKEY, "_xsrf")
if !ok {
expire := 0
if c.XSRFExpire > 0 {
expire = c.XSRFExpire
} else {
expire = XSRFExpire
}
token = GetRandomString(15)
c.SetSecureCookie(XSRFKEY, "_xsrf", token, expire)
}
c._xsrf_token = token
}
return c._xsrf_token
}
至于@luikore 提出的 session 需要支持 https 的支持,目前已经增加额外的参数支持
#124 楼 @cassiuschen http://product.china-pub.com/3767290WEB开发,可以买两本,一本是许大牛的,一本是谢大牛的,侧重点不同,一个偏重基本语法,一个偏重
昨天看了一点 go 的东西,感觉不应该拿来和 ruby 比较,完全不是一种类型的语言。 go 更像是简化了的,外加一些额外的语法糖的 c,做为系统级别的语言更合适。
#128 楼 @rasefon 其实这个帖子也没有和 ruby 对比,但是你真要说和 ruby 对比,那 ruby 完全不能比,ruby 是动态语言,Go 是静态语言,所以不具有对比性,但是你可以了解一下 Go,用来开发 ruby 擅长的 Web 方面,也不输多少。下面这个是 ruby 迁移到 Go 的经典案例:
Iron.io 从 Ruby 迁移到 Go:减少了 28 台服务器并避免了连锁故障:http://www.infoq.com/cn/news/2013/03/ruby-to-go
#130 楼 @rasefon 下面这些摘抄自《http://commandcenter.blogspot.com/2012/06/less-is-exponentially-more.html》 ,然后这一篇详细介绍了为什么设计 Go http://www.oschina.net/translate/go-at-google-language-design-in-the-service-of-software-engineering。
Go 中对 C 和 C++ 进行的重要简化的清单:
除了这个简化清单和一些未提及的琐碎内容,我相信,Go 相比 C 或者 C++ 是更加有表达力的。少既是多。
#130 楼 @rasefon 还有我觉得 robbin 的这一篇博客,也详细分析了 ruby 存在问题,我觉得对于 rubyer 来说,应该挺适合的,http://robbinfan.com/blog/40/ruby-off-rails
其实大家不用过分纠结 app server 的性能吧,只要够用就行了,就算是 GO 的,就算是 CGI 的,能飙到好几万,但是后面还有其他很多瓶颈的地方,比如数据库、调用相关其他系统的 API 等,所以说,应该从整体系统架构来优化,该上 cache 的上 cache,该集群的集群,该读写分离的读写分离等等,才能真正提高整体网站性能。
这篇帖子讨论的很有意义,刚开始 @astaxie 态度不是很好,其实没必要这么紧张,别人能指出的一些不足,说明他们都认真去研究了你的作品,应该感到高兴。
这个页面上 http://beego.me/about 性能
beego 构建于 Go HTTP 服务器之上,而 Go 在最近的 性能评测 中显示其可同时服务多于 Rails 三至十倍 的请求。
这句话能不能改一下!
#139 楼 @Numbcoder 我没有紧张,也没有态度不好,我一直都是这样直来直去的性格,也许说的过了,但是我觉得激烈的讨论很有帮助啊,我是很欢迎大家一起来挑刺,帮我找出各种问题,因为毕竟靠一个人做框架是做不好的,大家的力量才能做好。所以我很跑到这里来很乐意和大家一起来探讨。
针对性能对比的话,这个上面的对比性能确实是这样,而且你看我上面提的 iron 的例子,都是 ruby 迁移到 Go 的案例,我觉得没必要修改吧
#142 楼 @bhuztez 那些概念啊?我觉得一天应该可以了解基本了啊,你看浩哥写了两篇文章,我觉得你花个一下午应该就可以入门了:http://coolshell.cn/articles/8460.html http://coolshell.cn/articles/8489.html
#143 楼 @astaxie 都是从 rails 迁移过去的,然后报道一换就变成了从 ruby 迁移,把框架当成语言都是为了吸引眼球。换作其他 ruby 写的非阻塞的来做的话不一定就慢很多,可以看看这个 构建异步的 API 服务
robbin 写的是讲做 ruby 开发的不应该老是看 rails,还有其他更适合的 ruby 框架
#145 楼 @ywjno 我没说 ruby 一定是性能差,robin 写的文章里面也分析了 rails 存在的问题:总之,无论是 Linkedin 的移动 API 网关还是 Iron.io 的后台任务系统,用 Ruby 来编写,本身并不是问题,实践也有大量案例证明使用 Goliath 或者 Sinatra 编写高性能 Web Service 都是可行的。问题只是在于我们应该:Ruby off rails 了。 http://robbinfan.com/blog/40/ruby-off-rails
#145 楼 @ywjno 不过给你展示一下,sinatra 的作者最近在写 Go 的代码,https://github.com/bmizerany?tab=repositories 所以我们需要的是拥抱变化,Go 的并发比用 ruby 内部实现的多线程不知道简单多少
#22 楼 @rasefon 二叉树对比测试,那个网站的作者说:目的是测试 gc,不允许使用任何第三方和自定义的 pool,而 c 语言的实现版本却使用了 pool 有作弊嫌疑,有人使用 slice 实现了一个版本的二叉树,在那个网站的单核 32 位评测下,C 的速度是:12.84,Go 的速度是:14.24,相差无几 (链接: http://benchmarksgame.alioth.debian.org/u32/program.php?test=binarytrees&lang=go&id=6), 可是那个网站评测作者拒绝采纳,更多细节可以去 golang-nuts 讨论。 #19 楼 @luikore Go 1.1 相比之前版本性能提升非常明显,你可以抽空试试。Go 现在的 gc 和调度器还比较落后 (相比 jvm),gc 到 1.3 才会成为 100% 精确的 gc,而有了精确的 gc 才有实现分代、压缩,可移动 gc 的可能,这些都在不断开发中 (想想 ruby 都多少年了最近的 2.1 才宣布实现了分代式的 gc,汗~~搞 gc 的人才真不好找),调度器目前也只有函数实体实现了抢占式调度,所以底层编译器这些优化的还有很多,这些都是影响性能的关键,所以性能这东西说实在的还得靠时间去优化,比的就是编译器效率,静态编译的语言发展到最后性能应该不是问题。相比 llvm,6g/8g 还有很多工作要做,另外一点:Go 编译器的其中一个设计目标是快速的编译速度,这个可能会影响编译出代码的性能,具体看以后的优化程度了,像 llvm 这种,目前已经优化到极致,JVM 也是优化了 10 多年了,JIT 技术也非常成熟了,Go 目前比这些肯定要差点。但差 C 语言 10 倍,这个不太可能,可以 pprof 一下 Go 代码找出瓶颈,部分测试情况下出现 2-3 倍还可以接受。
#157 楼 @hooluupog 路过.. 按照 ko1 的说法,ruby 不好搞 generational GC 主要是因为要和现存大量 c extension 保持兼容造成的,所以 2.1 才想出来个 restricted generational GC。如果没有这个包袱,做个 generational 的出来不会如此困难。
go 比 c 慢 10 倍的场景并不少见,比如二叉树测试:
你知道这个测试为什么 Go 比 C 慢 10 倍吗?你看过 2 个语言的测试代码没有? 我是看过的。C 语言是基于 apr 的 pool 实现,而已还开启了 openmp 优化 (这是标准 C 语言吗?). Go 语言是基于 GC(不可否认 Go 语言的 GC 性能确实还有优化的余地), 如果也改用 pool 实现 Go 的测试就和 C 持平 (17 和 15 的差异).
各种实现的对比在: http://benchmarksgame.alioth.debian.org/u64q/performance.php?test=binarytrees
Pool 的实现代码在: http://benchmarksgame.alioth.debian.org/u64q/program.php?test=binarytrees&lang=go&id=6
这个测试的性能很不公平,因为 C 使用了 apr_pool 和 openmp. 那如果用 Go 写个汇编或 opencl 的版本是不是也可以呢?
实际项目中,瓶颈都在数据库查询那块了,你数据库不可能只有一台服务器。。。。 所以最终瓶颈在网络。 所以其实平台架构更关键啊。。 我之前玩 php,现在完全转到 nodejs 了~~ 现在是 expressjs + rethinkdb 做后端,前端 AngularJS 来开发 http://yaha.me
#1 楼 @luikore 很赞同。这种抛开业务谈性能就是耍流氓。你把 golang 的各种库,数据库访问都加上,会发现差别并不大。Golang 如果非要往 web 上靠(P.S. 其实这货搞 web 是搞错了方向,先天不足,很难和其他 web 框架竞争,单纯的写点 REST API 还是可以的),那么还会有很长的路要走。另外写后台服务,如果要保证 7*24 运行的服务,这种有异常也不允许挂掉的服务,没有 try catch 结构的语言是很不方便的,到处都要 if err != nil 引出异常,感觉很蛋痛,反正最近写 Golang worker 就很烦躁。接触 Golang 时间不长,一点挫见。
Mari bergabung dan dapatkan keuntungan maksimal hanya di royalaces88 , stasiunplay , win313 !