手机游戏服务器端用node.js 还是用go,fibjs nodejs 测试之类等比较好

fibjs 的 10 万并发连接的军工级测试_developerWorks_传送门
fibjs 的 10 万并发连接的军工级测试
developerWorks
本文选自《开发者头条》4 月 1 日用户分享,作者 @响马 ,感谢 powercenter 分享。欢迎分享:http://toutiao.io/contribute测试内容动态HTTP服务器极限性能,分为两项:优化前后的各版本fibjs优化后的fibjs、使用cluster的nodejs、基于模块的nginx、使用多核的go测试环境及方法服务器CPU:8核(4sockets*2cores),每核2.1GHz内存:24GB客户端(10个)CPU:1核,每核2.1GHz内存:1GB测试流程:首先在服务器端开启server调度机ssh到客户端触发对服务器的wrk请求(测试时长为30min)测试的并发量从1w~10w,递增幅度为1w测试项一:fibjs优化前后性能对比3个版本的fibjs,分别为:v0: 原版fibjsv1: 优化了SOCKET_ BUFF_ SIZE大小v2: socket 等待时释放 buffer 内存测试项二:优化后的fibjs与其他服务器性能对比服务器分别为:优化后的fibjs (v0.1.7)使用了cluster的nodejs (v0.10.25)使用多核的go (v1.5.1)nginx模块 (v1.9.2)测试结果结论模型fibjs和go均为单进程多线程nodejs(cluster)和nginx是多进程内存占用go平均每个请求所需内存最多,约为320KBfibjs和nodejs平均每个请求所需内存相差不多,均约为72KB,不过nodejs占用的固定内存多于fibjsnginx采用了Zero Copy技术,内存占用非常低QPSnginx和go都未跑满CPU,且在高并发下表现良好fibjs的http协议栈处理是多线程的,且CPU占用率高于nginx和go,在高并发情况下表现良好nodejs在3w并发时已基本跑满CPU,且性能下滑严重更多优质内容,欢迎安装、使用《开发者头条》iOS、Android 客户端。体验地址:http://toutiao.io/download???
觉得不错,分享给更多人看到
developerWorks 微信二维码
分享这篇文章
4月3日 20:20
developerWorks 最新头条文章
developerWorks 热门头条文章从Node.js 转到 Go平台
投稿:hebedich
字体:[ ] 类型:转载 时间:
回顾过去的一年,我们在技术栈上的最大改变就是从 Node.js 切换到 Go 。我们的联合创始人,Steve Kaliski, 在 Poptip 把 Node.js 切换成了 Go,可惜他没有学习到当时的教训。
在用 Node.js 建立了 Bowery 的第一个迭代版本后,我们在2014年2月切换到了 Go,我们的开发和部署速度也因此得到提升。
从那以后,我们整个团队都变成了专职的地鼠(译者注:Go 的吉祥物)。Go 清晰明确的标准和更简便的工作流程让我们用 Go 用得很舒服。下面是我们热爱用 Go 进行工作的原因,你可以从中瞄一眼我们的地鼠洞。
容易编写跨平台代码
我们切换成 Go 的其中一个最大原因就是它是那么容易去为不同系统编译代码。
在 Bowery, 我们在建立一个能帮忙你和你的团队管理你们的开发环境的app,我们必须要高效地支持所有操作系统——Linux,Windows 还有 OSX。在Go中,你可以为不同的操作系统定义不同的文件,从而实现依赖于操作系统的功能。一个绝佳的例子就是我们的同伴 Larz 在构建一个从命令行读取用户输入的包 Prompt 的事。Larz 希望去创建一个 Go 包用来实现跨平台的行编辑提示。这在 Go 中是如此简单:为每个操作系统创建不同的文件,Go 编译器会根据操作系统来选择应使用的文件来生成最终内容。
为其他的系统编译代码同样很简单,你要做的仅仅是设置一个环境变量,然后你就有了一个你在 Linux 系统上编译的 Windows 二进制文件。
更快的部署
Go 是一款编译型语言并且可以更轻松地在多个平台上分发应用。 对我们而言,部署和测试是很重要的,同时也是我们最终用户的一个资产。通过 Go,构建服务然后运行测试会很容易,因为迁移到生产环境的服务器时就准备好了。 Go 不需要任何的系统依赖,让它的发布真的很简单。 当要发布命令行工具或者其它应用时,我们的用户不需要担心要安装Java,RVM或者NPM才能运行。 我们喜欢这篇Jeremy Saenz 的文章,他讨论了为什么他把他所有的命令行工具迁移到Go(CLI tools to Go)。
当切换到Go时我们意识到Node.js的事件循环并不是一切。Node.js 没有提供太多的并发基元。唯一能同时运行的是I/O程序和定时器等。你无法通过这些程序通讯,所以用Node.js建立一个敏捷的系统是一个挑战。使用Go,你可以在运行任意并程序的同时,提供一个频道去给程序发送信号让它做一些事情,或者给它们发送一些值来共享数据。Go还提供了像 mutexes, wait groups等低级别的并发基元 。 有的你可能在NPM上找到,但我们发现在处理并发和并行时频道是决定性因素。
集成测试框架
用Node.js的时候,我们已经有了我们的测试框架选择,但一些框架对于前端来说更好用,比如Jasmine, 其它的框架则对后端来说更好用,比如Mocha。也有其它的选择像JSUnit和PhantomJS,如果你看过StackOverflow的这篇文章,那里也有人推荐许多的框架。在一些世界里,选择是一件好事,但使用Go的时候,我们喜欢测试框架的规范化。在Go里,所有的测试包都是内置的。如果你需要写一个新的测试套件,你必须做就是把(文件名)_test.go文件加到你要测试的软件的同一个包里,它将会在你每次执行go test的时候运行。
你可以在writing tests with Go学到更多关于Go 测试的知识。 需要测试HTTP services? Go同样提供了httptest包
我们喜欢仅用Go的标准库就能写大多数的软件。用Node.js时,我们几乎都是不得不引入一个外部的库, 这样做既增加了部署的时间,也增加了来自第三方软件的潜在隐患。只用标准库能让我们写的代码更快更安全。
开发者用的工作流工具更强大
Node.js除了NPM的包和脚本控件,没有真正的标准化的工作流。除此之外, 因为这些工具是社区创造的,虽然很好用但是实在太多了,以至于最终的结果就是事情被每个人以不同的方式完成了。在Go里工作流标准化的一个很好的例子就是工作区的布局。你要放弃很多开发自由因为你必须遵守工作区的布局,不过它提供了大量的结构:你可以保留你的Go源码和依赖在同一个位置。在你的工作区你有3个根目录: src 放源码包,pkg放编译过的包,bin放可执行的程序。让你的源码和依赖放在一个单独的工作区是一个最佳实践, 让它在每个人的机器上都是这个标准。在团队合作里这些可预测性是让人满意的。我们可以去任何人的机子上提供帮助,并且知道我们的代码将会出现在$GOPATH//Bowery这个路径,而不是其它像$HOME/some/path/to/Bowery这样的路径。类似的,gofmt用同样的方式格式化每个人的代码。对于一些肤浅的问题,像组织代码和代码风格差异在Go里根本不需要担心,这是一个大大的解放。你可以专注修复你的问题,其它的事都被考虑到了。
还有一大堆其它的原因去喜欢Go,我们看到越来越多的公司采用Go让内部应用变得更强大并且是可分布式的。但总的来说,Go团队发现如果你创造标准并弄成范例让别人同意的话,开发者们会更高产。 比如, MongoDB 的应用管理团队喜欢用Go的"明智的、 统一的开发经验"。 在 Soundcloud,他们喜欢用Go严格的格式化代码规则和“实现的方式只有一种”的哲学。这意味着你会在代码审查和争论代码风格和格式上花很少的时间,而可以用更多的时间去解决你问题的根源。
如果你刚开始使用Go并且想了解更多,这里有一些资源可以看看。
阅读Golang 官方博客的更新和核心团队的公告
阅读核心团队提供在官网的学习文档
我们喜欢Ardan工作室的Bill Kennedy写在博客 Going Go Programming 上的窍门和指南
Go by Example 有一堆用Go写的不同任务的例子
GopherAcademy 有很多关于Go的最佳实践的文章
Brian McCallister 有一篇很好的文章是 Go 工作区和总体开发环境
更多关于Go的代码组织,阅读Jared Carroll发布在 Pivotal Labs blog 的文章
如果要开始你的第一个Go项目,设置你的新环境并在Bowery分享给你的团队吧。
请您花一点时间将文章分享给您的朋友或者留下评论。我们将会由衷感谢您的支持!
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具IT-开发平台(1)
动态HTTP服务器极限性能,分为两项:
优化前后的各版本fibjs优化后的fibjs、使用cluster的nodejs、基于模块的nginx、使用多核的go
测试环境及方法
CPU:8核(4sockets*2cores),每核2.1GHz &br/&内存:24GB
客户端(10个)
CPU:1核,每核2.1GHz &br/&内存:1GB
测试流程:
首先在服务器端开启server调度机ssh到客户端触发对服务器的wrk请求(测试时长为30min)测试的并发量从1w~10w,递增幅度为1w
测试项一:fibjs优化前后性能对比
3个版本的fibjs,分别为:
v0: 原版fibjsv1: 优化了SOCKET_ BUFF_ SIZE大小v2: socket 等待时释放 buffer 内存
QPS(req/sec)
QPS曲线如下图:
内存占用(单位GB)
内存占用曲线如下图:
测试项二:优化后的fibjs与其他服务器性能对比
服务器分别为:
优化后的fibjs (v0.1.7)使用了cluster的nodejs (v0.10.25)使用多核的go (v1.5.1)nginx模块 (v1.9.2)
QPS(req/sec)
QPS曲线如下图
内存占用(单位GB)
内存占用曲线如下图
服务器CPU占用情况
fibjs和go均为单进程多线程 &br/&nodejs(cluster)和nginx是多进程
go平均每个请求所需内存最多,约为320KBfibjs和nodejs平均每个请求所需内存相差不多,均约为72KB,不过nodejs占用的固定内存多于fibjsnginx采用了Zero Copy技术,内存占用非常低
nginx和go都未跑满CPU,且在高并发下表现良好fibjs的http协议栈处理是多线程的,且CPU占用率高于nginx和go,在高并发情况下表现良好nodejs在3w并发时已基本跑满CPU,且性能下滑严重
服务器代码1_fibjs
var http = require('http'),
net = require('net'),
coroutine = require('coroutine');
var interval = 1000;
var hdlr = new http.Handler(function(req) {
if (req.address == &/fibjs&) {
req.response.write('Hello, World!');
var demon = function() {
while (true) {
console.error(&connections:&, svr.stats.connections,
&\trequest:&, hdlr.stats.request,
&\tresponse:&, hdlr.stats.response);
hdlr.stats.reset();
svr.stats.reset();
coroutine.sleep(interval);
var svr = new net.TcpServer(8080, hdlr);
coroutine.start(demon);
svr.run();
服务器代码2_使用cluster的nodejs
var cluster = require('cluster'),
http = require('http'),
url = require('url'),
numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
console.log(&master start...&);
// Fork workers.
for (var i = 0; i & numCPUs; i++) {
cluster.fork();
cluster.on('listening', function(worker, address) {
console.log('listening: worker ' + worker.process.pid + ', Address: ' + address.address + &:& + address.port);
cluster.on('exit', function(worker, code, signal) {
console.log('worker ' + worker.process.pid + ' died');
http.createServer(function(req, res) {
var pathname = url.parse(req.url).pathname;
if (&/node& === pathname) {
res.writeHead(200);
res.end(&Hello World!\n&);
}).listen(8080);
服务器代码3_使用多核的go
package main
&net/http&
func hdlr_hello(rw http.ResponseWriter, req *http.Request) {
req.ParseForm()
rw.Write([]byte(&Hello world!&))
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
http.HandleFunc(&/go&, hdlr_hello) //设置访问的路由
err := http.ListenAndServe(&:8083&, nil) //设置监听的端口
if err != nil {
log.Fatal(&ListenAndServe: &, err)
// panic(err)
服务器代码4_nginx模块
#include &ngx_config.h&
#include &ngx_core.h&
#include &ngx_http.h&
#include &ngx_buf.h&
指向ngx_conf_t 结构体指针,从指令后面传过来的参数
指向当前结构体ngx_command_t 的指针(互相指)
*conf 指向自定义模块配置结构体的指针
static char *ngx_http_hello_world(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static ngx_command_t ngx_http_hello_world_commands[]={
ngx_string(&hello_world&),
//指令名称,nginx.conf中使用
NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
ngx_http_hello_world,
//回调函数,上面申明
//保持的值存放位置:全局,server,location
//指令的值保存位置
ngx_null_command
//读入ngx_null_command 指令后停止
//ngx_http_&module name&_module_ctx用于创建和合并三个配置
static ngx_http_module_t ngx_http_hello_world_module_ctx={
//preconfiguration
//postconfiguration
//create main configuration
//init main configuration
//create server configuration
//merge server configuration
//create location configuration
//merge localtion configuration
//nginx进程,线程相关,ngx_http_&module name&_module把数据处理关联到特定模块
ngx_module_t ngx_http_hello_world_module={
NGX_MODULE_V1,
&ngx_http_hello_world_module_ctx,
//module context
ngx_http_hello_world_commands,
//module directives
NGX_HTTP_MODULE,
//module type
NULL, //init master
NULL, //init module
NULL, //init process
NULL, //init thread
NULL, //exit thread
NULL, //exit process
NULL, //exit master
NGX_MODULE_V1_PADDING
static ngx_int_t ngx_http_hello_world_handler(ngx_http_request_t *r)
if(!(r-&method & NGX_HTTP_GET))
return NGX_HTTP_NOT_ALLOWED;
ngx_int_t rc = ngx_http_discard_request_body(r);
if(rc != NGX_OK)
return rc;
ngx_str_t type = ngx_string(&text/plain&);
ngx_str_t response = ngx_string(&Hello World!&);
r-&headers_out.status = NGX_HTTP_OK;
r-&headers_out.content_length_n = response.len;
r-&headers_out.content_type = type;
rc = ngx_http_send_header(r);
if(rc == NGX_ERROR || rc & NGX_OK || r-&header_only)
return rc;
ngx_buf_t *b;
b = ngx_create_temp_buf(r-&pool, response.len);
if(b == NULL)
return NGX_HTTP_INTERNAL_SERVER_ERROR;
ngx_memcpy(b-&pos, response.data, response.len);
b-&last = b-&pos + response.len;
b-&last_buf = 1;
ngx_chain_t out;
out.buf = b;
out.next = NULL;
return ngx_http_output_filter(r,&out);
//回调函数,1获得location中的“核心”结构体,2为他分配个处理函数
static char *ngx_http_hello_world(ngx_conf_t *cf,ngx_command_t *cmd,void *conf)
ngx_http_core_loc_conf_t *clcf;
clcf = ngx_http_conf_get_module_loc_conf(cf,ngx_http_core_module);
clcf-&handler = ngx_http_hello_world_handler;
return NGX_CONF_OK;
###脚本_集群调度
#!/usr/bash
if [ $# -lt 1 ]; then
echo &option [conn | close]&
user=verdant
concurrency=50000
duration=600
logdir=&log/&
logfile=&ctrl.log.&
ip_array=(&171& &193& &209& &213& &231& &219& &222& &223& &224& &225&)
conn=$(($concurrency/${#ip_array[*]}))
sleeptime=1
# sleeptime=$(($concurrency/1))
remote_cmd=&~/wrk -t10 -c$conn -d&&$duration&&s http://192.168.1.61:8080/fibjs&
# remote_cmd=&~/wrk -t10 -c$conn -d&&$duration&&s http://192.168.1.61:8080/node&
# remote_cmd=&~/wrk -t10 -c$conn -d&&$duration&&s http://192.168.1.61:8080/go&
# remote_cmd=&~/wrk -t10 -c$conn -d&&$duration&&s http://192.168.1.61:8080/nginx&
function main()
echo &${#ip_array[*]} client each: $conn&
for ip in ${ip_array[*]}
if [ -e &$logdir$logfile$ip& ]; then
rm &$logdir$logfile$ip&
if [ $1 = 'close' ]; then
for ip in ${ip_array[*]}
result=$(ssh -t -t $user@&192.168.1.&$ip &killall -9 wrk&&& $logdir$logfile$ip &)
sleep &$sleeptime&
echo $result
if [ $1 = 'conn' ]; then
for ip in ${ip_array[*]}
ssh -t -t $user@&192.168.1.&$ip &$remote_cmd&&& $logdir$logfile$ip &
sleep &$sleeptime&
function recovery()
server_ok=()
while [ $running -ne ${#ip_array[*]} ]
for ip in ${ip_array[*]}
if [ ! -s &$logdir$logfile$ip& ]; then
echo &restart:&&$logdir$logfile$ip&
sleep $((5*$sleeptime))
ssh -t -t $user@&192.168.1.&$ip &killall -9 wrk&
sleep $((10*$sleeptime))
ssh -t -t $user@&192.168.1.&$ip &$remote_cmd&&& $logdir$logfile$ip &
if [[ &${server_ok[@]/$ip/}& = &${server_ok[@]}& ]]; then
server_ok[${#server_ok[@]}]=$ip
running=$(($running+1))
function calculate()
while [ $1 = 'conn' -a $result1 != $result2 ]
result1=`cat $logdir$logfile*|grep Requests/sec|awk '{print $2}'|awk '{sum+=$1} END {print sum}'`
if [ &$result1& = && ]; then
result2=`cat $logdir$logfile*|grep Requests/sec|awk '{print $2}'|awk '{sum+=$1} END {print sum}'`
echo &Requests/sec: $result1&
cat $logdir$logfile*|grep Latency
sleep $((${#ip_array[*]}*$sleeptime))
#客户端异常重连机制
if [ $1 = 'conn' ]; then
sleep $duration
echo &calculate...&
calculate $1
node用0.10、、、、、
会有差别吗?
会的,用4.2或5.x
估计会有多大差别?提升 100% 还是提升 1000%?提升 100% 以内就不麻烦再测试一遍了。
然而生态、、、、、
不可否认node的确曾经依靠纯异步有不错的性能表现,但现在要讲高性能,这得看跟谁比了,跟同步比那还能算高性能的,但跟其他异步框架比起来,还能说是高性能么?从测试成绩来看,顶多算还行,就算用4.2,5.x来测,结果也好看不到哪里去,至少不会出现数量极的改变。
现在node社区的人,唯一可以自慰的就是生态了,为什么会这样?因为性能已经不好意思拿来吹了。
感谢响马大哥的测试。
支持国产是重点
定位要准确,没有一种语言是万金油,选择适合自己的
fibjs 在牛X再好,我也不会去学习去使用用,也不会叫同事去学习去使用,只是一年内不会,等以后用的人多起来再观望。在一个团队或者项目中选择要使用fibjs,不但要看团队里面的使用的人多不多,还要看外面用的人多不多,否则招不到人也是悲剧。当然,本着追求探索的目的,玩玩还是可以的
nodejs 代码里 var pathname = url.parse(req.url). 这句可以省掉,直接用&/node& === req.url
很详细很赞的测试,我只能膜拜了。说说几点我的观点吧。
不管是fibjs, nodejs, go或者其他工具,在大规模以及大项目中使用不会只有一台服务器在跑,都会有相应的分流来均衡.追求性能的提升当然是件好事也是对各种技术的挑战以及自我的挑战,但是很多小公司小项目或者中型项目,在没有遇到性能瓶颈的时候我觉得没有很大的必要去追求高性能高并发. 我这里只是对那些小公司小项目说的。(楼主对技术的追求还是很赞的)性能瓶颈往往是出现在数据的存储以及调用方面以及磁盘IO
对楼主还是敬佩的。上面所列的几点只不过我站在客观角度所言。
做这个测试的原因当然是出于是业务需要,有一些业务场景是需要维持大量连接而运算量并不大的。
测试过程中也有两次对 fibjs 优化的结果。
最初并没有打算测试 nodejs,因为知道它肯定抗不住。但是考虑到发出来肯定有人会问 nodejs 的数据,就特意测了一份来。做出来才知道,nodejs 比我能想象的更差劲。一万以内,fibjs 是它的 2 倍,到 10 万的时候,已经是它的 15 倍了。就这点性能还启用了 cluster。
至于招人,还真不难,校招新人一周内上手,比 nodejs 快多了,而且基本不会写错代码。
fibjs的思想还是非常值得学习的,利用协程隐藏回调,实现形式同步,实质异步。形式同步是大势所驱,编程模型应该越简单越好,这不仅仅对nodejs,对其他所有技术都一样。 大哥的公司能够在大学里招人过来,一个礼拜上手,本身就说明了这点。学校里教的就是同步编程,业务大多也是同步需求。
显式的异步代码对异步本身的发展就是阻碍。我们只需要异步带来的性能好处,但并不需要由此引入的编程复杂度。
为何还不干掉go那个我讨厌的语言
虽然我掉进了回调的坑,但是我觉得掉的还蛮值得的。不管代码层面异步还是同步,我个人觉得没关系,而且通过异步代码的编写我多少了解了一点异步回调隐藏的方法。如果fibjs雄起甚至干掉nodejs也是蛮好的。如果确实性能突出, 而且生态好的话,必须用!大大们多做做实验吧~撇开这个测试不说,希望响马能多广告发扬一下fibjs,让广大编程工作者来检验一下,要是真把nodejs屁股给踢疼了,我觉得应该很赞!
首先我也肯定fibjs另一种开发思想和代码风格,我只是现在不看好fibjs在其他公司的应用,比较了解的人少,深入的人估计只有自己,至于
敢招大学里面的新手,那是因为他自己了解,其他人敢在他们公司的项目里面使用?然后也去学校里面招人?
对异步理解到了一个程度,异步的形式已经不重要了,这个时候追求的应该是非显式的异步,就像武功高强的人达到无招胜有招的境界。很多原来同步的语言,现在通过改进后,nodejs已经没有任何性能优势了,如果继续抱着原有的编程模型不放,只会越来越落后。
node在阿里的应用也仅仅限于大前端,阿里的人自己在之乎上说核心交易nodejs成绩为0。这里的原因,我想,java成熟稳定是一方面,nodejs显示异步的编程模型和业务同步逻辑之间的矛盾才是最主要的。核心交易业务复杂的程度,不是简单的理解了回调,理解了异步就能应对的。你只要自己试着用nodejs写一个异步文件夹遍历,就可以想象在复杂业务条件下,显示的异步是多么的无力。
回调不能代表异步,如果你愿意,同步代码也可以用回调来表达。回调在异步程序中的作用恰恰是保证同步,保证执行顺序的。
回调模式下的异步,现在已经成为nodejs的包袱,generator和promise的缓和作用有限,学习成本还是有的,是典型的为了解决一个问题,又引入另外一个问题的做法。这些东西在前端是适用的,但面对复杂的后端,形式同步才是终极解决方案。
nodejs用来做demo,做一些大前端页面渲染是合适的,这些应用不涉及复杂的后端数据库交互过程,只要一两次异步就能搞定,阿里就是这么搞的,真正的后端将数据准备好,nodejs取过来,套上模板渲染传给浏览器。
多谢鸡汤。PS:你撸汉字快赶上我撸代码速度了0.0
fibjs的源代码我大致浏览过,实现思路也大致了解,细节没有深入。我更看重的是思路,有了思路,代码堆出来只是时间问题。
我自己也在利用libuv和lua实现一个形式同步的网络库,做这个事情,是去年受到fibjs的触动,我那时正好在写文件夹遍历,被回调搞得很爽,这个过程我就有了反思,后来也看了openresty的代码,我c++不行,fibjs,v8都玩不转,就选择了c + lua + libuv,lua天生提供协程支持,openresty又有现成的通过协程回调转同步代码参考,lua和javascript在本质上很相似,libuv读nodejs的源代码的时候看过,自己很喜欢,自然就用这个网络库了。整个框架已经搭好,中间重构了一次,马上就可以发布出来。
那你写代码速度好快了,我除非写测试代码,不然一天也就顶多200行不到。
赞,期待中。。。
这样看go这么牛逼,要性能那直接上go,至少生态要好啊。
有对比,对语言,还是社区都是好事。 可否有空翻成英文,发到 HN 等,看看社区反映。
fibjs确实不错,目前还属于极客,还需要时间吧。
哈哈,你自己都说了你c++不行,那么出了bug你解决不了,我没有关注fibjs,只关注过node.js,但深入使用了node.js就发现很多bug,其中大部分是由于c++(包括node的核心库和v8引擎的)码引起的,所以即使深入使用node了都会引起问。
跟响马大哥的fibjs是没法比的,整个项目还很原始,但是通过协程异步转同步的思路还是表达出来了。fibjs的让我对异步有了更进一步的认识,同步代码才是异步程序的最终归宿,编程思想才是最重要的,非常感谢引路人响马大哥。
我c++水平太次,只能看懂代码,自己写不行,无奈只好用c+lua来实现,无法为fibjs做什么贡献。
其实你们可以把fibjs理解为一个能运行v8的框架,这个框架包括了文件数据库网络等等的东西node理解为一个封装有常用系统api和其它一些常用类库的服务端用的js运行时 只不过js引擎用的v8 其实也可以换成其他的比如微软就换成查克拉了 其它有些人换成spidermonkey了nodejs 和 fibjs 差不多的地方就是都碰巧选用了v8而已
fibjs 选 v8 倒不是碰巧,spidermonkey 和 JavascriptCore 都不能很好地支持 fiber,只有 v8 能够兼容这个模式。微软的引擎向来支持多线程,应该可以使用,但是跨平台是个问题。
因此 fibjs 最终选择了 v8。nodejs 对引擎依赖比较小,倒是可以很方便移植,几个 Javascript 引擎都有移植的版本。
看是什么代码了,哈哈,我指的其实是字符数!
我想知道nodejs以后有没有性能提高的可能,在现有架构下,毕竟前端工程师不想放弃npm丰富的支持
fibjs好像很有趣。我去看看。
我试过在ubuntu lts 32bit 上编译,每次都是段错误。在vs2015社区版无法按说明正常编译(非要用旧版本vs才可以么)。希望能提供二进制版本下载官网文档有点…(谈一些喜欢喝什么的问题真的好么)
与其唱双簧,还是希望能把官网的引导做好一点。(官网打开很慢,jquery的content-download时间20s,也不知道是网络问题还是服务器问题还是我的浏览器爆炸了)
用nodejs其实没别的,就是生态太完善了,想要的库基本上都有,再加上性能也还可以。最大的问题就是异步。成也异步败也异步,不过现在也已经有比较好的方案再解决这个问题。至于性能,很多时候说实话不是最关键,初创企业能有几个项目真能一开始就碰到太多性能问题,开发效率和速度才是最关键啊。
统一回复:
没有可能。
一、中间有几个版本在 32 bits 上运行是会出错,我们没做好全平台测试,一直也没有人回报,目前已经发现并修复了二、vs2015 稍微转换即可编译,而设置为 vs2015,vs2013 却肯定不能编译了。windows 版本仅为兼容,虽然性能同样很好,但是我们自己并没有大量使用,虽然我知道有公司在 windows 上投入生产环境,但是我们没有一手数据,所以不建议生产环境使用,做做测试尚可三、人力所限,不提供二进制下载,如果是
mac,可以通过 brew install fibjs 直接安装四、文档是萝卜青菜,各有所爱,大家都是程序员,就别在那些虚头巴脑的文字上纠结了,直接干代码就好了五、官网慢是因为 vps 慢,建议从 github 下载 docs 本地阅读,国内 vps 还要备案,烦躁
文无第一,武无第二,大家都是程序员,快就是快,不快就是不快。你看我就从来不辩解说生态不重要,没有就是没有。
我记得我去年在这里就看到,楼主发测试了。今年又是测试。。。对,fibjs快!
楼主大神,弄的我都不想学node了,好样的
佩服楼主的功力,但是还是不看好。
每次看到楼主的帖子就想放弃nodejs,还是安心做一个前端吧,想当初在java的泥潭里受不了,转前端也就是因为nodejs才下定决心
为啥要放弃,是因为你觉得楼主太厉害了吗。。。
这种贴,评论永远比正文更精彩
我觉得既然你们在这里发贴子,肯定也有想推广的心吧。能够看到更多的人使用才能证明他开源的成功不是。不然自己藏着就好了。。既然说文档不重要,那多做点demo啊=。=
有全套文档,代码目录的 test 内有每一个对象与模块的每一个 api 的使用用例。
这次对比测试后,fibjs 又进行了几个版本的迭代,这是历次迭代后的性能提升。这些提升都不是通过优化 http 逻辑得来,而是重构 fibjs 基础对象系统获取,因此对所有模块均有提升。
什么时候分享一下测试的东西
又见hello world测试。。。毫无意义。。。
你提到了go.可以去试试这个,性能是标库http的5倍以上。但有什么意义?
别人的工作怎么会毫无意义呢?一些人总喜欢纠结于测试本身的结果,而忽略了为什么会有这样的结果,也就是它快,但为什么这样快呢?
不但给出了具体的测试方法和代码,还告诉大家优化的过程和思路,这个过程和思路才是真正的精华所在。服务器优化到极至,拼的就是内存的使用效率,不该分配的地方绝对不重新分配,不该拷贝的地方绝对不做无谓的拷贝,可以重用的尽量重用。这些方法其实都是通用的优化方案,这些工作我认为是非常意义的。
fasthttp优化的原理也是大致相同的,同样是减少重新分配,少拷贝,多重用。
fibjs和go相对于nodejs而言,更重要的意义就是使得nodejs不得不朝更加易用的形式同步编程模式演化,把回调异步的神话打破。想当初nodejs是多么痴迷回调异步,拒绝引入协程,结果活生生被ES6打脸了,还闹出了分裂逼宫的闹剧,要想舒舒服服的写异步程序,协程是绕不过去的,即便是async/await还很低级,更不要说ES6了。当有的人看到一些人老早就在用同步代码写异步程序的时候,你就会觉得有的人的工作是意义大去了,这个意义不在代码本身,而在思想。
你所做的性能改进为什么不在nodejs上做呢?走分裂的路不对,添砖加瓦才有前途。
根本不是一个路线,没办法添啊。况且fibjs刚出来的时候,nodejs回调异步还如日中天,人根本看不上协程这种路线,虽然现在nodejs也事实上走了类协程路线,最终还是会发展成跟fibjs类似的形式同步,实质异步。nodejs加个新特性都要闹分裂,逼宫,fibjs这么激进的方式他们根本不会接受。
很奇怪,go语言有这么多如此优秀的框架,为什么网上总是有人批判go语言不好。
感觉fibjs在javascript语言里很牛逼啊,但总觉得在这里贬低nodejs没有什么用
我想问的是,前端web界面里面,ajax,可以用这种&协程&, 的方式来编程吗? 很多应用,前端也是有很多逻辑的
这个是“协程”的概念的,node里面有async支持协程,前台里面应该是promise这个库来支持的吧(不知道理解的对不对o(╯□╰)o)
我还是坚持我的观点,hello world无意义。纯浪费时候。。
最少加点template render, session in cookies之类cpu运算。最少得加点io操作模拟可能的阻塞吧。
这种测试和http paser + epoll测试有什么区别?
有个小故事,go界有个最近吹得很厉害的框架iris,自称性能秒杀标库http。。当然他自己测试用的也是hello world :)后来有人加了些许线上常出现的业务代码,性能下降到连martini不如,沦为笑柄。后来看代码才知道,这货是取巧缓存了context,当无阻塞时候,那当然快得很。但线上情况可能吗?
对于你说的引入coroutine的优势,还是认可的。
语言太朴实,没花头。。
无话可说,不谈性能,不谈生态,就是喜好~
这篇文章说,“协程”, 是有问题的
—有时,回调函数反而更加强大,虽然,goroutine协程口口声声说是用来替代万恶的回调函数的。协程只是比线程较为轻量,但是较为轻量不代表它是最轻量的。
我已经说过了,高性能服务器在不动内核的前提下,大家最后比的就是内存使用效率,同样原理,不同的代码,性能差距还是有的,helloworld就是为了排除其他影响,测试纯粹的网络性能的。这个东西不能代表性能的全部,但也是一个比较重要的指标。nodejs当初不也是helloworld起家的?
个别人做helloworld测试不严谨,投机取巧,甚至作弊,也不能证明helloworld测试性能就毫无意义啊,这个基本的逻辑关系,我想程序员都应该能够搞清楚的。你如果看过V8的源代码,就会明白缓存是一个非常重要的优化手段,不必要的计算不计算,这本身就是一种非常重要的优化思想。
我们需要谴责的是那种为了数据漂亮,不择手段的测试,像响马这样的测试,我觉得不是属于这种。但必须要明白,这些测试也仅仅对测试代码负责,并不能代表全部性能。框架性能再好,也架不住业务代码过分烂啊。但如果框架性能好点,业务代码的性能压力相对要小一些。
协程相对于纯粹的回调性能会差点,协程切换还是要保存CPU寄存器的,跟函数调用的代价比还是比较大的。
协程比回调优势的地方是在异步表达上,协程可以实现用同步代码编写异步程序,回调是无法做到的。
性能和编码效率在这里就是一对矛盾,现在已经证明纯粹的回调编码效率不行,javascript引入了generator/yield,async/await来缓解这个问题,但由于这两者背后还是基于回调,虽然代码局部同步了,但有的时候还是要用异步思维去写程序。javascript在纯粹的回调外又包装了一层,其性能很难说比协程有优势了。
我用C + lua5.3 + libuv 实现的异步框架luaio,TCP性能就比nodejs高一倍,luaio可以用完全同步的代码写异步程序。所以虽然理论上纯回调性能更好,但具体实现还要看实际情况。协程实现方法也有很多种,性能也不同。lua的是单线程setjmp/longjmp,fibjs是自己汇编实现的ucontext,go是多线程的。
选择什么样的异步编程模型,归根到底还是在编码效率和性能之间做个权衡,没有完全无懈可击的方案,只有适合自己的方案。
有空研究下fibjs的底层实现昨天也是偶然看到一个回复提到了fibjs,确实大开眼界
估计会有多大差别?提升 100% 还是提升 1000%?提升 100% 以内就不麻烦再测试一遍了。
用 0.10 做对比基本没什么参考价值,反倒误导了不少不留意的同学
goroutine协程本质上也是解决 io 密集型任务。其实就实现角度看,回调是基础,回调技术包含着闭包技术,闭包保存了打断的上下文,使得逻辑可以继续。现在 es6 的 generator 从 js 层面实现了,也可以从C++层面做这些事情,我觉得 fibjs 就是在 C++层面实现了,因为将异步代码写成同步的是大势所趋。
之前关注过fibjs,也非常看好它。很多小伙伴都有体会,从接触nodejs开始,大部分精力都耗费在如何通过同步的方法来写异步代码上了,现在连js都在语言层面来适应它,实在拧巴。fibjs从底层解决了这个问题,应该是很好的解决思路。有机会一定认真研究下fibjs,把亿书代码用fibjs实现一遍。
感觉又一波可以学
伟大的楼主,是否可以考虑再并行加上一个J2EE的跑分评测结果呀?这样的话,我就能对go, fibjs, nginx, J2EE有一个比较全面的评估了。还是说,J2EE跑分结果太低了,都不合适写到贴子里,再耽误功夫了。
文档感人,如果不把文档完善下的话,我不晓得有什么人敢用
fibjs支持server端的canvas(类似于node-canvas),我的项目里有需求:在后端合成图片。
大脸叔叔很厉害
node 应用范围确实要注意哦,如果国内有商家支持、咱们再给力积攒下生态fibjs 有希望哦;
有点理想化了
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:335956次
积分:4005
积分:4005
排名:第7955名
原创:23篇
转载:438篇
评论:31条
(13)(6)(31)(27)(19)(39)(17)(29)(16)(12)(40)(16)(5)(23)(10)(4)(32)(8)(1)(7)(9)(24)(2)(13)(9)(13)(37)}

我要回帖

更多关于 fibjs nodejs 测试 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信