Go GO 的性能真的是很惊人啊

匿名 · 2013年09月24日 · 最后由 outman 回复于 2015年12月06日 · 59211 次阅读
本帖已被管理员设置为精华贴

据说跟 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

#1 楼 @luikore 在 occnet.net 我也自己实现 csrf token, 不过是保存在浏览器的 session 里, 也就是 maxage =0, 好像 rails 的也是这样的, 因此在一个 session 里它是不变的, 不过登出或重新登录会更新 token. 我觉得没有必要每个 request 都更新 token .

可能不光是语言关系,纯 ruby 的的 http server,普通 socket 和用 em ab 还差好多呢。

匿名 #6 2013年09月25日

1 楼,您说的太夸张了,10 倍,您的说法很让人无语

大家到底学了多少语言?

我对 Google 的东西有点没信心了。Android 偶尔自动重启, Chrome 偶尔崩溃一下,还没 Firefox 稳定。

#5 楼 @jihua0a 您说的太夸张了,10%,您的说法让人无语。——说这个话很没技术含量。

作为一门编译型的语言在性能方面向 C/C++ 看齐有什么奇怪的。不把 C 甩个两三条街根本谈不上什么惊人。

Java 的 HTTP 性能不差的。你直接拿 apache 去和 jetty pk,java 落后的也不多。

#5 楼 @jihua0a c 在 server 的话我用 libmicrohttpd + mongodb-c-driver 和 go 对比测试过的, tps 大约 10 倍左右 (已经接近硬盘 io 极限了). 虽然也很 hello world 但也比不连 db 的测试靠谱点 c 在各种 micro benchmark 里基本都是比 go 快 2 到 10 几倍不等, 代码量和 go 在一个数量级

Sinatra 2.0 会使用 Go 重写?

#1 楼 @luikore 看过 beego 的 csrf 源码吗?签名没有?C 的比 Go 的快 10 倍,呵呵,上对比代码

瓶颈往往不在 hello world .

#12 楼 @astaxie 签名指的是 cookie session,首先得有一个CookieSessionStore,真的没找到

PS. 使用 HMAC 生成 csrf token 的做法有点杀鸡用牛刀的感觉,只是生成一个随机字符串呀,有必要么。

16 楼 已删除

任何用 hello world 来测性能的都是耍流氓

#12 楼 @astaxie 作者尼豪

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

匿名 #19 2013年09月25日

17 楼的兄弟,你是两年前的 GO,我了个去,您老还沉浸在两年前啊。。。。。。

知道 GO1.1 提高多大吗? 劝您重新测试下

#18 楼 @jihua0a 嗯. 有空测试下. go 的设计早就定型了, 也没 llvm 的编译器专业, 估计变化不大.

匿名 #21 2013年09月25日

#7 楼 @emanon 你说的两个都是吃内存大户,但是 GO 不同。。。。不信就自己写个简单代码来测

#17 楼 @luikore 第一,session 不是保存在服务器端那保存在哪里啊?session 和 cookie 的区别你了解吗? 第二、token 的这个产生方式我不觉得存在可预测的隐患,你有什么更好的建议吗?

第三,你别拿两年前的对比出来唬人啊,看得我都惊呆了,现在你可以再用 clang 和 Go 对比一下,这个是别人的对比情况:http://my.oschina.net/chai2010/blog/130859

go 比 c 慢 10 倍的场景并不少见,比如二叉树测试:

#22 楼 @rasefon 你看了对比的版本了吗?

#23 楼 @astaxie go version go1.1.2 linux/amd64

#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 加密就是用了牛刀了。

#15 楼 @bhuztez 欢迎提出宝贵意见

楼上各位,Go 其实除了性能之外,还有很多别的优势,我在这个里面总结了一些,很多人也补充了一些,希望对大家了解 Go 有帮助:http://www.zhihu.com/question/21409296

29 楼 已删除

#28 楼 @bhuztez 第一,你的 IP 变了那么 csrf 肯定要变,不然不算安全,第二,c.Ctx.Request.RemoteAddr 这个获取的是客户端请求 IP,不存在两个 IP,难道 tcp 协议变了?

31 楼 已删除

#30 楼 @bhuztez 你确信 CSRF 用了 session?是不是你没理解清楚 beego 里面怎么实现 csrf 的啊

33 楼 已删除

#32 楼 @bhuztez 你好像没搞清楚什么是 session,什么是 cookie 啊

35 楼 已删除

#34 楼 @bhuztez 所以我上面说了啊,你确信 CSRF 是放 session 里面的?你没理解 beego 的实现方式啊。然后你在看看http://en.wikipedia.org/wiki/Cross-site_request_forgery#Prevention 如何防御 csrf

cookie 里面不一定要放 sessionID 的,在 beego 的实现里面根本就没有 session 的概念在里面,所以你的理解是完全错误的

#25 楼 @astaxie 我对 go 不是很了解,今晚回去研究一下。

#37 楼 @rasefon 恩,还是很有趣的,欢迎多交流

#3 楼 @gihnius token 你应该设置一个超时时间啊,不然 csrf 就没啥意思了

42 楼 已删除

#39 楼 @astaxie 我是担心 刚好在用户 post 的时候重置了

匿名 #45 2013年09月25日

看到 BEEGO 的作者谢大牛进来讨论,俺闪了

#41 楼 @bhuztez 第一 在 Go 里面 session 是尽量不提倡的,你看 Go 里面默认是不带有任何的 session 模块的,第二 目前放在 cookie 里面的 csrf,我们做这个的目的是防止跨站攻击,javascript 不能读取跨站的 cookie 吧。

#43 楼 @astaxie 我知道,因为有订阅。不过之所以叫 round2, 就是因为和前一个不同,这个用了并发,所以不能说最新,只是另一组测试

48 楼 已删除

#42 楼 @gihnius 但是我觉得超时了就应该 post 不成功

#26 楼 @astaxie @bhuztez 说的没有错啊,是你对 session 的理解太狭隘了。

session 和 cookie 本来就没有那么界限分明。session id 是要通过 cookie 存储的,session 内容也可以通过 cookie 存储。并且基于 cookie 存储的 session 更符合 RESTful 的无状态特性。

防御 CSRF 的核心手段就是不可预测原则, 你把 IP 发生变化的请求拦截掉是在防御伪造请求?你需要的只是一个简单的随机算法,而不是签名算法。所以说是杀鸡用牛刀

#47 楼 @bhuztez 想抓 Go 里面的 XSS 还是很难写出这样的代码,因为 Go 的默认模板引擎就是全部 XSS 过滤的

52 楼 已删除
53 楼 已删除

#49 楼 @hooopo 看看我对于 session 和 cookie 的理解:https://github.com/astaxie/build-web-application-with-golang/blob/master/ebook/06.1.md

还有 csrf 的核心手段是不可预测原则没错,IP 变化的请求拦截当然是基于不同的 IP 伪造请求拦截,我觉得这个设计没有任何问题啊。随机算法比较容易破解,为什么采用 sha1 主要是防止破解,md5 就可以反破解

#51 楼 @bhuztez 那么我就认为你的请求是不对了,没有任何的逻辑问题

#52 楼 @bhuztez 现在是签名了啊

57 楼 已删除

#16 楼 @iamzhangdabei 非常赞同你的说法

59 楼 已删除

#58 楼 @bhuztez

首先移动设备基本上应用走的是 API 请求方式,就不存在 xsrf 开启的问题,一般都是认证的方式。顺带说一下 API 开发也是目前 Go 做的最好的,用 Go 来写 API 太爽了。

如果是移动设备来操作 web 的话,那变了只能说页面你必须重新刷新了

#53 楼 @astaxie

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 就不提了...) ...

#60 楼 @hooopo 首先 cookie 是客户端的没错对吧,为了区别 session 现在所有的语言里面是不是都是存在服务器端的?当然我理解你的意思,你的 session 值存在 cookie 里面是不是 cookie 的值就变成 session 的值了。

appA 和 B 的关系就是目前广告嵌入 cookie 的做法,在新浪的站点调用了 XX 的广告,然后 XX 的广告中了 cookie。

至于 XSS 的问题根本就是我上面说的,在 Go 里面很难 XSS,因为默认全部转义

#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

最后欢迎各种挑刺

#61 楼 @luikore flash 写成 falsh 就不提了 这个在哪里,我没看到啊,欢迎提啊

#62 楼 @astaxie 现代 web 框架 不是都把 session 存在客户端嘛...

对你模板默认转义就能避免 XSS 的观点不能认同,防御 XSS 需要根据外部输入所处的语境,单纯的自动转义只是防止开发者犯愚蠢的错误。

广告嵌入方式有很多种,流行的还都是第三方广告,通过 iframe 载入的,不存在跨域设置 cookie 的问题。 至于第一方广告,需要对广告提供方有足够的信任度才可以。

#63 楼 @astaxie

  1. 请仔细看... cookie 的 secure (https only) 和 httponly 不是同一个选项
  2. 那请继续这么做...
  3. 你是浪费好多 cpu 算了一段签名, 但是却不对它进行验证, 那有什么用...

只用时间作为随机因子确实不靠谱, <<白帽子讲 Web 安全>> 说的.

#65 楼 @hooopo 当然咯,这个需要程序员自己还要处理所有的输出,只是 Go 在这方面已经是最严格的输出,让开发者犯错误

#67 楼 @luikore 这个是文档吧,谢谢

#25 楼 @astaxie 你为什么要测 gcc -O2 ... 你可以用 gcc -Og 来表明 go 更快呀

#66 楼 @luikore 第一个、看错了,目前默认是 false,确实不开放 https 的设置 第二个、随机时间的做法我觉得确实可以改进一下,但是目前两次随机的时间,两个用户相同是不可能的 第三个、认证这一块目前有一个 pull request,目前还在 review

#63 楼 @astaxie 随带说一下 nginx 之后的 Go 是可以拿到真实 IP 的

#68 楼 @zgm #66 楼 @luikore #70 楼 @astaxie

我觉得这个 XSRF token 的实现问题很大:

因子只有四个:

所以我觉得很容易实施定向 CSRF 攻击的。

#74 楼 @hooopo unixnano 用了两个是不会碰撞的,XSRFKEY 是用户可以设置的,除非破解了 sha1 算法

#73 楼 @astaxie nginx 之后的 go 当然可以拿到 real ip, 但是 @luikore 说的代理的情况, 甚至是一个路由下面的 ip 都是一样的.

#74 楼 @hooopo nanotime 虽然不 那么 靠谱, 但是还不能说 轻易 碰撞, 况且两次更难, 但不那么严谨.

对于作者说, 换个 ip 就掉线, 我觉得对于普通用户都会觉得奇怪, 更别说了解 web 的程序员了.

#71 楼 @luikore gcc -Og这是什么命令啊?没听过

#77 楼 @astaxie 要对两种语言都有充分了解才能真正了解性能差别哦

#76 楼 @zgm 好吧 有道理

是的,我还是觉得,IP 放在里面除了添乱没起到任何防御 CSRF 的作用。

其实 CSRF Token 设置过期时间也是没什么必要的。

回家吃饭...

那啥 CSRF token 放在 cookie 里面有啥问题么? 话说 AngularJs 就要求服务端设置一个 csrf cookie(实际上除了放 cookie 根本没别的地方可以放啊,服务端整个页面都是静态模板,渲染是在客户端进行的)……另外为啥 API 就不需要 CSRF?

拿 secure cookie 当 session 在 ruby、php、python、node 甚至 go(gorilla) 都很常见

ruby、php、python、node 的主流模板默认对变量 auto escaping 已经是老黄历了

消息不对称很可怕😏

匿名 #83 2013年09月25日

看到高手们热烈讨论,又学到了很多东西

#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 的唯一优势是有字符串...

#83 楼 @luikore 说起字符窜, 前阵还见人吐槽 Go 的大道至简就是把 java 和 python 里的 bytes 和 unicode 折腾成了 bytes, utf-8 string 和 runes...

#83 楼 @luikore Go 里面函数是可以被当作参数传递,或者为返回值的,当然也支持匿名函数

#86 楼 @nevill 难道 C 不可以?

#87 楼 @bhuztez C 传的是函数指针,要模拟出 closure 还要另外传个 void* 之类的东西。如果要返回得传个 void**。可以是可以不过麻烦得多

#87 楼 @bhuztez 只是对 83 楼 说不支持函数式的 idiom而言,C 语言里面指针这个东西,我不知道该不该算作弊。。。

#88 楼 @reus 不总是需要 void *

golang 的好处不在性能,在并发模型、库、工具链这些。 其实我认为 web 开发这类拼接下字符串的工作,用 golang 感觉和用 C 差不多,本身就没啥语法糖,对于重复性的体力劳动不像 ruby 那样能搞出各种 DSL 来提高表达效率。

#83 楼 @luikore 麻烦你,gcc 没有-Og 命令,-o2,-o3 我当然是怎么回事,麻烦看看 gcc 的命令啊

94 楼 已删除

#83 楼 @luikore clang 我没有用过,所以我不评价

#95 楼 @reus

gcc (GCC) 4.7.2 20121109 (Red Hat 4.7.2-8)

表示没有

#91 楼 @reus 一个刚冒出来的语言也好意思说库、工具链 ...

#95 楼 @reus 哇,你都用这么新了啊,我的确实没有

#96 楼 @bhuztez 那应该就是 4.8 才引入的了

#98 楼 @astaxie gcc 4.4 这么老的版本估计连最新版的 clang 都比不过...

#98 楼 @astaxie 我用 archlinux,挺激进的发行版

#100 楼 @bhuztez 新版本我学习学习 #101 楼 @reus 我用 vagrant 装一个去

#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 就是安全的。

#93 楼 @bhuztez IP 的做法确实有待改进,我打算接下来用 UUID 来做这个认证,但是我还是觉 csrf 放在 cookie 是目前 Go 里面实现比较好的方法,不然引入 session 有点过度

106 楼 已删除

#105 楼 @bhuztez 采用 securitycookie 的话应该不会有很大的问题

108 楼 已删除

#107 楼 @bhuztez 所以在 csrf 里面增加过期时间

110 楼 已删除

#108 楼 @astaxie #107 楼 @bhuztez 你们又聊回来了啊.???

#109 楼 @bhuztez 目前的一个 pull 里面的代码其实已经有认证这一块了,只是这个代码我们还在 review

#110 楼 @zgm 欢迎大家各种意见啊,这样才能把框架做的更好

#109 楼 @bhuztez https://github.com/astaxie/beego/pull/215/files 但是我觉得这个放的位置需要改进,还有一些实现的方式

#109 楼 @bhuztez 还有目前时间的认证已经有了的

昨天本来去采购书籍,本来想买 go 的书来着...结果看了几页受不了了有点不符合我之前的逻辑,于是只好先弄了几本 nodejs 的书回去...lz 推荐几本 go 的书呗?

117 楼 已删除

一个从讨论性能的帖子一下变成了讨论某策略实现上了。。。

#103 楼 @astaxie 你很懂, 没什么好讨论的了...

#120 楼 @luikore 亲,不要这样嘛,讨论讨论还是很有帮助的,至少我知道了 session 需要增加 https 的支持,csrf 里面的 IP 作为认证不可取,其实通过讨论还是学习到很多东西

#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 2013年09月26日

虽然跑题了,但是跑的让人感觉学到不少东西。

#115 楼 @cassiuschen, @astaxie 谢老大写的就不错啊,正在学习中

#123 楼 @jihua0a 嗯……打算学完 node 就学 go……

匿名 #127 2013年09月26日

#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

#129 楼 @astaxie 减少了 28 台机器,go 作为静态语言在速度上有优势是一方面,用 ruby 写的原本的那堆东西没有优化或者架构好也是一方面。我对 web 不是特别懂,以我有限的知识的角度来说,制约 web 性能的多数在 IO 上而不是语言层面。 另外虽然理论上 ruby 会比 c 这类静态语言慢十几倍,但实际应用场景下并没有这么大的差距,多数执行时间还是耗费在本身就是用 c 写的一些库上。ruby 的优势是对程序员友好,弱点是慢。go 作为系统级别的语言,和 c 比较更好,能说说和 c 比的优劣势么?

#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++ 进行的重要简化的清单:

  • 规范的语法(无需用于解析的符号表)
  • 垃圾收集(唯一)
  • 没有头文件
  • 明确依赖
  • 无循环依赖
  • 常量只能为数字
  • int 和 int32 是不同的类型
  • 字母大小写设定可见性
  • 任何类型都可以有方法(没有类)
  • 没有子类型继承(没有子类)
  • 包级别初始化和定义好的初始化顺序
  • 文件编译到一个包中
  • 包级别的全局表达与顺序无关
  • 没有算数转换(常量做了辅助处理)
  • 隐式的接口实现(无需 “implements” 定义)
  • 嵌入(没有向父类的升级)
  • 方法如同函数一样进行定义(没有特的别位置要求)
  • 方法就是函数
  • 接口仅仅包含方法(没有数据)
  • 方法仅通过名字匹配(而不是通过类型)
  • 没有构造或者析构方法
  • 后自增和后自减是语句,而不是表达式
  • 没有前自增或前自减
  • 赋值不是表达式
  • 按照赋值、函数调用定义时的顺序执行(没有 “sequence point”)
  • 没有指针运算
  • 内存总是零值初始化
  • 对局部变量取地址合法
  • 方法没有 “this”
  • 分段的堆栈
  • 没有静态或其他类型注解
  • 没有模板
  • 没有异常
  • 内建 string、slice、map
  • 数组边界检查

除了这个简化清单和一些未提及的琐碎内容,我相信,Go 相比 C 或者 C++ 是更加有表达力的。少既是多。

据说吵来了,来看一下哈.

#130 楼 @rasefon 还有我觉得 robbin 的这一篇博客,也详细分析了 ruby 存在问题,我觉得对于 rubyer 来说,应该挺适合的,http://robbinfan.com/blog/40/ruby-off-rails

#132 楼 @debugger 其实是有意义的讨论,我们都是好孩子

其实大家不用过分纠结 app server 的性能吧,只要够用就行了,就算是 GO 的,就算是 CGI 的,能飙到好几万,但是后面还有其他很多瓶颈的地方,比如数据库、调用相关其他系统的 API 等,所以说,应该从整体系统架构来优化,该上 cache 的上 cache,该集群的集群,该读写分离的读写分离等等,才能真正提高整体网站性能。

#62 楼 @astaxie session 只是一种概念吧,懂英文的都知道是会话的意思

#131 楼 @astaxie Go 这么复杂也好意思说简单

我宁愿用 node.js~

这篇帖子讨论的很有意义,刚开始 @astaxie 态度不是很好,其实没必要这么紧张,别人能指出的一些不足,说明他们都认真去研究了你的作品,应该感到高兴。

这个页面上 http://beego.me/about 性能

beego 构建于 Go HTTP 服务器之上,而 Go 在最近的 性能评测 中显示其可同时服务多于 Rails 三至十倍 的请求。

这句话能不能改一下!

#137 楼 @bhuztez 艾玛,Go 这个还算复杂啊

#140 楼 @astaxie go 确实简单不少,相比 c 歧义也少,不过灵活性也降低了。

#140 楼 @astaxie 真的是太复杂太复杂了,概念那么多,一天都讲不完啊...

#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 内部实现的多线程不知道简单多少

#146 楼 @astaxie 但是你拿 golang 跟 rails 这个 ruby 的框架 比较说快 三至十倍 的请求,能否直接写上使用的 golang 的框架的名字呢,这样才是框架跟框架之间比较嘛

#148 楼 @ywjno 这个对比里面什么都有,sinatra、rails,各种框架,各种语言

#150 楼 @ywjno 我没说 sinatra 要用 Go 写,而是作者在用 Go 写一些东西,最近一直在做这方面的研究开发,所以才会出来这样的笑话

#149 楼 @astaxie 我说的是那个http://beego.me/about里面同步并发的介绍,直接写上 beego 比 rails 快不就妥了,

#152 楼 @ywjno 是写了 rails 啊,没写 ruby 啊,但是比 ruby 也快啊

#153 楼 @astaxie 哦不对,写错引用了,应该是高性能这里。 不过点开那个链接看到Framework有个叫做go的,语言也是go,莫非在 golang 里面还真有个叫做 go 的框架么?

#154 楼 @ywjno Go 本身就是一个框架啊,内置的包足够强大

cookie 直接用 gorilla 的 securecookie 就挺好的

#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 的出来不会如此困难。

#10 楼 @luikore Go 有些库的性能确实比不完全是 C 写的极端优化的库性能要慢很多. 但是, 拿这个来证明 Go 语言比 C 语言慢 10 倍就比较扯了.

#19 楼 @luikore Go 编译器的性能在 2012 年底已经和 C 很靠近 (GCC 测试 10% 差距). 但是, Go1.1 和 1.2 在 runtime 和很多库的改进还是很大的 (包含网络部分). LLVM 是很厉害, 有些测试也可以甩 GCC 很多.

#22 楼 @rasefon

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 的版本是不是也可以呢?

#71 楼 @luikore gcc 的 o2/o3 差别不大, 有个别的 o3 还不如 o2 快.

实际项目中,瓶颈都在数据库查询那块了,你数据库不可能只有一台服务器。。。。 所以最终瓶颈在网络。 所以其实平台架构更关键啊。。 我之前玩 php,现在完全转到 nodejs 了~~ 现在是 expressjs + rethinkdb 做后端,前端 AngularJS 来开发 http://yaha.me

初步测试跟 c++ 性能差不多

每次想看都删一堆

瓶颈不在语言,在各种 IO 上。。。。。简单的输出 hello world 的话随便起个 httpserver 都能飚这么高。。。

#1 楼 @luikore 很赞同。这种抛开业务谈性能就是耍流氓。你把 golang 的各种库,数据库访问都加上,会发现差别并不大。Golang 如果非要往 web 上靠(P.S. 其实这货搞 web 是搞错了方向,先天不足,很难和其他 web 框架竞争,单纯的写点 REST API 还是可以的),那么还会有很长的路要走。另外写后台服务,如果要保证 7*24 运行的服务,这种有异常也不允许挂掉的服务,没有 try catch 结构的语言是很不方便的,到处都要 if err != nil 引出异常,感觉很蛋痛,反正最近写 Golang worker 就很烦躁。接触 Golang 时间不长,一点挫见。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号