Go微服務實戰 - 用戶服務開發(gRPC+Protocol Buffer)

来源:https://www.cnblogs.com/qloog/archive/2022/10/02/microservice-practice-user-service.html
-Advertisement-
Play Games

resultMap處理欄位和屬性的映射關係 如果欄位名與實體類中的屬性名不一致,該如何處理映射關係? 第一種方法:為查詢的欄位設置別名,和屬性名保持一致 下麵是實體類中的屬性名: private Integer empId; private String empName; private Integ ...


概要

用戶服務基本是每個互聯網產品里必備的一個服務了,因為沒有用戶基本是什麼也幹不了。所以他的重要性不言而喻。本文主要介紹下如何開發一個用戶微服務,以及他的詳細開發流程。

目錄

調用流程圖

技術棧

介面開發

使用proto方式定義,主要包含以下介面

開發步驟

這裡詳細的記錄了開發的步驟,方便參看本項目的同學知道其實現過程。

1、生成proto模板文件

eagle proto add api/user/v1/user.proto

內容如下

syntax = "proto3";

package api.user.v1;

option go_package = "github.com/go-microservice/user-service/api/user/v1;v1";
option java_multiple_files = true;
option java_package = "api.user.v1";

service UserService {
	rpc CreateUser (CreateUserRequest) returns (CreateUserReply);
	rpc UpdateUser (UpdateUserRequest) returns (UpdateUserReply);
	rpc DeleteUser (DeleteUserRequest) returns (DeleteUserReply);
	rpc GetUser (GetUserRequest) returns (GetUserReply);
	rpc ListUser (ListUser1Request) returns (ListUserReply);
}

message CreateUser1Request {}
message CreateUser1Reply {}

message UpdateUserRequest {}
message UpdateUserReply {}

message DeleteUserRequest {}
message DeleteUserReply {}

message GetUserRequest {}
message GetUserReply {}

message ListUserRequest {}
message ListUserReply {}

2、為proto填充業務方法及欄位定義

vim api/user/v1/user.proto

3、生成pb文件

# 生成所有proto
make grpc

# 或者
# 生成指定proto的pb文件
eagle proto client api/user/v1/user.proto

# Output
ll api/user/v1/
user.pb.go #新增
user.proto
user_grpc.pb.go #新增

會生成兩個文件 api/user/v1/user.pb.goapi/user/v1/user.pb.go

4、生成server骨架代碼

# 生成骨架代碼
eagle proto server api/user/v1/user.proto

# 預設會輸出到 internal/service
# 如果需要指定到對應的目錄,可以使用 -t 參數, eg: 
# eagle proto server -t internal/logic

# 查看
internal/service/user_svc.go

5、註冊服務到gRPC Server

// internal/server/grpc.go 

import (
		...
		v1 "github.com/go-microservice/user-service/api/user/v1"
		...
)

...

// NewGRPCServer creates a gRPC server
func NewGRPCServer(
	cfg *app.ServerConfig,
	// 新增
	svc *service.UserServiceServer, 
) *grpc.Server {

	grpcServer := grpc.NewServer(
		grpc.Network("tcp"),
		grpc.Address(cfg.WriteTimeout),
		grpc.Timeout(cfg.WriteTimeout),
	)

	// register biz service
	// 新增
	v1.RegisterUserServiceServer(grpcServer, svc)

	return grpcServer
}

6、在生成的server中編寫業務邏輯

// vim internal/service/user_svc.go

package service

import (
	"context"

	pb "github.com/go-microservice/moment-service/api/user/v1"
)

var (
	_ pb.UserServiceServer = (*UserServiceServer)(nil)
)

type UserServiceServer struct {
	pb.UnimplementedUserServiceServer
}

func NewUserServiceServer() *UserServiceServer {
	return &UserServiceServer{
}
}

func (s *UserServiceServer) CreateUser(ctx context.Context, req *pb.CreateUserRequest) (*pb.CreateUserReply, error) {

	return &pb.CreateUserReply{}, nil
}
func (s *UserServiceServer) UpdateUser(ctx context.Context, req *pb.UpdateUserRequest) (*pb.UpdateUserReply, error) {
	return &pb.UpdateUserReply{}, nil
}
func (s *UserServiceServer) DeleteUser(ctx context.Context, req *pb.DeleteUserRequest) (*pb.DeleteUserReply, error) {
	return &pb.DeleteUserReply{}, nil
}
func (s *UserServiceServer) GetUser(ctx context.Context, req *pb.GetUserRequest) (*pb.GetUserReply, error) {
	return &pb.GetUserReply{}, nil
}
func (s *UserServiceServer) ListUser(ctx context.Context, req *pb.ListUserRequest) (*pb.ListUserReply, error) {
	return &pb.ListUserReply{}, nil
}

後面就可以在這裡補充具體的業務邏輯處理了。

7、啟動服務

# 在根目錄下運行
go run main.go

確保運行gRPC server

// main.go

...
eagle.WithServer(
	// init gRPC server
	gs,
),
...

8、介面調試

調試工具,這裡使用 [grpcurl](https://github.com/fullstorydev/grpcurl)

# 查看服務列表
grpcurl -plaintext localhost:9090 list

# Output
api.user.v1.UserService
grpc.health.v1.Health
grpc.reflection.v1alpha.ServerReflection

# 訪問列表
grpcurl -plaintext -d '{"user_id":2}' localhost:9090 api.user.v1.UserService/ListUser

參數說明

  • -d 提交的參數, json格式
  • -plaintext 使用純文本連接,跳過TLS

也可以使用以下工具進行本地測試

部署

兩種部署方式

  • docker
  • k8s (本地部署可以使用minikube)

部署步驟

  • 構建docker鏡像

    docker build -t user-service:v1.0.0 -f deploy/docker/Dockerfile .
    
  • 打docker tag

    docker tag user-service:v1.0.0 qloog/user-service:v1.0.0
    
  • push tag 到 docker hub

    docker push qloog/user-service:v1.0.0
    
  • 部署到k8s

    kubectl apply -f deploy/k8s/go-deployment.yaml
    kubectl apply -f deploy/k8s/go-service.yaml
    

以上命令都是一步一步執行的,為了方便期間,這裡也提供了一件部署腳本,執行如下

sh deploy/deploy.sh

項目源碼

最終源碼在這裡:https://github.com/go-microservice/user-service

完結

到此,開發、測試、部署已經操作完了,後面會繼續完善鏈路追蹤和監控相關的部分。

感謝閱讀, 祝大家 Happy coding~


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、節流 概念:在規定的間隔時間範圍內不會重覆觸發回調,只有大於這個時間間隔才會觸發回調,把頻繁觸發變為少量觸發。 類似於技能CD。 應用:點擊按鈕,輪播圖點擊左右箭頭。 插件lodash.js,它裡面封裝了函數的防抖與節流業務。 <p>計數器:<span>0</span></p> <button> ...
  • Spring 5框架 一、Spring概念 1、Spring是輕量級的JavaEE框架 2、Spring可以解決企業應用開發的複雜性 3、Spring有兩個核心部分:IOC和AOP ​ 1)IOC:控制反轉,把創建對象過程交給Spring進行管理 ​ 2)AOP:面向切麵,不修改源代碼進行功能增強 ...
  • LinkList可以定義指向List的指針 1.當函數參數為LinkList L時,意味著只改變或操作List的內容,而不需要改變L這個指針 如 Status GetElem(LinkList L,int i,ElemType) 2.當參數為LinkList &L時,意味著需要改變或操作L這個指針本 ...
  • ♠ use C++11 倍數 若 $a,b,k \in \mathbb N$,且 $a \times k=b$,那麼 $b$ 是 $a$ 的倍數,稱 $a$ 整除 $b$,記作 $a \mid b$。 $[1,n]\in \mathbb N$ 中 $x \in \mathbb N$ 的倍數有 $\l ...
  • 本文講解了決策樹的創鍵的過程,包括熵,信息增益的計算,還有決策樹的創建,以及使用matplotlib讓決策樹可視化的詳細過程 ...
  • 設計模式的目的 編寫軟體過程中,程式員面臨著來自 耦合性,內聚性以及可維護性,可擴展性,重用性,靈活性 等多方面的 挑戰,設計模式是為了讓程式(軟體),具有更好 代碼重用性 (即:相同功能的代碼,不用多次編寫) 可讀性 (即:編程規範性, 便於其他程式員的閱讀和理解) 可擴展性 (即:當需要增加新的 ...
  • 給定一個不含重覆數字的數組 nums ,返回其 所有可能的全排列 。你可以 按任意順序 返回答案。 示例 1: 輸入:nums = [1,2,3] 輸出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] 示例 2: 輸入:nums = [0,1] 輸 ...
  • 大家在看到這篇文章前,為了有一個舒適的c++IDE,一定感受到了Dev-c++的廉價感,Clion功能的多餘,VS的臃腫。他們也有自己的優點,但糟點太多,令人十分難受。而VS Code,可以取長補短。下麵的配置內容,可以讓你在刷題時,享受絲滑的動畫,體會集成終端的方便,讓你覺得Coding不再枯燥。 ...
一周排行
    -Advertisement-
    Play Games
  • public static void GetRegistData() { string name = "huishuangzhu"; //搜索到註冊表根目錄 RegistryKey hkml = Registry.ClassesRoot; //搜索到註冊表根目錄下的XXX文件夾。 RegistryK ...
  • 用acme.sh自動部署功能變數名稱證書 安裝ACME 目前使用量最大的免費SSL證書就是Let’s Encrypt,自2018-03開始,Let’s Encrypt官方發佈上線了免費的SSL泛功能變數名稱證書,目前通過DNS方式獲取比較快,國內可以通過鵝雲的DNSPod功能變數名稱API或者貓雲功能變數名稱API自動簽發Let’ ...
  • 經常看到有群友調侃“為什麼搞Java的總在學習JVM調優?那是因為Java爛!我們.NET就不需要搞這些!”真的是這樣嗎?今天我就用一個案例來分析一下。 昨天,一位學生問了我一個問題:他建了一個預設的ASP.NET Core Web API的項目,也就是那個WeatherForecast的預設項目模 ...
  • 1、環境搭建 1.1 依賴 <!-- nacos註冊中心 註解 @EnableDiscoveryClient --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba- ...
  • ULID:Universally Unique Lexicographically Sortable Identifier(通用唯一詞典分類標識符) UUID:Universally Unique Identifier(通用唯一標識符) 為什麼不選擇UUID UUID 目前有 5 個版本: 版本1: ...
  • 虛基類/抽象類 抽象類:有純虛函數的類 虛繼承 通過修飾繼承方式, 如代碼2是虛繼承,被虛繼承的類稱為虛基類 虛繼承派生類的記憶體佈局方式 先是vbptr => 派生類的數據 =>基類的數據 , 對比代碼1和代碼2,發現原本基類數據在前面,派生類數據在後面,但是在虛繼承的時候 基類數據方式放到了後面, ...
  • 下麵給出 Kafka 一些重要概念,讓大家對 Kafka 有個整體的認識和感知,後面還會詳細的解析每一個概念的作用以及更深入的原理 • Producer:消息生產者,向 Kafka Broker 發消息的客戶端。 • Consumer:消息消費者,從 Kafka Broker 取消息的客戶端。 • ...
  • 前面介紹了對稱加密演算法,本文將介紹密碼學中另一類重要應用:消息摘要(Digest),什麼是消息摘要?簡單的定義是:對一份數據,進行一個單向的Hash函數,生成一個固定長度的Hash值,這個值就是這份數據的摘要,也稱為指紋。 ...
  • 弟弟最近要考試,臨時抱佛腳在網上找了一堆學習資料複習,這不剛就來找我了,說PDF上有水印,影響閱讀效果,到時候考不好就怪資料不行,氣的我差點當場想把他揍一頓! 算了,弟弟長大了,看在打不過他的份上,就不打他了~ 稍加思索,我想起了Python不是可以去水印?說搞就搞! 去除水印原理 去除方法: 用 ...
  • 作者:陳昌浩 1 導讀 if…else…在代碼中經常使用,聽說可以通過Java 8的Function介面來消滅if…else…!Function介面是什麼?如果通過Function介面介面消滅if…else…呢?讓我們一起來探索一下吧。 2 Function介面 Function介面就是一個有且僅有 ...