자바 I/O & NIO 네트워크 정리 15 : 셀렉터

0

1. 🍕 셀렉터 개요

Selector 는 Reactor의 역할을 한다.

Reactor

이벤트 중심의 어플리케이션이 하나 이상의 클라이언트로부터 동시에 전달되는 서비스요청들을 서비스 제공자에게 구별해서 보내주는 비블록킹 서버 구현의 밑바탕

즉, 여러 selectableChannel을 자신에게 등록하게 하고 등록된 SeletableChannel의 이벤트 요청들을 적절한 서비스 제공자에게 처리하게하는 멀티플렉스 IO이다.

멀티플렉스 IO

멀티플렉스 IO는 하나의 스레드로 동시에 많은 IO채널들을 효율적으로 관리할 수 있게 해주어, 기존의 서버보다 빠르고 많은 동시 접속자를 수용할수있는 확장성 서버를 만들 수 있다.

2. 🍔 기존의 IO모델 네트워크 프로그래밍 보고 셀렉터의 힘 깨닫기

기존의 IO는 블록킹 IO이다.

블록킹 IO란?

특정 디바이스에서 읽기/쓰기 작업을 할때 데이터를 이용할 수 있을떄까지 해당 IO작업을 수행하던 쓰레드가 아무것도 하지않고 대기하는것

Socket s = serverSocket.accept()
			
InputSream in = s.getInputStream()
OutputStream out = s.getOutputStream();

in.read()

out.write()

s.close

해당구조의 서버는 싱글스레드 기반이므로 하나의 요청밖엔 처리하지 못한다.
이것을 해결하기 위해 두가지 방법을 선택하는데 하나는 멀티스레드 기반의 서버이다.

멀티스레드 기반의 단점

멀티스레드 기반의 서버는 많은 문제점이있는데
클라이언트 수가 많아지면 스레드 개수가 그만큼 증가하는것이다.

  • 많은스레드 생성에 따른 스레드 컨텍스트 스위치 부하
    약 천여개의 스레드가 생성되면 스레드 컨테스트 스위치 부하로 인해 급격한 성능저하가 발생한다.
  • 스레드 자체가 CPU와 고유스텍을 갖는데 따른 컴퓨터 리소스 부하
  • 클라이언트의 빈번한 접속과 종료에 따라 많은 가비지가 생성되는 문제점
  • 서버 메모리가 부족해서 OutOfMemoryException 발생 가능성

이런 많은 문제점이 있기 때문에 두번째 비 블록킹 모델을 활용한다.

3. 🍟 비블록킹 모델

멀티 플렉스 모델의 서버를 만들기 위해 핵심적인 역할을 하는 것이 Selector, SelectableChannel, SelectionKey 클래스 이다.

  1. 이미 생성된 바운드되어 있는 채널(SelectableChannel)들을 Selector에 자신이 발생시키고 싶은 이벤트와 함께 등록한다.
  2. 등록에 관련된 채널과 Selector 사이의 관계를 캡슐화한 SelectionKey가 Selector에 저장되고
    리턴값으로 SelectionKey가 리턴
  3. SelectionKey는 어떤채널에 어떤 Selector가 등록되었는지, 채널이Selector에 등록할때 어떤모드로 등록했는지, 동작할 준비가 되었는지 저장

4. 🌮 SelectableChannel

SelectableChannel은 블록킹, 비블록킹 모드와 채널을 Selector에 등록하는 기능이 함께 존재하는데,
이유는 비블록킹과 멀티플렉스가 서로 협력관계에 있다.

sel : Selector 객체,ops : 어떤이벤트를 발생시키고 싶은지 확인하는 값 , att : 참조할객체를 함께 등록
public abstract SelectionKey register(Selector  sel, int ops)
public abstract SelectionKet register(Selector sel, int ops, Object att)

다음은 소켓 채널을 Selector에 등록하는 코드템플릿이다.

ServerSocketChannel server = (ServerScoektChannel) key.channel();
SocketChannel sc = server.accept();
boolean isRegist =  registerChannel(selector, sc, SelectionKey.OP_READ);

private boolean registerChannel(Selector selector, SelectableChannel sc, in ops)
throws ClosedChannelException, IOException{
	if(sc==null){
    return false;
    }
	sc.cofigureBlocking(false);
    sc.register(selector, ops);
    
    return true;
}

Selector는 이벤트가 발생한 채널들만을 선택해서 각이벤트에 맞는 동작을 하도록 중간에서 모든이벤트들에 대한 컨트롤러 역할을 한다.

5. 🥞 SelectionKey

SelectionKey는 특정 채널과 selector 사이의 관계를 캡슐화 한다.
특정 Selector에 register() 메소드로 등록하면 Selector에 등록한 오퍼레이션들을 저장하는 interest set이다.

캡슐화는 중요한 데이터를 보존,보호하는 것입니다.

캡슐화(encapsulation)는 일반적으로 연관 있는 변수와 함수를 클래스로 묶는 작업을 말합니다

구분내용
OP_ACCEPT클라이언트가 ServerSocketChannel에 접속을 시도했을 때 발생
OP_CONNECT서버가 클라이언트의 접속을 허락했을때 발생한다.
OP_READ서버가 클라이언트의 요청을 read 할 수 있을 때 발생한다.
OP_WRITE서버 클라이언트에게 응답을 write 할수 있을 때 발생한다.
if((key.readyOps()& SelectionKey.OP_READ) != 0) {
	...
    // 읽기 작업을 수행한다
    ```
}

6. 🥙 Selector

Selector는 채널이나 스트림처럼 데이터 전송을 위한 클래스가 아니다.
Selector는 등록된 채널들이 발생시킨 이벤트에 대해 적절한 처리 핸들러로 그요청을 분기시켜주는 컨트롤로 역할을 하는 객체다.

profile
쉽게 가르칠수 있도록 노력하자

0개의 댓글