Gateway雜談:Gateway環境的構建和整合

前言

不少朋友問我,Gateway如何使用,有沒有文檔。在github上有一些文檔說明,詳細描述瞭如何構建Gateway,Gateway中的各個概念是什麼意思,Gateway可以作些什麼,可是這些文檔缺少串聯。趁着年前工做不忙,寫一篇介紹如何利用Gateway整合已有系統的文章,但願能夠幫助更多的人。文章裏會虛構一個已經存在的業務系統,以及如何使用Gateway來解決問題和整合。若是你對Gateway還不瞭解,能夠訪問:Gateway,文檔在docs目錄下nginx

已有的業務系統

假設咱們有2個業務系統,A和B。A和B兩個系統對外提供HTTP服務git

環境

業務 地址
A-1 192.168.0.101
A-2 192.168.0.102
B-1 192.168.0.201
B-2 192.168.0.202

搭建Gateway

Gateway分爲2部分:apiserver和proxy,其中apiserver負責元數據的管理,proxy是真正的用戶入口,能夠理解爲nginx或者apache的角色,proxy是無狀態的,能夠scale-out。搭建參考:githubgithub

整合

建立Cluster

使用Gateway提供的client編寫以下代碼:apache

func createCluster() error {
	c, err := getClient()
	if err != nil {
		return err
	}

	id, err := c.NewClusterBuilder().Name("cluster-A").Loadbalance(metapb.RoundRobin).Commit()
	if err != nil {
		return err
	}

        id, err  = c.NewClusterBuilder().Name("cluster-B").Loadbalance(metapb.RoundRobin).Commit()
	if err != nil {
		return err
	}
	return nil
}

以上代碼建立了A和B兩個Cluster,分別對應業務A和業務B.後端

建立Server

server是對應真是的業務服務器,使用Gateway提供的client編寫以下代碼:api

func createServer() error {
	c, err := getClient()
	if err != nil {
		return err
	}

	sb := c.NewServerBuilder()
	// 必選項
	sb.Addr("192.168.0.101").HTTPBackend().MaxQPS(100)

	// 健康檢查,可選項
	// 每一個10秒鐘檢查一次,每次檢查的超時時間30秒,即30秒後端Server沒有返回認爲後端不健康
	sb.CheckHTTPCode("/check/path", time.Second*10, time.Second*30)

	// 熔斷器,可選項
	// 統計週期1秒鐘
	sb.CircuitBreakerCheckPeriod(time.Second)
	// 在Close狀態60秒後自動轉到Half狀態
	sb.CircuitBreakerCloseToHalfTimeout(time.Second * 60)
	// Half狀態下,容許10%的流量流入後端
	sb.CircuitBreakerHalfTrafficRate(10)
	// 在Half狀態,1秒內有2%的請求失敗了,轉換到Close狀態
	sb.CircuitBreakerHalfToCloseCondition(2)
	// 在Half狀態,1秒內有90%的請求成功了,轉換到Open狀態
	sb.CircuitBreakerHalfToOpenCondition(90)

	id, err := sb.Commit()
	if err != nil {
		return err
	}

	// 把這個server加入到cluster A
	c.AddBind(clusterA, id)
	return nil
}

以上代碼建立了一個192.168.0.101的server,而後把這個server和Cluster-A作了綁定。能夠繼續建立192.168.0.102,192.168.0.201,192.168.0.202三個Server,而後分別和A,B兩個Cluster綁定。這樣在Gateway的元數據中就存在以下對應關係:服務器

  • ClusterA
    • 192.168.0.101
    • 192.168.0.102
  • ClusterB
    • 192.168.0.201
    • 192.168.0.202

建立API

針對A和B提供的API,在Gateway上建立對應的API。好比:負載均衡

func createAPI() error {
	c, err := getClient()
	if err != nil {
		return err
	}

	sb := c.NewAPIBuilder()
	// 必選項
	sb.Name("用戶API")
	// 設置URL規則,匹配全部開頭爲/api/user的請求
	sb.MatchURLPattern("/api/user/(.+)")
	// 匹配GET請求
	sb.MatchMethod("GET")
	// 匹配全部請求
	sb.MatchMethod("*")
	// 不啓動
	sb.Down()
	// 啓用
	sb.UP()
	// 分發到Cluster A
	sb.AddDispatchNode(clusterA)

	// 可選項
	// 匹配全部host,和MatchMethod、MatchURLPattern互斥
	sb.MatchDomain("user.xxx.com")
	// 增長訪問黑名單
	sb.AddBlacklist("192.168.0.1", "192.168.1.*", "192.168.*")
	// 增長訪問報名單
	sb.AddWhitelist("192.168.3.1", "192.168.3.*", "192.168.*")
	// 移除黑白名單
	sb.RemoveBlacklist("192.168.0.1") // 剩餘:"192.168.1.*", "192.168.*"
	sb.RemoveWhitelist("192.168.3.1") // 剩餘:"192.168.3.*", "192.168.*"

	// 增長默認值
	sb.DefaultValue([]byte("{\"value\", \"default\"}"))
	// 爲默認值增長header
	sb.AddDefaultValueHeader("token", "xxxxx")
	// 爲默認值增長Cookie
	sb.AddDefaultValueCookie("sid", "xxxxx")

	id, err := sb.Commit()
	if err != nil {
		return err
	}

	fmt.Printf("api id is: %d", id)
	return nil
}

以上代碼建立了一個API,這個API被轉發到ClusterA。Gateway會使用ClusterA的負載均衡設置訪問ClustreA中的真是服務器,如法炮製,能夠建立A系統和B系統中提供的其餘API。ui

爲何使用Gateway

看了上面的介紹,讀者可能會提出疑問,這些我用Nginx或者Apache就能夠完成大部分功能,爲何須要Gateway。這裏仍是簡單介紹了下Gateway的最近本使用,Gateway還有不少的特性,而且這些都是在運行期你經過訪問apiserver能夠動態的修改Gateway的行爲。這裏給出Gateway的一份Features:spa

  • 流量控制
  • 熔斷
  • 負載均衡
  • 服務發現
  • 插件機制
  • 路由
  • API 聚合
  • API 參數校驗
  • API 訪問控制(黑白名單)
  • API 默認返回值
  • API 定製返回值
  • 後端server的健康檢查
  • 使用 fasthttp
  • 開放管理API

更多介紹請訪問 github

相關文章
相關標籤/搜索