소켓의 동작 방식은 블로킹 모드와 논블로킹 모드로 나뉜다. 블로킹은 요청한 작업이 성공하거나 에러가 발생하기 전까지는
응답을 돌려주지 않는 것을 말하며 논블로킹은 요청한 작업의 성공여부와 상관없이 바로 결과를 돌려주는 것을 말한다.
이때 요청의 응답값에 의해서 에러나 성공 여부를 판단한다.
자바에서는 JDK 1.3까지 블로킹 방식의 I/O만을 지원했다. 이후 JDK 1.4가 발표되면서 NIO(New I/O)라는 논블로킹 I/O API
가 추가 되었다. API의 이름에서 유추할 수 있듯이 입출력과 관련된 기능을 제공하는데, 소켓도 입출력 채널의 하나로써 NIO API
를 사용할 수 있으며 NIO API를 통해서 블로킹과 논블로킹 모드의 소켓을 사용할 수 있다.
블로킹 소켓과 논블로킹 소켓은 데이터 송수신을 위한 함수의 동작 방식에 따른 분류다. 자바는 두 가지 소켓을 구분하기 위해서 별도의 클래스를 사용한다.
블로킹 소켓은 ServerSocket, Socket 클래스, 논블로킹 소켓은 ServerSocketChannel, SocketChannel 클래스를 사용한다.
블로킹 소켓은 호출된 입출력 메서드의 처리가 완료될때까지 응답을 돌려주지 않고 대기한다.
블로킹 소켓은 데이터 입출력에서 스레드의 블로킹이 발생하기 때문에 동시에 여러 클라이언트에 대한 처리가 블가능하게 된다.
블로킹 모드의 소켓을 사용하는 서버가 다중 클라이언트의 접속 처리를 하지 못하는 문제점을 해결하기 위해서 등장한 모델은
연결된 클라이언트별로 각각 스레드를 할당하는 방법이다.
ServerSocket 클래스가 제공하는 accept 메서드는 단위 시간에 하나의 연결만을 처리하는 블로킹 모드로 동작하기 때문에
여러 클라이언트가 동시에 접속 요청을 하는 상황에서 대기시간이 길어진다는 단점이 있다.
또한 접속할 클라이언트 수가 정해져 있지 않은 상황에서도 문제가 있을 수 있다.
서버에 접속하는 클라이언트 수가 증가하면 애플리케이션 서버의 스레드 수가 증가 하게 되는데,
이때 자바의 힙 메모리 부족으로 인한 OOM(Out Of Memory) 오류가 발생할 수 있다.
이런상황이 발생하면 서비스 불가 상태로 이어지게 된다.
위와 같은 서비스 불가 상황이 발생하지 않도록 하려면 서버에서 생성되는 스레드 수를 제한 하는 방법인
스레드 풀링을 사용하기도 한다.
동시에 접속 가능한 사용자 수가 스레드 풀에 지정된 스레드 수에 의존하는 현상이 발생한다.
여기서 말하는 동시 접속이란 동일한 시간에 서버에 연결되어 있는 클라이언트 수를 의미한다.
동시 접속 수를 늘리기 위해서 스레드 풀의 크기를 자바 힙이 허용하는 최대 한도에 도달할 때까지 늘리는 것이 합당한지 두 가지 관점에서
생각해 볼 필요가 있다.
첫번째는 자바의 가비지 컬랙션에 대한 고찰이다. 만약 하드웨어에 장착된 메모리가 충분히 커서 자바 프로세스의 힙 메모리를
원하는 만큼 할당할 수 있다고 가정하자. 자바 프로세스가 가동되고 시간이 흐름에 따라 가비지 컬랙션의 대상이 되는 객체 수가
늘어나게 되고 가비지 컬랙션이 동작하게 된다. 이때 자바 프로세스는 가비지 컬랙션을 완료하기 위해서 다른 스레드를
멈추게 되는데, 그러면 어플리케이션이 먹통이 된 것처럼 보이게 된다. 특히 힙 크기가 크면 클수록 가비지 컬랙션에 드는 시간이
길어진다는 점이다. 즉, 힙 크기와 생성 가능한 스레드 수는 비례한다. 힙에 할당된 메모리가 크면 클수록 가비지 컬랙션이
수행되는 횟수는 줄어들지만 수행시간은 상대적으로 길어진다.
두 번째는 운영체제에 사용되는 컨텍스트 스위칭에 관한 고찰이다. 컨텍스트 스위칭이란 한 프로세스에서 수행되는 스레드들이
CPU 점유를 위해서 자신의 상태를 변경하는 작업니다. 이때 수많은 스레드가 CPU 자원을 획득하기 위하여 경쟁하면서 CPU
자원을 소모하기 때문에 실제로 작업에 사용할 CPU 자원이 적어지게 된다.
지금까지 살펴본 내용을 종합해보면 블로킹 소켓의 동작 방식으로 인하여 블로킹 소켓을 사용한 서버는 충분히 많은 동시접속
사용자를 수용하지 못한다. 이런 단점을 개선한 방식이 논블로킹 소켓 방식이다.
'JAVA > Netty' 카테고리의 다른 글
Netty 프레임워크 SOCKET 옵션 (0) | 2019.05.20 |
---|---|
[Netty] 1. Netty의 기본설명 (0) | 2017.10.31 |
[Netty]3.3.1 ServerBootStrap API (0) | 2016.03.15 |
[Netty]네티 유저 가이드 4.x (Netty User guide for 4.x) 한글 번역 (0) | 2016.03.11 |
[Netty]2.1. 동기 와 비동기 (0) | 2016.03.11 |
▶ JAVA 20. 소켓 통신 (0) | 2016.03.04 |
[JAVA] java.util package_Properties Class_예제 (0) | 2016.03.04 |
[JAVA]자바 소켓통신 예제 (0) | 2016.03.04 |