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個訂單。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM