main函數在哪里?

看到這個go文件時大家是不是有一種找到入口的欣喜,同時有一種難以言表的郁悶,為什么那么短?獲取一個command,然后執行一個Execute()就運行了?好像是這么回事,然后點開了Execute()方法:

越往下看越郁悶,咋那么難。。。
這時候看一下我們在哪里,可以發現當前路徑是:
D:/go/src/k8s.io/kubernetes/vendor/github.com/spf13/cobra/command.go:790
尷尬,一開始就陷入了3方庫。點開NewSchedulerCommand()函數看看呢:

到這里好像我們發現了什么,cobra是個什么東西?似乎cobra影響了整個代碼結構,獲取command是cobra的Command對象,最后的Execute()方法也是cobra提供的方法。於是不難發現,這是一個繞不過去的三方庫,我們得先花點力氣查查cobra是什么!
cobra是什么?
我們可以在github上看到這個項目

來自spf13,看來是精品!上圖的英文介紹里可以看到一點消息:A Commander for modern Go CLI interactions
然后瀏覽一下README.md(建議大家到github上認真看一下這個說明文檔),我們大致可以看出來

天哪,那么多知名開源go項目,k8s生態的etcd、docker、之上的openshift等等居然都用了cobra!明顯這些項目都用了cobra當做“腳手架”,也就是入口風格會很像!spf13寫的pflag等都是大名鼎鼎的輪子中的精品啊,看來cobra很值得稍微深入一下,如果自己開發命令行工具,需要用到子命令和flag的話,spf13的cobra和pflag是不二之選了。
一句話介紹cobra,然后我們簡單實踐一下:支持子命令行模式和復雜flag的時髦命令行程序腳手架!
cobra程序長什么樣?
要寫個demo,當然得先install cobra. 作為一只gopher,我相信大家install 一個github上的go項目是沒有壓力的,此中無非可能遇到網絡問題,go get不行就git clone,缺啥找啥,最終下載完是這樣的:


下面我們試着寫一個小小的cobra程序:

如上命令,cobra告訴我們application is ready at xxx,所以我們看一下本地生成了些什么:

本地自動創建好了一個項目,我們看一下main.go里面是什么:

是不是有點小激動?和kube-scheduler的入口一樣一樣的!我們運行如下命令來添加2個command:


我們打開version.go稍微修改一下:


發現沒有,當我們執行一個命令時,對應的command中Run方法會被執行!我們最后看一個子命令的玩法:

怎么樣,輕輕松松寫了一個支持多級命令的程序,后面一張圖可以看到上面我們輸入命令中serverCmd的含義:

下面看kube-scheduler中對應的Run在哪里?
cmd/kube-scheduler/app/server.go:322 func NewSchedulerCommand() *cobra.Command

繼續看一下Run:后面是什么:

這個Run()方法繼續跟一下:

是不是發現好像接近真相了?
這個server.Run()我們繼續看看:

太和諧了!這個注釋也可以直觀看到這就是運行SchedulerServer的入口,這個函數接收到stop信息前會一直運行下去,也就是一直運行着的kube-scheduler!!!
我們最后回頭看一下main.go

是不是很好理解了?第一個紅框中設置Run()方法中需要做什么,后面的Execute()方法其實就是運行了前面定義的Run()方法!
今天就講到這里,我們下一講尋找調度算法!

