<aside> APM 도구(atatus)를 활용해 리소스 사용을 최적화하고, 판매 예약으로 인한 동시 요청 트래픽을 ngrinder로 사전 시뮬레이션하여 병목 현상을 분산 처리함으로써 시스템의 안정성을 확보
</aside>
음원 NFT를 발행할 때 판매 예약이라는 기능이 있습니다. 영향력 있는 사람이 NFT 음원을 발행하기 전에 사전 광고를 하고 지정 시간에 동시 판매를 진행합니다. 저희는 시크릿 넘버의 스페셜 앨범을 NFT로 발행하여 소유권을 인정받은 사람만 전체 영상을 볼 수 있도록 진행하였습니다.


시크릿 넘버의 스페셜 앨범을 총 만개 NFT를 발행하고 NFT 1개당 3만 원에 동시 판매를 진행하기 앞서 대규모 트래픽이 예상되어 nGrinder(wrk2 , nGrinder 부하 테스트 도구 사용하기)로 NFT 구매 사전 시뮬레이션을 진행하였습니다.

apm으로 확인했을 때 주로 NFT의 구매 예약 상태를 변경하는 부분에서 500 에러가 나는 것을 확인했습니다. 구매 예약은 판매 예약 상태에서 해당 시간에 판매가 개시되면 구매를 진행할 수가 있는데 구매를 진행하는 중에 다른 사용자가 해당 NFT를 구매를 못하도록 하기 위한 일종의 락 상태입니다.

PHP에서 많은 에러가 발생하면서 테스트가 종료되는 상황입니다. 해당 이미지는 GIF 이미지로 PDF시 정적인 이미지로 대체되며, 자세한 내용은 노션에서 확인 할수 있습니다.
nGrinder를 통해 부하 테스트를 진행해 봤을 때 결과 error가 계속 발생하면서 테스트가 도중에 끊기는 걸 확인할 수 있습니다. 해당 사이트는 php 기반 프레임워크인 Codeigniter 애플리케이션입니다. php 특성상 요청마다 프로세스를 생성하면서 애플리케이션 쪽 문제가 아닐지 추측으로 Apache에 의존한 php가 아닌 php-fpm을 통해 별도의 WAS 서버를 구성해 보았지만 역시 해당 원인도 아니었습니다.

Spring boot에서 약간의 에러가 발생하면서 테스트는 유지되는 상황입니다. 해당 이미지는 GIF 이미지로 PDF시 정적인 이미지로 대체되며, 자세한 내용은 노션에서 확인 할수 있습니다.
다른 방법으로 동일한 환경으로 같은 비즈니스 코드를 Spring Boot에 작성하고 부하 테스트 시 에러 없이 정상 동작하는 것을 볼 수 있었습니다.
Codeigniter과 Spring Boot 프레임워크를 비교했을 때 Spring Boot는 JPA를 통해 HikariCP가 자동으로 설정되어 DB 커넥션풀을 관리하고 있었지만, Codeigniter는 요청마다 DB 커넥션, 종료를 하고 있었습니다. 이렇게 되면 동시에 많은 부하가 발생 시 max connections를 초과하게 된 요청에 대해서는 모두 500에러가 발생하게 됩니다.

AWS에는 이미 RDS Proxy라는 서비스를 제공하고 있고 이를 통해 커넥션풀을 관리해 줄 수 있습니다. EC2, RDS를 사용하고는 있지만 RDS Proxy 비용까지 추가되는 것이 고민되어 직접 구현하도록 하였습니다.
Swoole을 통해 별도의 PHP 서버를 생성하고 Mysql과 미리 커넥션을 맺은 다음 Codeigniter는 Swoole 서버로 쿼리 요청을 하면 되겠지만 이는 꽤 많은 비즈니스 영역에 코드 변경이 필요했습니다. 결국 ProxySQL(ProxySQL란? 설치 및 사용방법 )를 사용하기로 했습니다. ProxySQL은 MySQL 및 MariaDB 데이터베이스를 위한 고성능 프록시 서버입니다. 이를 통해 데이터베이스의 성능과 가용성을 개선하고, 데이터베이스 서버의 부하를 관리할 수 있습니다.
