Nginx openresty web服务 与 Go 原生web服务性能对比

1 概述

Nginx采用的是IO复用模型,能处理超高并发。

Go语言采用协程,能轻量级的处理超高并发。

那么在不考虑业务逻辑复杂的前提下,即假如将Nginx和Go都提供一个/test接口,并在接口逻辑中都只是让其做20毫秒的耗时操作,那么这两者的性能差异大概是多少呢?尝试一下

2 环境说明

Centos 服务器环境说明:

3 源代码

3.1 go

复制代码
package main

import (
  "net/http"
  "time"
  "log"
)

func handler(w http.ResponseWriter, r *http.Request) {
  // 模拟 20ms 业务处理
  time.Sleep(20 * time.Millisecond)
  w.Write([]byte("OK"))
}

func main() {
  http.HandleFunc("/test", handler)
  log.Println("Go server listening on :8080")
  if err := http.ListenAndServe(":8080", nil); err != nil {
    log.Fatal(err)
  }
}

3.2 nginx openresty

复制代码
worker_processes  auto;
events {
  worker_connections 10240;
}

http {
  # 如果你原来有其它配置项(如 log_format、lua_shared_dict 等),保留它们
  
  server {
    listen 8081;
    location = /test {
      content_by_lua_block {
        -- 模拟 20 ms 业务处理
        ngx.sleep(0.02)
        ngx.say("OK")
      }
    }
  }
}

4 启动服务

go服务启动端口为8080

nginx openresty 服务启动端口为8081

5 ab工具压测

5.1 第一轮:100并发共请求1万次

go:

ab -n 10000 -c 100 http://127.0.0.1:8080/

复制代码
Concurrency Level:      100
Time taken for tests:   2.134 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Non-2xx responses:      10000
Total transferred:      1760000 bytes
HTML transferred:       190000 bytes
Requests per second:    4685.38 [#/sec] (mean)
Time per request:       21.343 [ms] (mean)
Time per request:       0.213 [ms] (mean, across all concurrent requests)
Transfer rate:          805.30 [Kbytes/sec] received

nginx:

复制代码
Concurrency Level:      100
Time taken for tests:   3.322 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      1288900000 bytes
HTML transferred:       1286460000 bytes
Requests per second:    3010.62 [#/sec] (mean)
Time per request:       33.216 [ms] (mean)
Time per request:       0.332 [ms] (mean, across all concurrent requests)
Transfer rate:          378944.26 [Kbytes/sec] received

小结:100并发情况下,go的QPS为4685,nginx的qps为3010

5.2 第二轮:500并发共请求5万次

ab -n 50000 -c 500 http://127.0.0.1:8080/

go:

复制代码
Concurrency Level:      500
Time taken for tests:   8.483 seconds
Complete requests:      50000
Failed requests:        0
Write errors:           0
Non-2xx responses:      50000
Total transferred:      8800000 bytes
HTML transferred:       950000 bytes
Requests per second:    5893.87 [#/sec] (mean)
Time per request:       84.834 [ms] (mean)
Time per request:       0.170 [ms] (mean, across all concurrent requests)
Transfer rate:          1013.01 [Kbytes/sec] received

nginx:

复制代码
Concurrency Level:      500
Time taken for tests:   18.526 seconds
Complete requests:      50000
Failed requests:        0
Write errors:           0
Total transferred:      6444500000 bytes
HTML transferred:       6432300000 bytes
Requests per second:    2698.86 [#/sec] (mean)
Time per request:       185.264 [ms] (mean)
Time per request:       0.371 [ms] (mean, across all concurrent requests)
Transfer rate:          339702.78 [Kbytes/sec] received

奇怪,为什么500并发情况下,go的QPS有5893,而Nginx只有2698

5.3 第三轮:1000并发共请求10万次

go:

复制代码
Concurrency Level:      1000
Time taken for tests:   21.770 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Non-2xx responses:      100000
Total transferred:      17600000 bytes
HTML transferred:       1900000 bytes
Requests per second:    4593.43 [#/sec] (mean)
Time per request:       217.702 [ms] (mean)
Time per request:       0.218 [ms] (mean, across all concurrent requests)
Transfer rate:          789.50 [Kbytes/sec] received

nginx:

复制代码
Concurrency Level:      1000
Time taken for tests:   39.272 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Total transferred:      12889000000 bytes
HTML transferred:       12864600000 bytes
Requests per second:    2546.37 [#/sec] (mean)
Time per request:       392.715 [ms] (mean)
Time per request:       0.393 [ms] (mean, across all concurrent requests)
Transfer rate:          320509.78 [Kbytes/sec] received

1000并发下,go的QPS有4593,nginx的QPS只有2546

6 小结

1.在如上配置的服务器环境+配置(注意:Nginx的配置应该可以一定程度上进行调优,这里暂时先不测试了)的情况下

2.go和nginx都提供一个/test的接口,且耗时都是在固定20秒的情况下

3.1000并发请求是,go的QPS为4.5k左右,nginx的QPS大概为2.5k左右。

7 临时想到的Python和Java

7.1 Python3.6

既然看到了go语言的情况,自然又要拿出我们的老朋友python来测试一下了:

复制代码
import asyncio
from aiohttp import web

async def handler(request):
    # 模拟 20 毫秒的耗时操作
    await asyncio.sleep(0.02)
    return web.Response(text="OK")

app = web.Application()
app.router.add_get('/test', handler)

if __name__ == '__main__':
    web.run_app(app, host='0.0.0.0', port=8080)

在经过了漫长的等待:故障了!

所以决定将并发控制在200,总请求数控制在20000

复制代码
Concurrency Level:      200
Time taken for tests:   52.494 seconds
Complete requests:      20000
Failed requests:        0
Write errors:           0
Non-2xx responses:      20000
Total transferred:      3440000 bytes
HTML transferred:       280000 bytes
Requests per second:    381.00 [#/sec] (mean)
Time per request:       524.941 [ms] (mean)
Time per request:       2.625 [ms] (mean, across all concurrent requests)
Transfer rate:          64.00 [Kbytes/sec] received

从这里来看python3.6的QPS大概是381(注意!应该是有调优空间的,且每个接口中耗时20毫秒)

7.2 java1.8

复制代码
import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpExchange;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;

public class SimpleHttpServer {
    public static void main(String[] args) throws IOException {
        // 创建 HTTP 服务器,监听端口 8080
        HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);
        // 创建上下文,处理 /test 路径的请求
        server.createContext("/test", new MyHandler());
        // 设置默认的执行器
        server.setExecutor(null);
        // 启动服务器
        server.start();
        System.out.println("Java HTTP server started on port 8080");
    }

    static class MyHandler implements HttpHandler {
        @Override
        public void handle(HttpExchange exchange) throws IOException {
            try {
                // 模拟 20 毫秒的耗时操作
                Thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            String response = "OK";
            exchange.sendResponseHeaders(200, response.length());
            OutputStream os = exchange.getResponseBody();
            os.write(response.getBytes());
            os.close();
        }
    }
}

200并发2万请求试试:3171

复制代码
Concurrency Level:      200
Time taken for tests:   6.306 seconds
Complete requests:      20000
Failed requests:        0
Write errors:           0
Non-2xx responses:      20000
Total transferred:      2420000 bytes
HTML transferred:       1000000 bytes
Requests per second:    3171.68 [#/sec] (mean)
Time per request:       63.058 [ms] (mean)
Time per request:       0.315 [ms] (mean, across all concurrent requests)
Transfer rate:          374.78 [Kbytes/sec] received

1000并发10万请求试试:5271

复制代码
Concurrency Level:      1000
Time taken for tests:   18.969 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Non-2xx responses:      100000
Total transferred:      12100000 bytes
HTML transferred:       5000000 bytes
Requests per second:    5271.80 [#/sec] (mean)
Time per request:       189.688 [ms] (mean)
Time per request:       0.190 [ms] (mean, across all concurrent requests)
Transfer rate:          622.94 [Kbytes/sec] received

8 总结

1.go1.20 QPS 4.5k左右

2.nginx QPS 2.5k左右

3.python3.6 QPS 381左右

4.java1.8 QPS 5.2k左右

难不成是我测试的有问题?怎么java比go的QPS居然还要高?(有可能是调优问题+环境问题,go语言的性能可能在更高配置的环境下可能性能更高)该数据仅供参考

相关推荐
Hello.Reader28 分钟前
基于 Nginx 的 WebSocket 反向代理实践
运维·websocket·nginx
我的golang之路果然有问题2 小时前
案例速成GO+redis 个人笔记
经验分享·redis·笔记·后端·学习·golang·go
大鹏dapeng4 小时前
使用gonectr操作gone项目,包括:创建项目、安装依赖、生成代码、编译和运行
后端·go·github
pedestrian_h4 小时前
gin框架学习笔记
笔记·学习·go·web·gin
ak啊5 小时前
Nginx 常见问题总结与解决
nginx
朱颜辞镜花辞树‎6 小时前
关于GoWeb(1)
go·web
纪元A梦6 小时前
华为OD机试真题——绘图机器(2025A卷:100分)Java/python/JavaScript/C++/C/GO最佳实现
java·javascript·c++·python·华为od·go·华为od机试题
异常君8 小时前
Nginx 架构深度剖析:多进程单线程模型与异步事件驱动
后端·nginx·架构
java1234_小锋9 小时前
什么是Lua模块?你会如何使用NGINX的Lua模块来定制请求处理流程?
开发语言·nginx·lua