PhxRPC源碼分析(三) RPC

RPC

整個RPC的定義基本都在hsha_server這個文件。主要有一下幾個類:

  • DataFlow :數據流,所有請求和應答分別保存在兩個線程安全的隊列中。
  • HshaServerStat HshaServerQos: 統計運行狀態,獨立線程。
  • Worker :獨立的工作線程,如果是協程模式,每個worker會有多個協程。
  • WorkerPool:工作池,管理Worker
  • HshaServerUnit:獨立線程的工作單元,每個單元都有一個WorkerPool ,UThreadEpollSchedulerDataFlow
  • HshaServerIO:在HshaServerUnit線程處理IO事件。
  • HshaServer:server對象,有多個工作單元。
  • HshaServerAcceptor:接受連接,工作在主線程。

運行起來有一個accept線程,每個unit有一個IO線程,多個worker線程。

各個模塊之間的關係如下

這裏寫圖片描述

DataFlow

DataFlow包含request和response隊列,並附加了時間戳和參數指針。

HshaServerStat HshaServerQos

獨立線程負責統計運行信息,線程綁定爲CallFunc函數,使用了設置超時時間的條件變量,超時時間爲1s,這樣如果沒有通知則每秒統計一次。

Worker

獨立工作線程,綁定爲Worker::Func

void Worker::Func() {
    if (uthread_count_ == 0) {  //如果沒有設置協程數量
        ThreadMode();  //線程模式
     } else {
        UThreadMode();  //協程模式
    }
}

線程模式直接從DataFlow中拉一個request然後執行WorkerLogic
協程模式創建一個調度器並設置處理新請求的函數。

void Worker::UThreadMode() {
    worker_scheduler_ = new UThreadEpollScheduler(utherad_stack_size_, uthread_count_, true);
    assert(worker_scheduler_ != nullptr);
    worker_scheduler_->SetHandlerNewRequestFunc(bind(&Worker::HandlerNewRequestFunc, this));
    worker_scheduler_->RunForever();
}

HandlerNewRequestFunc會將WorkerLogic的包裝UThreadFunc加入調度器的任務隊列。
WorkerLogic是真正處理邏輯的函數,對沒有超時的請求,會分發到具體的函數處理,最後將結果push到response隊列中。

WorkPool

WorkPool負責創建Worker

HshaServerIO

void HshaServerIO::RunForever() {
    scheduler_->SetHandlerAcceptedFdFunc(bind(&HshaServerIO::HandlerAcceptedFd, this));
    scheduler_->SetActiveSocketFunc(bind(&HshaServerIO::ActiveSocketFunc, this));
    scheduler_->RunForever();
}

RunForever設置Run中執行的兩個回調函數分別處理新建連接和寫response

AddAcceptedFd函數負責將已連接的fd放入accepted_fd_list_中。

HandlerAcceptedFd函數從隊列中取出已連接的fd,並綁定IOFunc函數加入協程調度器的任務隊列。

IOFunc函數新建一個關聯socketfd的UThreadTcpStream,然後判斷請求協議的類型並解析請求,將解析完成的request push到DataFlow中,
然後調用

worker_pool_->Notify();

這一步針對UThreadMode,worker_pool的Notify函數會調用worker的Notify來通知worker的UThreadEpollScheduler,接下來IOFunc調用UThreadWait設置一個超時時間Yield出去。

此時worker的UThreadEpollSchedulerRun函數處輪詢,接下來會執行開啓UThreadMode時綁定的handler_new_request_func_也就是Worker::HandlerNewRequestFunc,這個函數將從DataFlow中拉取request然後將WorkerLogic加入worker_scheduler_的任務隊列。這樣開始執行WorkerLogic,執行完邏輯後WorkerLogic將response加入DataFlow的隊列中。最後執行

    pool_->scheduler_->NotifyEpoll();

這一步調用worker_pool_的UThreadEpollSchedulerNotifyEpoll,接下來流程回到pool_->scheduler_的Run中,此時執行active_socket_func_DataFlow中取出response,將其包裝爲該socket的args並返回,最後Resume到此socket的協程也就是之前的IOFunc,將response send出去。

這個應該是整個流程最複雜的一個函數了,主要是worker線程和workpool的UThreadEpollScheduler的互相喚醒。一次完整的收發數據流程如下:

這裏寫圖片描述

HshaServerUnit

HshaServerUnit是IO線程,其RunFunc AddAcceptedFd調用的都是成員HshaServerIO的相應函數。

HshaServerAcceptor

HshaServerAcceptorLoopAccept函數負責accept新連接,idx_變量通過每次取餘的方式來確定將accept的fd放到哪個HshaServerUnit

HshaServer

HshaServer獲取配置文件中的IO線程數量創建相同數量的HshaServerUnit,根據配置文件的工作線程數量初始化其參數,然後push到server_unit_list_中。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章