Sensu Server原始碼剖析

2021-08-27 20:16:56 字數 4124 閱讀 1981

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...