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 작업에 최적화되어 있습니다. . async 를 사용하여 그리고 await 키워드를 사용하면 스레드를 확보하여 더 많은 요청을 동시에 처리할 수 있습니다.

✅ 예:비동기 컨트롤러 작업

 
 [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);
 }
}
 

Task<IActionResult> 을 사용하여 , 데이터베이스 쿼리나 API 호출과 같은 I/O 바인딩 작업을 기다리는 동안 스레드가 차단되지 않습니다. 이는 과부하 시 확장성을 획기적으로 향상시킵니다.

🧩 미들웨어 파이프라인 최적화

미들웨어 구성 요소는 각 요청을 순차적으로 처리합니다. 미들웨어를 가볍게 유지하고 불필요한 처리를 피하세요.

✅ 예:맞춤형 경량 미들웨어

 
 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() 읽기 전용 쿼리의 경우

  • 컴파일된 쿼리 반복적인 접근을 위해

  • 연결 풀링

✅ 예: 사용 AsNoTracking()

 
 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();
 

이제 모두 application/json 응답은 자동으로 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은 올바르게 구성되면 초당 수십만 개의 요청을 처리할 수 있습니다.

✅ 예: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는 개체 풀링을 지원합니다. .

✅ 예: 사용 ArrayPool<T>

 
 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 부담을 줄여줍니다. 이는 성능에 민감한 애플리케이션에 매우 중요합니다.

🧱 시작 시간 및 메모리 공간 최소화

  • 불필요한 서비스 피하기 Program.cs 에서 .

  • AddSingleton 사용 AddTransient 대신 적절한 경우.

  • 종속성 제거 *.csproj 에서 파일.

✅ 예:최소 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로 상용구를 줄이고 시작 성능을 향상시킵니다.

📊 모니터링 및 벤치마킹

측정하지 않는 것은 개선할 수 없습니다. 다음과 같은 도구를 사용하세요:

  • dotnet-추적 dotnet-counters

  • 애플리케이션 인사이트

  • BenchmarkDotNet

✅ 예:BenchmarkDotNet 사용

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

이 벤치마크를 실행하여 병목 현상과 메모리 비효율성을 식별하세요.

🧩 추가 최적화 팁

  • HTTP/2 또는 HTTP/3 활성화 더 나은 병렬성을 위해.

  • CDN 사용 정적 자산의 경우.

  • 연결 풀링 사용 데이터베이스 및 HTTP 클라이언트용.

  • IHttpClientFactory 를 사용하세요 소켓 소모를 방지합니다.

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

🏁 결론

ASP.NET Core의 고성능 및 확장성은 비동기 설계의 조합을 통해 달성됩니다. , 캐싱 , 효율적인 데이터 액세스 스마트 인프라 선택하세요.

미들웨어 및 Kestrel 구성 최적화에서 Redis 및 압축 활용에 이르기까지 논의된 전략을 적용함으로써 ASP.NET Core 애플리케이션은 짧은 대기 시간과 높은 안정성으로 대규모 워크로드를 처리할 수 있습니다.