• Feeds

  • C, Erlang, Java and Go Web Server performance test

    I had tested a hello world web server in C, Erlang, Java and the Go programming language.
    * C, use the well-known high performance web server nginx, with a hello world nginx module
    * Erlang/OTP
    * Java, using the MINA 2.0 framework, now the JBoss Netty framework.
    * Go, http://golang.org/

    1. Test environment

    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 Software version

    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, netty-3.2.0.ALPHA1-dist.tar.bz2
    Go, hg clone -r release https://go.googlecode.com/hg/ $GOROOT (Nov 12, 2009)

    1.3 Source code and configuration

    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);
            }
        }
    }

    Nov 24 update Because the above Mina code doesn’t parse HTTP request and handle the necessary HTTP protocol, replaced with org.jboss.netty.example.http.snoop.HttpServer from Netty example, but removed all the string builder code from HttpRequestHandler.messageReceived() and just return a “hello world” result in HttpRequestHandler.writeResponse(). Please read the source code and the Netty documentation for more information.

    $ taskset -c 1-7 \
    java -server -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(Linux use CPU0 for network interruptions).

    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/
    1000 thread, 334 from 3 different machine
    ab -c 334 -n 334000 http://192.168.10.1:8080/
    5000 thread, 1667 from 3 different machine
    ab -c 1667 -n 334000 http://192.168.10.1:8080/

    2. Test results

    2.1 request per second

    30 (threads) 100 1,000 5,000
    Nginx html(1C) 21,301 21,331 23,746 23,502
    Nginx module(1C) 25,809 25,735 30,380 29,667
    Nginx module(Multi-core) 25,057 24,507 31,544 33,274
    Erlang(1C) 11,585 12,367 12,852 12,815
    Erlang(Multi-Core) 15,101 20,255 26,468 25,865
    Java, Mina2(without HTTP parse)
    30,631 26,846 31,911 31,653
    Java, Netty 24,152 24,423 25,487 25,521
    Go 14,080 14,748 15,799 16,110

    c_erlang_java_go
    2.2 latency, 99% requests within(ms)

    30 100 1,000 5,000
    Nginx html(1C) 1 4 42 3,079
    Nginx module(1C) 1 4 32 3,047
    Nginx module(Multi-core) 1 6 205 3,036
    Erlang(1C) 3 8 629 6,337
    Erlang(Multi-Core) 2 7 223 3,084
    Java, Netty 1 3 3 3,084
    Go 26 33 47 9,005

    3. Notes

    * On large concurrent connections, C, Erlang, Java no big difference on their performance, results are very close.
    * Java runs better on small connections, but the code in this test doesn’t parse the HTTP request header (the MINA code).
    * 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)
    After redo 1,000 and 5,000 tests on Nov 18
    * Nginx module is the winner on 5,000 concurrent requests.
    * Although there is improvement space for Go, Go has the same performance from 30-5,000 threads.
    * Erlang process is impressive on large concurrent request, still as good as nginx (5,000 threads).

    4. Update Log

    Nov 12, change nginx.conf work_connections from 1024 to 10240
    Nov 13, add runtime.GOMAXPROCS(8); to go’s code, add sysctl -p env
    Nov 18, realized that ApacheBench itself is a bottleneck under 1,000 or 5,000 threads, so use 3 clients from 3 different machines to redo all tests of 1,000 and 5,000 concurrent tests.
    Nov 24, use Netty with full HTTP implementation to replace Mina 2 for the Java web server. Still very fast and low latency after added HTTP handle code.

    如想及时阅读Tim Yang的文章,可通过页面右上方扫码订阅最新更新。

    « | »

    124 Comments  »

    1. Graham

      The Go GC probably accounts for much of the difference here. The Go garbage collector, by the language designers own admission, needs some improvements.

      You should easily see 20k+ requests/sec on a quad core cpu with the garbage collector turned off. While running the test with the GC off is not really valid, it does give a clear indication where there is *lots* of room for improvement and does give a hint of what the language ought to be capable off given time to mature.

      You could test this with:

      export GOGC=off && taskset -c 1-7 ./6.out

      I guess you’ll need somewhere between 1-2Gb of system RAM with the GC turned off.

    2. Falcon

      I hope you include node.js in the next version of this fantastically useful performance test.

    3. rivercheng

      The Go program cannot be compiled.
      ‘runtime’ should be imported.
      ‘panic’ only takes one argument now.
      Moreover, now ‘;’s are not necessary.

      You used taskset -c 1-7, but in the code
      runtime.GOMAXPROCS(8); // 8 cores

    4. rivercheng

      The Go program cannot be compiled.
      ‘runtime’ should be imported.
      ‘panic’ only takes one argument now.
      Moreover, the ‘;’s at the end of each statement are not necessary now.

      You used taskset -c 1-7, but in the code
      “runtime.GOMAXPROCS(8); // 8 cores”
      How about chang ‘8’ to ‘7’ too?

    5. victor

      hi timyang, very good article.

      Could tell me which tools do You use to get the results and graphics?

      Thank you very much

      Victor

    6. Tim

      to vcitor:
      excel

    7. Great test. Interesting how well Java stands in these tests. At the level of C performance with much higher level features.

      What would really really make the picture perfect is adding the node.js hello world. (It’s on the front page of http://nodejs.org/). People talk very highly about it’s performance, but I don’t know how it would stack-up to these top speed platforms.

      It probably can’t be faster than compiled Go, and even go is relatively “bad” in this company.

    8. est

      博主牛啊,上Hacker News和reddit了。

    9. Broofa

      +1 for adding node.js to the list here.

    10. Too bad you did not include G-WAN in your test:

      http://gwan.ch/

      Not only G-WAN’s C scripts are much easier to write than the ‘modules’ of other servers, but they execute much faster.

      Here is the (10-line) source code of an hello world sample:

      http://gwan.ch/en_developers.html

      And many other samples (SQL, etc.) are there:

      http://gwan.ch/source/

    11. homi nauter

      Would like to see node.js included!

    12. I saw a test of node.js vs Erlang somewhere else, and in that test node.js had memory leak issues. For me there’s no question, Erlang is better and more reliable then node.js for high load services.

    13. ivictus

      Excellent work.

      Go-lang must stay on improvement way.

    14. Simon

      Tim: I’d love to see run-time memory usage added to the results of the test.

      homi nauter:

      I tested node.js here: http://simonhf.wordpress.com/2010/10/23/node-js-versus-lua-hello-world-postmortem/
      And nginx here: http://simonhf.wordpress.com/2010/10/02/nginx-versus-sxe-hello-world/

    15. I have the same., First miss california sex tape, [url= http://misscaliforniasextapes.fe.pl/ ]First miss california sex tape[/url], 748211,

    16. Nice, Discount jessica simpson sex tape [url=http://jessicasimpsonsextape.fe.pl/#1]Discount jessica simpson sex tape[/url], xgzah,

    17. can you do thi for me, lindsay lohan sex tape [url=http://www.ted.com/profiles/945680#1]lindsay lohan sex tape[/url], blvzx,

    18. Incredible site!, All about lindsay lohan sex tape [url=http://lindsaylohansextape.fe.pl/#1]All about lindsay lohan sex tape[/url], mtyb,

    19. Ryan

      Node.js = cancer. If you use that piece of crap for any sizable project you have much bigger problems than performance.

    20. fjjiaboming

      unfair test .
      Web Containers are few .

    21. C, Erlang, Java and Go Web Server performance test – Tim[后端技术] I was recommended this blog by my cousin. I’m not sure whether this post is written by him as no one else know such detailed about my difficulty. You are incredible! Thanks! your article about C, Erlang, Java and Go Web Server performance test – Tim[后端技术]Best Regards Shane

    22. Malix

      Interesting comparison. Can you rerun it now that Go get a new GC?

    23. EML

      Very interested in seeing updated Go performance!

    24. Ege

      I use node.js in a project with 15k lines of code. It’s mature (even though it still didn’t reach v1) and definitely fast. I think it’s one of the best things happened to web development.

    25. yihex

      我想golang 你需要重新测试一下了。性能超高!

    26. Everyone loves what you guys are usually up too. This kind of clever work and exposure!
      Keep up the awesome works guys I’ve you guys to our blogroll.

    27. xbkgpdjwgkgyqjtjzxtcb

    28. Hey there just wanted to give you a quick heads up.
      The text in your article sem to be running off the screen in Firefox.
      I’m not suree if this is a formatting issue or something tto do with internet browser compatibility but I
      figured I’d post to let you know. The design annd style look
      great though! Hope you geet the problem fixed soon. Many
      thanks

    29. Michelreacy

      Имеется такая услуга – добровольное медицинское обслуживание (или ДМО).
      Она предполагает, что пациент вносит небольшую сумму за то, что ходит на прием целый год бесплатно.
      Однако соцопросы показали, что лишь 3% жителей Санкт-Петербурга знают о такой программе.
      Почему?
      Да потому что частным клиникам намного выгодней брать плату за каждое посещение.
      А если какой-нибудь сотрудник клиники попытается посоветовать добровольное медицинское обслуживание клиенту – это сулит ему увольнением.
      Эта информация уже вызвала множество возмущений, сразу после того как информацию об этом распространил один врач.
      Его уволили “по собственному желанию”, после того, как он предложил ДМО постоянному клиенту.
      Самое страшное, что официальные положения по ДМО находились в открытом доступе, просто находили на эту информацию только случайные люди.
      Как отстоять свои права?
      О правилах предоставления услуги и обязанностях частных клиник можно узнать, сделав запрос в Яндексе: “добровольное медицинское обслуживание”.
      Обязательно обслуживание, а не страхование.

      34j5c6h86

    30. It’s not my first time to pay a quick visit this website,
      i am browsing this site dailly and get pleasant facts from
      here daily.

    31. Thanks foor any other great post. The place else
      may anyone get that tyle of info in such a perfect method of writing?

      I have a presentation next week, and I am at the look
      for such info.

    32. Amazing! Itts truly amazing piece of writing, I have got much clear idea regarding
      from this piece of writing.

    33. this tips has help me so much as i still new learn the coding, thanks
      my site run 3 unblocked

    34. i’ve found this articles while searching on goole. This tricks have lot of helpful for me thanks. cool math games run 3

    35. i though this article is very good, we can learn this tips very help us, thanks girly wallpapers

    36. Thanks for youyr marvelous posting! I certainly enjoyed reading it, you happen to be a great author.
      I will be sure to bookmark your blog and will often come back in the
      future. I want to encourage you to ultimately continue your great posts, have a nice
      weekend!

    37. Great information. Lucky me I ran across your site by chance (stumbleupon).

      I have bookmarked it for later!

    38. This post was extremely interesting, particularly because I was looking for thoughts on this topic last week.

    39. Great website, Love it!
      Interesting stats.

    40. I can’t wait for new Cyber Punk, did you know that it was card game 30 years ago?

    41. Like where’s the rush? Wait little bit, we will find fix for your problem, I promise.

    42. I love to watch different short animation movies, sometimes they are sad, and sometimes they are funny…

    43. https://paknice.com/ is a Free Classified Website in Pakistan you’ll Unlimited Ads With Images
      For FREE it’s Easy And prevent Will Reach an outsized Public everywhere Pakistan And
      Save Mony,
      FIND All You Need: Services,Job,Property,Mobile,Laptops,Computer,MotorBike,Furniture,
      Vehicles,jewelry,Gifts,Clothes,Footwear,And Many Other Ads,,

      Why do you have to Post Your Free Ad in Paknice.com/
      Post Unlimited Ads you’ll Put Images it’s 100% FREE Buy And Sell
      Locally Within Citys At a Communtiy Level Share Your Ads ON Social Media Network
      Access the location From Your mobile Easily

    44. Lexy

      I’m satisfied with JAVA’s scripts that i’m using at http://www.drywallwinstonsalem.com. All the best!

    45. Teak Furniture Malaysia operates as a specialist importer of best quality Furniture shop Malaysia solid wood furniture, indoor furniture, Garden Furniture and outdoor furniture . Visit Our Showroom Kuala Lumpur KL and Shah Alam Selangor Malaysia.

    46. Scade Concepts Furniture Manufacturers Indonesia offers Indonesia furniture, exporter of indoor furniture and outdoor furniture for project, decorative lighting, home decor, and craft with retail & wholesale prices. Because Our high-quality furniture products for homes, restaurant, resorts, villas, apartments, hospitality, private house, and hotel projects furniture manufacturers Indonesia. We are Teak Outdoor Furniture Manufacturers and Teak Indoor Furniture Manufacturers.

    47. order now SEO Backlinks Services

    Leave a Comment