1. 程式人生 > >Go的微服務庫kite

Go的微服務庫kite

targe post 服務 core 調用 protocol tag 運行 interface

Kite

Kite是用Go開發的一套RPC庫,很適合作為分布式微服務的開發框架。

Kite 的傳輸層使用 SockJS 提供的WebSocket服務, 瀏覽器Javascript也可以連接到Kite上 (Kite.js);

Kite 的RPC消息格式使用修改過的 dnode 協議,Kite 增加了 session 和 authentication 層, 用於Kites 的發現和識別。

標識一個Kite的參數如下:

  • Username: Kite的屬主;
  • Environment: 當前環境,比如“production”, “testing”, “staging” 等;
  • Name: 標識Kite類別的名稱,比如mykite, fs, terminal 等;
  • Version: 版本號,比如1.0.0;
  • Region: 當前區域, 比如 “Europe”, “Asia” 或其它地區;
  • Hostname: Kite的Hostname;
  • ID: 識別Kite的唯一ID,這個是由Kite庫生成的,但用戶也可以自己指定一個;

註意:以上參數的順序很重要;

Kite的使用

如下面的例子:

服務端:

package main
import "github.com/koding/kite"
func main() {
    k := kite.New("first", "1.0.0")
    k.Config.Port = 6000
    k.Run()
}

代碼說明:

  1. kite.New創建了一個名字為"first",版本號為"1.0.0"的Kite;
  2. k.Config 用於設置Kite的屬性,比如端口號;
  3. Run方法表示運行此服務,這是個阻塞式的調用,之後,Kite就可以接收請求了;

客戶端:

package main
import (
    "fmt"
    "github.com/koding/kite"
)
func main() {
    k := kite.New("second", "1.0.0")
    client := k.NewClient("http://localhost:6000/kite")
    client.Dial()
    response, _ :
= client.Tell("kite.ping") fmt.Println(response.MustString()) }

代碼說明:

  1. NewClient方法指定需要連接的服務端的URL;
  2. Tell方法傳入調用的方法名,在服務端,這個方法名對應一個handler,這裏的kite.ping是一個默認的方法,當調用這個方法的時候,client端會受到一個字符串"pong";

下面再來看看怎麽調用一個自定義方法:

服務端:

package main
import "github.com/koding/kite"
func main() {
    k := kite.New("first", "1.0.0")
    k.Config.Port = 6000
    k.Config.DisableAuthentication = true
    k.HandleFunc("square", func(r *kite.Request) (interface{}, error) {
        a := r.Args.One().MustFloat64()
        return a * a, nil
    })
k.Run() }

定義了一個squid方法,對應的handler接收一個數字,並返回這個數字的平方;

客戶端:

package main
import (
    "fmt"
    "github.com/koding/kite"
)
func main() {
    k := kite.New("second", "1.0.0")
    client := k.NewClient("http://localhost:6000/kite")
    client.Dial()
    response, _ := client.Tell("square", 4)
    fmt.Println(response.MustFloat64())
}

服務註冊和發現Kontrol

Kite之間可以互相通信,通過Kontrol的服務發現機制,一個Kite可以發現其它的Kites。也就是說一個Kite可以在Kontrol註冊自己,從而讓其它的kites能找到它;

Kontrol本身也是一個Kite,它用於對服務進行註冊和鑒權;Kontrol 使用 etcd 作為後端存儲, 當然,也可以用其它數據庫替換,比如PostgreSQL。任何滿足 kontrol.Storage接口的都可以作為後端存儲。

服務端:

package main
import (
    "net/url"
    "github.com/koding/kite"
)

func main() {
    k := kite.New("first", "1.0.0")
    k.Config.Port = 6000
    k.HandleFunc("square", func(r *kite.Request) (interface{}, error) {
        a := r.Args.One().MustFloat64()
        return a * a, nil
    })

    k.Register(&url.URL{Scheme: "http", Host: "localhost:6000/kite"})
    k.Run()
}

服務端調用Register方法將自己註冊到Kontrol,使用的URL參數是其它kites連接本kite的地址,Kontrol會保存這個url,方便其它kites獲取;

客戶端:

package main

import (
    "fmt"
    "github.com/koding/kite"
    "github.com/koding/kite/protocol"
)

func main() {
    k := kite.New("second", "1.0.0")
    // search a kite that has the same username and environment as us, but the
    // kite name should be "first"
    kites, _ := k.GetKites(&protocol.KontrolQuery{
        Username:    k.Config.Username,
        Environment: k.Config.Environment,
        Name:        "first",
    })

    // there might be several kites that matches our query
    client := kites[0]
    client.Dial()
    response, _ := client.Tell("square", 4)
    fmt.Println(response.MustFloat64())
}

GetKites方法會連接Kontrol,並獲取符合查找條件的kites列表。

本例子中是查找同一個用戶名下面名為"first"的所有kites,如果該用戶註冊了10個名為"first"的kites,在client都能返回,調用方可以使用特定的負載均衡算法(例如round robin)選擇其中一個。

參考文檔:

Kite API

https://blog.gopheracademy.com/birthday-bash-2014/kite-microservice-library/
https://toutiao.io/posts/yfwvyt/preview

Go的微服務庫kite