개발자는 기록이 답이다

패스트캠퍼스 환급챌린지 12일차 미션 (2월 12일) : Spring Webflux 완전 정복 : 코루틴부터 리액티브 MSA 프로젝트까지 강의 후기 본문

패스트캠퍼스

패스트캠퍼스 환급챌린지 12일차 미션 (2월 12일) : Spring Webflux 완전 정복 : 코루틴부터 리액티브 MSA 프로젝트까지 강의 후기

slow-walker 2024. 2. 12. 21:24

 

1. Java NIO non-blocking의 문제점

while (true) {
    var clientSocket = serverChannel.accept();
    if (clientSocket !== null) { !// clientSocket이 없으면 wait
        Thread.sleep(100);
        continue; 
}
  • main 쓰레드에서 accept 완료되는지 주기적 으로
  • 각각의 쓰레드에서 read 가능한지 주기적으로
  • 채널상태를 수동으로 관리해하고 코드복잡성이 증가
  • 동시에 발생하는 요청이 증가하는경우, 연결처리가 순차적으로 발생하여 성능

1-1.  busy wait

  • 주로 동기 non-blocking에서 발생
    • caller가 방해받지않고 본인의 일을 할 수 있는데, 결과가 궁금해서 주기적으로 물어봐야 함
  • 지속적으로 cpu를 점유하기 때문에 cpu자원이 낭비
    • Thread.sleep을 하고 다시 Running 상태로 바뀌는 과정에서 Context Switching이 발생하기 때문에 cpu 자원도 낭비
  • 확인하는 주기에 따라서 응답 지연이 발생
    • Context Switching을 줄이기 위해 주기를 길게 가져가면 응답 지연

1-2. 동기 non-blocking의 원인

  • I/O와 관련된 이벤트를 각각의 쓰레드가 확인한다
    • read를 할 수 있다
    • accept를 할 수 있다
  • 채널의 상태를 수동으로 관리해야 한다

2. 한번에 여러 이벤트를 추적할 수 있는 방법은 없을까?

여러 accept와 여러 read 같은 이벤트를 우리가 직접 관리하는게 아니라 추적하는게 좋다

 

2-1. SelectableChannel

public abstract class SelectableChannel
        				extends AbstractInterruptibleChannel
 						implements Channel { 
        public abstract SelectableChannel configureBlocking(boolean block)
                    throws IOException;
	public final SelectionKey register(Selector sel, int ops) throws ClosedChannelException 
    {...}
}
  • configureBlocking 과 register 함수 제공
  • register: Selector에 channel을 등록할 수 있다
  • SocketChannel, ServerSocketChannel 모두 AbstractSelectableChannel을 상속

    AbstractSelectableChannelSelectableChannel을 상

 

2-2. Selector

  • java.nio.channels 패키지
  • 여러 Channel의 이벤트를 등록하고 준비된 이
  • 벤트를 모아서 조회 가능
  • select와 selectedKeys 메소드 제공
/**
 * A multiplexor of {@link SelectableChannel} objects.
 *
**/
public abstract class Selector implements Closeable {
    public abstract int select() throws IOException;
    public abstract Set<SelectionKey> selectedKeys();
}

 

2-3. Selector 생성

  • Selector.open 으로 생성 가능
  • Closable을 구현했기 때문에 직접 close하거나 try-with-resources 사용 가능
// selector 생성
var selector = Selector.open();
// do something
// select 닫기
selector.close();
// 혹은
try (var selector = Selector.open()) {
    // do something
}

 


본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성하였습니다. https://bit.ly/48sS29N