Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Redis

การเพิ่มประสิทธิภาพและความสามารถในการปรับขนาดสูงสุดใน ASP.NET Core:กลยุทธ์ที่ได้รับการพิสูจน์แล้ว

ASP.NET Core เป็นเฟรมเวิร์กข้ามแพลตฟอร์มแบบโอเพ่นซอร์สที่ทันสมัย ออกแบบมาเพื่อสร้างเว็บแอปพลิเคชันประสิทธิภาพสูงและปรับขนาดได้ ตั้งแต่ไมโครเซอร์วิสไปจนถึง API ระดับองค์กร สถาปัตยกรรมทำให้มั่นใจได้ว่านักพัฒนาจะได้รับปริมาณงานที่ยอดเยี่ยม เวลาแฝงที่น้อยที่สุด และการใช้ทรัพยากรอย่างมีประสิทธิภาพ

ในบทความนี้ เราจะสำรวจกลยุทธ์หลัก เคล็ดลับการกำหนดค่า และส่วนย่อยโค้ดเพื่อเพิ่มประสิทธิภาพและความสามารถในการปรับขนาดสูงสุดในแอปพลิเคชัน ASP.NET Core ของคุณ

🚀 ทำความเข้าใจประสิทธิภาพและความสามารถในการขยายขนาด

ก่อนที่จะเริ่มนำไปปฏิบัติ เรามานิยามแนวคิดสำคัญสองประการก่อน:

  • ประสิทธิภาพ :แอปพลิเคชันของคุณตอบสนองต่อคำขอเดียวได้เร็วแค่ไหน
    (ตัวอย่าง:การลดเวลาตอบสนองจาก 300ms เป็น 100ms)

  • ความสามารถในการขยายขนาด :แอปพลิเคชันของคุณรองรับโหลดที่เพิ่มขึ้นได้ดีเพียงใด
    (ตัวอย่าง:การจัดการผู้ใช้พร้อมกัน 10,000 รายโดยไม่ขัดข้อง)

ASP.NET Core บรรลุทั้งผ่านการจัดการหน่วยความจำที่มีประสิทธิภาพ การเขียนโปรแกรมแบบอะซิงโครนัส การฉีดการขึ้นต่อกัน การแคช และการสนับสนุนในตัวสำหรับระบบแบบกระจาย

การเพิ่มประสิทธิภาพและความสามารถในการปรับขนาดสูงสุดใน ASP.NET Core:กลยุทธ์ที่ได้รับการพิสูจน์แล้ว

⚙️ การใช้การเขียนโปรแกรมแบบอะซิงโครนัส

รันไทม์ ASP.NET Core ได้รับการปรับให้เหมาะสมสำหรับ การดำเนินการ I/O แบบอะซิงโครนัส . โดยใช้ 00 และ 12 คำหลัก คุณสามารถเพิ่มเธรดเพื่อรองรับคำขอเพิ่มเติมพร้อมกันได้

✅ ตัวอย่าง:การดำเนินการของคอนโทรลเลอร์แบบอะซิงโครนัส

 
 [ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
 private readonly IProductService _productService;
 public ProductsController(IProductService productService)
 {
 _productService = productService;
 }
 [HttpGet("{id}")]
 public async Task<IActionResult> GetProductById(int id)
 {
 var product = await _productService.GetProductAsync(id);
 if (product == null)
 return NotFound();
 return Ok(product);
 }
}
 

โดยใช้ 25 เธรดจะไม่บล็อกในขณะที่รอการดำเนินการ I/O-bound เช่น การสืบค้นฐานข้อมูลหรือการเรียก API สิ่งนี้ช่วยเพิ่มความสามารถในการปรับขนาดได้อย่างมากภายใต้ภาระงานหนัก

🧩 เพิ่มประสิทธิภาพไปป์ไลน์มิดเดิลแวร์

ส่วนประกอบมิดเดิลแวร์จัดการแต่ละคำขอตามลำดับ รักษามิดเดิลแวร์ของคุณให้มีน้ำหนักเบาและหลีกเลี่ยงการประมวลผลที่ไม่จำเป็น

✅ ตัวอย่าง:มิดเดิลแวร์น้ำหนักเบาแบบกำหนดเอง

 
 public class RequestTimingMiddleware
{
 private readonly RequestDelegate _next;
 private readonly ILogger<RequestTimingMiddleware> _logger;
 public RequestTimingMiddleware(RequestDelegate next, ILogger<RequestTimingMiddleware> logger)
 {
 _next = next;
 _logger = logger;
 }
 public async Task InvokeAsync(HttpContext context)
 {
 var start = DateTime.UtcNow;
 await _next(context);
 var elapsed = DateTime.UtcNow - start;
 _logger.LogInformation($"Request took {elapsed.TotalMilliseconds} ms");
 }
}
// Registration in Program.cs
app.UseMiddleware<RequestTimingMiddleware>();
 

👉 เคล็ดลับ ::
วางมิดเดิลแวร์น้ำหนักเบาไว้ที่ด้านบนสุด (เช่น การกำหนดเส้นทางหรือการบีบอัด) และมิดเดิลแวร์จำนวนมาก (เช่น การตรวจสอบสิทธิ์) อยู่ต่ำกว่าในไปป์ไลน์

⚡ เปิดใช้งานการแคชการตอบสนอง

การแคชช่วยลดความจำเป็นในการคำนวณผลลัพธ์ใหม่หรือเข้าถึงฐานข้อมูลซ้ำๆ ASP.NET Core มี มิดเดิลแวร์แคชการตอบสนอง ในตัว .

✅ ตัวอย่าง:เปิดใช้งานการแคชการตอบสนอง

 
 // In Program.cs
builder.Services.AddResponseCaching();
var app = builder.Build();
app.UseResponseCaching();
app.MapGet("/time", (HttpContext context) =>
{
 context.Response.GetTypedHeaders().CacheControl =
 new Microsoft.Net.Http.Headers.CacheControlHeaderValue()
 {
 Public = true,
 MaxAge = TimeSpan.FromSeconds(30)
 };
 return DateTime.UtcNow.ToString("T");
});
 

ขณะนี้ คำขอที่ตามมาภายใน 30 วินาทีจะให้บริการจากแคช ซึ่งปรับปรุงประสิทธิภาพอย่างมาก

🧠 เพิ่มประสิทธิภาพการเข้าถึงข้อมูลด้วย EF Core

การเข้าถึงฐานข้อมูลมักเป็นปัญหาคอขวดหลัก ใช้ Entity Framework Core อย่างมีประสิทธิภาพโดยการใช้:

  • AsNoTracking() สำหรับข้อความค้นหาแบบอ่านอย่างเดียว

  • ข้อความค้นหาที่เรียบเรียง สำหรับการเข้าถึงซ้ำ

  • การรวมการเชื่อมต่อ

✅ ตัวอย่าง:การใช้ 31

 
 public async Task<IEnumerable<Product>> GetAllProductsAsync()
{
 return await _context.Products
 .AsNoTracking() // Improves performance
 .ToListAsync();
}
 

หากคุณเรียกใช้คำค้นหาที่คล้ายกันบ่อยครั้ง ลองพิจารณาคำค้นหาที่คอมไพล์แล้ว :

 
 private static readonly Func<AppDbContext, int, Task<Product?>> _getProductById =
 EF.CompileAsyncQuery((AppDbContext context, int id) =>
 context.Products.FirstOrDefault(p => p.Id == id));
public Task<Product?> GetProductAsync(int id) =>
 _getProductById(_context, id);
 

🧰 ใช้การบีบอัดเอาต์พุต

การบีบอัดคำตอบก่อนส่งไปยังไคลเอนต์จะช่วยลดการใช้แบนด์วิดท์และเพิ่มความเร็วในการจัดส่ง

✅ ตัวอย่าง:เปิดใช้งานการบีบอัดการตอบสนอง

 
 // In Program.cs
builder.Services.AddResponseCompression(options =>
{
 options.EnableForHttps = true;
 options.MimeTypes = new[] { "text/plain", "application/json" };
});
var app = builder.Build();
app.UseResponseCompression();
 

ตอนนี้ทั้งหมด 45 การตอบกลับจะถูกบีบอัด GZIP โดยอัตโนมัติ

🌍 ขยายขนาดด้วยการปรับสมดุลโหลด

การปรับประสิทธิภาพไม่เพียงพอเมื่อมีปริมาณการเข้าชมเพิ่มขึ้น ความสามารถในการขยายขนาด มักเกี่ยวข้องกับการกระจายโหลดไปยังเซิร์ฟเวอร์หลายเครื่องโดยใช้:

  • มาตราส่วนแนวนอน :การเพิ่มเซิร์ฟเวอร์เพิ่มเติม

  • โหลดบาลานเซอร์ :NGINX, Azure Front Door, AWS ELB ฯลฯ

ในระบบแบบกระจาย สถานะเซสชัน และ แคช ควรเป็นแบบภายนอก (เช่น Redis)

✅ ตัวอย่าง:กำหนดค่าแคชแบบกระจาย (Redis)

 
 builder.Services.AddStackExchangeRedisCache(options =>
{
 options.Configuration = "localhost:6379";
});
public class CacheService
{
 private readonly IDistributedCache _cache;
 public CacheService(IDistributedCache cache)
 {
 _cache = cache;
 }
 public async Task SetCacheAsync(string key, string value)
 {
 await _cache.SetStringAsync(key, value, new DistributedCacheEntryOptions
 {
 AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5)
 });
 }
 public Task<string?> GetCacheAsync(string key) => _cache.GetStringAsync(key);
}
 

ซึ่งจะทำให้แอปของคุณ ไร้สถานะ ซึ่งจำเป็นสำหรับการปรับสมดุลโหลด

🧩 กำหนดค่าชวาและโฮสติ้งเพื่อให้ได้ปริมาณงานสูง

Kestrel ซึ่งเป็นเว็บเซิร์ฟเวอร์ ASP.NET Core ในตัว สามารถรองรับคำขอนับแสนคำขอต่อวินาทีเมื่อกำหนดค่าอย่างเหมาะสม

✅ ตัวอย่าง:ปรับการกำหนดค่า Kestrel ให้เหมาะสม

 
 builder.WebHost.ConfigureKestrel(options =>
{
 options.Limits.MaxConcurrentConnections = 10000;
 options.Limits.MaxConcurrentUpgradedConnections = 1000;
 options.Limits.RequestHeadersTimeout = TimeSpan.FromSeconds(30);
});
 

นอกจากนี้:

  • ใช้ พร็อกซีเซิร์ฟเวอร์ย้อนกลับ (เช่น NGINX หรือ IIS) สำหรับการจัดการไฟล์แบบคงที่และการยกเลิก TLS

  • ปรับใช้ใน สภาพแวดล้อมที่มีคอนเทนเนอร์ สำหรับการปรับขนาดอัตโนมัติ (เช่น Kubernetes)

🧮 ใช้หน่วยความจำและการรวมวัตถุ

เพื่อหลีกเลี่ยงการจัดสรรวัตถุบ่อยครั้งและการรวบรวมขยะ ASP.NET Core สนับสนุน การรวมวัตถุ .

✅ ตัวอย่าง:การใช้ 52

 
 using System.Buffers;
public class BufferService
{
 public void ProcessData()
 {
 var pool = ArrayPool<byte>.Shared;
 var buffer = pool.Rent(1024); // Rent 1KB buffer
 try
 {
 // Use the buffer
 }
 finally
 {
 pool.Return(buffer);
 }
 }
}
 

วิธีการนี้ช่วยลดการจัดสรรฮีปให้เหลือน้อยที่สุดและลดความกดดันของ GC ซึ่งเป็นสิ่งสำคัญสำหรับแอปพลิเคชันที่คำนึงถึงประสิทธิภาพ

🧱 ลดเวลาเริ่มต้นและรอยเท้าหน่วยความจำให้เหลือน้อยที่สุด

  • หลีกเลี่ยงบริการที่ไม่จำเป็น ใน 63 .

  • ใช้ AddSingleton แทน AddTransient ตามความเหมาะสม

  • ตัดการพึ่งพา ใน 78 ไฟล์

✅ ตัวอย่าง:การตั้งค่า API ขั้นต่ำ

 
 var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<IProductService, ProductService>();
var app = builder.Build();
app.MapGet("/products", async (IProductService service) =>
 await service.GetAllProductsAsync());
app.Run();
 

API ขั้นต่ำจะช่วยลดรูปแบบสำเร็จรูปและปรับปรุงประสิทธิภาพการเริ่มต้นระบบ

📊 การตรวจสอบและการเปรียบเทียบ

คุณไม่สามารถปรับปรุงสิ่งที่คุณไม่ได้วัดได้ ใช้เครื่องมือเช่น:

  • การติดตามดอทเน็ต และ ดอทเน็ตเคาน์เตอร์

  • ข้อมูลเชิงลึกของแอปพลิเคชัน

  • เกณฑ์มาตรฐานดอทเน็ต

✅ ตัวอย่าง:การใช้ BenchmarkDotNet

 
 [MemoryDiagnoser]
public class PerformanceTests
{
 private readonly ProductService _service = new();
 [Benchmark]
 public async Task FetchProducts()
 {
 await _service.GetAllProductsAsync();
 }
}
 

เรียกใช้เกณฑ์มาตรฐานนี้เพื่อระบุปัญหาคอขวดและความไร้ประสิทธิภาพของหน่วยความจำ

🧩 เคล็ดลับการเพิ่มประสิทธิภาพเพิ่มเติม

  • เปิดใช้งาน HTTP/2 หรือ HTTP/3 เพื่อความเท่าเทียมที่ดีขึ้น

  • ใช้ CDN สำหรับสินทรัพย์คงที่

  • ใช้งาน การรวมการเชื่อมต่อ สำหรับฐานข้อมูลและไคลเอ็นต์ HTTP

  • ใช้ 86 เพื่อป้องกันไม่ให้ซ็อกเก็ตหมด

 
 builder.Services.AddHttpClient("MyClient")
 .SetHandlerLifetime(TimeSpan.FromMinutes(5));
 

🙌 บทสรุป

ประสิทธิภาพและความสามารถในการปรับขนาดสูงใน ASP.NET Core เกิดขึ้นได้จากการผสมผสานระหว่าง การออกแบบแบบอะซิงโครนัส , แคช , การเข้าถึงข้อมูลอย่างมีประสิทธิภาพ และ โครงสร้างพื้นฐานอัจฉริยะ ทางเลือก

ด้วยการใช้กลยุทธ์ที่กล่าวถึง — ตั้งแต่การเพิ่มประสิทธิภาพมิดเดิลแวร์และการกำหนดค่า Kestrel ไปจนถึงการใช้ประโยชน์จาก Redis และการบีบอัด — แอปพลิเคชัน ASP.NET Core ของคุณสามารถจัดการกับปริมาณงานจำนวนมากโดยมีความหน่วงต่ำและความน่าเชื่อถือสูง