常用的 Git 配置,你知道幾個?
- 使用NewServer函數構建服務實例,利用依賴注入方式將所有的依賴參數包含進來。
func NewServer(
logger *Logger
config *Config
commentStore *commentStore
anotherStore *anotherStore
) http.Handler {
mux := http.NewServeMux()
addRoutes(
mux,
Logger,
Config,
commentStore,
anotherStore,
)
var handler http.Handler = mux
handler = someMiddleware(handler)
handler = someMiddleware2(handler)
handler = someMiddleware3(handler)
return handler
}
- 在routes.go文件中統一定義所有路由函數。
func addRoutes(
mux *http.ServeMux,
logger *logging.Logger,
config Config,
tenantsStore *TenantsStore,
commentsStore *CommentsStore,
conversationService *ConversationService,
chatGPTService *ChatGPTService,
authProxy *authProxy
) {
mux.Handle("/api/v1/", handleTenantsGet(logger, tenantsStore))
mux.Handle("/oauth2/", handleOAuth2Proxy(logger, authProxy))
mux.HandleFunc("/healthz", handleHealthzPlease(logger))
mux.Handle("/", http.NotFoundHandler())
}
- 主函數只調用run函數來運行服務
func run(ctx context.Context, w io.Writer, args []string) error {
ctx, cancel := signal.NotifyContext(ctx, os.Interrupt)
defer cancel()
// ...
}
func main() {
ctx := context.Background()
if err := run(ctx, os.Stdout, os.Args); err != nil {
fmt.Fprintf(os.Stderr, "%s\n", err)
os.Exit(1)
}
}
- 返回閉包 handle
// handleSomething handles one of those web requests
// that you hear so much about.
func handleSomething(logger *Logger) http.Handler {
thing := prepareThing()
return http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
// use thing to handle request
logger.Info(r.Context(), "msg", "handleSomething")
}
)
}
- 定義通用的encode和decode函數
func encode[T any](w http.ResponseWriter, r *http.Request, status int, v T) error {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(status)
if err := json.NewEncoder(w).Encode(v); err != nil {
return fmt.Errorf("encode json: %w", err)
}
return nil
}
func decode[T any](r *http.Request) (T, error) {
var v T
if err := json.NewDecoder(r.Body).Decode(&v); err != nil {
return v, fmt.Errorf("decode json: %w", err)
}
return v, nil
}
- 提供一個抽象的 Validator 接口用于驗證
// Validator is an object that can be validated.
type Validator interface {
// Valid checks the object and returns any
// problems. If len(problems) == 0 then
// the object is valid.
Valid(ctx context.Context) (problems map[string]string)
}
func decodeValid[T Validator](r *http.Request) (T, map[string]string, error) {
var v T
if err := json.NewDecoder(r.Body).Decode(&v); err != nil {
return v, nil, fmt.Errorf("decode json: %w", err)
}
if problems := v.Valid(r.Context()); len(problems) > 0 {
return v, problems, fmt.Errorf("invalid %T: %d problems", v, len(problems))
}
return v, nil, nil
}
自定義校驗需要實現 Validator 接口。
7.使用 Once 延遲調用來提高啟動性能。
func handleTemplate(files string...) http.HandlerFunc {
var (
init sync.Once
tpl *template.Template
tplerr error
)
return func(w http.ResponseWriter, r *http.Request) {
init.Do(func(){
tpl, tplerr = template.ParseFiles(files...)
})
if tplerr != nil {
http.Error(w, tplerr.Error(), http.StatusInternalServerError)
return
}
// use tpl
}
}
What is OpenTelemetry?
這是一篇 OTel 的科普文章
OpenTelemetry 提供一個統一、可擴展的框架,用于收集、分析和觀察分布式系統的性能數據。它包括一組API、庫、代理和收集器,這些組件可以跨多種編程語言和平臺實現對應用程序的監控。
OpenTelemetry 整合 OpenTracing 和 OpenCensus。
2019年,兩個社區進行了合并。
同時 OTel 具備以下特征:
- 統一性:OpenTelemetry 提供了一個統一的API,使得開發者可以在不同的編程語言和框架中以一致的方式實現監控。
- 可擴展性:可以編寫自己的擴展來滿足個性化需要
- 跨平臺:OpenTelemetry 支持多種編程語言,如 Java、Python、Go、.NET 等,以及多種云服務和容器平臺。
- 社區驅動:作為一個開源項目,OpenTelemetry 由一個活躍的社區支持,社區成員貢獻代碼、文檔和最佳實踐。
- 與現有工具的兼容性:OpenTelemetry 設計時考慮了與現有監控工具的兼容性,如 Prometheus、Jaeger、Zipkin 等,這使得它可以輕松地集成到現有的監控基礎設施中。
提供了一種名為:OTLP(OpenTelemetry Protocol)的通訊協議,基于 gRPC。
使用該協議用于客戶端與 Collector 采集器進行交互。
Collector 是 OpenTelemetry 架構中的一個關鍵組件,它負責接收、處理和導出數據(Trace/log/metrics)。
它可以接受從客戶端發出的數據進行處理,同時可以導出為不同格式的數據。
總的來說 OTel 是可觀測系統的新標準,基于它可以兼容以前使用的 Prometheus、 victoriametrics、skywalking 等系統,同時還可以靈活擴展,不用與任何但一生態或技術棧進行綁定。
Popular git config options
本文總結了一些常用的 git 配置
- pull.ff only 或 pull.rebase true:這兩個選項都可以避免在執行git pull時意外創建合并提交,特別是當上游分支已經發生了變化的時候。
- merge.conflictstyle diff3:這個選項使得合并沖突更易于閱讀,通過在沖突中顯示原始代碼版本,幫助用戶更好地解決沖突。
- rebase.autosquash true 和 rebase.autostash true:這些選項使得修改舊提交變得更容易,并且自動處理stash。
- push.default simple 或 push.default current:這些選項告訴git push自動推送當前分支到同名的遠程分支。
- init.defaultBranch main:創建新倉庫時,默認創建main分支而不是master分支。
- commit.verbose true:在提交時顯示整個提交差異。
- rerere.enabled true:啟用rerere功能,自動解決沖突
- help.autocorrect:設置自動矯正的級別,以自動運行建議的命令。
- core.pager delta:設置Git使用的分頁器,例如使用delta來查看帶有語法高亮的diff。
- diff.algorithm histogram:設置Git的diff算法,以改善函數重排時的diff顯示。
文章鏈接: