webhook搭建

webhook搭建

WebHook

网页开发中的网络钩子(Webhook)是一种通过自定义回调函数来增加或更改网页表现的方法。这些回调可被可能与原始网站或应用相关的第三方用户及开发者保存、修改与管理。术语“网络钩子”由杰夫·林德塞(Jeff Lindsay)于 2007 年通过给计算机编程术语“钩子”(Hook)加上前缀得来

为什么我需要搭建一个 webhook

那可要从搭建这个博客系统说起了,由于该博客使用 hexo 搭建,所以每次更新博客需要部署一下然后才能生效。而我又不愿意每次写完都去部署,这样就埋下了一个 webhook 的坑!其实 webhook 就是一个回调地址每次推送都访问下那个地址然后做部署

搭建 webhook

其实搭建这个有很多第三方的库已经支持了,但是偏偏我选择了 gitee(可恶啊!!!)

1. 设置 gitee 的签名


如果你是 java 或者 python 搭建 webhoook gitee 有事例代码
下面使用 go 语言实现

1
2
3
4
5
6
7
8
9
// Sign secret 为你在gitee设置的秘钥,time为请求头中的X-Gitee-Timestamp 也可以用当前收到请求的时间戳 但与请求调用时间误差不能超过1小时
func Sign(secret string, time string) string {
stringToSign := time + "\n" + secret
key := []byte(secret)
h := hmac.New(sha256.New, key)
h.Write([]byte(stringToSign))
signData := h.Sum(nil)
return base64.StdEncoding.EncodeToString(signData)
}

2. 搭建后端服务

使用 gin 搭建 webhook 的后端服务

1
2
3
4
5
func main() {
r := gin.Default()
router.RegisterRouter(r) // 就是你需要注册的路由
r.Run(":3000") // 监听并在 0.0.0.0:8080 上启动服务
}

router 中的代码以及目录结构

其实我就是简单的分了一下目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
webhook
├─Dockerfile // 打包
├─Makefile // 部署
├─boot.sh // sh脚本
├─main.go // 程序入口
├─utils
| ├─response // 通用响应体
├─internal
| ├─router
| | ├─gitee.go // gitee 的路由
| | └router.go // 总路由
| ├─handler // 处理函数
| | ├─blog.go
| | └webhook.go
├─gitee
| ├─errors.go // 错误常量码
| ├─event.go //一些事件的常量
| ├─gitee.go //gitee包
| ├─push_event_payload.go //推送事件的请求数据结构体
| ├─sign //签名包

3. 编写处理函数

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
type GiteeService struct {
hook *gitee.Webhook
}

// New 创建一个新的服务
func NewGitee() *GiteeService {
hook, _ := gitee.New(gitee.WithSecret(GITEESECRET))
return &GiteeService{
hook: hook,
}
}

func (g *GiteeService) Blog(c *gin.Context) {
payload, err := g.hook.Parse(c.Request, gitee.PushEvents)
if err != nil {
if err == gitee.ErrEventNotFound {
// ok event wasn;t one of the ones asked to be parsed
fmt.Printf("ErrEventNotFound %s\n", err)
response.Err(c, err)
return
}
// ok event wasn;t one of the ones asked to be parsed
fmt.Printf("unkonw error %s\n", err)
response.Err(c, err)
return
}
switch payload.(type) {
case gitee.PushEventPayload:
//release := payload.(gitee.PushEventPayload)
go func() {
cmd := exec.Command("sh", "/root/app/blog/webhook.sh")
output, err := cmd.CombinedOutput()
if err != nil {
fmt.Println(string(output))
fmt.Printf("command error %s\n", err)
response.Err(c, err)
return
}
fmt.Println(string(output))
}()
response.Ok(c, nil)
}

}

上面就是一个简单的处理函数,但是值得说的一个点是 为什么需要使用携程去处理 由于打包部署的时间比较久但是 gitee 的 webhook 请求时长为 5s
所以我们这个请求得开一个携程去处理否则请求将请求超时

4. 部署 webhook

由于我需要执行其他需要自动部署的 app 的 shell 脚本,然而我有不想讲整个目录软连接进去所以我就直接二进制部署了就没有使用 docker, 可以看到 Dockerfile 都还在 呜呜呜

下面是我的部署 shell 脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/bin/bash
path=/root/app/webhooks

cd $path
git pull

port=3000
# 找到占用 3000 端口的进程 ID
pid=$(lsof -t -i:$port)

if [ -n "$pid" ]; then
# 杀死进程
echo "Killing process $pid"
kill -9 $pid
fi

outlog="$path/out.log"
if [ -e "$outlog" ]; then
rm "$outlog"
fi

rm -rf $path/main
go build -o $path/main .
nohup $path/main >> $outlog &

先将之前的服务停止,然后再将日志清除,最后再后台运行。

5. gitee 配置 webhook

这个就简单了就将你的后台路由填进去然后测试一把就行

总结
以上就是搭建 webhook 的整个流程咯,实际上就是写个后端服务,然后当你出发 git 某个操作就会请求这个 url 然后执行你需要执行的代码。

docker-compose使用

docker-compose使用

Docker Compose 是一个工具,用于定义和运行多个 Docker 容器的应用程序。使用 Docker Compose 可以轻松地将多个容器组合成一个应用程序,并通过简单的命令进行管理。在本篇博客中,我将向您介绍 Docker Compose 的基本知识和使用方法。

安装 Docker Compose

Docker Compose 可以从 Docker 官网下载安装。在安装之前,您需要确保已安装 Docker。

安装完成后,您可以在终端中输入以下命令来验证 Docker Compose 是否安装成功:

1
docker-compose --version

如果成功安装,您将看到 Docker Compose 的版本信息。

编写 Docker Compose 文件

Docker Compose 使用一个名为 docker-compose.yml 的文件来定义应用程序的服务、网络和卷等。在编写 docker-compose.yml 文件时,您需要定义每个服务的名称、映像、端口和环境变量等。

以下是一个简单的 docker-compose.yml 文件示例,其中定义了一个名为 web 的服务,使用了 nginx 映像,并将容器端口映射到主机的端口 80:

1
2
3
4
5
6
version: '3'
services:
web:
image: nginx
ports:
- "80:80"

在上面的示例中,version 字段指定了 Docker Compose 文件的版本,services 字段用于定义应用程序的服务,web 是服务的名称,image 指定了要使用的 Docker 映像,ports 指定了将容器端口 80 映射到主机端口 80。

您可以根据需要添加其他服务,并为每个服务指定要使用的映像和端口等。

运行 Docker Compose

当您完成 docker-compose.yml 文件的编写后,可以使用以下命令来启动应用程序:

1
docker-compose up

该命令将启动所有服务,并将输出信息输出到终端。如果需要在后台运行应用程序,请使用以下命令:

1
docker-compose up -d

该命令将启动所有服务,并将它们作为后台进程运行。

您可以使用以下命令停止应用程序:

1
docker-compose down

该命令将停止所有服务,并清除它们的容器。

结论

在本篇博客中,我介绍了 Docker Compose 的基本知识和使用方法。使用 Docker Compose,您可以轻松地定义和管理多个 Docker 容器的应用程序,提高开发效率,降低应用程序部署成本。希望这篇博客对您有所帮助。

easegress

easegress

Easegress

官方架构
Easegress 是一个全功能型的流量调度和编排系统,通过 API 网关技术,可以在不改一行代码的情况下,最大限度的帮助后台服务扩大系统可用性和稳定性,并且可以增加整体的性能。其可以让企业在快速业务增长的同时不用对整个技术架构进行大改造,以赢得并抓住稍瞬即逝的商业机会。官方文档

在这里插入图片描述
官方文档上的介绍以及架构图。

1. 下载源码

1
git clone https://github.com/megaease/easegress.git

源码中有一个 server 端和一个命令行工具
easegress的服务端和命令行启动程序

我们首先得需要编译命令行工具形成一个可执行的二进制文件,之后再用这个可执行文件去对服务端进行操作。当然你如果不需要 debug 的话你也可以编译 server 端。接下来我们直接就编译成两个二进制文件

2. 编译

里面有个 Makefile 文件,我们只需在最外层目录下执行

1
make build

然后他就会给你下载依赖并且编译,会在文件中生成 bin 文件夹,里面会有两个二进制文件

1
2
easegress-server 	//服务端
egctl //命令行工具

二进制文件

3. 运行

1
./easegress-server	//运行服务端

启动
启动成功后我们就需要创建 httpserver 了,这个就是用来对于流量的控制。

4. 创建一个 HttpServer

以下一切操作都在在 bin 目录下。

1
2
3
4
5
6
7
8
9
10
11
12
13
echo '
kind: HTTPServer
name: server-demo
port: 10080
keepAlive: true
https: false
rules:
- paths:
- pathPrefix: /pipeline
backend: pipeline-demo
- pathRegexp: ^/user/(.*)$
rewriteTarget: /$1
backend: test-demo '| ./egctl object create

以上的操作是创建了一个 httpserver 监听 10080 端口,并且有两个服务,一个是以/pipeline 为前缀的服务的流量直接打到 pipeline-demo 这个命名的后端上(虽然现在还未创建,我知道你很急,但是你先别急)下面的另一个服务就是 path 是一个正则表达式,所有匹配上的流量都会被打到 test-demo 服务上,rewriteTarget 为啥是/$1 呢,请看下面图片,
在这里插入图片描述
在这里插入图片描述
看官是否能看懂?也就是说这个路径重写是用了 go 标准库中的 ReplaceAllString 方法,然后这个$1 的话就是匹配到的字符串(这个话题就不延伸了,不然我怎么水博客🤪,可能某天就把这个坑填上了)

5. 创建服务端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
echo '
name: pipeline-demo
kind: Pipeline
flow:
- filter: proxy
filters:
- name: proxy
kind: Proxy
pools:
- servers:
- url: http://127.0.0.1:9095
- url: http://127.0.0.1:9096
- url: http://127.0.0.1:9097
loadBalance:
policy: roundRobin' | ./egctl object create

请听我解释: - servers 你部署的后端服务 (为啥有三个呢?) 你流量大需要分流呗 - loadBalance 你分流总得有个策略吧 - flow 就是 api 编排流量进来会根据你编排的顺序去走相应的流程
好吧下面我要装一波了:

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
echo '
name: test-demo2
kind: Pipeline
flow:
- filter: proxy
jumpIf:
failureCode: failResponse
- filter: failResponse
- filter: successResponse
filters:
- name: successResponse
kind: ResponseBuilder
protocol: http
template: |
statusCode: 200
headers:
"Content-Type": ["application/json"]
body: "{{.responses.DEFAULT.Body}}"
- name: failResponse
kind: ResponseBuilder
protocol: http
template: |
statusCode: 200
headers:
"Content-Type": ["application/json"]
body: |
{
"code": -1
"data": null
"message": "{{.responses.DEFAULT.JSONBody.message}}"
}
- name: proxy
kind: Proxy
pools:
- servers:
- url: http://127.0.0.1:8001
failureCodes: [400, 404, 408, 429, 500, 501, 503, 504]
loadBalance:
policy: roundRobin' | ./egctl object create

怎么样?是不是脑瓜子嗡嗡的,上面就是对数据的返回格式做了统一。
flow 中有个 jumpIf 这个就是当 failureCode 等于 failureCodes 中的某个值时就直接跳转到 failResponse 过滤器。好了好了我们启动一下看一下吧!

6. 启动

终于启动了

在这里插入图片描述
成功了 xdm,官方文档还有很多操作,比如说 ip 限制啊,跨域啊,鉴权等等…他还支持 K8s Ingress Controller 是不是值得一学?虽然小编学不会k8s但是或许某天我更新了k8s文章可别喷我!!!

docker常用命令

docker常用命令

docker 常用命令

  1. 进入容器
1
docker exec -it 容器名 /bin/bash
  1. 参数说明
1
2
3
4
5
6
7
8
9
10
11
agent: 表示启动 agent 进程
server: 表示 consul 为 server 模式
client: 表示 consul 为 client 模式
bootstrap: 表示这个节点是 Server-Leader
ui: 启动 Web UI, 默认端口 8500
node: 指定节点名称, 集群中节点名称唯一
client: 绑定客户端接口地址, 0.0.0.0 表示所有地址都可以访问
name 给这个容器起个名字

--progress=plain 显示未从缓存中加载的运行命令的输出
--no-cache 此次构建不使用缓存
  1. 常用镜像
1
2
3
1.curl
kubectl run -it --rm --namespace dev curl --image curlimages/curl -- sh