반응 기 모드
reactor 모델 에 대한 이해.
reactor 디자인 모델: 이벤트 구동 을 바탕 으로 하 는 디자인 모델 입 니 다.현 재 는 주로 reactor 디자인 모델 에 대해 네트워크 프로 그래 밍 을 사용 하기 때문에 reactor 의 주요 사건 은 연결, 수용, 읽 기, 쓰기 등 네 가지 사건 유형 으로 나 뉜 다.물론 reactor 는 이벤트 구동 외 에 도 폴 링 선택 기 가 있 습 니 다. 어떤 파일 이 어떤 상태 에 있 는 지 확인 하 는 것 입 니 다.또는 어떤 채널 이 어떤 상태 에 있 는 지 확인 하고 이 상 태 를 선택 기의 대기 열 에 넣 습 니 다.마지막 으로 reactor 배포 기 는 구체 적 인 이벤트 유형 에 따라 스케줄 러 배포 로 구체 적 인 실행 작업 을 수행 합 니 다.다음은 구체 적 인 코드 에 대한 분석 이다.
우선 reactor 클래스 분석 (구성 요소)
class Reactor implements Runnable
{
// :
/**
Selector 。
abstract class Selector {
static Selector open() throws IOException;
Set keys();
Set selectedKeys();
int selectNow() throws IOException;
int select(long timeout) throws IOException;
int select() throws IOException;
void wakeup();
void close() throws IOException;
} */
//
final Selector selector;
// serverSocket;
final ServerSocketChannel serverSocket;
// 。
Reactor(int port) throws IOException
{ //Reactor
//
selector = Selector.open();
//
serverSocket = ServerSocketChannel.open();
//
serverSocket.socket().bind(new InetSocketAddress(port));
// 。 , , 。
serverSocket.configureBlocking(false);
// , , accept , 。 。
// 。
SelectionKey sk =
serverSocket.register(selector, SelectionKey.OP_ACCEPT);
//attach callback object, Acceptor
// , , ( , , , , )
sk.attach(new Acceptor());
// 。
}
public void run()
{
// ,run()
try
{
while (!Thread.interrupted())
{
//select ,
selector.select();
// ,
Set selected = selector.selectedKeys();
//
Iterator it = selected.iterator();
while (it.hasNext())
{
//Reactor dispatch , handle 。
dispatch((SelectionKey) (it.next()));
}
selected.clear();
}
} catch (IOException ex)
{ /* ... */ }
}
void dispatch(SelectionKey k)
{
// handler
Runnable r = (Runnable) (k.attachment());
// callback
if (r != null)
{
r.run();
}
}
// inner class
class Acceptor implements Runnable
{
public void run()
{
try
{
// , serverSocket 。
SocketChannel channel = serverSocket.accept();
if (channel != null)
new Handler(selector, channel);
} catch (IOException ex)
{ /* ... */ }
}
}
}
/ / 여기 서 Handler 류 를 분석 합 니 다.
class Handler implements Runnable
{
final SocketChannel channel;
final SelectionKey sk;
ByteBuffer input = ByteBuffer.allocate(SystemConfig.INPUT_SIZE);
ByteBuffer output = ByteBuffer.allocate(SystemConfig.SEND_SIZE);
static final int READING = 0, SENDING = 1;
int state = READING;
Handler(Selector selector, SocketChannel c) throws IOException
{
channel = c;
c.configureBlocking(false);
// Optionally try first read now
sk = channel.register(selector, 0);
// Handler callback
sk.attach(this);
// , Read
sk.interestOps(SelectionKey.OP_READ);
// , run , 。 ,OP_READ handle 。 Acceptor run() 。
selector.wakeup();
}
boolean inputIsComplete()
{
/* ... */
return false;
}
boolean outputIsComplete()
{
/* ... */
return false;
}
void process()
{
/* ... */
return;
}
public void run()
{
try
{
if (state == READING)
{
read();
}
else if (state == SENDING)
{
send();
}
} catch (IOException ex)
{ /* ... */ }
}
void read() throws IOException
{
channel.read(input);
if (inputIsComplete())
{
process();
state = SENDING;
// Normally also do first write now
// , write
sk.interestOps(SelectionKey.OP_WRITE);
}
}
void send() throws IOException
{
channel.write(output);
//write , select key
if (outputIsComplete())
{
sk.cancel();
}
}
}
위 는 주로 reactor 의 단일 스 레 드 모드 입 니 다. 단일 스 레 드 모드 가 모드 가 아니 어야 합 니 다. 스 레 드 가 데 이 터 를 처리 할 때 (process () 가 막 히 면 뒤의 연결 이 들 어가 지 못 하고 뒤의 연결 이 실 패 됩 니 다.따라서 reactor 단일 스 레 드 는 높 은 병행 상황 에서 사용 하지 않 는 다.
그 다음 에 reactor 다 중 스 레 드 모델 을 고려 하 겠 습 니 다. 다 중 스 레 드 모델 은 데 이 터 를 처리 하 는 데 다 중 스 레 드 처 리 를 하 는 것 입 니 다. 그러면 스 레 드 가 막 히 지 않 습 니 다.다음 코드 는 단일 스 레 드 의 Handle 류 를 바탕 으로 수정 되 었 습 니 다.
synchronized void read() throws IOException
{
// ...
channel.read(input);
if (inputIsComplete())
{
state = PROCESSING;
// pool
pool.execute(new Processer());
}
}
다 중 스 레 드 처 리 는 후속 Handle 처리 과정 에서 의 차단 문제 만 해 결 했 습 니 다. 그러나 Reactor 의 메 인 스 레 드 가 연결 을 받 아들 이 느 냐, 단일 연결 을 받 아들 이 느 냐, 높 은 병행 또는 연결 을 받 아들 이 는 과정 에서 어떤 안전 인증 처 리 를 해 야 하 느 냐 에 따라 연결 이 막 힐 수도 있 습 니 다. 이 럴 때 Reactor 도 여러 스 레 드 를 열 어야 합 니 다.그럼 마지막 으로 Reactor 는 스 레 드 그룹 으로 바 뀌 었 습 니 다.
main 방법 이 실행 되 었 는데 도 프로 세 스 가 종료 되 지 않 았 습 니 다. 그것 은 스 레 드 탱크 의 하위 스 레 드 안의 작업 스 레 드 가 차단 대기 열 에서 데 이 터 를 가 져 올 때 데 이 터 를 가 져 갈 수 없 기 때 문 입 니 다. 데이터 가 있 기 를 기다 리 고 있 기 때 문 입 니 다.데 이 터 를 받 은 후에 작업 스 레 드 를 제외 하고 다시 가 져 갑 니 다. 이렇게 순환 하면 작업 스 레 드 가 죽지 않 고 프로 세 스 도 죽지 않 습 니 다.
NGINX 의 백만 연결 에 대한 링크 설명 추가
리 액 터 모드
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
linux 에서 텍스트 처리 삼 총사정규 표현 식 (정규 표현 식,): grep 텍스트 필터 grep 문법 sed 흐름 편집기 sed 문법 awk: 보고서 생 성기, 포맷 후 표시 다른 텍스트 보기 도구 vim 편집기...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.