Jafka原始碼分析——Processor

來源:互聯網
上載者:User

標籤:jafka   kafka   原始碼   訊息中介軟體   分布式   

Jafka Acceptor接收到用戶端請求並建立串連後,Acceptor會將Socket串連交給Processor進行處理。Processor通過以下的處理步驟進行用戶端請求的處理:

1. 讀取用戶端請求。

2. 根據用戶端請求類型的不同,調用相應的處理函數進行處理。

Processor讀取用戶端請求是一個比較有意思的事情,需要考慮兩個方面的事情:第一,請求規則(Processor需要按照一定的規則進行請求的解析);第二,如何確定一次請求的讀取已經結束(因為是非阻塞串連,非常有可能第一次讀操作讀取了請求的一部分資料,第二次到第N次讀取才能把整個用戶端請求讀取完整)。下面我們詳細解析一下用戶端請求的格式。用戶端請求首先包含一個int,該int指明本次用戶端請求的大小(size)。隨後,請求包含一個兩個byte(short)的請求類型(請求類型包括:CreaterRequest、DeleterRequest、FetchRequest、MultiFetchRequest、MultiProducerRequest、OffsetRequest和ProducerRequest。然後每種請求類型有固定的格式。具體說明了ProducerRequest的格式:



知道了上面的格式之後,問題二(如何確定一次請求已經讀取完成)就很容易解決了。首先為“請求長度”分配一個4byte的ByteBuffer,直到該Buffer讀滿,否則說明長度一直沒有讀取完成。“請求長度”讀取完成後,為請求分配一個“請求長度”大小的ByteBuffer,直到該Buffer讀滿則說明一次請求讀取完成。讀取完成後,根據“請求類型”調用相應的處理函數(Handler)進行處理。在jafka中,上述的兩個Buffer在類BoundedByteBufferReceive中進行聲明和管理。Processor接收到Acceptor分配的socket串連後,會為socke串連建立一個BoundedByteBufferReceive並將其與socket串連進行綁定。每當該socket串連“可讀”時,將BoundedByteBufferReceive拿出來從上次讀取的基礎上繼續讀取,直到一次請求徹底讀取完成,具體過程如下面代碼(Processor.read)所示:

private void read(SelectionKey key) throws IOException {SocketChannel socketChannel = channelFor(key);Receive request = null;request = new BoundedByteBufferReceive(maxRequestSize);key.attach(request);} else {request = (Receive) key.attachment();}int read = request.readFrom(socketChannel);stats.recordBytesRead(read);if (read < 0) {close(key);} else if (request.complete()) {Send maybeResponse = handle(key, request);key.attach(null);// if there is a response, send it, otherwise do nothingif (maybeResponse != null) {key.attach(maybeResponse);key.interestOps(SelectionKey.OP_WRITE);}} else {// more reading to be donekey.interestOps(SelectionKey.OP_READ);getSelector().wakeup();if (logger.isTraceEnabled()) {logger.trace("reading request not been done. " + request);}}}


BoundedByteBufferReceive.readFrom的實現具體如下:主要是申請兩個Buffer並不斷的讀取資料。

public int readFrom(ReadableByteChannel channel) throws IOException {        expectIncomplete();        int read = 0;        if (sizeBuffer.remaining() > 0) {            read += Utils.read(channel, sizeBuffer);        }        if (contentBuffer == null && !sizeBuffer.hasRemaining()) {            sizeBuffer.rewind();            int size = sizeBuffer.getInt();            if (size <= 0) {                throw new InvalidRequestException(...);            }            if (size > maxRequestSize) {                final String msg = "Request of length %d is not valid, it is larger than the maximum size of %d bytes.";                throw new InvalidRequestException(format(msg, size, maxRequestSize));            }            contentBuffer = byteBufferAllocate(size);        }        //        if (contentBuffer != null) {            read = Utils.read(channel, contentBuffer);            //            if (!contentBuffer.hasRemaining()) {                contentBuffer.rewind();                setCompleted();            }        }        return read;    }


讀取完成後,Processor會解析“請求類型”,根據請求類型的不同調用不同的Handler進行相應請求的處理。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.