CAT的Server初始化

2021-08-28 02:28:22 字數 4467 閱讀 2686

1. server初始化從web.xml檔案開始,作為乙個war包專案,首先需要初始化servlet,首先是catservlet專門初始化cat相關的server程式,比如接受客戶端傳過來的資料等等,另乙個servlet為mvc專門提供資料查詢介面的普通的mvc功能,功能相當於縮小版的springmvc。過濾器有兩個catfilter最主要是做一些過濾處理,每次請求經過environment,id_setup,log_client_payload,log_span的handle方法,列印一些日誌,統計一些資訊。domainfilter主要是對domain進行處理。

2. catservlet初始化,首先執行父類abstractcontainerservlet的init方法,這是servlet統一的初始化方法,初始化上下文ioc容器plexuscontainer,在catservlet中開始準備初始化各模組,在上下文中儲存客戶端和服務端檔案路徑,後文會用到。

protected void initcomponents(servletconfig servletconfig) throws servletexception  catch (exception e) 

}

執行defaultmoduleinitializer#execute方法,先執行各模組的setup方法,只有cathomemodule實現了該方法
private void expandall(modulecontext ctx, module modules, setall) throws exception 

expandall(ctx, module.getdependencies(ctx), all);

all.add(module);}}

}}

判斷各模組初始化狀態,未初始化的進行初始化處理

expandall(ctx, modules, all);

for (module module : all)

}

初始化各個模組,設定初始化狀態,abstractmodule#=>abstractmodule#execute,只有catclientmodule和cathomemodule有具體的執行內容,因為catclientmodule的執行內容前文已經介紹過,可以參考前文。

private synchronized void executemodule(modulecontext ctx, module module, int index) throws exception
3. 至此主要就是解析cathomemodule類,首先是它的setup方法,根據之前設定到上下文的伺服器檔案來初始化serverconfigmanager,初始化tcpsocketreceiver主要用於和客戶端之前進行訊息通訊,也就是充當netty的服務端,設定服務結束時的關閉鉤子,銷毀netty的執行緒池通道,關閉通道等等。

protected void setup(modulecontext ctx) throws exception 

});} }

public synchronized void startserver(int port) throws interruptedexception 

});bootstrap.childoption(channeloption.so_reuseaddr, true);

bootstrap.childoption(channeloption.tcp_nodelay, true);

bootstrap.childoption(channeloption.so_keepalive, true);

bootstrap.childoption(channeloption.allocator, pooledbytebufallocator.default);

try catch (exception e)

}

4. 當訊息從客戶端傳送的時候需要對資料進行編碼處理,m_codec.encode(tree, buf);記憶體塊的前四個位元組為訊息的總長度,先獲取當前可寫的下標,然後寫入長度佔位數字0,開始給訊息頭編碼,統計長度

public void encode(messagetree tree, bytebuf buf) 

buf.setint(index, count);

}

給訊息體編碼,這裡以主要的transaction型別訊息距離,當本次執行緒只傳送乙個訊息時也就是子訊息列表為空,會設定type為a,如果有兩個訊息的話就會一次設定t,a,t三個type,不同的type也對應不同的encodeline處理,增加訊息時間等等。最後就是統計長度,最後統一覆蓋到之前的佔位下標。(訊息型別transaction,event,trace,metric,heartbeat)

public int encodemessage(message message, bytebuf buf)  else 

}count += encodeline(transaction, buf, 't', policy.with_duration);

return count;

}} else if (message instanceof event) else if (message instanceof trace) else if (message instanceof metric) else if (message instanceof heartbeat) else

}

同樣,資料流到達服務端的時候就需要進行解碼處理,pipeline.addlast("decode", new messagedecoder());解碼操作在plaintextmessagecodec#decode,先解碼訊息頭,然後判斷是否有可讀位元組,

public void decode(bytebuf buf, messagetree tree) 

}

先解析出父訊息,這個時候前面設定的type就會起到分支的作用,乙個訊息直接走'a',兩個訊息依次走t,a,t,剛好最開始放入棧中的訊息為空case 't':stack.push(parent);這個剛好是退出while迴圈的條件,case 'a':parent.addchild(tran);case 't':return stack.pop();同時把該設定的子訊息設定到父訊息中,解析m_durationinmicro時需要減2是因為編碼的時候新增了"us"字串。具體方法在plaintextmessagecodec#decodeline中。完整的訊息defaultmessagetree就這樣解碼完成。

protected void decodemessage(context ctx, messagetree tree)  else 

} }

當然在解碼之前,會對資料的完整性進行校驗,因為每條訊息都會有個四位元組的長度,所以可讀位元組數不能小於4,mark暫存資料塊的讀下標,開始讀取訊息長度,讀下標往後移動了四個位置,現在重置回讀取之前的位置reset也就是往前移動了四位,繼續校驗可讀位元組數,最後讀取訊息內容資料塊進行解碼。解碼完成後把資料塊儲存在defaultmessagetree中,記錄執行數量m_processcount以及其他的統計值,最後開始進行訊息處理。

protected void decode(channelhandlercontext ctx, bytebuf buffer, listout) throws exception 

buffer.markreaderindex();

int length = buffer.readint();

buffer.resetreaderindex();

if (buffer.readablebytes() < length + 4)

try

} else

} catch (exception e)

}

5. 執行cathomemodule#execute方法,初始化訊息處理類realtimeconsumer,初始化配置更新守護執行緒configreloadtask並且進行啟動,根據服務配置類serverconfigmanager的相關配置啟動其他的幾個守護執行緒。

public void run()  catch (exception e) 

try catch (exception e)

transaction t = cat.newtransaction("reloadconfig", "router");

try catch (exception e) finally

try catch (exception e)

try catch (exception e)

try catch (interruptedexception e)

} }

最後設定服務關閉鉤子messageconsumer#docheckpoint做一些訊息處理的結尾工作,在檔案中儲存訊息資料等等。

初始化 指定初始化

id alloc 物件的誕生過程,主要是從作業系統獲得一塊足夠大的記憶體,以存放該類的全部例項變數,並將其指定為存放記憶體物件的實力變數的位置。alloc方法同時將這塊記憶體全部設定為0。結果是 bool變數初始化為no,所有的int型別變數為0,float變數為0.0,所有的指標為nil.obje...

初始化 1 預設初始化 列表初始化

初始化的基本概念 事實 初始化和賦值是兩個完全不同的操作。初始化,是建立變數時賦予其乙個初始值。賦值,是把物件的當前值擦除,用乙個新值代替。列表初始化 p39 作為c 11新標準的一部分,用花括號 來初始化變數得到了全面應用。出於某些原因,這種初始化的方式叫做列表初始化。現在,無論是初始化物件還是某...

初始化 MyBatis初始化之載入初始化

在mybatis初始化過程中,大致會有以下幾個步驟 1.建立configuration全域性配置物件,會往typealiasregistry別名註冊中心新增mybatis需要用到的相關類,並設定預設的語言驅動類為xmllanguagedriver 3.構建defaultsqlsessionfacto...