iris(go)和.netcore的web速度测试和对比

近期在开发一个抢口罩的系统,类似于电商常见的秒杀系统。当时选型的的时候准备在netcore和golang之间选择一个作为系统的开发语言,网上的说法各异,有的说iris快,有的说.netcore快。于是决定自己做下测试。

iris在go的web开发框架中是非常流行的,它自己的介绍是最快的go语言web框架,这个肯定有一家之言的成分,但是说它是最快的go框架之一肯定没有问题。使用的iris的版本是12.1.8

aspnetcore 就是微软在.netcore中开发的标准框架,不需要用到其他第三方框架。这里使用的.netcore版本是3.0

iris的代码为:

// package main

// import "github.com/gin-gonic/gin"

// func main() {
// 	r := gin.Default()
// 	r.GET("/ping", func(c *gin.Context) {
// 		c.JSON(200, gin.H{
// 			"message": "pong",
// 		})
// 	})
// 	r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
// }

package main

import (
	"github.com/kataras/iris"
	"github.com/kataras/iris/context"

	//"strings"
	"math/rand"
)

const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 "

func randomString(n int) string {
	b := make([]byte, n)
	for i := range b {
		b[i] = letterBytes[rand.Intn(len(letterBytes))]
	}
	return string(b)
}

func main() {
	app := iris.New()

	//txt := strings.Repeat("g", 10000)
	app.Get("/api/values/{id}", func(ctx context.Context) {
		txt := randomString(1024)
		ctx.WriteString(txt)
	})

	app.Run(iris.Addr(":5000"))
}

aspnetcore的代码为:(吐槽一下,微软整的代码太多,让人有点添堵)

public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseKestrel(options =>
                    {
                        options.Listen(IPAddress.Any, 5080); //HTTP port
                    });
                    webBuilder.UseStartup<Startup>();
                }).ConfigureLogging(a => a.SetMinimumLevel(LogLevel.None));
    }
public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
        }
        const string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ";

        static string RandomString(int length)
        {
            var random = new Random(DateTime.Now.Millisecond);
            var bytes = new Char[length];
            for (var i = 0; i < length; i++)
            {
                bytes[i] = chars[random.Next(chars.Length)];
            }
            return new string(bytes);
        }
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGet("/", async context =>
                {
                    var txt = RandomString(1024);
                    await context.Response.WriteAsync(txt);
                    // await context.Response.WriteAsync("Hello World!");
                });
            });
        }
    }

windows下的测试:

iris: 通过 go build 进行编译,然后运行。启用 bombardier测试。结果如下

bombardier.exe -c 50 -n 300000 http://localhost:5000/api/values/id

Bombarding http://localhost:5000/api/values/id with 300000 request(s) using 50 connection(s)
300000 / 300000 [=================================================================================] 100.00% 8798/s 34s
Done!
Statistics Avg Stdev Max
Reqs/sec 8860.00 1065.69 38087.60
Latency 5.65ms 187.86us 31.91ms
HTTP codes:
1xx - 0, 2xx - 300000, 3xx - 0, 4xx - 0, 5xx - 0
others - 0
Throughput: 10.27MB/s

aspnetcore: dotnet publish -c Release 编译。结果如下

Bombarding http://localhost:5080 with 300000 request(s) using 50 connection(s)
300000 / 300000 [=================================================================================] 100.00% 34749/s 8s
Done!
Statistics Avg Stdev Max
Reqs/sec 35283.26 6100.68 45069.66
Latency 1.41ms 8.08ms 1.06s
HTTP codes:
1xx - 0, 2xx - 300000, 3xx - 0, 4xx - 0, 5xx - 0
others - 0
Throughput: 40.35MB/s

结果让人大跌眼镜。.netcore比iris 的qps快了4倍以上。(注意上面代码,我移除了.netcore的日志)

因为是windows平台的结果,我怀疑go语言在windows没有优化,所以后来加入了linux amd64的测试

iris: 发布成linux单文件 SET GOOS=linux SET GOARCH=amd64 go build. 拷贝到debian 10(vmware在本地搭建的虚拟机)上执行。(这个夸一下,go编译的结果非常小巧,方便携带)

Bombarding http://192.168.236.131:5000/api/values/id with 300000 request(s) using 50 connection(s)
300000 / 300000 [=================================================================================] 100.00% 8176/s 36s
Done!
Statistics Avg Stdev Max
Reqs/sec 8179.10 677.17 11293.41
Latency 6.11ms 757.13us 51.84ms
HTTP codes:
1xx - 0, 2xx - 300000, 3xx - 0, 4xx - 0, 5xx - 0
others - 0
Throughput: 9.55MB/s

结果和windows下面差不多,可能是应该在vm中跑,性能有稍微的损失。

aspnetcore: 发布成linux单文件 dotnet publish -r linux-x64 -c Release /p:PublishSingleFile=true .(这里说一下,这个文件有95M,有点大,不过还能接收),执行结果如下

Bombarding http://192.168.236.131:5080 with 300000 request(s) using 50 connection(s)
300000 / 300000 [================================================================================] 100.00% 17002/s 17s
Done!
Statistics Avg Stdev Max
Reqs/sec 17078.01 1997.18 20679.28
Latency 2.93ms 267.95us 31.91ms
HTTP codes:
1xx - 0, 2xx - 300000, 3xx - 0, 4xx - 0, 5xx - 0
others - 0
Throughput: 19.62MB/s

结果比在windows下面大幅下滑,不过还是比iris高了2倍多。

结论:

  • 微软在.netcore上的性能优化不留余地,尤其是在windows平台上,可能也是为了显示windows平台还是有优势的:)
  • .netcore, go ,java 总体性能上是一个数量级的,相互之间不可能差距太多。但是在当前的测试中,.netcore略微领先于其他的两门语言
  • go语言有一些其他优势,比如内存占用低(这次的测试大于占19M内存,.netcore占用54M),打包方便,容易入门等。(C#的语言花样有点多,初学者学习曲线长)
  • 这里只是记录下测试的结果,并无比较说明孰优孰劣的意思。当然后来我们选用了.netcore,确实秒杀结果令人满意,一秒能出去近1000个订单。

猜你喜欢

转载自www.cnblogs.com/robertAlexAmy/p/12321244.html