使用grpc開發RPC服務(一)

前言

筆者最近換了一份工做從一家新零售公司去到一家作電子商務的公司,主要的編程語言也從NodeJs轉爲了Go,由於新公司使用的是grpc作的微服務,因此要從新開始學習新的東西了,正好把這周學習的東西作個總結。
整個系列主要涉及Golang、gRPC、go-micros、Docker、Docker-compose、consul,經過本系列,你能夠了解到如何一、使用grpc/go-mircos構建微服務,二、使用docker進行服務的部署,三、使用consul進行服務發現html

grpc簡介

gRPC是谷歌開源的一款跨平臺、高性能的RPC框架,筆者目前主要使用它來進行後端微服務的開發。
可能會有的同窗對RPC不太熟悉,其實在筆者看來,RPC和HTTP並沒有多大的區別都是一種調用方式,區別則是在於RPC會限制傳輸協議、傳輸的參數等,以此換取高效的傳輸流程,好比grpc就使用的是google開源的protobuf協議,使用TCP的方式進行傳輸,使得請求比起普通的JSON+HTPP更加快捷。關於更多protobuf的信息,能夠查看這裏nginx

必要的準備

  • 瞭解Golang及其生態
  • 安裝gRPc及protobuf,教程
  • 安裝golang
  • 安裝protobuf編譯器

本期目標

本期目標是使用gRPC實現一個很是小的微服務user-service,服務的功能很是簡單,只提供一個獲取用戶信息的接口golang

1、首先咱們須要定義好整個服務的protobuf文件user.proto
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 類型

}

而後咱們經過protoc命令編譯proto文件,生成對應的go文件docker

protoc -I . --go_out=plugins=grpc:. ./user.proto

具體文件太長就不放出來展現了編程

2、咱們來實現server.go

首先咱們應該明確實現的步驟:
一、實現GetUserInfo接口
二、使用gRPC創建服務,監聽端口
三、將咱們實現的服務註冊到gRPC中去
話很少說,代碼以下後端

package  main

import (
"fmt"
"log"
"net"
// Import the generated protobuf code
pb "go_mirco_service/proto"
"golang.org/x/net/context"
"google.golang.org/grpc"

)
type  UserInfoService  struct{}
var  u  = UserInfoService{}

func (u *UserInfoService) GetUserInfo(ctx context.Context, req *pb.UserRequest) (resp *pb.UserResponse, err error) {

name  := req.Name

if name ==  "leoython" {

resp  =  &pb.UserResponse{

Id: 233,

            Name: name,

Age: 20,

            Title: []string{"Gopher"},

        }

    }

err  =  nil

return

}

  

func  main() {

port  :=  ":2333"

l, err  := net.Listen("tcp", port)

if err !=  nil {

        log.Fatalf("listen error: %v\n", err)

    }

    fmt.Printf("listen %s\n", port)

s  := grpc.NewServer()

  

// 將 UserInfoService 註冊到 gRPC

// 注意第二個參數 UserInfoServiceServer 是接口類型的變量

// 須要取地址傳參

    pb.RegisterUserInfoServiceServer(s, &u)

    s.Serve(l)

}

到此咱們就實現了利用gRPC實現了一個很是簡單可是五臟俱全的RPC服務,可是卻出現了一個問題,咱們沒法直接調用,因此咱們還須要實現一個調用server的客戶端,代碼以下數組

package  main

  

import (

"fmt"

"log"

  

pb "go_mirco_service/proto"

  

"golang.org/x/net/context"

"google.golang.org/grpc"

)

  

func  main() {

conn, err  := grpc.Dial(":2333", grpc.WithInsecure())

if err !=  nil {

        log.Fatalf("dial error: %v\n", err)

    }

defer conn.Close()

  

// 實例化 UserInfoService 微服務的客戶端

client  := pb.NewUserInfoServiceClient(conn)

  

// 調用服務

req  :=  new(pb.UserRequest)

req.Name  =  "leoython"

resp, err  := client.GetUserInfo(context.Background(), req)

if err !=  nil {

        log.Fatalf("resp error: %v\n", err)

    }

    fmt.Printf("Recevied: %v\n", resp)

}

結語

至此,咱們已經學會使用gRPC進行開發,採用protobuf進行參數的定義,下一篇筆者將會使用grpc-gateway將RPC接口轉換爲rest接口供客戶端調用,而不須要客戶端實現RPC,這也是如今主流微服務的一種服務提供方式,對外使用REST,對內使用RPC,關於更多微服務的內容,推薦查看nginx的關於微服務的文章框架

關於做者

  • Leoython,擅長Javascript, Python, Go,最近在研究Rust和k8s
  • E-Mail: leoython@gmail.com
  • 文章編寫於: 2019/01/31

轉載請註明出處:tcp

http://www.leoython.club/arti...編程語言

相關文章
相關標籤/搜索