ChannelOutboundBuffer가 가득 차면 쓰기는 어떻게 되나요?

Nov 20 2020

채널이 응답하지 않을 때 요청을 작성하면 어떻게되는지 알아 내려고합니다. 예를 들어 피어가 갑자기 네트워크를 끊고 RST를 얻지 못할 때 이런 일이 발생합니다.

문서 읽기 및 netty 채널 버퍼 및 워터 마크 이해 에서 높은 WriterBufferWaterMark 에 도달하면 ChannelOutboundBuffer가 가득 찬 것으로 간주되고 다음과 같이 표시됩니다.

Channel.isWritable ()은 false를 반환하기 시작합니다.

에서 ) (Channel.isWritable :

I / O 스레드가 요청 된 쓰기 작업을 즉시 수행 할 경우에만 true를 반환합니다. 이 메서드가 false를 반환 할 때 작성된 모든 쓰기 요청은 I / O 스레드가 대기중인 쓰기 요청을 처리 할 준비가 될 때까지 대기됩니다.

나의 초기 질문은 : 어쨌든 우리가 계속 글을 쓰면 어떻게 되는가?

Netty 채널 isWritable이 false를 반환 하면 내부 버퍼가 있음을 나타내며 제한되지 않음을 의미하는 경우 데이터가 대기열에 추가됩니다 .

질문은 정확히 어디에 쓰기 요청이 대기하고 있으며, 더 중요한 것은 이러한 대기열의 크기를 관찰 할 수 있다는 것입니다 .

또는 : Netty / OS가 연결이 끊어져 닫아야하는 것을 감지 할 때 제한이 있습니까?

답변

1 NormanMaurer Nov 24 2020 at 08:59

여전히에서 대기열에 ChannelOutboundBuffer있습니다. 버퍼가 가득 차면 쓰기를 중지하고 비어있는 버퍼를 다시 시작해야합니다. 을 통해이를 관찰 할 수 있습니다 ChannelInboundHandler.channelWritabilityChanged(...).

cfstras Nov 25 2020 at 12:30

4.1.37의 ChannelOutboundBuffer에 대한 소스를 살펴보면이 메서드 는 상태에 관계없이addMessage 항상 들어오는 메시지를 내부 연결 목록에 추가합니다 . 이 목록은 무제한으로 늘어납니다.isWritable

이 버퍼의 총 바이트 길이는를 통해 도달 할 수 channel.unsafe().outboundBuffer().totalPendingWriteBytes()있습니다.

간접 값의 경우 unsafe ()를 사용하지 않으려면 channel.bytesBeforeWritable()대기중인 바이트에서 로우 워터 마크를 뺀 값을 반환하는 대신 사용할 수 있습니다 .