不少朋友問我,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分爲2部分:apiserver和proxy,其中apiserver負責元數據的管理,proxy是真正的用戶入口,能夠理解爲nginx或者apache的角色,proxy是無狀態的,能夠scale-out。搭建參考:githubgithub
使用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是對應真是的業務服務器,使用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的元數據中就存在以下對應關係:服務器
針對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
看了上面的介紹,讀者可能會提出疑問,這些我用Nginx或者Apache就能夠完成大部分功能,爲何須要Gateway。這裏仍是簡單介紹了下Gateway的最近本使用,Gateway還有不少的特性,而且這些都是在運行期你經過訪問apiserver能夠動態的修改Gateway的行爲。這裏給出Gateway的一份Features:spa
更多介紹請訪問 github