Trong bài viết này, chúng tôi sẽ so sánh hiệu suất HTTP của ASP.NET Core và Go. Để đạt được sự so sánh công bằng, chúng tôi sẽ sử dụng mô hình kiến trúc MVC trên cả ASP.NET Core và Go.
Go (hay Golang): là một ngôn ngữ lập trình mã nguồn mở đang phát triển nhanh chóng được thiết kế để xây dựng phần mềm đơn giản, nhanh chóng và đáng tin cậy.
Không có nhiều web framework cho Go có hỗ trợ MVC nhưng may mắn cho chúng tôi là Iris đã làm được công việc đó.
Iris: Một micro web framework nhanh chóng, đơn giản và hiệu quả cho Go. Nó cung cấp một nền tảng tuyệt vời và dễ sử dụng cho trang web, API hoặc ứng dụng được phân phối tiếp theo của bạn.
C#: là một ngôn ngữ lập trình hướng đối tượng, đa mục đích chung. Nhóm phát triển của nó được dẫn dắt bởi Anders Hejlsberg.
.NET Core: Phát triển các ứng dụng hiệu suất cao trong thời gian ngắn hơn, trên mọi nền tảng.
Tải xuống Go từ https://golang.org/dl và .NET Core từ https://www.microsoft.com/net/core.
Sau khi bạn tải xuống và cài đặt chúng, bạn sẽ cần cài đặt Iris cho Go. Cài đặt rất dễ dàng, chỉ cần mở thiết bị đầu cuối (cửa sổ dòng lệnh) của bạn và gõ lệnh:
go get -u github.com/kataras/iris
5.000.000 request
- càng nhỏ càng tốt.Cả hai ứng dụng ASP.NET Core và Go sẽ chỉ trả về dữ liệu dạng text khi gọi vào API url “api/values/{id}”.
Được tạo bằng cách sử dụng lệnh dotnet new webapi
. Mẫu webapi
sẽ tạo mã API sẵn cho bạn.
Mã nguồn của API như sau:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace netcore_mvc
{
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace netcore_mvc
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvcCore();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseMvc();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace netcore_mvc.Controllers
{
// ValuesController is the equivalent
// `ValuesController` of the Iris 8.3 mvc application.
[Route("api/[controller]")]
public class ValuesController : Controller
{
// Get handles "GET" requests to "api/values/{id}".
[HttpGet("{id}")]
public string Get(int id)
{
return "value";
}
// Put handles "PUT" requests to "api/values/{id}".
[HttpPut("{id}")]
public void Put(int id, [FromBody]string value)
{
}
// Delete handles "DELETE" requests to "api/values/{id}".
[HttpDelete("{id}")]
public void Delete(int id)
{
}
}
}
Chạy ASP.NET Core web server:
$ cd netcore-mvc
$ dotnet run -c Release
Hosting environment: Production
Content root path: C:\mygopath\src\github.com\kataras\iris\_benchmarks\netcore-mvc
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.
Kết quả benchmark:
$ bombardier -c 125 -n 5000000 http://localhost:5000/api/values/5
Bombarding http://localhost:5000/api/values/5 with 5000000 requests using 125 connections
5000000 / 5000000 [=====================================================] 100.00% 2m3s
Done!
Statistics Avg Stdev Max
Reqs/sec 40226.03 8724.30 161919
Latency 3.09ms 1.40ms 169.12ms
HTTP codes:
1xx - 0, 2xx - 5000000, 3xx - 0, 4xx - 0, 5xx - 0
others - 0
Throughput: 8.91MB/s
Mã nguồn của API như sau:
package main
import (
"github.com/kataras/iris"
"github.com/kataras/iris/_benchmarks/iris-mvc/controllers"
)
func main() {
app := iris.New()
app.Controller("/api/values/{id}", new(controllers.ValuesController))
app.Run(iris.Addr(":5000"), iris.WithoutVersionChecker)
}
package controllers
import "github.com/kataras/iris/mvc"
// ValuesController is the equivalent
// `ValuesController` of the .net core 2.0 mvc application.
type ValuesController struct {
mvc.Controller
}
// Get handles "GET" requests to "api/values/{id}".
func (vc *ValuesController) Get() {
// id,_ := vc.Params.GetInt("id")
vc.Ctx.WriteString("value")
}
// Put handles "PUT" requests to "api/values/{id}".
func (vc *ValuesController) Put() {}
// Delete handles "DELETE" requests to "api/values/{id}".
func (vc *ValuesController) Delete() {}
Chạy Go web server:
$ cd iris-mvc
$ go run main.go
Now listening on: http://localhost:5000
Application started. Press CTRL+C to shut down.
Kết quả benchmark:
$ bombardier -c 125 -n 5000000 http://localhost:5000/api/values/5
Bombarding http://localhost:5000/api/values/5 with 5000000 requests using 125 connections
5000000 / 5000000 [======================================================] 100.00% 47s
Done!
Statistics Avg Stdev Max
Reqs/sec 105643.81 7687.79 122564
Latency 1.18ms 366.55us 22.01ms
HTTP codes:
1xx - 0, 2xx - 5000000, 3xx - 0, 4xx - 0, 5xx - 0
others - 0
Throughput: 19.65MB/s
ASP.NET Core Web API:
Go với Iris MVC:
Trong phần này chúng ta sẽ tiến hành benchmark cho web MVC.
Mã nguồn của Web MVC như sau:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace netcore_mvc_templates
{
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace netcore_mvc_templates
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using netcore_mvc_templates.Models;
namespace netcore_mvc_templates.Controllers
{
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
public IActionResult About()
{
ViewData["Message"] = "Your application description page.";
return View();
}
public IActionResult Contact()
{
ViewData["Message"] = "Your contact page.";
return View();
}
public IActionResult Error()
{
return View(new ErrorViewModel { Title = "Error", Code = 500});
}
}
}
using System;
namespace netcore_mvc_templates.Models
{
public class ErrorViewModel
{
public string Title { get; set; }
public int Code { get; set; }
}
}
Chạy ASP.NET Core web server:
$ cd netcore-mvc-templates
$ dotnet run -c Release
Hosting environment: Production
Content root path: C:\mygopath\src\github.com\kataras\iris\_benchmarks\netcore-mvc-templates
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.
Kết quả benchmark:
$ bombardier -c 125 -n 1000000 http://localhost:5000/home/error
Bombarding http://localhost:5000 with 1000000 requests using 125 connections
1000000 / 1000000 [====================================================] 100.00% 1m20s
Done!
Statistics Avg Stdev Max
Reqs/sec 11738.60 7741.36 125887
Latency 10.10ms 22.10ms 1.97s
HTTP codes:
1xx — 0, 2xx — 1000000, 3xx — 0, 4xx — 0, 5xx — 0
others — 0
Throughput: 89.03MB/s
Mã nguồn của Web MVC như sau:
package controllers
import "github.com/kataras/iris/mvc"
type AboutController struct{ mvc.Controller }
func (c *AboutController) Get() {
c.Data["Title"] = "About"
c.Data["Message"] = "Your application description page."
c.Tmpl = "about.html"
}
package controllers
import "github.com/kataras/iris/mvc"
type ContactController struct{ mvc.Controller }
func (c *ContactController) Get() {
c.Data["Title"] = "Contact"
c.Data["Message"] = "Your contact page."
c.Tmpl = "contact.html"
}
package models
// HTTPError a silly structure to keep our error page data.
type HTTPError struct {
Title string
Code int
}
package controllers
import "github.com/kataras/iris/mvc"
type IndexController struct{ mvc.Controller }
func (c *IndexController) Get() {
c.Data["Title"] = "Home Page"
c.Tmpl = "index.html"
}
package main
import (
"github.com/kataras/iris/_benchmarks/iris-mvc-templates/controllers"
"github.com/kataras/iris"
"github.com/kataras/iris/context"
)
const (
// templatesDir is the exactly the same path that .NET Core is using for its templates,
// in order to reduce the size in the repository.
// Change the "C\\mygopath" to your own GOPATH.
templatesDir = "C:\\mygopath\\src\\github.com\\kataras\\iris\\_benchmarks\\netcore-mvc-templates\\wwwroot"
)
func main() {
app := iris.New()
app.Configure(configure)
app.Controller("/", new(controllers.IndexController))
app.Controller("/about", new(controllers.AboutController))
app.Controller("/contact", new(controllers.ContactController))
app.Run(iris.Addr(":5000"), iris.WithoutVersionChecker)
}
func configure(app *iris.Application) {
app.RegisterView(iris.HTML("./views", ".html").Layout("shared/layout.html"))
app.StaticWeb("/public", templatesDir)
app.OnAnyErrorCode(onError)
}
type err struct {
Title string
Code int
}
func onError(ctx context.Context) {
ctx.ViewData("", err{"Error", ctx.GetStatusCode()})
ctx.View("shared/error.html")
}
Chạy ASP.NET Core web server:
$ cd iris-mvc-templates
$ go run main.go
Now listening on: http://localhost:5000
Application started. Press CTRL+C to shut down.
Kết quả benchmark:
$ bombardier -c 125 -n 1000000 http://localhost:5000/home/error
Bombarding http://localhost:5000 with 1000000 requests using 125 connections
1000000 / 1000000 [======================================================] 100.00% 37s
Done!
Statistics Avg Stdev Max
Reqs/sec 26656.76 1944.73 31188
Latency 4.69ms 1.20ms 22.52ms
HTTP codes:
1xx — 0, 2xx — 1000000, 3xx — 0, 4xx — 0, 5xx — 0
others — 0
Throughput: 192.51MB/s
ASP.NET Core MVC:
Go với Iris MVC:
Bạn có thể vui lòng tắt trình chặn quảng cáo ❤️ để hỗ trợ chúng tôi duy trì hoạt động của trang web.
Trong bài viết này, chúng ta sẽ tìm hiểu cách đặt tên cho các endpoint để có thể tạo liên kết đến chúng từ bất kỳ đâu trong ứng dụng ASP.NET Core.
Trong bài viết này, chúng ta sẽ khám phá Model trong ASP.NET Core và các sub-framework khác như ASP.NET Core MVC, Razor Pages, Endpoints và Blazor.
Bài viết này sẽ giới thiệu cho bạn những điều cơ bản về việc thiết lập một dự án ASP.NET Core để sử dụng các component Svelte phía máy khách.
Bài viết này hướng dẫn cách triển khai một background service trong ứng dụng ASP.NET Core và cách giao tiếp với background service từ một HTTP request.