Skip to content

jacking75/edu_Learn_ASPNetCore_APIServer

Repository files navigation

ASP.Net Core Web API Game Server 학습

이 저장소에 있는 코드는 약간의 오류나 좋지 않은 코드는 일부러 놓아두고 있습니다. 학습하는 사람이 학습하면서 수정하는 것을 유도하고 있습니다. PR은 받지 않습니다.


1. 학습하기

직접 예제 코드를 만들어 보면서 학습을 잘하자

Redis 프로그래밍

MySQL 프로그래밍

로그 라이브러리 ZLogger

.NET 에서 로그 라이브러리로 ZLogger를 추천한다.
사용 방법은 ZLogger 디렉토리를 보기 바란다.

2022년 인턴 사원이 만든 학습 자료

학습자료_2022년_인턴 이라는 디렉토리에 2022년 인턴 사원으로 근무한 분이 만든 학습 자료가 있다.
이 자료들을 순서대로 한번 보기 바란다.
이것들을 본 후 실습을 하나씩 한다. 03_Dapper, 06연습 프로젝트 구현은 따라서 실습을 할 필요는 없다. 그냥 보기만 한다.

학습에서는 데이터 베이스 프로그래밍으로 Dapper를 사용하고 있는데 실제 실습에서는 SqlKata를 사용한다
SqlKata 소개
demo 프로그램 codes 디렉토리에 있는 github_sqlkata_demo.zip 파일이다.

서버 캠퍼스 1기 수료생 정리 자료

서버 캠퍼스 1기 수료생 정리 자료

학습자료_2024_서버캠퍼스2기 디렉토리를 보기 바란다

문서



단계 별로 따라하면서 API 서버 만들기

아래 영상과 예제 코드를 참고하면서 단계 별로 만들면서 배운다.


API Server 개발하기

  • code 디렉토리의 APIServer_Templete 디렉토리에 있는 코드를 참고해서 만들기 바란다.
  • 프로젝트는 새로 만들고 구조나 코드 등을 참고한다.
  • APIServer_Templete 에 있는 코드 보다 더 좋은 코드를 만드는 것을 목표로 한다.

API 서버간 통신 때 HttpClientFactory 사용하기

MS Docs: ASP.NET Core에서 IHttpClientFactory를 사용하여 HTTP 요청 만들기

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpClient("Google", httpClient =>{
    httpClient.BaseAddress = new Uri("https://www.google.com/");
});
builder.Services.AddHttpClient("BaiDu", httpClient =>{
    httpClient.BaseAddress = new Uri("https://www.baidu.com/");
});
interface IGoogleService{
    Task<string> GetContentAsync();
}
class GoogleService : IGoogleService{
    private readonly IHttpClientFactory _httpClientFactory;

    public GoogleService(IHttpClientFactory httpClientFactory)
    {
        _httpClientFactory = httpClientFactory;
    }
	
    public async Task<string> GetContentAsync()
    {
        var googleClient = _httpClientFactory.CreateClient("Google");
		var response = await googleClient.GetAsync("some-endpoint");
		...
    }
}

IHttpClientFactory는 ASP.NET Core에서 HTTP 클라이언트를 관리하는 데 많은 장점을 제공한다.

  • 클라이언트 인스턴스 풀링: IHttpClientFactory는 HttpClient 인스턴스를 풀링하여 재사용합니다. 이로 인해 매 요청마다 새로운 HttpClient를 생성하는 비용을 줄이고 성능을 향상시킵니다.
  • 수명 관리: IHttpClientFactory는 HttpClient 인스턴스의 수명을 관리합니다. 요청이 완료되면 HttpClient를 반환하고 재사용할 수 있도록 합니다. 이로 인해 메모리 누수를 방지하고 리소스를 효율적으로 사용할 수 있습니다.
  • 구성 가능한 클라이언트: IHttpClientFactory를 사용하면 여러 클라이언트를 구성할 수 있습니다. 위의 코드에서 “Google” 및 “BaiDu” 클라이언트를 등록했습니다. 각 클라이언트는 서로 다른 BaseAddress를 가지며 다른 서비스에 대한 요청을 보낼 수 있습니다.
  • DI (의존성 주입) 지원: IHttpClientFactory는 DI 컨테이너와 통합되어 의존성 주입을 통해 HttpClient를 쉽게 주입할 수 있습니다.
  • 테스트 용이성: IHttpClientFactory를 사용하면 HttpClient를 목(Mock)으로 대체하여 단위 테스트를 수행할 수 있습니다. 이는 외부 서비스에 의존하는 코드를 테스트할 때 유용합니다.

요약하자면, IHttpClientFactory는 성능, 메모리 관리, 구성 가능성 및 테스트 용이성 측면에서 HTTP 클라이언트를 효율적으로 관리하는 데 도움이 됩니다.

동시 요청을 많이 보내고 싶을 때

ASP.NET Core Web API 서버에서 HttpClientFactory를 사용하여 다른 서버에 많은 요청을 동시에 보내야 하는 경우, 다음과 같은 사항들을 고려해야 합니다.


1. 기본 연결 제한 (MaxConnectionsPerServer) 조정

.NET의 기본 SocketsHttpHandler에는 서버당 최대 동시 연결 수가 제한되어 있습니다. 기본값은 일반적으로 2로 설정되어 있어, 많은 요청을 동시에 보낼 경우 병목현상이 발생할 수 있습니다. 이를 해결하기 위해 MaxConnectionsPerServer 값을 늘려야 합니다.

예를 들어, 다음과 같이 HttpClientFactory를 통해 생성되는 HttpClient에 대해 최대 연결 수를 늘릴 수 있습니다:

services.AddHttpClient("MyClient")
    .ConfigurePrimaryHttpMessageHandler(() =>
        new SocketsHttpHandler
        {
            MaxConnectionsPerServer = 100 // 필요에 맞게 설정 (예: 100 또는 그 이상)
        });

이렇게 설정하면, 동일한 서버로의 동시 연결 수가 증가하여 많은 요청을 동시에 처리할 수 있습니다.


2. HttpMessageHandler 재사용 및 관리

HttpClient는 재사용이 가능한 인스턴스를 만드는 것이 중요합니다. IHttpClientFactory를 사용하면 HttpMessageHandler를 효율적으로 관리할 수 있으며, 사용 후에도 Dispose 호출로 인한 소켓 포트 소진(Socket exhaustion)을 예방할 수 있습니다.

  • 핵심 포인트:
    • HttpClient 인스턴스를 재사용하거나, HttpClientFactory를 통해 관리하도록 하여 연결 재사용을 극대화합니다.
    • 필요하다면 PooledConnectionLifetime 또는 PooledConnectionIdleTimeout을 설정하여 오래된 연결을 주기적으로 닫을 수 있습니다.

예시:

services.AddHttpClient("MyClient")
    .ConfigurePrimaryHttpMessageHandler(() =>
        new SocketsHttpHandler
        {
            MaxConnectionsPerServer = 100,
            PooledConnectionLifetime = TimeSpan.FromMinutes(5), // 최대 연결 수명
            PooledConnectionIdleTimeout = TimeSpan.FromMinutes(2) // 유휴 연결 유지 시간
        });

3. 폴리시 및 타임아웃 적용

많은 요청을 동시에 보낼 때는 잠재적인 네트워크 지연이나 실패를 고려해 타임아웃재시도(retry) 정책등을 적용하는 것이 좋습니다.

  • 타임아웃 설정:
    HttpClient의 Timeout 속성을 조정하여 매 요청의 최대 대기 시간을 설정합니다.

  • 폴리시 설정:
    Polly 라이브러리를 사용하여 재시도, 회로 차단기(Circuit Breaker) 등의 폴리시를 추가할 수 있습니다.

예시 (Polly를 사용한 재시도 정책):

services.AddHttpClient("MyClient")
    .ConfigurePrimaryHttpMessageHandler(() =>
        new SocketsHttpHandler
        {
            MaxConnectionsPerServer = 100,
            PooledConnectionLifetime = TimeSpan.FromMinutes(5),
            PooledConnectionIdleTimeout = TimeSpan.FromMinutes(2)
        })
    .AddTransientHttpErrorPolicy(builder =>
        builder.WaitAndRetryAsync(
            retryCount: 3,
            sleepDurationProvider: retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))
        )
    );

4. 적절한 부하 테스트 및 모니터링

  • HttpClientFactory 사용 시, 설정한 옵션들이 실제 환경에서 기대한 대로 동작하는지 부하 테스트를 수행합니다.
  • ASP.NET Core의 로깅 및 모니터링 기능을 통해 연결 상태, 응답 시간, 오류 등을 체크하여 필요한 경우 추가적인 조정을 수행합니다.

결론

많은 요청을 동시에 처리하기 위해서는 기본 연결 제한 값을 늘리고, HttpClient 및 HttpMessageHandler 재사용, 적절한 타임아웃과 폴리시 적용, 그리고 이후 모니터링을 통한 지속적인 관리가 필수적입니다. 이러한 설정을 통해 ASP.NET Core 웹 API에서 HttpClientFactory를 효율적으로 사용하여 높은 동시성의 요청을 안정적으로 처리할 수 있습니다.


example_filter_APIServer

  • 아래 프로그램은 codes 디렉토리 안에 있다.
  • 기획데이터(마스터 데이터)가 json으로 된 것을 로딩
  • 미들웨어로 라우팅을 커스텀마이징
  • 미들웨어로 클라이언트 보낸 요청 데이터의 암호를 풀어서 핸들러에 전달하도록 한다
  • 필터로 클라이언트에 보내는 응답의 포맷을 변환하거나 암호화 하도록 한다

gRPC Server


참고할 실습 프로젝트

  • (2022년) 신입 사원 교육 프로젝트
    • codes/practice_robotmon-go 디렉토리에 있다.
    • .NET 6 버전 사용
  • 2023년 지니어스 인턴 프로젝트
  • (2024년 1월) 신입 사원 교육 프로젝트
    • 미니게임천국 모작
    • codes/practice_MiniGameHeavenAPIServer 디렉토리에 있다.
    • .NET 8 버전 사용
  • 2024년 API 서버로 만든 오목 게임 서버
    • 두 개의 프로젝트가 있다. 둘다 만드는 게임은 같지만 각각 개발자는 달라서 구현도 조금씩 다르다
    • API 서버로 실시간 게임 콘텐츠를 구현하는 방법을 볼 수 있다. 롱 폴링 방식 사용
    • codes/practice_omok_game-1 , 'codes/practice_omok_game-2`


API 서버의 디렉토리 구성 예

  • Controllers: 컨트롤러 클래스를 저장하는 곳
  • Dto: 클라이언트와 데이터를 주고받을 때 모델 클래스를 저장하는 곳
  • Infrastructure: DB, 메일, 기타 시스템 연동 등의 설정파일을 저장하는 곳
  • Libraries: 프로젝트 내 공통 처리를 저장하는 곳
  • Repositories: DB 접근 처리를 저장하는 곳
  • Services : 비즈니스 로직을 저장하는 곳
│   ├── Controllers
│   │   └── TodoController.cs
│   ├── Dto
│   │   ├── CreateRequestDto.cs
│   │   └── CreateResponseDto.cs
│   ├── Infrastructure
│   │   ├── Configure
│   │   │   ├── DatabaseConfigure.cs
│   │   │   └── ServiceConfigure.cs
│   │   └── Database
│   │       └── TodoEntity.cs
│   ├── Libraries
│   │   ├── Exception
│   │   │   └── ValidationException.cs
│   │   └── Middleware
│   │       └── CustomExceptionMiddleware.cs
│   ├── Program.cs
│   ├── Properties
│   │   └── launchSettings.json
│   ├── Repositories
│   │   └── Todo
│   │       ├── ITodoRepository.cs
│   │       └── TodoRepository.cs
│   ├── Services
│   │   └── Todo
│   │       ├── ITodoService.cs
│   │       └── TodoService.cs
│   ├── TodoApi.csproj
│   ├── TodoApi.sln	
│   ├── TodoApi.http
│   ├── appsettings.Development.json
│   └── appsettings.json
├── Api.Tests
│   ├── Api.Tests.csproj
│   ├── Api.Tests.sln	
│   ├── GlobalUsings.cs
│   └── UnitTests
│       └── Services
│           └── TodoServiceTests.cs
└── dotnet-todo-web-api.sln	

실습

  • 팜 게임 만들기: api_server_training_tany_farm 디렉토리
  • 수집형 RPG 게임 만들기: api_server_training_dungeon_farming 디렉토리

C# 학습 자료

About

ASP.NET Core Web API 학습을 위한 저장소

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published