C++ 콘솔앱에서 std::cout으로 로그를 출력하는데, 리소스를 많이 잡아먹기 때문에 별도의 로깅용 스레드를 사용한다는 이야기를 들은 기억이 있다. 그리고 이번에 로깅으로 인한 레이턴시를 경험했다.
udp 서버를 만들었다.
총 13개의 스레드를 사용하고 작업 내용은 아래와 같다.
- 메인스레드
초기화 로직을 거친 후 대기에 들어간다.
- udp 서버 클래스 (3개의 스레드)
1. 임의의 피어로부터 데이터를 수신하고, 정해진 소켓에게 해당 데이터를 다이렉트로 전송한다.
2. 메모리에 저장된 데이터를 틱마다 특정 피어에게 송신한다.
3. 임의의 피어로부터 데이터를 수신하고 메모리에 저장된 데이터를 업데이트한다.
-> 멀티스레드 특성상 lock을 사용하여 동기화를 해줘야하나, 정확한 동기화보다는 속도가 중요한 이벤트라 정확성보다는 신속성을 택했다.
udp 서버 클래스를 8개 생성하고 각 클래스마다 용도에 맞게 1번과 2번 스레드 두개, 또는 3번 스레드 한개를 워커로 지정한다.
ex) a, b, c, d 클래스 총 스레드 8개 / e, f, g, h 클래스 총 스레드 4개
멀티스레드로 로깅을 하다보면, 로그끼리 겹쳐 정확한 데이터를 읽을 수 없게 된다.
# 기대한 로그
[RECV] IP: 192.168.10.100 PORT: 2000
[RECV] IP: 192.168.10.101 PORT: 2001
# 예상과 다른 결과물
[RE192.168
[RECV] IP: CV] IP: 192.168.10.100 PORT: 2000.10.101 PORT: 2001
중요한건 로그로 확인하는 것보다, 로그 출력으로 인해 리소스를 잡아먹어 스레드의 병목현상이 생긴다.
A가 3초 전에 보낸 패킷이 있다면, 3초 후 해당 패킷 로그를 찍을 것이고 이후 B에게 전송하게된다.
B는 영문도 모르고 현재 시간에 3초 전의 패킷을 받게 된다.
해결방법은 단순하다.
로깅용 스레드를 분배하거나, 로깅을 하지 않으면 된다.
'Study > 에러 정리' 카테고리의 다른 글
NestJS <-> MySQL 트랜잭션 데드락 (0) | 2025.03.28 |
---|---|
NestJS) 함수 사용에서 일관되지 않은 this 참조 (0) | 2025.02.19 |
NestJS) useGlobalFilters, APP_FILTER (0) | 2025.02.18 |
NestJS) circular-dependency, forwardRef, undefined (0) | 2025.02.17 |
NestJS) EC2 -> crypto is not defined (0) | 2025.02.07 |