Notice
Recent Posts
Recent Comments
Link
개발자는 기록이 답이다
패스트캠퍼스 환급챌린지 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을 상속
AbstractSelectableChannel은 SelectableChannel을 상속
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