Netty 서버 스레드 모델 개요(전)

5062 단어
ServerBootstrap
netty 서버를 초기화하고 포트의 socket 요청을 감청하기 시작합니다.
bootstrap bootstrap = new ServerBootstrap(
	new NioServerSocketChannelFactory(
		Executors.newCachedThreadPool(),//boss 
		Executors.newCachedThreadPool()//worker 
	)
);
bootstrap.setPipelineFactory(new HttpChannelPipelineFactory());
bootstrap.setOption("child.tcpNoDelay", true);
bootstrap.setOption("child.keepAlive", true);
bootstrap.bind(new InetSocketAddress(httpPort));// 
Server Bootstrap은 Server Socket Channel Factory로 실례화됩니다.Server Socket Channel Factory는 두 가지 선택이 있는데 하나는 Nio Server Socket Channel Factory이고 하나는 Oio Server Socket Channel Factory입니다.전자는 NIO를 사용하고 후자는 일반 차단 IO를 사용합니다.그것들은 모두 두 개의 스레드 탱크의 실례를 매개 변수로 초기화해야 한다. 하나는 boss 스레드 탱크이고, 하나는worker 스레드 탱크이다.ServerBootstrap.bind(int)는 연결 포트를 책임집니다. 이 방법이 실행되면 ServerBootstrap은 지정된 포트의 socket 연결을 받아들일 수 있습니다.하나의 ServerBootstrap으로 여러 포트를 바인딩할 수 있습니다

boss 스레드와worker 스레드

이렇게 말할 수 있다. Server Bootstrap이 감청하는 포트는 boss 라인에 대응하고 그것들은 일일이 대응한다.예를 들어 넷티 감청 80과 443 포트가 필요하면 두 개의 boss 라인이 각각 두 포트에서 온 socket 요청을 처리합니다.boss 라인이 socket 연결 요청을 받아들인 후,channel (열려 있는 socket은 열려 있는 channel) 을 생성하고, 이 channel을 ServerBootstrap 초기화 시 지정한 ServerSocket Channel Factory에 전달하여 처리하고, boss 라인은 socket 요청을 계속 처리합니다.Server Socket Channel Factory는worker 스레드 탱크에서 worker 스레드를 찾아서 이 요청을 계속 처리합니다.Oio Server Socket Channel Factory라면 이 채널에 있는 모든 socket 메시지 메시지는 시작부터 channel (socket) 닫기까지 이 특정한worker로만 처리됩니다. 즉, 열린 socket은 지정한worker 라인에 대응합니다. 이worker 라인은 socket이 닫히지 않은 상황에서도 이 socket을 위해 메시지를 처리할 수 있고 서버의 socket을 처리할 수 없습니다.Nio Server Socket Channel Factory라면 그렇지 않다. 모든 worker가 서로 다른 socket 또는 채널, worker 라인과 채널은 더 이상 일일이 대응하는 관계가 없다.분명히 Nio Server Socket Channel Factory는 소량의 활동적인worker 라인과 많은 채널을 잘 처리할 수 있고, Oio Server Socket Channel Factory는 채널을 열 수 있는 것과 같은 양의worker 라인을 사용해야 한다.라인은 일종의 자원이기 때문에 넷티 서버가 긴 연결을 처리해야 할 때 Nio Server Socket Channel Factory를 선택하면 대량의worker 라인을 만드는 것을 피할 수 있다.http 서버로 사용할 때도 Nio Server Socket Channel Factory를 선택하는 것이 좋습니다. 현대 브라우저는 http keepalive 기능(브라우저의 서로 다른 http 요청을 공유할 수 있는 채널)을 사용하는데 이것도 긴 연결이기 때문입니다

worker 라인의 생명주기(lifecircle)

어떤 채널에 메시지가 도착하거나 socket에 쓸 메시지가 있을 때,worker 라인은 라인에서 하나를 꺼냅니다.Worker 라인에서 메시지는 설정된 Channel Pipeline 처리를 거칩니다.Channel Pipeline은 순서가 있는 필터로 두 부분으로 나뉘는데 그것이 바로 Upstream Handler와 Down Stream Handler이다.본고는 넷티의 스레드 모델을 중점적으로 소개하기 때문에pipeline에 대한 내용은 간략하게 설명한다.클라이언트가 보내는 메시지는 먼저 많은 UpstreamHandler가 순서대로 처리하고, 처리된 데이터는 응용 프로그램의 업무 논리 Handler에 전송되며, 보통 Simple Channel UpstreamHandler로 이 부분을 실현한다
public class SimpleChannelUpstreamHandler{
	public void messageReceived(ChannelHandlerContext c,MessageEvent e) throws Exception{
		// 
	}
}
Nio에 대해messageReceived() 방법이 실행된 후 이상이 발생하지 않으면worker 라인이 실행됩니다. 이것은 라인 탱크에 회수됩니다.업무 논리hander는 일부 방법을 통해 되돌아오는 데이터를 지정한 순서의 Down Stream Handler 처리에 맡기고 처리된 데이터가 필요하면 채널에 기록되어 연결된 socket을 통해 클라이언트에게 전송합니다.이 과정은 다른 스레드 탱크의worker 스레드로 이루어집니다.Oio의 경우 처음부터 끝까지 지정한worker가 처리합니다..

Worker 스레드 처리 시간 감소

worker 스레드는 넷티 내부에서 관리하고 통일적으로 조립된 자원이기 때문에 가능한 한 빨리worker 스레드를 실행하고 스레드 탱크에 회수하여 이용하는 것이 가장 좋다.Worker 라인의 대부분 시간은 Channel Pipeline의 각종handler에 소모되며, 이 Handler 중에서 일반적으로 응용 프로그램의 업무 논리를 담당하는 Handler가 가장 시간을 차지하며, 이것은 보통 마지막 Upstream Handler에 랭크되어 있다.따라서 이 부분의 처리 내용을 다른 라인에 맡기면 워커 라인의 주기 순환 시간을 효과적으로 줄일 수 있다.일반적으로 두 가지 방법이 있다

messageReceived () 방법에서 새로운 라인을 열어 업무 논리를 처리합니다

public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception{
	 ...
	 new Thread(...).start();
}
메시지 리시버드 () 에서 업무 논리를 계속 처리하기 위한 새로운 라인을 열고,worker 라인은 메시지 리시버드 () 를 실행하면 끝납니다.더욱 우아한 방법은 업무 논리 처리 임무를 제출하기 위해 별도의 스레드 탱크를 구축하는 것이다

netty 프레임워크를 이용한 자체 ExecutionHandler

기본 사용 방법
public class DatabaseGatewayPipelineFactory implements ChannelPipelineFactory {
 
     private final ExecutionHandler executionHandler;
 
     public DatabaseGatewayPipelineFactory(ExecutionHandler executionHandler) {
         this.executionHandler = executionHandler;
     }
 
     public ChannelPipeline getPipeline() {
         return Channels.pipeline(
                 new DatabaseGatewayProtocolEncoder(),
                 new DatabaseGatewayProtocolDecoder(),
                 executionHandler, //  pipeline ExecutionHandler
                 new DatabaseQueryingHandler());// handler,IO 
     }
 }
공유된 ExecutionHandler 실례를 업무 논리handler 앞에 두면 됩니다. ExecutionHandler는 반드시 서로 다른 pipeline 사이에서 공유해야 한다는 것을 주의하십시오.그것의 역할은 자동적으로 ExecutionHandler가 스스로 관리하는 스레드 탱크에서 하나의 스레드를 꺼내서 그 뒤에 배열된 업무 논리handler를 처리하는 것이다.작업자 라인은 ExecutionHandler를 거친 후에 종료됩니다. 채널팩토리의 작업자 라인에서 회수됩니다.그것의 구조 방법은 ExecutionHandler (Executor executor) 이다. 분명히 executor는 ExecutionHandler 내부 관리의 스레드 탱크이다.netty는 우리에게 두 가지 스레드 탱크를 추가로 제공했다. MemoryAwareThreadPoolExecutor와 OrderedMemoryAwareThreadPoolExecutor. 모두 org에 있다.jboss.netty.handler.execution 패키지.Memory Aware Thread Pool Executor는 jvm가 너무 많은 스레드로 인해 메모리 넘침 오류가 발생하지 않도록 합니다. Ordered Memory Aware Thread Pool Executor는 이전 스레드 탱크의 하위 클래스입니다. 메모리 넘침이 없음을 제외하고channel 이벤트의 처리 순서를 보장할 수 있습니다.자세한 내용은 API 문서를 참조하십시오.

좋은 웹페이지 즐겨찾기