部署Gateway

参考:github.com\fagongzi\gateway\docs\build.md

网关依赖于ETCD,用于设备发现服务,可使用如下命令进行安装:

1
2
3
4
5
$ wget https://github.com/coreos/etcd/releases/download/v3.3.9/etcd-v3.3.9-linux-amd64.tar.gz 

$ tar -xzvf etcd-v3.3.9-linux-amd64.tar.gz

$ ./etcd (默认配置运行即可)

根据build.md文档,生成apiserver和proxy可执行文件后,将两者启动。

proxy使用的是80接口,可能会被占用,可使用“–addr”参数进行设置,apiserver默认使用9092作为HTTP Server接口,9093作为Rpc Server接口,可保持不变,若接口依然被占用,则可参考build.md文档中参数进行设置。

1
2
$ ./apiserver &
$ ./proxy --addr=:8088 &

程序运行失败将打印error信息。

docker部署gateway

  • 8080:80,将本机的8080端口映射至docker的80端口;
1
sudo docker run -d -p 0.0.0.0:8080:80 -p 9095:9092 -p 9093:9093 fagongzi/gateway

编写测试

编写程序进行测试,用到gateway的client接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package main

import (
"fmt"
"log"
"net/http"
"time"

"github.com/fagongzi/gateway/pkg/pb/metapb"

"github.com/fagongzi/gateway/pkg/client"
"github.com/gin-gonic/gin"
)

var clusterA uint64

func main() {
router := gin.Default()

router.GET("/hello/1", func(c *gin.Context) {
c.JSON(http.StatusOK, "yes, this is hello")
})

// 第一步: 创建Cluster,类似于服务分类
if err := createCluster1(); err != nil {
log.Println("1 error,", err)
return
}

// 第二步: 对应真正的业务服务器
err := createServer1()
if err != nil {
log.Println("2 error,", err)
return
}

// 第三步: 创建API,该API会被转发到ClusterA
if err := createAPI1(); err != nil {
log.Println("3 error,", err)
return
}

router.Run(":8068")
}

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

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

return nil
}

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

sb := c.NewServerBuilder()
// 必选项
sb.Addr("127.0.0.1:8068").HTTPBackend().MaxQPS(100)

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

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

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

sb := c.NewAPIBuilder()
// 必选项
sb.Name("用户API")
// 设置URL规则,匹配所有开头为/api/user的请求
sb.MatchURLPattern("/hello/(.+)")
// 匹配GET请求
sb.MatchMethod("GET")
// 匹配所有请求
//sb.MatchMethod("*")
// 不启动
//sb.Down()
// 启用
sb.UP()
// 分发到Cluster A
sb.AddDispatchNode(clusterA)

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

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

// 如果你的api server使用了"--discovery"参数启动
func getClientWithDiscovery() (client.Client, error) {
return client.NewClientWithEtcdDiscovery("/services",
time.Second*10,
"127.0.0.1:2379")
}

// 如果你的api server没有使用"--discovery"参数启动
func getClient() (client.Client, error) {
return client.NewClient(time.Second*10,
"127.0.0.1:9091")
}

运行测试程序

若程序出现如下打印,代表程序运行成功。

1
2
3
4
5
6
7
2018/09/17 19:16:08.755386 [info] cluster <1> added, data <id:1 name:"cluster-A" >
2018/09/17 19:16:08.763781 [info] analysis: added, key=<2> interval=<1s>
2018/09/17 19:16:08.763872 [info] server <2> added, data <id:2 addr:"127.0.0.1:8068" maxQPS:100 >
2018/09/17 19:16:08.763883 [warning] server <2> heath check not setting
2018/09/17 19:16:08.763887 [info] server <2> UP
2018/09/17 19:16:08.771950 [info] bind <1,2> created
2018/09/17 19:16:08.771957 [info] bind <1,2> actived

可使用curl命令去测试接口:

1
$ curl http://localhost:8088/hello/1

出现"yes, this is hello",代表程序测试成功。

部署gateway_ui

gateway有两个UI管理界面,这里我只部署了一个,gateway_ui。

https://github.com/archfish/gateway_ui

https://github.com/wilehos/gateway_admin_ui

拉取镜像:

1
docker pull hub.c.163.com/weihailang/gateway_ui:latest

使用docker进行部署:

1
sudo docker run -d --restart always -p 3000:3000 --name gateway_ui -u 1001:1001 -h gateway.ui.production -e RAILS_ENV=production -e GATEWAY_BACKEND=172.31.242.128:9093 hub.c.163.com/weihailang/gateway_ui

由于没有登录鉴权接口(可以使用Nginx密码登录验证来代替),所以管理界面是不建立部署在外网环境中。

UI使用docker部署是最为方便的,若UI使用docker部署,那么gateway也得使用docker进行部署,因为docker内的应用是无法访问到外网的,需要使用NAT技术进行桥接。以后的服务也是需要统一部署到docker中的。