회고/TIL

논블록킹 I/O 에 관하여, 단위 테스트를 설계하는 방법

KEEMSY 2023. 10. 18. 22:34

오늘은 어제 저녁에 승원이와 이야기를 나눴던 비동기 데이터 베이스에 대한 내용을 좀더 찾아보고, 어제 마무리하지 못한 단위 테스트에 대한 내용(단위 테스트를 설계하는 방법)을 정리했다.

 

비동기 데이터베이스의 경우 R2DBC(Reactive Relational Database Connectivity)  를 처음 알게되었는데 아주 흥미로웠다. 원래는 비동기처리에 대한 이야기를 하고있었는데, 비동기를 도입하면 그럼 R2DBC 사용하겠네? 를 시작으로 해당 내용을 생각해보게되었다. 

이와 관련해서 나는 단지 Reactive 프로그래밍을 통해 사용하는 메서드를 비동기적으로 처리한다. 라고만 알고 있었다. 근데 이 메서드를 DB와 상호작용하는 부분에 대해서는 생각해보지 못했다. 그래서 관련해서 해당 내용을 공부해 봤다.

 

 


블로킹 I/O 와 논블로킹 I/O

 

나는 데이터베이스 관련 IO 작업에 대해서 큰 고민을 해본 적이없다. 나는 IO 작업에 리소스가 많이 들며, 데이터베이스가 병목지점이 될 수 있어 데이터베이스를 다중화한다. 정도로 공부하고 인지하고 있었다. 그리고 담당했던 프로젝트에서 IO 작업이 많은 경우, 멀티 스레딩을 활용하여, 작업의 효율성을 증진시킨 코드 를 봤었다. 나는 왜인지모르게 IO 의 효율성을 높이기 위해서는 멀티스레딩을 활용해야한다 라는 생각에 갇혀 있었다.

 


블로킹 I/O

 

일반적으로 JPA 를 활용한 쿼리 는 모두 블로킹 IO 이다. 이말은 즉슨, HTTP 요청 중 데이터베이스 관련된 작업이 있을 경우 해당 요청을 처리하는 메서드는 블로킹 처리가 되어, 스레드가 다른 작업을 할 수 없게 된다.(차단) 이것은 효율적이지 않다. 

 

일반적으로, 스레드의 숫자는 CPU 코어의 숫자만큼 설정하는 것이 좋다고 알려져있다.(나는 이렇게 알고있다.) 하지만, 특정 블로킹 호출이 포함된다면 최대한 스레드 풀을 가동해도 CPU 를 최대로 활용할 수 없으며 최선의 성능을 낼 수 없다. 

 

뿐만아니라, 블로킹 호출이 몇개 없더라도, 전체 애플리케이션에 영향을 줄 수 있게 된다. 만약 코어의 숫자가 4개, 스레드의 숫자를 4개로 설정할 때, 전체 다양한 요청들 중, 4개이상 블로킹 호출(데이터베이스 접근 등)을 할 경우에 다른 요청(블로킹 호출X)들은 CPU를 점유할 수 없게 된다.

 

나는 지금까지 데이터베이스 다중화(리플레케이션, master-slave) 를 통해 가용성을 보장하고, 작업을 Command 와 Query 로 구분하여 성능을 증진 시킬 수 있다 라고 생각을 했었는데, 이번 승원이와의 대화를 통해 다시 생각을 많이 해보게 되었다.  

 

 


논블로킹I/O

 

나는 논블로킹 에 대해서는 동기와 비동기를 공부하면서 처음 접하게 되었다. 간략하게만 이야기한다면, 동기는 응답을 기다리는 것을 말하며, 비동기는 응답을 기다리지 않고 다음 작업을 이어가는 것을 말한다. 그리고 블로킹은 제어권을 갖고 있는 것을 말하며, 논블로킹은 제어권한을 다시 반환하는 것을 말한다.

  • 동기: 작업이 진행되는 동안 응답을 기다리는 상태
  • 비동기: 작업이 진행되는 동안 응답을 기다리지 않고 다음 작업이나 코드가 즉시 실행될 수 있는 상태
  • 블로킹: 한 작업이 완료될 때까지 다음 작업이 기다려야 하는 상태
  • 논블로킹: 한 작업이 진행되는 동안 다른 작업이 계속 수행될 수 있는 상태

그리고 나는 이러한 비동기 논블로킹을 단순히 HTTP 요청에서만으로 제한하여 생각하고 있었다.(왜그랬지?)

 

그렇다면 논블로킹 I/O(Non-blocking I/O)는 무엇일까? 말 그대로이다, 입출력 작업에서 데이터를 읽거나 쓸 때, 대기하지 않고 다른 작업을 수행할 수 있는 비동기적인 방식을 말한다.

 

그럼 논블로킹IO 는 왜 좋을까? 다음과 같은 특징을 때문이라고 이야기 할 수 있다.

  • 대기하지 않고 다른 작업 수행한다: 입출력 작업이 진행되는 동안 프로그램은 블로킹되지 않고 다른 작업을 계속 수행할 수 있다.
  • 스레드 관리 용이: 논블로킹 I/O를 사용하면 더 적은 수의 스레드로 많은 연결을 처리할 수 있습니다. 이는 스레드 간의 컨텍스트 스위칭 비용을 낮출 수 있어 효율적인 리소스를 활용할 수 있다.

따라서, 논블로킹 I/O는 주로 네트워크 프로그래밍( 웹 서버, 데이터베이스 액세스, 파일 시스템 액세스 등의 작업) 성능 향상과 확장성을 보장할 수 있게 된다.

 

많이 유용해보이는 이것이 너무 흥미롭다. 잘 공부해서 알맞은 때에 써먹을 수 있도록 공부해봐야겠다.

 


단위 테스트를 설계하는 방법

 

오늘은 어제 마무리 하지 못한 단위테스트에 대한 내용을 마무리 정리해보았다.

 

https://github.com/KEEMSY/STUDY/blob/6dfd92f76d53a98ab8b6490f69d5de7b6510c0b8/System-Development-Skills/UnitTest.md

 

단위 테스트는 코드에 대한 다양한 입력, 예외, 경계 조건을 다루는 테스트 케이스 를 설계하고 테스크 케이스를 코드로 변환하는 프로세스이다. 이와 관련하여, 단위 테스트를 설계하는 방법 을 중심으로 내용을 알아두면 유용하다. 정리한 내용을 간략하게만 설명한다면 다음과 같다.

 

  • 이전에 작성한 단위 테스트를 재활용하여 작성한다.
  • 테스트 케이스가 가능한 모든 가능한 케이스, 특히 일부 특별한 케이스를 포함하는지 주의를 기울인다.
  • 단위테스트는 테스트 중인 함수의 특정 구현 논리에 집중하지 않으며, 그 기능에만 초점을 맞춘다.

 

분명 이외에도 더 다양한 단위테스트를 설계하는 팁이 존재하겠지만, 일단은 책의 내용과 기억나는 내용을 토대로 정리를 해보았다. 그리고 계속해서 좋은 내용이 있다면 추가해볼 생각이다.

 


벌써 또 하루가 지나갔다. 책과 강의를 복습하며 하루를 보냈다. 사실 Payment 도메인에 대하여 설계를 하는것을 온르 가장 큰 핵심으로 생각했는데, 자꾸만 잡생각이 들어서 책과 강의를 보면서 내용을 정리하는 것으로 하루 목표를 바꿨다.

 

정말 내가 이렇게까지 결과를 기다릴줄 몰랐는데, 내일은 오늘보다 잡 생각 하지 않고 정한 목표에 집중할 수 있었으면 좋겠다.

 

집중집중집중!!

728x90