不少朋友问我,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