4 類ObRootWorker
這是個大傢伙,它繼承自前面講過的ObBaseServer這個簡單框架類。自此已經很接近底層了。
4.1 成員變量
ObRootWorker本身引用了很多類,有關於log系統的,有關於Packet的,有關於client manage的,還有關於rpc的,等等;ObRootWorker正是集合了這些資源,完成了Root Server的功能。其成員變量如下:
ObRootServer2 root_server_;
common::ObPacketQueueThreadread_thread_queue_;
common::ObPacketQueueThreadwrite_thread_queue_;
common::ObPacketQueueThreadlog_thread_queue_;
common::ObClientManager client_manager;
common::ObServer rt_master_;
common::ObServer self_addr_;
common::ObRoleMgr role_mgr_;
common::ObSlaveMgr slave_mgr_;
common::ObCheckRunnable check_thread_;
ObRootFetchThread fetch_thread_;
ObRootRpcStub rt_rpc_stub_;
ObRootLogReplay log_replay_thread_;
ObRootLogManager log_manager_;
ObRootStatManager stat_manager_;
如前所述,它是ObBaseServer的子類,這裏重載了initialize和start_service方法;它還繼承自tbnet::IPacketQueueHandler,所以還需要重載handlePacket的兩個方法;爲了實現admin的merge指令,它還定義了public start_merge接口。
此外,還需要實現tbnet::IPacketQueueHandler定義的handlePacketQueue這個接口,此接口將被上面定義的幾個thread queue調用。
其private的rt_xxx函數族,從命名來看就是和heart beat、get update server info等方法相對應的。
先掃掉兩個小嘍羅,首先是common::ObServer,這其實就是個ipv4/v6的封裝而已,提供一個比較功能和to string操作;其次是common::ObRoleMgr,就是一個狀態enum,可以根據enum轉換成對應的string。
4.2 初始化和服務啓動
先來看看初始化函數initialize()的基本邏輯,無外乎是完成各成員變量的初始化。
client_manager.initialize(get_transport(),get_packet_streamer());
rt_rpc_stub_.init(&client_manager,&my_thread_buffer);
// 設置並獲取本機IP
int32_tlocal_ip = tbsys::CNetUtil::getLocalAddr(dev_name_);
self_addr_.set_ipv4_addr(local_ip,port_);
slave_mgr_.init(vip,&rt_rpc_stub_, log_sync_timeout, lease_interval, lease_reserv);
// 設置RW、log線程參數,注意W和log都是單線程的
thread_count= TBSYS_CONFIG.getInt(STR_ROOT_SECTION, STR_THREAD_COUNT, 20);
read_thread_queue_.setThreadParameter(thread_count,this, NULL);
void*args = reinterpret_cast<void*>(WRITE_THREAD_FLAG);
write_thread_queue_.setThreadParameter(1,this, args);
args =reinterpret_cast<void*>(LOG_THREAD_FLAG);
log_thread_queue_.setThreadParameter(1,this, args);
// 如果本機是vip,就以master角色啓動,否則就是slave
// vip從配置中讀取
if(tbsys::CNetUtil::isLocalAddr(vip))
role_mgr_.set_role(ObRoleMgr::MASTER);
else
role_mgr_.set_role(ObRoleMgr::SLAVE);
rt_master_.set_ipv4_addr(vip,port_);
check_thread_.init(&role_mgr_,vip, vip_check_period_us,
&rt_rpc_stub_,&rt_master_, &self_addr_);
root_server_.init(config_file_name_,now, this);
具體成員的初始化,暫且放到後面再看吧,現在先了解worker初始化的基本邏輯。
接下來是啓動服務,start_service這個函數很簡單,如上面的代碼,需要根據vip決定是以master還是以slave啓動。
ObRoleMgr::Role role =role_mgr_.get_role();
if (role == ObRoleMgr::MASTER)
ret = start_as_master();
else if (role ==ObRoleMgr::SLAVE)
ret = start_as_slave();
先買先看master角色的邏輯吧。
4.3 以master角色啓動
以master啓動,就進入到start_as_master()函數中。第一件事就是初始化log manager並replay log。
ret =log_manager_.init(&root_server_, &slave_mgr_);
ret =log_manager_.replay_log();
log_manager_.get_log_worker()->reset_cs_hb_time();
其後轉移到ACTIVE狀態,並啓動RW、LOG線程
role_mgr_.set_state(ObRoleMgr::ACTIVE);
read_thread_queue_.start();
write_thread_queue_.start();
check_thread_.start();
最後是循環等待結束,並檢查是否有狀態遷移發生
for(;;){
if (ObRoleMgr::STOP ==role_mgr_.get_state()
|| ObRoleMgr::ERROR ==role_mgr_.get_state()){
TBSYS_LOG(INFO, "role managerchange state, stat=%d", role_mgr_.get_state());
break;
}
usleep(10 * 1000); // 10 ms
}
還是沿着該函數的軌跡來吧,接下來先來看看log manager這塊。