亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

利用go-kit組件進(jìn)行服務(wù)注冊(cè)與發(fā)現(xiàn)和健康檢查的操作

 更新時(shí)間:2021年04月27日 08:40:27   作者:鹿灝楷silves  
這篇文章主要介紹了利用go-kit組件進(jìn)行服務(wù)注冊(cè)與發(fā)現(xiàn)和健康檢查的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧

在go的微服務(wù)架構(gòu)中

使用go-kit組件進(jìn)行開(kāi)發(fā)微服務(wù)

type Reg struct {
	Host string
	Port int
	Client consul.Client
}
func MakeReg (host string , port int) (*Reg , error) {
	reg := api.DefaultConfig()
	reg.Address = host + ":" + strconv.Itoa(port)
	apiclient , err = api.NewClient(reg)
	if err != nil {
		return nil , err
	}
	client := consul.NewClient(apiclient)
	return &Reg{Host : host , Port : port ,Client : client} , nil
}
func (r Reg) Resiter (servicename , tag , host , seviceid ,checkinter ,healthcheckhttp ,deregisterafter string , port int) bool {
	congig := api.AgentServiceRegistration{
		Port : port ,
		Address : host ,
		Name := servicename,
		ID := serviceid,
		Ckeck : &api.AgentServiceCheck{
			Interval : checkinter,
			HTTP : "http://" + host + ":" + healthcheckhttp ,
			DeregisterCriticalServiceAfter : deregisterafter,
		}
	}
	if err := r.Client.Register(&config) ; err != nil {
		fmt.Println(err)
		return false
	}
	return true
}
func (r Reg) Deregister (serviceid string) bool {
	dreg := api.AgentServiceRegistration{ID : serviceid}
	if err != r.Client.Deregister(&config) ; err != nil {
		fmt.Println(err)
		return false
	}
	return true
}
func (r Reg) discover (servicename , tag string ,passingonly bool) ( []*api.ServiceEntry ,error ) {
	if entries ,_ ,err := r.Client.Service(servicename , tag , passingonly , nil) ;err != nil {
		return nil ,err
	}else{
		return entries , nil
	}
}

補(bǔ)充:go-kit 與 grpc 結(jié)合實(shí)現(xiàn)注冊(cè)發(fā)現(xiàn)與負(fù)載均衡

介紹

grpc提供了簡(jiǎn)單的負(fù)載均衡,需要自己實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)resolve。我們既然要使用go-kit來(lái)治理微服務(wù),那么我們就使用go-kit的注冊(cè)發(fā)現(xiàn)、負(fù)載均衡機(jī)制。

go-kit官方【stringsvc3】例子中使用的負(fù)載均衡方案是通過(guò)服務(wù)端轉(zhuǎn)發(fā)進(jìn)行,翻找下源碼go-kit的服務(wù)注冊(cè)發(fā)現(xiàn)、負(fù)載均衡在【sd】包中。下面我們介紹怎么通過(guò)go-kit進(jìn)行客戶(hù)端負(fù)載均衡。

go-kit提供的注冊(cè)中心

1、 etcd

2、 consul

3、 eureka

4、 zookeeper

go-kit提供的負(fù)載均衡

1、 random[隨機(jī)]

2、 roundRobin[輪詢(xún)]

只需實(shí)現(xiàn)Balancer接口,我們可以很容易的增加其它負(fù)載均衡機(jī)制

type Balancer interface {  
   Endpoint() (endpoint.Endpoint, error)  
}

etcd注冊(cè)發(fā)現(xiàn)

etcd和zookeeper類(lèi)似是一個(gè)高可用、強(qiáng)一致性的存儲(chǔ)倉(cāng)庫(kù),擁有服務(wù)發(fā)現(xiàn)功能。 我們就通過(guò)go-kit提供的etcd包來(lái)實(shí)現(xiàn)服務(wù)注冊(cè)發(fā)現(xiàn)

服務(wù)端代碼

服務(wù)注冊(cè)

1、連接注冊(cè)中心

2、注冊(cè)當(dāng)前服務(wù)

var (  
   //etcd服務(wù)地址  
   etcdServer = "127.0.0.1:2379"   
   //服務(wù)的信息目錄  
   prefix     = "/services/book/"    
   //當(dāng)前啟動(dòng)服務(wù)實(shí)例的地址  
   instance   = "127.0.0.1:50052"  
   //服務(wù)實(shí)例注冊(cè)的路徑  
   key        = prefix + instance    
   //服務(wù)實(shí)例注冊(cè)的val  
   value      = instance  
   ctx        = context.Background()  
   //服務(wù)監(jiān)聽(tīng)地址  
   serviceAddress = ":50052"  
)  
//etcd的連接參數(shù)  
options := etcdv3.ClientOptions{  
   DialTimeout: time.Second * 3,  
   DialKeepAlive: time.Second * 3,  
}  
//創(chuàng)建etcd連接  
client, err := etcdv3.NewClient(ctx, []string{etcdServer}, options)  
if err != nil {  
   panic(err)  
}  
// 創(chuàng)建注冊(cè)器  
registrar := etcdv3.NewRegistrar(client, etcdv3.Service{  
   Key:   key,  
   Value: value,  
}, log.NewNopLogger())  
// 注冊(cè)器啟動(dòng)注冊(cè)  
registrar.Register()

完整代碼

package main  
import (  
   "grpc-test/pb"  
   "context"  
   grpc_transport "github.com/go-kit/kit/transport/grpc"  
   "github.com/go-kit/kit/endpoint" 
   "google.golang.org/grpc" 
   "net" 
   "github.com/go-kit/kit/sd/etcdv3" 
   "github.com/go-kit/kit/log" 
   "time"
)  
type BookServer struct {  
   bookListHandler  grpc_transport.Handler  
   bookInfoHandler  grpc_transport.Handler  
}  
//通過(guò)grpc調(diào)用GetBookInfo時(shí),GetBookInfo只做數(shù)據(jù)透?jìng)? 調(diào)用BookServer中對(duì)應(yīng)Handler.ServeGRPC轉(zhuǎn)交給go-kit處理  
func (s *BookServer) GetBookInfo(ctx context.Context, in *book.BookInfoParams) (*book.BookInfo, error) {  
   _, rsp, err := s.bookInfoHandler.ServeGRPC(ctx, in)  
   if err != nil {  
      return nil, err  
   }  
   return rsp.(*book.BookInfo),err  
}  
//通過(guò)grpc調(diào)用GetBookList時(shí),GetBookList只做數(shù)據(jù)透?jìng)? 調(diào)用BookServer中對(duì)應(yīng)Handler.ServeGRPC轉(zhuǎn)交給go-kit處理  
func (s *BookServer) GetBookList(ctx context.Context, in *book.BookListParams) (*book.BookList, error) {  
   _, rsp, err := s.bookListHandler.ServeGRPC(ctx, in)  
   if err != nil {  
      return nil, err  
   }  
   return rsp.(*book.BookList),err  
}  
//創(chuàng)建bookList的EndPoint  
func makeGetBookListEndpoint() endpoint.Endpoint {  
   return func(ctx context.Context, request interface{}) (interface{}, error) {  
      //請(qǐng)求列表時(shí)返回 書(shū)籍列表  
      bl := new(book.BookList)  
      bl.BookList = append(bl.BookList, &book.BookInfo{BookId:1,BookName:"21天精通php"})  
      bl.BookList = append(bl.BookList, &book.BookInfo{BookId:2,BookName:"21天精通java"})  
      return bl,nil  
   }  
}  
//創(chuàng)建bookInfo的EndPoint  
func makeGetBookInfoEndpoint() endpoint.Endpoint {  
   return func(ctx context.Context, request interface{}) (interface{}, error) {  
      //請(qǐng)求詳情時(shí)返回 書(shū)籍信息  
      req := request.(*book.BookInfoParams)  
      b := new(book.BookInfo)  
      b.BookId = req.BookId  
      b.BookName = "21天精通php"  
      return b,nil  
   }  
}  
func decodeRequest(_ context.Context, req interface{}) (interface{}, error) {  
   return req, nil  
}  
func encodeResponse(_ context.Context, rsp interface{}) (interface{}, error) {  
   return rsp, nil  
}  
func main() {  
   var (  
      //etcd服務(wù)地址  
      etcdServer = "127.0.0.1:2379"  
      //服務(wù)的信息目錄  
      prefix     = "/services/book/"  
      //當(dāng)前啟動(dòng)服務(wù)實(shí)例的地址  
      instance   = "127.0.0.1:50052"  
      //服務(wù)實(shí)例注冊(cè)的路徑  
      key        = prefix + instance  
      //服務(wù)實(shí)例注冊(cè)的val  
      value      = instance  
      ctx        = context.Background()  
      //服務(wù)監(jiān)聽(tīng)地址  
      serviceAddress = ":50052"  
   )  
   //etcd的連接參數(shù)  
   options := etcdv3.ClientOptions{  
      DialTimeout: time.Second * 3,  
      DialKeepAlive: time.Second * 3,  
   }  
   //創(chuàng)建etcd連接  
   client, err := etcdv3.NewClient(ctx, []string{etcdServer}, options)  
   if err != nil {  
      panic(err)  
   }  
   // 創(chuàng)建注冊(cè)器  
   registrar := etcdv3.NewRegistrar(client, etcdv3.Service{  
      Key:   key,  
      Value: value,  
   }, log.NewNopLogger())  
   // 注冊(cè)器啟動(dòng)注冊(cè)  
   registrar.Register()  
   bookServer := new(BookServer)  
   bookListHandler := grpc_transport.NewServer(  
      makeGetBookListEndpoint(),  
      decodeRequest,  
      encodeResponse,  
   )  
   bookServer.bookListHandler = bookListHandler  
   bookInfoHandler := grpc_transport.NewServer(  
      makeGetBookInfoEndpoint(),  
      decodeRequest,  
      encodeResponse,  
   )  
   bookServer.bookInfoHandler = bookInfoHandler  
   ls, _ := net.Listen("tcp", serviceAddress)  
   gs := grpc.NewServer(grpc.UnaryInterceptor(grpc_transport.Interceptor))  
   book.RegisterBookServiceServer(gs, bookServer)  
   gs.Serve(ls)  
}

客戶(hù)端代碼

客戶(hù)端流程

1、 連接注冊(cè)中心

2、 獲取提供的服務(wù)

3、 監(jiān)聽(tīng)服務(wù)目錄變化,目錄變化更新本地緩存

4、 創(chuàng)建負(fù)載均衡器

5、 獲取請(qǐng)求的 endPoint

完整代碼

package main  
import (  
   "context"  
   "github.com/go-kit/kit/sd/etcdv3" 
   "time" 
   "github.com/go-kit/kit/sd" 
   "github.com/go-kit/kit/log" 
   "github.com/go-kit/kit/endpoint" 
   "io" 
   "github.com/go-kit/kit/sd/lb" 
   "grpc-test/pb" 
   "fmt" 
   "google.golang.org/grpc"
)  
func main() {  
   var (  
      //注冊(cè)中心地址  
      etcdServer = "127.0.0.1:2379"  
      //監(jiān)聽(tīng)的服務(wù)前綴  
      prefix     = "/services/book/"  
      ctx        = context.Background()  
   )  
   options := etcdv3.ClientOptions{  
      DialTimeout: time.Second * 3,  
      DialKeepAlive: time.Second * 3,  
   }  
   //連接注冊(cè)中心  
   client, err := etcdv3.NewClient(ctx, []string{etcdServer}, options)  
   if err != nil {  
      panic(err)  
   }  
   logger := log.NewNopLogger()  
   //創(chuàng)建實(shí)例管理器, 此管理器會(huì)Watch監(jiān)聽(tīng)etc中prefix的目錄變化更新緩存的服務(wù)實(shí)例數(shù)據(jù)  
   instancer, err := etcdv3.NewInstancer(client, prefix, logger)  
   if err != nil {  
      panic(err)  
   }  
   //創(chuàng)建端點(diǎn)管理器, 此管理器根據(jù)Factory和監(jiān)聽(tīng)的到實(shí)例創(chuàng)建endPoint并訂閱instancer的變化動(dòng)態(tài)更新Factory創(chuàng)建的endPoint  
   endpointer := sd.NewEndpointer(instancer, reqFactory, logger)  
   //創(chuàng)建負(fù)載均衡器  
   balancer := lb.NewRoundRobin(endpointer)  
   /**  
   我們可以通過(guò)負(fù)載均衡器直接獲取請(qǐng)求的endPoint,發(fā)起請(qǐng)求  
   reqEndPoint,_ := balancer.Endpoint() 
   */  
   /**  
   也可以通過(guò)retry定義嘗試次數(shù)進(jìn)行請(qǐng)求  
   */  
   reqEndPoint := lb.Retry(3, 3*time.Second, balancer)  
   //現(xiàn)在我們可以通過(guò) endPoint 發(fā)起請(qǐng)求了  
   req := struct{}{}  
   if _, err = reqEndPoint(ctx, req); err != nil {  
      panic(err)  
   }  
}  
//通過(guò)傳入的 實(shí)例地址  創(chuàng)建對(duì)應(yīng)的請(qǐng)求endPoint  
func reqFactory(instanceAddr string) (endpoint.Endpoint, io.Closer, error) {  
   return func(ctx context.Context, request interface{}) (interface{}, error) {  
      fmt.Println("請(qǐng)求服務(wù): ", instanceAddr)
      conn, err := grpc.Dial(instanceAddr, grpc.WithInsecure())  
      if err != nil {  
         fmt.Println(err)  
         panic("connect error")  
      }  
      defer conn.Close()  
      bookClient := book.NewBookServiceClient(conn)  
      bi,_:=bookClient.GetBookInfo(context.Background(),&book.BookInfoParams{BookId:1})  
      fmt.Println("獲取書(shū)籍詳情")  
      fmt.Println("bookId: 1", " => ", "bookName:", bi.BookName)  
      bl,_ := bookClient.GetBookList(context.Background(), &book.BookListParams{Page:1, Limit:10})  
      fmt.Println("獲取書(shū)籍列表")  
      for _,b := range bl.BookList {  
         fmt.Println("bookId:", b.BookId, " => ", "bookName:", b.BookName)  
      }  
      return nil,nil  
   },nil,nil  
} 

測(cè)試

請(qǐng)求測(cè)試

請(qǐng)求服務(wù): 127.0.0.1:50052
獲取書(shū)籍詳情
bookId: 1  =>  bookName: 21天精通php
獲取書(shū)籍列表
bookId: 1  =>  bookName: 21天精通php
bookId: 2  =>  bookName: 21天精通java

負(fù)載均衡測(cè)試

1、 修改server的注冊(cè)監(jiān)聽(tīng)端口,啟動(dòng)多個(gè)server

instance   = "127.0.0.1:50052"  
serviceAddress = ":50052"

2、client發(fā)起多次請(qǐng)求

req := struct{}{}  
for i := 1; i <= 8; i++ {  
   if _, err = reqEndPoint(ctx, req); err != nil {  
      panic(err)  
   }  
}

通過(guò)返回結(jié)果中記錄的請(qǐng)求地址,我們可以看到已經(jīng)按照輪詢(xún)的方式請(qǐng)求不同的微服務(wù)實(shí)例。

請(qǐng)求服務(wù):  127.0.0.1:50051
        獲取書(shū)籍詳情
        bookId: 1  =>  bookName: 21天精通php
        獲取書(shū)籍列表
        bookId: 1  =>  bookName: 21天精通php
        bookId: 2  =>  bookName: 21天精通java
請(qǐng)求服務(wù):  127.0.0.1:50052
        獲取書(shū)籍詳情
        bookId: 1  =>  bookName: 21天精通php
        獲取書(shū)籍列表
        bookId: 1  =>  bookName: 21天精通php
        bookId: 2  =>  bookName: 21天精通java
請(qǐng)求服務(wù):  127.0.0.1:50051
        獲取書(shū)籍詳情
        bookId: 1  =>  bookName: 21天精通php
        獲取書(shū)籍列表
        bookId: 1  =>  bookName: 21天精通php
        bookId: 2  =>  bookName: 21天精通java
請(qǐng)求服務(wù):  127.0.0.1:50052
        獲取書(shū)籍詳情
        bookId: 1  =>  bookName: 21天精通php
        獲取書(shū)籍列表
        bookId: 1  =>  bookName: 21天精通php
        bookId: 2  =>  bookName: 21天精通java
請(qǐng)求服務(wù):  127.0.0.1:50051
        獲取書(shū)籍詳情
        bookId: 1  =>  bookName: 21天精通php
        獲取書(shū)籍列表
        bookId: 1  =>  bookName: 21天精通php
        bookId: 2  =>  bookName: 21天精通java
請(qǐng)求服務(wù):  127.0.0.1:50052
        獲取書(shū)籍詳情
        bookId: 1  =>  bookName: 21天精通php
        獲取書(shū)籍列表
        bookId: 1  =>  bookName: 21天精通php
        bookId: 2  =>  bookName: 21天精通java
請(qǐng)求服務(wù):  127.0.0.1:50051
        獲取書(shū)籍詳情
        bookId: 1  =>  bookName: 21天精通php
        獲取書(shū)籍列表
        bookId: 1  =>  bookName: 21天精通php
        bookId: 2  =>  bookName: 21天精通java
請(qǐng)求服務(wù):  127.0.0.1:50052
        獲取書(shū)籍詳情
        bookId: 1  =>  bookName: 21天精通php
        獲取書(shū)籍列表
        bookId: 1  =>  bookName: 21天精通php
        bookId: 2  =>  bookName: 21天精通java
Process finished with exit code 0

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。

相關(guān)文章

  • Go1.21新增slices包的用法詳解

    Go1.21新增slices包的用法詳解

    Go?1.21新增的?slices?包提供了很多和切片相關(guān)的函數(shù),可以用于任何類(lèi)型的切片,這篇文章主要來(lái)和大家介紹一下slices包中相關(guān)函數(shù)的用法,需要的可以參考一下
    2023-08-08
  • Golang實(shí)現(xiàn)http重定向https

    Golang實(shí)現(xiàn)http重定向https

    這篇文章介紹了Golang實(shí)現(xiàn)http重定向https的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-07-07
  • Golang10進(jìn)制轉(zhuǎn)16進(jìn)制的幾種方法代碼示例

    Golang10進(jìn)制轉(zhuǎn)16進(jìn)制的幾種方法代碼示例

    這篇文章主要給大家介紹了關(guān)于Golang10進(jìn)制轉(zhuǎn)16進(jìn)制的幾種方法,進(jìn)制轉(zhuǎn)換是Golang的一些基本操作,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07
  • GO?集合?map?使用示例小結(jié)

    GO?集合?map?使用示例小結(jié)

    Go語(yǔ)言的集合稱(chēng)為映射(map),它是一種無(wú)序的鍵值對(duì)(key-value)的集合,集合是通過(guò)鍵(key)來(lái)快速檢索值(value)的,鍵(key)類(lèi)似于索引,它指向值(value)的數(shù)據(jù),這篇文章主要介紹了GO集合map使用總結(jié),本文通過(guò)示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-06-06
  • 從Node.js 轉(zhuǎn)到 Go平臺(tái)

    從Node.js 轉(zhuǎn)到 Go平臺(tái)

    回顧過(guò)去的一年,我們?cè)诩夹g(shù)棧上的最大改變就是從 Node.js 切換到 Go 。我們的聯(lián)合創(chuàng)始人,Steve Kaliski, 在 Poptip 把 Node.js 切換成了 Go,可惜他沒(méi)有學(xué)習(xí)到當(dāng)時(shí)的教訓(xùn)。
    2015-03-03
  • 淺談golang通道類(lèi)型

    淺談golang通道類(lèi)型

    本文主要介紹了淺談golang通道類(lèi)型,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • Go語(yǔ)言的JSON處理詳解

    Go語(yǔ)言的JSON處理詳解

    json格式可以算我們?nèi)粘W畛S玫男蛄谢袷街涣?Go語(yǔ)言作為一個(gè)由Google開(kāi)發(fā),號(hào)稱(chēng)互聯(lián)網(wǎng)的C語(yǔ)言的語(yǔ)言,自然也對(duì)JSON格式支持很好。
    2018-10-10
  • 詳解在Go語(yǔ)言單元測(cè)試中如何解決文件依賴(lài)問(wèn)題

    詳解在Go語(yǔ)言單元測(cè)試中如何解決文件依賴(lài)問(wèn)題

    現(xiàn)如今的?Web?應(yīng)用程序往往采用?RESTful?API?接口形式對(duì)外提供服務(wù),后端接口直接向前端返回?HTML?文件的情況越來(lái)越少,所以在程序中操作文件的場(chǎng)景也變少了,在編寫(xiě)單元測(cè)試時(shí),文件就成了被測(cè)試代碼的外部依賴(lài),本文就來(lái)講解下測(cè)試過(guò)程中如何解決文件外部依賴(lài)問(wèn)題
    2023-08-08
  • Go數(shù)組與切片輕松掌握

    Go數(shù)組與切片輕松掌握

    在Java的核心庫(kù)中,集合框架可謂鼎鼎大名:Array、List、Set等等,隨便拎一個(gè)出來(lái)都值得開(kāi)發(fā)者好好學(xué)習(xí)如何使用甚至是背后的設(shè)計(jì)源碼。雖然Go語(yǔ)言沒(méi)有如此豐富的容器類(lèi)型,但也有一些基本的容器供開(kāi)發(fā)者使用,接下來(lái)讓我們認(rèn)識(shí)一下這些容器類(lèi)型吧
    2022-11-11
  • Go語(yǔ)言MySQLCURD數(shù)據(jù)庫(kù)操作示例詳解

    Go語(yǔ)言MySQLCURD數(shù)據(jù)庫(kù)操作示例詳解

    這篇文章主要為大家介紹了Go語(yǔ)言MySQLCURD數(shù)據(jù)庫(kù)操作示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12

最新評(píng)論