《gPRC使用protobuf構建微服務》閱讀筆記


首先我需要去了解一些概念,根據百度百科了解到:

l  微服務架構:微服務架構是一項在雲中部署應用和服務的新技術。微服務可以在“自己的程序”中運行,並通過“輕量級設備與HTTP型API進行溝通”。

l  gPRC:gRPC 是一款高性能、開源的 RPC 框架,產自 Google,基於 ProtoBuf 序列化協議進行開發,支持多種語言。

我們過去根據 MVC 划分目錄結構,由Controller 層處理業務邏輯,Model 層作為對象實體類,對數據庫進行 CURD操作,View 視圖層處理數據渲染和頁面交互。以及 MVP、MVVM 都是將整個項目的代碼是集中在一個代碼庫中,進行業務處理。這種單一聚合代碼的方式在前期實現業務的速度很快,但在后期會暴露很多問題:

1. 開發與維護困難:隨着業務復雜度的增加,代碼的耦合度往往會變高,多個模塊相互耦合后不易橫向擴展

2. 效率和可靠性低:過大的代碼量將降低響應速度,應用潛在的安全問題也會累積

微服務將一個大且聚合的業務項目拆解為多個小且獨立的業務模塊,每一模塊即服務,各服務間使用高效的協議(protobuf、JSON 等)相互調用即是 RPC。這種拆分代碼庫的方式有以下特點:

每個服務應作為小規模的、獨立的業務模塊在運行,類似 Unix 的 Do one thing and do it well

每個服務應在進行自動化測試和(分布式)部署時,不影響其他服務

每個服務內部進行細致的錯誤檢查和處理,提高了健壯性

本質上,二者只是聚合與拆分代碼的方式不同。

安裝gRPC與protoc編譯器:

go get -u google.golang.org/grpc

go get -u github.com/golang/protobuf/protoc-gen-go

定義微服務的user.protoc文件

syntax = "proto3";    // 指定語法格式,注意 proto3 不再支持 proto2 的 required 和 optional

package proto;        // 指定生成的 user.pb.go 的包名,防止命名沖突

 

 

// service 定義開放調用的服務,即 UserInfoService 微服務

service UserInfoService {

    // rpc 定義服務內的 GetUserInfo 遠程調用

    rpc GetUserInfo (UserRequest) returns (UserResponse) {

    }

}

 

 

// message 對應生成代碼的 struct

// 定義客戶端請求的數據格式

message UserRequest {

    // [修飾符] 類型 字段名 = 標識符;

    string name = 1;

}

 

 

// 定義服務端響應的數據格式

message UserResponse {

    int32 id = 1;

    string name = 2;

    int32 age = 3;

repeated string title = 4;    // repeated 修飾符表示字段是可變數組,即 slice 類型

生成 user.pb.go

package proto

 

import (

    context "golang.org/x/net/context"

    grpc "google.golang.org/grpc"

)

 

// 請求結構

type UserRequest struct {

    Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`

}

 

// 為字段自動生成的 Getter

func (m *UserRequest) GetName() string {

    if m != nil {

        return m.Name

    }

    return ""

}

 

// 響應結構

type UserResponse struct {

    Id    int32    `protobuf:"varint,1,opt,name=id" json:"id,omitempty"`

    Name  string   `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`

    Age   int32    `protobuf:"varint,3,opt,name=age" json:"age,omitempty"`

    Title []string `protobuf:"bytes,4,rep,name=title" json:"title,omitempty"`

}

// ...

 

// 客戶端需實現的接口

type UserInfoServiceClient interface {

    GetUserInfo(ctx context.Context, in *UserRequest, opts ...grpc.CallOption) (*UserResponse, error)

}

 

 

// 服務端需實現的接口

type UserInfoServiceServer interface {

    GetUserInfo(context.Context, *UserRequest) (*UserResponse, error)

}

 

// 將微服務注冊到 grpc

func RegisterUserInfoServiceServer(s *grpc.Server, srv UserInfoServiceServer) {

    s.RegisterService(&_UserInfoService_serviceDesc, srv)

}

// 處理請求

func _UserInfoService_GetUserInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {...}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM