首頁 > 軟體

Go語言從單體服務到微服務設計方案詳解

2023-03-23 22:03:14

概述

微服務是一種思想,與程式語言無關,程式語言是思想下具體的一種實現方式,怎麼設計架構方案和實現主要看主要面臨的業務場景。

業務場景

主站核心業務使用的是yaf(php)開發的,要實現k8s + x程式語言 自主微服務實現,受到陳皓(左耳聽風)的影響,我選用的程式語言是Go,Go語言有更強大的生態,有谷歌,k8s作為強大的後盾,摸著石頭過河。

設計方案

Api閘道器

提到微服務我們就聯想到Rpc,主流微服務價格設計,微服務之間的呼叫都使用Rpc,微服務也有直接用http實現的,Rpc限制了開發時候的靈活性和相容性,主要3點原因:

1.Http協定是實際通訊的標準,靈活性和相容性得到了很好的市場驗證,對Rpc我抱有懷疑態度,在Api層進行許可權的統一認證( Token/Cookies ) , 後期微服務體系成熟,可以統一接入Api閘道器服務,Api閘道器服務是不可缺少的,全使用Nginx反向代理的方式,再資料統計的角度上侷限性。

2.控制異常,如果發生異常,Rpc服務掛掉或者遭到網路攻擊/刷請求,請求會直接打到Rpc上,如果有閘道器層,可以在Redis中加Redis鎖,把無效的網路請求進行隔離。

資料

拆分微服務最大的兩個問題是資料的一致性效能,系統效能的瓶頸主要是因為計算機Cpu,記憶體(memory/記憶體條、cache/Cpu的記憶體) 是非常快的,所有的效能問題大同小異,磁碟I/O往往才是效能的瓶頸。

1.資料的一致性的解決辦法

模組化拆分和遷移微服務功能,把涉及到的整塊進行遷移,可以按比重分流/整體功能進行,按比重分流要保留新舊資料的相容,需要雙寫,現在的有聲業務體量小,可以整塊整塊的遷移。

2.效能:有聲的資料量非常小,暫時不使用redis快取可能也不會造成什麼效能問題,所以我把很小的公共部分進行了快取,主要考慮C端使用者的體驗。

Go中的Grpc使用

Go-zero這個框架使用goctl工具開發速度非常高效,對呼叫外部的Grpc服務需要做更多的相容,這裡做一個解釋說明,protoc-gen-goprotoc-gen-go-grpc這兩個工具是protobuf的工具,是Go 1.5版本後新加的,這個地方饒了好大一圈。

GitHub Demo 地址 : github.com/grpc/grpc-g…

$ go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28
$ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2

在有聲微服務中,是呼叫UserRpc的許可權驗證部分,Go-zero不支援,所以自己寫了一些相容包。

1.首先pb檔案生成Pb和Grpc檔案

$ ll
-rw-r--r--  1 stark  staff    69K  3 20 15:51 cp_user_internal.pb.go
-rw-r--r--  1 stark  staff    34K  3 20 15:51 cp_user_internal_grpc.pb.go

2.呼叫UserRpc服務,需要實現的包是使用者端部分程式碼,本地需要TLS加密,服務才能被呼叫的到,grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})))是TLS靈魂。

package client
func Auth(Session string, Action string, Controller string, Param string) bool {
    // 1.建立連結
    flag.Parse()
	conn, err := grpc.Dial("testing.gongzicp.com:1443", grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})))
	if err != nil {
		log.Fatalf("did not connect: %v", err)
	}
	defer conn.Close()
	client := pb.NewUserInternalClient(conn)
	//2.驗證管理員許可權
	resp, err := client.AdminMid(context.Background(), &pb.UserInternalParams_AdminMidReq{
		Session: Session,
	})
	//3.驗證選單許可權
	auth, err := client.AdminAuth(context.Background(), &pb.UserInternalParams_AdminAuthReq{
			Action:     Action,
			Controller: Controller,
			Param:      Param,
			Session:    Session,
		})
	//....
}

問題和反思

1.有聲服務和主站的關聯非常小,但是也有關聯NovelId獲取資訊的部分,Novel屬於核心服務,可能每一個地方的需要都不少。

2.Web端(Ukey) 、App安卓/Ios(Token) 本質上是一個維度的東西,型別上應該只用戶/和系統管理員2種型別,最好是把服務類抽離出來做成單獨的服務,可能會更好一些。

以上就是Go語言從單體服務到微服務設計方案詳解的詳細內容,更多關於Go單體服務微服務設計的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com