>  기사  >  Java  >  골드 함량이 높은 더보 면접 질문 5가지!

골드 함량이 높은 더보 면접 질문 5가지!

Java后端技术全栈
Java后端技术全栈앞으로
2023-08-17 16:04:161083검색

오늘은 Dubbo IO 상호 작용에 대한 기사를 가져왔습니다.

이 기사는 동료가 흥미로운 단어를 사용하여 지루한 지식 포인트를 적어 놓은 것입니다. 이해하기 쉽고 매우 흥미로워서 작성자의 승인을 찾아 모두와 공유하고 싶습니다.


몇 가지 흥미로운 질문

Dubbo는 복잡한 스레딩 모델을 갖춘 뛰어난 RPC 프레임워크입니다. 이 기사에서 저자는 내 피상적인 지식을 바탕으로 Dubbo의 전체 IO 프로세스를 분석합니다. 시작하기 전에 먼저 다음 질문을 살펴보겠습니다.

  • 비즈니스 메소드가 실행된 후 데이터 패킷이 전송됩니까?
  • netty3과 netty4의 스레딩 모델의 차이점은 무엇인가요?
  • 데이터 패킷이 운영 체제 소켓 버퍼에 도달했는데 무슨 일이 일어났나요?
  • 공급자가 생성한 로그는 시간이 거의 걸리지 않지만 소비자 측에서는 시간이 초과됩니다. 문제를 어떻게 해결할 수 있나요?
  • 물리 계층에서 파이프를 통해 데이터 패킷을 직접 보낼 수 있나요?
  • 소비자 비즈니스 스레드 대기가 켜져 있는 상태인데 몇시에 깨어나나요?
  • ...

다음으로 저자는 소비자로 Dubbo2.5.3을 사용하고 공급자로 2.7.3을 사용하여 전체 상호 작용 프로세스를 설명합니다. 저자는 데이터 패킷의 관점에서 이를 설명합니다. 1인칭으로 ​​안전벨트를 매세요.

흥미로운 여행

1. Dubbo2.5.3 Consumer가 요청을 시작합니다

나는 Dubbo2.5.3 Consumer라는 마을에서 태어난 데이터 패킷입니다. 여행.

어느 날 파견을 앞두고 있었는데, Dubbo 2.7.3 Provider라는 곳으로 가게 되었다고 하더군요.

이 날 비즈니스 스레드는 FailoverClusterInvoker#doInvoke code> 공급자를 선택한 다음 다양한 소비자 필터를 통과한 다음 Netty3 파이프라인을 통과하고 마지막으로 <code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius : 4px ;여백: 0 2px;배경색: rgba(27,31,35,.05);글꼴 계열: 연산자 Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: # ff6441; ">NioWorker#scheduleWriteIfNecessary 메소드, NioWorker의 writeTaskQueue 대기열에 왔습니다. FailoverClusterInvoker#doInvoke我选择了一个Provider,然后经过各种Consumer Filter,再经过Netty3的pipeline,最后通过NioWorker#scheduleWriteIfNecessary方法,我来到了NioWorker的writeTaskQueue队列中。

当我回头看主线程时,发现他在DefaultFuture中的Condition等待,我不知道他在等什么,也不知道他要等多久。

我在writeTaskQueue队列排了一会队,看到netty3 IO worker线程在永不停歇的执行run方法,大家都称这个为死循环。

最后,我很幸运,NioWorker#processWriteTaskQueue

메인 스레드를 다시 보니 그가 DefaultFuture의 Condition에서 기다리고 있는 것을 발견했습니다. 나는 그가 무엇을 기다리고 있는지, 얼마나 기다려야 하는지 알 수 없었습니다.

writeTaskQueue 대기열에 잠시 대기했는데 netty3 IO 작업자 스레드가 run 메서드를 끝없이 실행하는 것을 보았습니다. 모두가 이것을 무한 루프라고 불렀습니다.
골드 함량이 높은 더보 면접 질문 5가지!마침내 운이 좋았습니다. NioWorker#processWriteTaskQueue가 나를 선택했습니다. I 운영체제의 소켓버퍼에 기록되서 기다렸는데 어쨌든 시간은 충분했다. 이 기간동안 메인스레드와 netty3 IO라는 두 개의 투어그룹을 거쳤다. 작업자 스레드입니다. 둘 다 모든 투어 그룹의 서비스가 훌륭하고 매우 효율적입니다.

오늘 본 모습을 간단하게 기록해서 그림으로 그려봤습니다. 물론 중요하지 않은 부분은 무시했습니다.

2. 운영체제가 데이터 패킷을 보낸다
  1. 운영체제 소켓 버퍼에서 마법 같은 일을 많이 경험했다.

  2. 전송 레이어라는 곳에 타겟 포트번호와 소스 포트번호를 추가해줬어요

  3. 네트워크 레이어라는 곳에 타겟 IP와 소스 IP를 추가하고 동시에 시간, 대상 IP를 마스크와 AND하여 "다음 홉" IP

    🎜🎜🎜🎜를 찾습니다. 데이터 링크 계층이라는 곳에 ARP 프로토콜을 통해 "다음 홉" 대상 MAC 주소를 추가했습니다. 소스 MAC 주소🎜

가장 흥미로운 점은 케이블카를 구간별로 탈 때마다 대상 MAC 주소와 소스 MAC 주소를 수정해야 한다는 것입니다. 이 모드를 "Next Jump"라고 부르는 동일한 업계에서는 점프 후 점프를 뛰어넘습니다. 여기에는 많은 데이터 패킷이 있으며 큰 것은 하나의 케이블카에 있고 작은 것은 하나의 케이블카에 압착되어 있습니다. 더 큰 경우 여러 케이블로 분할해야합니다. (우리의 데이터 패킷에는 중요하지 않지만) 이것을 포장 풀기 및 붙이기라고 합니다. 이 기간 동안 우리는 스위치와 라우터를 통과했으며 이러한 장소는 매우 즐거웠습니다.

물론 불쾌한 일, 즉 혼잡도 있습니다. 목적지의 케이블카는 꽉 차서 데려갈 시간이 없어서 기다릴 수 밖에 없습니다.

3. Provider 측에서의 경험

마침내 목적지에 도착했습니다. "Zero Copy"라는 쾌속정을 타고 빠르게 netty4에 도착했습니다. 그는 포장 풀기와 접착을 처리할 수 있습니다. NioEventLoop#processSelectedKeys,再经过pipeline中的各种入站handler,我来到了AllChannelHandler的线程池,当然我有很多选择,但是我随便选了一个目的地,这里会经历解码、一系列的Filter,才会来的目的地“业务方法”,NettyCodecAdapter#InternalDecoder

골드 함량이 높은 더보 면접 질문 5가지!
당분간 AllChannelHandler의 스레드 풀에 머물 예정이라 그 여정을 기록하기 위해 그림도 그려봤습니다.

골드 함량이 높은 더보 면접 질문 5가지!
이제 나의 여행은 끝났고, 새로운 데이터 패키지로 새로운 이야기가 이어집니다.

4. Provider 측에서 새로운 데이터 패킷이 생성되었습니다

나는 Dubbo2.7.3 Provider라는 마을에서 태어난 데이터 패킷입니다. 나의 임무는 운명의 스레드를 깨우는 것입니다. 다음은 당신이 할 것입니다. Dubbo2.5.3 Consumer라는 곳으로 여행을 시작하세요.

Provider 비즈니스 메소드 실행 후

  • 由业务线程经过io.netty.channel.AbstractChannelHandlerContext#writeAndFlush
  • io.netty.channel.AbstractChannelHandlerContext#writeAndFlush
  • 再经过io.netty.util.concurrent.SingleThreadEventExecutor#execute 执行addTask
  • 将任务放入队列io.netty.util.concurrent.SingleThreadEventExecutor#taskQueue
  • 我便跟随着io.netty.channel.AbstractChannelHandlerContext$WriteTask等待NioEventLoop发车,等待的过程中,我记录了走过的脚步。
  • 골드 함량이 높은 더보 면접 질문 5가지!

    在这里,我看到NioEventLoop是一个死循环,不停地从任务队列取任务,执行任务AbstractChannelHandlerContext.WriteAndFlushTask,然后指引我们到socket缓冲区等候,永不知疲倦,我似乎领略到他身上有一种倔强的、追求极致的匠人精神。

    经过io.netty.channel.AbstractChannel.AbstractUnsafe#write

    再经过io.netty.util. 동시.SingleThreadEventExecutor#execute 执行addTask🎜🎜将任务放入队列io.netty.util.concurrent.SingleThreadEventExecutor#taskQueue🎜🎜我便跟随着io.netty.channel.AbstractChannelHandlerContext$WriteTask等待NioEventLoop发车,等待的过程中,我记录了走过的脚步。
    골드 함량이 높은 더보 면접 질문 5가지!

    여기에서 ,我看到NioEventLoop是一个死循环,不停地从任务队列取任务,执行任务AbstractChannelHandlerContext.WriteAndFlushTask, 우리는 소켓을 사용하여 소켓을 사용하고 있습니다.匠人精神。🎜

    经过io.netty.channel.AbstractChannel.AbstractUnsafe#write 과대다양한 장소, 也是做缆车达到目的地.

    5.dubbo 2.5.3 Consumer 도착

    dubbo 2.5.3 Consumer 도착 후 운영체제 소켓 버퍼에서 잠시 기다리다가 "Zero Copy" 스피드보트를 타고 도착했다. 실제 목적지. 목적지 dubbo 2.5.3 소비자, 여기서 찾았습니다. NioWorker#run는 무한 루프가 된 후 <code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px; background-color: rgba( 27,31,35,.05);글꼴 계열: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: #ff6441;">NioWorker#processSelectedKeys, NioWorker#read 읽는 방법으로 스레드 풀에 도달했습니다. AllChannelHandler의 비즈니스 스레드 풀입니다. NioWorker#run是一个死循环,然后执行NioWorker#processSelectedKeys,通过NioWorker#read方式读出来,我就到达了AllChannelHandler的线程池,这是一个业务线程池。

    我在这里等待一会,等任务被调度,我看见com.alibaba.dubbo.remoting.exchange.support.DefaultFuture#doReceived

    여기서 잠시 기다리다가 작업이 예정되기만을 기다리고 있었는데 com.alibaba .dubbo.remoting.exchange.support.DefaultFuture#doReceived가 실행됨과 동시에 Condition의 시그널이 실행되었습니다. 멀리서 막힌 실이 깨어나는 것을 보니, 내가 도착했기 때문에 잠든 실이 깨어난 것임을 이해한 것 같았다. 이것이 내 삶의 의미가 되어야 한다고 생각한다.

    이 시점에서 내 임무는 완료되었고 이번 여행도 끝났습니다.

    netty3 및 netty4의 스레딩 모델 요약

    두 데이터 패킷의 자체 설명을 기반으로 netty3 및 netty4의 스레딩 모델을 요약합니다. netty4 읽기 및 쓰기 과정 : NetTy3 읽기 프로세스가 없습니다. netty4, 파이프라인 IO 스레드에 의해 실행됩니다.

    요약: netty3과 netty4 스레드 모델의 차이점은 쓰기 프로세스에 있습니다. netty3에서는 파이프라인이 비즈니스 스레드에 의해 실행되는 반면, netty4에서는 읽기 및 쓰기에 관계없이 파이프라인이 IO 스레드에 의해 실행됩니다.

    netty4의 ChannelPipeline에 있는 핸들러 체인은 I/O 스레드에 의해 균일하게 직렬로 예약됩니다. 읽기 작업이든 쓰기 작업이든 netty3의 쓰기 작업은 비즈니스 스레드에 의해 처리됩니다. netty4에서는 스레드 간 컨텍스트 전환으로 인한 시간 소모를 줄일 수 있지만, netty3에서는 비즈니스 스레드가 핸들러 체인을 동시에 실행할 수 있습니다. netty4의 효율성을 저하시키는 시간 소모적인 핸들러 작업이 있는 경우 이러한 시간 소모적인 작업을 핸들러에서 처리하는 대신 비즈니스 스레드에서 먼저 실행하는 것을 고려할 수 있습니다. 비즈니스 스레드가 동시에 실행될 수 있으므로 효율성도 향상될 수 있습니다.

    어려운 문제 해결

    공급자가 약속한 didi.log에 정상적인 시간이 걸리지만 이때 소비자 측에서 시간이 초과되는 등 몇 가지 일반적인 어려운 문제에 직면했습니다. 문제 해결 지침, didi.log 필터는 실제로 매우 내부 수준에 있으며 비즈니스 메서드의 실제 실행을 반영하지 못하는 경우가 많습니다.

    1. Provider 비즈니스 방향 실행 외에도 직렬화에는 시간이 많이 걸릴 수 있으므로 arthas를 사용하여 가장 바깥쪽 메서드 org.apache.dubbo.remoting.transport.DecodeHandler#received를 모니터링하여 다음과 같은 비즈니스 메서드를 제외할 수 있습니다. 질문

    2. io.netty.channel.AbstractChannelHandlerContext#invokeWrite 메소드를 모니터링하세요

    3. 현재 tcp의 일부 정보도 확인할 수 있습니다. Recv-Q , Send-Q 및 Recv-Q 와 같은 netstat를 통한 소켓은 수신 버퍼에 도착했지만 아직 애플리케이션 코드에서 읽히지 않은 데이터입니다. Send-Q가 송신 버퍼에 도달했지만 상대방이 아직 Ack 데이터로 응답하지 않았습니다. 이 두 가지 유형의 데이터는 일반적으로 누적되지 않습니다. 누적되면 문제가 발생할 수 있습니다.

    골드 함량이 높은 더보 면접 질문 5가지!
    1. Consumer NioWorker#processSelectedKeys(dubbo2.5.3) 방법이 시간이 많이 걸리는지 확인하세요.

    2. 전체 링크의 모든 세부 사항까지... 문제는 확실히 해결될 수 있습니다.

    Epilogue

    전체 상호 작용 프로세스 동안 저자는 직렬화 및 역직렬화, dubbo가 전체 데이터 패킷을 읽는 방법, 필터는 어떻게 되는 등 스레드 스택 호출 및 소스 코드 세부 사항에 대한 일부 세부 정보를 생략했습니다. 비즈니스 메소드가 실행되기 전에 정렬 및 배포되며 Netty의 Reactor 모드는 어떻게 구현됩니까? 매우 흥미로운 질문입니다...

    위 내용은 골드 함량이 높은 더보 면접 질문 5가지!의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    성명:
    이 기사는 Java后端技术全栈에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제