阅读更多

17顶
1踩

编程语言

转载新闻 C, Erlang, Java, Go 语言的Web Server 性能测试

2009-11-18 12:42 by 资深编辑 wutao0603 评论(17) 有19620人浏览

 

对C, Erlang, Java and the Go 编程语言的Hello world web服务进行了测试 .


* C, 使用高性能的web server-nginx,以及一个 hello world 的nginx模块
* Erlang/OTP
* Java, 使用MINA 2.0框架.
* Go, http://golang.org/

1. 测试环境

1.1 Hardware/OS

2 Linux boxes in a gigabit ethernet LAN, 1 server and 1 test client
Linux Centos 5.2 64bit
Intel(R) Xeon(R) CPU E5410  @ 2.33GHz (L2 cache: 6M), Quad-Core * 2
8G memory
SCSI disk (standalone disk, no other access)

1.2 软件版本

nginx, nginx-0.7.63.tar.gz
Erlang, otp_src_R13B02-1.tar.gz
Java, jdk-6u17-linux-x64.bin, mina-2.0.0-RC1.tar.gz
Go, hg clone -r release https://go.googlecode.com/hg/ $GOROOT (Nov 12, 2009)

1.3 源代码及配置

Linux, run sysctl -p

net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
kernel.panic = 1
net.ipv4.tcp_rmem = 8192	873800	8738000
net.ipv4.tcp_wmem = 4096	655360	6553600
net.ipv4.ip_local_port_range = 1024	65000
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216

# ulimit -n
150000

C: ngnix hello world module, copy the code ngx_http_hello_module.c from http://timyang.net/web/nginx-module/

in nginx.conf, set “worker_processes  1; worker_connections 10240″ for 1 cpu test, set “worker_processes  4; worker_connections 2048″ for multi-core cpu test. Turn off all access or debug log in nginx.conf, as follows

worker_processes  1;
worker_rlimit_nofile 10240;
events {
    worker_connections  10240;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  0;
    server {
        listen       8080;
        server_name  localhost;
        location / {
            root   html;
            index  index.html index.htm;
        }
          location /hello {
            ngx_hello_module;
            hello 1234;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

$ taskset -c 1 ./nginx or $ taskset -c 1-7 ./nginx

Erlang hello world server
The source code is available at yufeng’s blog, see http://blog.yufeng.info/archives/105
Just copy the code after “cat ehttpd.erl”, and compile it.

$ erlc ehttpd.erl
$ taskset -c 1 erl +K true +h 99999 +P 99999 -smp enable +S 2:1 -s ehttpd
$ taskset -c 1-7 erl +K true -s ehttpd


We use taskset to limit erlang vm to use only 1 CPU/core or use all CPU cores. The 2nd line is run in single CPU mode, and the 3rd line is run in multi-core CPU mode.

Java source code, save the 2 class as HttpServer.java and HttpProtocolHandler.java, and do necessary import.

public class HttpServer {
    public static void main(String[] args) throws Exception {
        SocketAcceptor acceptor = new NioSocketAcceptor(4);
        acceptor.setReuseAddress( true );

		int port = 8080;
		String hostname = null;
		if (args.length > 1) {
			hostname = args[0];
			port = Integer.parseInt(args[1]);
		}

        // Bind
        acceptor.setHandler(new HttpProtocolHandler());
        if (hostname != null)
        	acceptor.bind(new InetSocketAddress(hostname, port));
        else
        	acceptor.bind(new InetSocketAddress(port));

        System.out.println("Listening on port " + port);
        Thread.currentThread().join();
    }
}

public class HttpProtocolHandler extends IoHandlerAdapter {
    public void sessionCreated(IoSession session) {
        session.getConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
        session.setAttribute(SslFilter.USE_NOTIFICATION);
    }

    public void sessionClosed(IoSession session) throws Exception {}
    public void sessionOpened(IoSession session) throws Exception {}
    public void sessionIdle(IoSession session, IdleStatus status) {}
    public void exceptionCaught(IoSession session, Throwable cause) {
        session.close(true);
    }

    static IoBuffer RESULT = null;
	public static String HTTP_200 = "HTTP/1.1 200 OK\r\nContent-Length: 13\r\n\r\n" +
			"hello world\r\n";
	static {
    	RESULT = IoBuffer.allocate(32).setAutoExpand(true);
    	RESULT.put(HTTP_200.getBytes());
    	RESULT.flip();
    }
    public void messageReceived(IoSession session, Object message)
            throws Exception {
        if (message instanceof IoBuffer) {
        	IoBuffer buf = (IoBuffer) message;
        	int c = buf.get();
        	if (c == 'G' || c == 'g') {
        		session.write(RESULT.duplicate());
        	}
        	session.close(false);
        }
    }
}

$ taskset -c 1-7 \
java -Xmx1024m -Xms1024m -XX:+UseConcMarkSweepGC -classpath . test.HttpServer 192.168.10.1 8080

 

We use taskset to limit java only use cpu1-7, and not use cpu0, because we want cpu0 dedicate for system call.

Go language, source code

package main
import (
   "http";
    "io";
)
func HelloServer(c *http.Conn, req *http.Request) {
    io.WriteString(c, "hello, world!\n");
}
func main() {
     runtime.GOMAXPROCS(8); // 8 cores
     http.Handle("/", http.HandlerFunc(HelloServer));
     err := http.ListenAndServe(":8080", nil);
    if err != nil {
        panic("ListenAndServe: ", err.String())
    }
}

$ 6g httpd2.go
$ 6l httpd2.6
$ taskset -c 1-7 ./6.out

1.4 Performance test client

ApacheBench client, for 30, 100, 1,000, 5,000 concurrent threads
ab -c 30 -n 1000000 http://192.168.10.1:8080/
ab -c 100 -n 1000000 http://192.168.10.1:8080/
ab -c 1000 -n 1000000 http://192.168.10.1:8080/
ab -c 5000 -n 1000000 http://192.168.10.1:8080/

2. 测试结果

2.1 request per second

  30 (threads) 100 1000 5000
Nginx html(1C) 21,301 21,331 17,803 11,901
Nginx module(1C) 25,809 25,735 17,562 12,412
Nginx module(Multi-core) 25,057 24,507 18,110 11,681
Erlang(1C) 11,585 12,367 12,185 10,200
Erlang(Multi-Core) 15,101 20,255 18,687 11,613
Java, Mina2 30,631 26,846 18,134 11,945
Go 14,080 14,748 13,292 7,754

c_erlang_java_go
2.2 latency, 99% requests within(ms)

  30 100 1,000 5,000
Nginx html(1C) 1 4 69 504
Nginx module(1C) 1 4 73 502
Nginx module(Multi-core) 1 6 70 501
Erlang(1C) 3 8 3,023 1,874
Erlang(Multi-Core) 2 7 73 495
Java, Mina2 3 5 67 501
Go 26 33 3,006 9,059

3. Notes

* On large concurrent connections, C, Erlang, Java no big difference on their performance, all are about 18k/s (1,000 threads) .
* Java runs better on small connections, but the code in this test doesn’t parse the HTTP request header.
* Although Mr. Yu Feng (the Erlang guru in China) mentioned that Erlang performance better on single CPU(prevent context switch), but the result tells that Erlang has big latency(> 1S) under 1,000 or 5,000 connections.
* Go language is very close to Erlang, but still not good under heavy load (5,000 threads)

 

查看原文:http://timyang.net/programming/c-erlang-java-performance/

17
1
评论 共 17 条 请登录后发表评论
17 楼 witeman 2011-02-27 15:02
我看了一下Yu Feng的代码,里面用到了io:format。为了公平起见,请去掉所有的不必要的io:format。因为这个调用现在在Erlang里面,公认的是比较慢的。会影响整体Erlang的性能。

原因请参考:
"Eventually I came to believe that Erlang’s I/O library is very slow and that that might be the reason for its sub-optimal performance in the benchmarks above."

http://muharem.wordpress.com/2007/07/31/erlang-vs-stackless-python-a-first-benchmark/
16 楼 witeman 2011-02-27 14:55
Request Per Second的图标有问题。

在5000Threads的时候,Erlang(1Core)应该比Go要多,而且,和其他的区别不大,可是,怎么图标上看上去和别的对比起来是少了一半左右的?
15 楼 Stero 2010-01-21 03:50
测试服务器端,就一定要确保让服务器端成为瓶颈,而客户端和网络非饱和。

高并发的情况下,ab本身就是瓶颈。用更好的机器跑ab,用两台机器一起跑ab。用10G网卡来连接网络。
14 楼 fsword 2009-12-10 14:16
redsea 写道
还有, 根据以往的经验, ab client 方的连接数目大于 3000 以上的, 就要看看 ab client 的 cpu 使用了, 我在测试中, 经常发现的是 ab client 的 cpu 消耗比 nginx 高得多.

你测试性能都在本机进行?
13 楼 olive009 2009-11-22 17:44
      
12 楼 rain2005 2009-11-19 12:51
呵呵,一般情况下java就够用了,关键是开发速度和可读性比较好。
11 楼 CharlesCui 2009-11-19 11:51
gqf2008 写道
这种比较没有实质意义,没有一种语言是万能的,关键是选择合适的语言做合适的事情


说到点子上了,语言这东西学来学去没意义,知道了算法,会一种高效的语言,之后设计出来的东东对客户来说足够足够了.
作为一个老板更不会关心你用什么语言.

跟买车一样,买的时候挑来挑去,总在比较,没意义.合适就好!
10 楼 sleets 2009-11-19 11:00
GOMAXPROCS设置了,在多核下比libevent还强一点。

9 楼 gqf2008 2009-11-19 09:24
这种比较没有实质意义,没有一种语言是万能的,关键是选择合适的语言做合适的事情
8 楼 linux1689 2009-11-19 08:39
Arden 写道
erlang号称是高并发,go号称最快的系统开发语言,看来都是吹出来的~~


Erlang支持高并发,但是是有是有条件的。
7 楼 redsea 2009-11-19 08:20
还有, 根据以往的经验, ab client 方的连接数目大于 3000 以上的, 就要看看 ab client 的 cpu 使用了, 我在测试中, 经常发现的是 ab client 的 cpu 消耗比 nginx 高得多.
6 楼 redsea 2009-11-19 08:18
nginx 的 log 都没有关掉啊.
5 楼 skzr.org 2009-11-19 07:31
Arden 写道
erlang号称是高并发,go号称最快的系统开发语言,看来都是吹出来的~~


同意,我一直觉得java的server还是很不错的选择!应付大多数应用应该足够了
4 楼 gakaki 2009-11-18 23:06
那么比的是什么 开发平台 开发的便利 和开发的速度
3 楼 gakaki 2009-11-18 23:06
他们都是用C开发出来的 想单纯超越C几乎是不可能的

除非直接写汇编然后汇编上写语言 java和.net是用了虚拟机

2 楼 wangxinpier 2009-11-18 19:15
java还不错,呵呵
1 楼 Arden 2009-11-18 17:14
erlang号称是高并发,go号称最快的系统开发语言,看来都是吹出来的~~

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

Global site tag (gtag.js) - Google Analytics