etcd套路(九)註冊服務中心程式碼封裝

huxiaobai_001發表於2020-08-27

上上篇我們講了如何搞etcd的服務註冊中心功能,程式碼還會比較臃腫的,因為剛開始寫麻,後期絕對會進行封裝的,昨晚的時間進行了一次簡單的封裝
上上篇當中的server.go裡面的程式碼替換為:
更名為serverone.go:

package main

import (
    "flag"
    "fmt"
    "google.golang.org/grpc"
    demo "grpclb/rpcfile"
    "grpclb/rpcserver"
    "grpclb/rpcserverimpl"
)

var (
    port1  = flag.Int("pp",50002,"server port1")
)
const (
    key1 string = "vector_rpc_server1"
)

func main() {
    //解析標籤
    flag.Parse()
    //etcd服務註冊中心需要用到的配置
    config := &rpcserver.RpcServiceConfig{
        //etcd當中key的字首
        Key:           key1,
        //rpc監聽的地址和埠號
        ServerAddress: fmt.Sprintf("127.0.0.1:%d", *port1),
        //etcd叢集地址
        Endpoints:     []string{"127.0.0.1:2379"},
    }

    //註冊etcd中心以及grpc服務
    if server, err := rpcserver.NewRpcService(config, func(server1 *grpc.Server) {
        demo.RegisterDemoServiceServer(server1, &rpcserverimpl.DemoServiceServerImpl{})
    });err == nil {
        if err := server.Run();err != nil {
            panic(err)
        }

    }
}

重點是這裡的rpcserver.go 建立一個新檔案,封裝的東東都在這裡面哦:

package rpcserver

import (
    "go.etcd.io/etcd/clientv3"
    "google.golang.org/grpc"
    "grpclb/register"
    "log"
    "net"
    "os"
    "os/signal"
    "syscall"
)

type (
    //函式作為值來傳遞 型別是自定義的型別RpcServiceFunc 傳入的值是grpc.NewServer()指標型別*grpc.Server
    RpcServiceFunc func(server *grpc.Server)
    //定義一個結構體來承裝register和註冊中心和傳遞過來的函式 這個函式是幹嘛的往下看
    RpcService struct{
        //register註冊中心
        register *register.Register
        //作為值傳遞過來的函式
        //demo.RegisterDemoServiceServer(server1, &rpcserverimpl.DemoServiceServerImpl{})
        //上邊RegisterDemoServiceServer是形成的 pb.go檔案裡面的哦  註冊服務 第二個引數是你實現介面的struct結構體
        //總的來說是為了實現註冊rpc服務的一部分
        rpcServiceFunc RpcServiceFunc
    }
    //將一些配置搞到裡面去 etcd服務註冊中心用到的比如key的字首   rpc服務地址  etcd叢集地址配置
    RpcServiceConfig struct {
        Key string
        ServerAddress string
        Endpoints []string
    }
)

//例項化各類操作
func NewRpcService(conf *RpcServiceConfig,rpcServiceFun RpcServiceFunc) (*RpcService,error){

    //連結etcd服務
    client3,err := clientv3.New(
        clientv3.Config{
            Endpoints:            conf.Endpoints,//etcd叢集地址配置
            //你還可以設定更過的引數 如果開啟了auth驗證 也可以配置username和password
        },
    )
    if err != nil {
        return nil,err
    }
    //返回的結構體當中有 註冊好的Register註冊中心結構體
    return &RpcService{
            //例項化服務註冊中心 方便接下來的呼叫
            register:register.NewRegister(conf.Key, client3, conf.ServerAddress),
            //返回函式
            rpcServiceFunc:rpcServiceFun,
        },nil
}

//執行etcd服務註冊中心和監聽rpc服務
func(s *RpcService) Run() error    {
    //監聽rpc服務
    listen, err := net.Listen("tcp", s.register.GetServiceAddress())
    if err != nil {
        return err
    }
    log.Printf("Rpc server listen at:%s:",s.register.GetServiceAddress())
    //etcd服務註冊中心  這裡真正的調起服務註冊中心的reg()註冊方法
    s.register.Reg()
    //etcd的善後工作
    //我們的rpc服務有沒有掛掉 伺服器有沒有當機......
    //所以我們需要建立一個通道 告訴etcd我的服務掛掉了 伺服器當機了...... 趕緊把我的合同解約刪掉key 好讓接下里的請求不再調取我的rpc服務
    //所以 我們要接收來自系統的訊號
    s.deadNotify()
    //grpc  例項化grpc服務 返回的是 *grpc.Server
    server := grpc.NewServer()
    //grpc  s.rpcServiceFunc()其實就是在呼叫傳遞進來的函式  函式要求傳入的是 *grpc.Server 所以就把grpc.NewServer()傳遞進去就可以啦
    //這樣就真的將我們實現的DemoServiceServerImpl註冊進到了grpc服務當中 就等著下邊啟動就完事了
    s.rpcServiceFunc(server)
    //server.Serve(listen) 啟動grpc服務 進行實時監聽 程式不會中斷!
    if err := server.Serve(listen);err != nil {
        return err
    }
    return nil

}

//etcd的善後工作
//我們的rpc服務有沒有掛掉 伺服器有沒有當機......
//所以我們需要建立一個通道 告訴etcd我的服務掛掉了 伺服器當機了...... 趕緊把我的合同解約刪掉key 好讓接下里的請求不再調取我的rpc服務
//所以 我們要接收來自系統的訊號
func (s *RpcService) deadNotify() error {
    ch := make(chan os.Signal,1)
    //接收系統訊號寫到ch管道當中去
    signal.Notify(ch,syscall.SIGTERM,syscall.SIGINT,syscall.SIGKILL,syscall.SIGHUP,syscall.SIGQUIT)
    go func() {
        sign := <-ch
        log.Printf("signal.notify %v",sign)
        //服務停掉之後 刪除掉註冊進etcd中心的key 我的服務都停了還留著你幹啥用呢!
        s.register.UnReg()
    }()
    return nil
}

其他的涉及到的檔案跟上上篇保持一致即可!
這樣就實現了完美的一次封裝!
每次呼叫也不用寫這麼臃腫的程式碼去呼叫了!
如果看著費勁 那就請把上上篇的程式碼和今天的程式碼貼到你本地 一點一點實現 只要想實現就一定能實現!

本作品採用《CC 協議》,轉載必須註明作者和本文連結
胡軍

相關文章