sensu server是sensu的核心元件,是sensu業務邏輯實現的核心元件。
sensu server的入口在sensu/bin/sensu-server
options = sensu::cli.read
sensu::server::process.run(options)
和這裡client幾乎一樣,解析命令列引數,呼叫process.run
run方法也是,建立乙個server的服務例項,啟動服務:server.start,然後處理訊號
再看start方法
def start
setup_redis
setup_transport
bootstrap
end
setup_redis:連線redis;
setup_transport:連線rabbitmq;
bootstrap:啟動;
接下來看bootstrap方法
def bootstrap
setup_keepalives
setup_results
setup_master_monitor
@state = :running
end
setup_keepalives:保持和客戶端的聯絡:訂閱客戶端的註冊的訊息,當客戶端註冊過來(客戶端每過20秒會註冊自己),則將客戶端新增到客戶端佇列裡;
setup_results:訂閱check的結果並處理結果;
setup_master_monitor:為保證server的ha定時選舉master;
最後將該server的狀態設定為running
這時候server就啟動起來了
重點關注:process_check_result方法,該方法主要對check的結果儲存,並對相同錯誤累計,並處理結果
def process_check_result(result)
@logger.debug("processing result", :result => result)
@redis.get("client:#") do |client_json| # 找到result json裡對應的client
unless client_json.nil?
client = multijson.load(client_json)
check = case
when @settings.check_exists?(result[:check][:name]) && !result[:check][:standalone] # 如果check不在配置裡,且不為standalone check
@settings[:checks][result[:check][:name]].merge(result[:check]) # 則新增乙個check
else
result[:check]
endaggregate_check_result(result) if check[:aggregate] # 如果需要聚合,聚合check結果,稍後再看
store_check_result(client, check) do # 儲存check結果
check_history(client, check) do |history, total_state_change| # 計算狀態改變百分比
check[:history] = history
check[:total_state_change] = total_state_change
# 建立乙個事件,如果該次check失敗,則增加該事件的失敗次數,並記錄,如果之前失敗,這次成功,則刪除該事件的失敗記錄
update_event_registry(client, check) do |event|
process_event(event) # 呼叫handler處理事件
endend
endelse
@logger.warn("client not in registry", :client => result[:client])
endend
end
儲存結果的方法:store_check_result
def store_check_result(client, check, &callback)
@redis.sadd("history:#", check[:name]) # 新增該check到該client的history裡,如果已存在則忽略,history:#包含了該client的所有check
result_key = "#:#"
history_key = "history:#"
@redis.rpush(history_key, check[:status]) do # 將check的結果push到歷史佇列裡
@redis.set("execution:#", check[:executed])
@redis.ltrim(history_key, -21, -1) # 只儲存21條歷史記錄
callback.call
endend
該方法將check的結果新增到歷史佇列裡,即:redis的佇列裡。並且只儲存21條歷史記錄。
處理事件方法:process_event,該方法獲取事件裡的handlers,並迴圈處理,在處理前會過濾和修改。
def process_event(event)
log_level = event[:check][:type] == "metric" ? :debug : :info # 如果是metric,日誌級別為debug
@logger.send(log_level, "processing event", :event => event)
event_bridges(event)
handler_list = array((event[:check][:handlers] || event[:check][:handler]) || "default") # 找到處理的handler(s)
handlers = derive_handlers(handler_list) # 根據handler名字找到handler定義
handlers.each do |handler| # 迴圈處理
@handling_event_count += 1
filter_event(handler, event) do |event| # 過濾事件
mutate_event(handler, event) do |event_data| # 修改事件
handle_event(handler, event_data) # 處理事件
endend
endend
handler的handle_event方法,記錄日誌,呼叫handler_type_router,該方法根據不同的處理型別呼叫不同的處理方法
def handler_type_router(handler, event_data)
case handler[:type]
when "pipe"
pipe_handler(handler, event_data)
when "tcp"
tcp_handler(handler, event_data)
when "udp"
udp_handler(handler, event_data)
when "transport"
transport_handler(handler, event_data)
when "extension"
handler_extension(handler, event_data)
endend
pipe_handler:執行配置的指令碼,並日誌記錄結果;
tcp_handler:傳送資料到handler配置的tcp主機和埠;
udp_handler:和tcp_handler一樣,只是傳送的時udp包;
transport_handler:發布乙個事件到rabbitmq;
handler_extension:處理擴充套件;
spring security認證原始碼剖析
spring security 和shiro目前最主流的安全框架,很好的保護了系統的安全性。shiro實現的原理和spring security具有異曲同工之妙,學會乙個框架,另乙個框架也會很容易上手。1 spring security流程 usernamepasswordauthenticatio...
ReentrantLock獨佔鎖原始碼剖析
在開始分析reentrantlock 獨佔鎖之前,我們先來簡單了解幾個概念 悲觀鎖指對資料被外界修改持保守態度,認為資料很容易就會被其他執行緒修改,所以在資料被處理前先對資料進行加鎖,並在整個資料處理過程中,使資料處於鎖定狀態。例如synchronized。樂觀鎖是相對悲觀鎖來說對,它認為資料在一般...
locust對應原始碼HttpUser剖析(7)
老規矩,先貼 self.client session比較簡單,無非就是繼承了user的各個屬性,這裡把類變數client清空了,不再是noclientwarningraiser 了。其他都是繼續沿用,只是例項化的時候client變成了session。這個時候第乙個關注點就是,例項化的時候一定要有ho...