K8s源碼風格及規範


1、工程概述

  • 本項目主要基於Kubernetes集羣開展,針對開源項目進行功能擴展。要求基於已有的Kubernetes集羣和Prometheus 監控系統進行擴展開發。
  • K8s是由Google開發,並使用go語言進行開發的。

2、源碼準備

1.系統環境:
  • 操做系統:咱們使用Linux做爲k8s源碼分析和調試環境,fedora、centos、ubuntu都行,我這裏使用fedora;
  • golang相關:
GOROOT=/usr/local/lib/golang
GOPATH=/root/go
go version go1.10.3 linux/amd64
2.源碼下載
mkdir -p /root/go/src/k8s.io
cd /root/go/src/k8s.io/
git clone https://github.com/kubernetes/kubernetes.git
  • 目錄展現:
    html

  • 主要目錄:mysql

目錄名 功能
cmd 每一個組件代碼入口(main函數)
pkg 各個組件的具體功能實現
staging 已經分庫的項目
vendor 依賴
3.IDE
  • 經過學校郵箱申請JetBrains的教育帳號,經過Goland看代碼:

3、go語言特色及命名規範

1.go語言特色

GO語言的關鍵特性主要包括如下幾方面:linux

  • 併發與協程
  • 基於消息傳遞的通訊方式
  • 豐富實用的內置數據類型
  • 函數多返回值
  • defer機制
  • 反射(reflect)
  • 高性能HTTP Server
  • 工程管理
  • 編程規範
2.相關規範
  • package名字
    保持package的名字和目錄保持一致,儘可能採起有意義的包名,簡短,有意義,儘可能和標準庫不要衝突。git

  • import 規範
    import在多行的狀況下,自動工具會自動幫你格式化,可是咱們這裏仍是規範一下import的一些規範,若是你在一個文件裏面引入了一個package,仍是建議採用以下格式:github

import (
    "fmt"
)

若是你的包引入了三種類型的包,標準庫包,程序內部包,第三方包,建議採用以下方式進行組織你的包:golang

import (
    "strings"

    "myproject/models"
    "myproject/controller"

    "github.com/mysql"
)

有順序的引入包,不一樣的類型採用空格分離,第一種實標準庫,第二是項目包,第三是第三方包。在項目中不要使用相對路徑引入包:sql

// 這是很差的導入
import 「../pkg」

// 這是正確的作法
import 「github.com/tx23/pkg」
  • 變量申明
    變量名採用駝峯標準,不要使用_來命名變量名,多個變量申明放在一塊兒
    在函數外部申明必須使用var,不要採用:=,容易踩到變量的做用域的問題。
var (
    Found bool
    count int
)
  • 自定義類型的string循環問題
    若是自定義的類型定義了String方法,那麼在打印的時候會產生隱藏的一些bug。
type MyInt int
func (m MyInt) String() string { 
    return fmt.Sprint(m)   //BUG:死循環
}

func(m MyInt) String() string { 
    return fmt.Sprint(int(m))   //這是安全的,由於咱們內部進行了類型轉換
}
  • 避免返回命名的參數
    若是你的函數很短小,少於10行代碼,那麼可使用,否則請直接使用類型,由於若是使用命名變量很容易引發隱藏的bug。
func Foo(a int, b int) (string, ok){

}

固然若是是有多個相同類型的參數返回,那麼命名參數可能更清晰。數據庫

func (f *Foo) Location() (float64, float64, error)編程

  • 錯誤處理
    錯誤處理的原則就是不能丟棄任何有返回err的調用,不要採用_丟棄,必須所有處理。接收到錯誤,要麼返回err,要麼實在不行就panic,或者使用log記錄下來,error的信息不要採用大寫字母,儘可能保持你的錯誤簡短,可是要足夠表達你的錯誤的意思。ubuntu

  • 注意閉包的調用
    在循環中調用函數或者goroutine方法,必定要採用顯示的變量調用,不要再閉包函數裏面調用循環的參數

fori:=0;i<limit;i++{
    go func(){ DoSomething(i) }() //錯誤的作法
    go func(i int){ DoSomething(i) }(i)//正確的作法
}
  • 在邏輯處理中禁用panic
    在main包中只有當實在不可運行的狀況採用panic,例如文件沒法打開,數據庫沒法鏈接致使程序沒法正常運行,可是對於其餘的package對外的接口不能有panic,只能在包內採用。強烈建議在main包中使用log.Fatal來記錄錯誤,這樣就能夠由log來結束程序。

  • struct規範
    struct申明和初始化格式採用多行:
    定義以下:

type User struct{
    Username  string
    Email     string
}

初始化以下:

u := User{
    Username: "astaxie",
    Email:    "astaxie@gmail.com",
}
  • recieved是值類型仍是指針類型
    究竟是採用值類型仍是指針類型主要參考以下原則:
func(w Win) Tally(playerPlayer)int    //w不會有任何改變 
func(w *Win) Tally(playerPlayer)int    //w會改變數據

更多的請參考:
https://code.google.com/p/go-wiki/wiki/CodeReviewComments#Receiver_Type

  • 帶mutex的struct必須是指針receivers
    若是你定義的struct中帶有mutex,那麼你的receivers必須是指針

參考資料:
https://code.google.com/p/go-wiki/wiki/CodeReviewComments
http://golang.org/doc/effective_go.html

相關文章
相關標籤/搜索