OrderedMemoryAwareThreadPoolExecutor 및 MemoryAwareThreadPoolExecutor

8193 단어
최근의 온라인 프로젝트 (인증 서버) 는 항상 서비스 지연 상황이 발생한다.구체적인 문제 설명:
(1) 클라이언트가 요청 A(긴 연결)를 보내면 서버 측의 업무층에서 20초 이상 걸려야 받을 수 있습니다.
(2) 클라이언트가 요청 B(단 연결)을 보내면 서버 측의 업무층에서 신속하게 받을 수 있다.
문제는 서버 측의 네트워크 수신층에서 비롯된 것으로 대체적으로 알 수 있다. 대량의 긴 연결을 통해 전송된 요청이 네트워크 층에 막혀 처리되지 않는다(네트워크 층에 줄을 서서 응용층에 도착하지 않았다).
나중에 조사를 통해 Netty의 Ordered Memory Aware Thread Pool Executor 원인이 밝혀졌다.관련 코드는 다음과 같습니다.
MemoryAwareThreadPoolExecutor executor = new OrderedMemoryAwareThreadPoolExecutor(threadNums, maxChannelMemorySize, maxTotalMemorySize, keepAliveTime, TimeUnit.SECONDS); ExecutionHandler executionHandler = new ExecutionHandler(executor); public ChannelPipeline getPipeline() throws Exception { ChannelPipeline pipeline = pipeline(); pipeline.addLast("decoder", new AuthDecoder()); pipeline.addLast("encoder", new AuthEncoder()); pipeline.addLast("executor", executionHandler); pipeline.addLast("handler", new AuthServerHandler(commandFactory)); return pipeline; } 

먼저 배경 지식을 소개한 다음에 문제를 분석한다.
Netty는 이벤트에 기반한 NIO 프레임워크임을 잘 알고 있습니다.Netty에서 모든 네트워크 동작은 이벤트를 통해 전파되고 처리된다. 예를 들어 채널 읽기, 채널 쓰기 등이다.Netty의 흐름 처리 모델을 참조하십시오.
Boss 스레드 (하나의 서버 포트) --- 클라이언트 연결을 수신 --- Channel 생성 --- Work 스레드 풀 (여러 개의 Work 스레드) 에 맡기십시오.
구체적인 Work 스레드 - 수신된 데이터를 ChannelBuffer로 읽고 - ChannelPipeline의 ChannelHandler 체인을 터치하여 업무 논리를 처리합니다.
참고: ChannelHandler 체인을 실행하는 전체 과정은 동기화됩니다. 만약에 업무 논리의 소모 시간이 비교적 길면 Work 라인이 장시간 동안 사용되지 않아 전체 서버의 병렬 처리 능력에 영향을 줄 수 있습니다.
따라서 합병수를 높이기 위해 일반적으로 ExecutionHandler 스레드 탱크를 통해 비동기적으로 ChannelHandler 체인을 처리한다(worker 스레드는 ExecutionHandler를 거친 후에 끝난다. 이것은 ChannelFactory의worker 스레드 탱크에 의해 회수된다).Netty에서 코드를 한 줄만 추가하면 됩니다.
public ChannelPipeline getPipeline() { return Channels.pipeline( new DatabaseGatewayProtocolEncoder(), new DatabaseGatewayProtocolDecoder(), executionHandler, // Must be shared new DatabaseQueryingHandler()); } 

예: ExecutionHandler executionHandler = new ExecutionHandler(new OrderedMemoryAwareThreadPoolExecutor(16, 1048576, 1048576)
Netty는 ExecutionHandler에 필요한 스레드 풀 모델에 두 가지 옵션을 제공합니다.
1) Memory Aware ThreadPool Executor는 스레드 탱크 메모리에 대한 사용 제어를 통해 Executor에서 처리할 작업의 상한선을 제어할 수 있고 (상한선을 초과하면 후속적으로 들어오는 작업이 막힌다), 단일 채널이 처리할 작업의 상한선을 제어하여 메모리가 넘치는 오류를 방지할 수 있다.
2) Ordered Memory Aware Thread Pool Executor는 Memory Aware Thread Pool Executor의 하위 클래스입니다.Memory Aware Thread Pool Executor의 기능을 제외하고는 같은 채널에서 처리되는 이벤트 흐름의 순서성을 보장할 수 있다. 이것은 주로 비동기적인 처리 모드에서 발생할 수 있는 오류를 제어하는 이벤트 순서이지만, 같은 채널에서 처리되는 이벤트가 한 라인에서 실행되는 것을 보장하지는 않는다.
예:
Thread X: --- Channel A (Event A1) --. .-- Channel B (Event B2) --- Channel B (Event B3) ---> \ / X / \ Thread Y: --- Channel B (Event B1) --' '-- Channel A (Event A2) --- Channel A (Event A3) ---> 

위의 그림은 몇 가지 의미를 나타냅니다.
(1) 전체 스레드 풀에서 동일한 Channel 이벤트를 처리하려면 순서대로 처리해야 합니다.예를 들어, Channel A(Event A1)를 처리한 다음 Channel A(Event A2), Channel A(Event A3)를 처리해야 합니다.
(2) 같은 채널의 여러 이벤트는 스레드 탱크의 여러 스레드에 분포되어 처리됩니다.
(3) 서로 다른 채널의 사건은 동시에 처리할 수 있고 (여러 라인까지 분담) 서로 영향을 주지 않는다.
Ordered Memory Aware Thread Pool Executor의 이러한 이벤트 처리 질서성은 의미가 있다. 일반적인 상황에서 요청 발송자는 서버가 자신의 요청을 순서대로 처리하기를 원하기 때문이다. 특히 여러 번 악수를 해야 하는 응용층 프로토콜이 필요하기 때문이다.예: XMPP 프로토콜.
이제 구체적인 업무로 돌아가면 이곳의 인증 서비스도 Ordered Memory Aware Thread Pool Executor를 사용합니다.인증 서비스의 한 부분은 긴 연결을 사용하여 다른 서버에서 온 인증 요청을 끊임없이 처리하는 것이다.통신하는 데이터 패키지는 모두 매우 작아서 일반적으로 200바이트 이내이다.일반적인 상황에서 이 과정을 처리하는 것은 매우 빠르기 때문에 아무런 문제가 없다.그러나 인증 서비스는 제3자의 인터페이스를 호출해야 하기 때문에 제3자의 인터페이스가 지연되면 이 과정이 늦어진다.일단 하나의 사건이 다 처리되지 않으면, 사건 처리의 질서성을 유지해야 하기 때문에, 다른 사건들은 모두 막힌다!짧은 연결이 문제가 없는 이유는 짧은 연결이 하나의 채널에 하나의 요청 데이터 패키지를 가지고 채널을 처리하면 닫히고 순서에 문제가 존재하지 않기 때문에 업무층에서 신속하게 요청을 받을 수 있지만 같은 이유(제3자 인터페이스)로 인해 처리 시간이 비교적 길기 때문이다.
사실 인증 과정은 모두 독립된 요청 데이터 패키지(단일 계정)로 모든 요청 데이터 패키지 사이에는 아무런 관계가 없다. 이런 순서를 유지하는 것은 의미가 없다!
마지막 개선 사항:
1. Ordered Memory Aware Thread Pool Executor를 제거하고 Memory Aware Thread Pool Executor로 변경합니다.
2. 제3자 인터페이스를 호출하는 시간 초과 시간을 줄이고 처리 라인이 가능한 한 빨리 라인 탱크로 돌아가도록 한다.
참조:
  • Netty 병렬 최적화된 ExecutionHandlerhttp://www.cnblogs.com/baronzhao/p/netty_2.html
  • Netty 장거리 연결의 이벤트 처리 순서 문제http://www.blogjava.net/hankchen/archive/2012/04/08/373572.html
  • 좋은 웹페이지 즐겨찾기