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
  • 1. 說明 /* Performs operations on System.String instances that contain file or directory path information. These operations are performed in a cross-pla ...
  • 視頻地址:【WebApi+Vue3從0到1搭建《許可權管理系統》系列視頻:搭建JWT系統鑒權-嗶哩嗶哩】 https://b23.tv/R6cOcDO qq群:801913255 一、在appsettings.json中設置鑒權屬性 /*jwt鑒權*/ "JwtSetting": { "Issuer" ...
  • 引言 集成測試可在包含應用支持基礎結構(如資料庫、文件系統和網路)的級別上確保應用組件功能正常。 ASP.NET Core 通過將單元測試框架與測試 Web 主機和記憶體中測試伺服器結合使用來支持集成測試。 簡介 集成測試與單元測試相比,能夠在更廣泛的級別上評估應用的組件,確認多個組件一起工作以生成預 ...
  • 在.NET Emit編程中,我們探討了運算操作指令的重要性和應用。這些指令包括各種數學運算、位操作和比較操作,能夠在動態生成的代碼中實現對數據的處理和操作。通過這些指令,開發人員可以靈活地進行算術運算、邏輯運算和比較操作,從而實現各種複雜的演算法和邏輯......本篇之後,將進入第七部分:實戰項目 ...
  • 前言 多表頭表格是一個常見的業務需求,然而WPF中卻沒有預設實現這個功能,得益於WPF強大的控制項模板設計,我們可以通過修改控制項模板的方式自己實現它。 一、需求分析 下圖為一個典型的統計表格,統計1-12月的數據。 此時我們有一個需求,需要將月份按季度劃分,以便能夠直觀地看到季度統計數據,以下為該需求 ...
  • 如何將 ASP.NET Core MVC 項目的視圖分離到另一個項目 在當下這個年代 SPA 已是主流,人們早已忘記了 MVC 以及 Razor 的故事。但是在某些場景下 SSR 還是有意想不到效果。比如某些靜態頁面,比如追求首屏載入速度的時候。最近在項目中回歸傳統效果還是不錯。 有的時候我們希望將 ...
  • System.AggregateException: 發生一個或多個錯誤。 > Microsoft.WebTools.Shared.Exceptions.WebToolsException: 生成失敗。檢查輸出視窗瞭解更多詳細信息。 內部異常堆棧跟蹤的結尾 > (內部異常 #0) Microsoft ...
  • 引言 在上一章節我們實戰了在Asp.Net Core中的項目實戰,這一章節講解一下如何測試Asp.Net Core的中間件。 TestServer 還記得我們在集成測試中提供的TestServer嗎? TestServer 是由 Microsoft.AspNetCore.TestHost 包提供的。 ...
  • 在發現結果為真的WHEN子句時,CASE表達式的真假值判斷會終止,剩餘的WHEN子句會被忽略: CASE WHEN col_1 IN ('a', 'b') THEN '第一' WHEN col_1 IN ('a') THEN '第二' ELSE '其他' END 註意: 統一各分支返回的數據類型. ...
  • 在C#編程世界中,語法的精妙之處往往體現在那些看似微小卻極具影響力的符號與結構之中。其中,“_ =” 這一組合突然出現還真不知道什麼意思。本文將深入剖析“_ =” 的含義、工作原理及其在實際編程中的廣泛應用,揭示其作為C#語法奇兵的重要角色。 一、下劃線 _:神秘的棄元符號 下劃線 _ 在C#中並非 ...