文章目录
⚡️: 应领导要求想要把
Apollo
配置变更信息更新到企业微信群中,线上出现异常可根据变更时间,快速反应是否是配置变更导致异常
启用方式
🌛: 前提有一个可正常使用的Apollo服务
配置项统一存储在ApolloPortalDB.ServerConfig表中,也可以通过
管理员工具 - 系统参数
页面进行配置,修改完一分钟实时生效。
1、webhook.supported.envs
开启 webhook 的环境列表,多个环境以英文逗号分隔,如
DEV,FAT,UAT,PRO
2、config.release.webhook.service.url
webhook 通知的 url 地址,需要接收 HTTP POST 请求。如有多个地址,以英文逗号分隔,如
shell
http://ip:port/webhook1,http://ip:port/webhook2
hook编写
🏴: 这里使用的
golang
进行hook编写,拿到信息之后数据格式以MakeDown
形式发送到企业微信小机器人上,key
根据实际替换
以下是代码展示:
go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"time"
)
const (
weChatWebhookURL = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx-xxx-xxx-xxx" #
)
type ApolloChange struct {
AppID string `json:"appId"`
NamespaceName string `json:"namespaceName"`
Operator string `json:"operator"`
ReleaseComment string `json:"releaseComment"`
Operation int64 `json:"operation"`
Time string `json:"time"`
}
const (
OperatorNormalRelease = "0"
OperatorConfigRollback = "1"
OperatorGrayRelease = "2"
OperatorFullRelease = "3"
)
func main() {
fmt.Println("**** 开启apollo配置监听 ****")
http.HandleFunc("/apollo/webhook", HandleWarning)
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Printf("Error listening HTTP: %s", err.Error())
}
}
func HandleWarning(w http.ResponseWriter, r *http.Request) {
time.Sleep(time.Second)
body, err := io.ReadAll(r.Body)
if err != nil {
http.Error(w, "Error reading HTTP request", http.StatusBadRequest)
log.Printf("Error reading HTTP request: %s", err.Error())
return
}
var change ApolloChange
if err := json.Unmarshal(body, &change); err != nil {
http.Error(w, "Error parsing JSON", http.StatusBadRequest)
log.Printf("Error parsing JSON: %s", err.Error())
return
}
apolloType := getApolloType(change.Operator)
change.Time = time.Now().Format("2006-01-02 15:04:05.000")
message := fmt.Sprintf("******* <font color=\"info\">【 PRO环境 】Apollo 配置变更通知</font> *******\n"+
">项目名: <font color=\"comment\">%s</font>\n"+
">配置空间: <font color=\"comment\">%s</font>\n"+
">操作人员: <font color=\"comment\">%s</font>\n"+
">更新时间: <font color=\"comment\">%s</font>\n"+
">更新类型: <font color=\"comment\">%s</font>\n"+
">更新内容: <font color=\"comment\">%s</font>",
change.AppID, change.NamespaceName, change.Operator, change.Time, apolloType, change.ReleaseComment)
fmt.Println(message)
payload, err := json.Marshal(map[string]interface{}{
"msgtype": "markdown",
"markdown": map[string]interface{}{
"content": message,
},
})
if err != nil {
http.Error(w, "Error creating JSON payload", http.StatusInternalServerError)
log.Printf("Error creating JSON payload: %s", err.Error())
return
}
resp, err := http.Post(weChatWebhookURL, "application/json", bytes.NewBuffer(payload))
if err != nil {
http.Error(w, "Error sending HTTP request", http.StatusInternalServerError)
log.Printf("Error sending HTTP request: %s", err.Error())
return
}
defer resp.Body.Close()
if resp.StatusCode == http.StatusOK {
fmt.Println("Message sent successfully!")
} else {
fmt.Println("Error sending message. Status code:", resp.StatusCode)
}
}
func getApolloType(operator string) string {
switch operator {
case OperatorNormalRelease:
return "正常发布"
case OperatorConfigRollback:
return "配置回滚"
case OperatorGrayRelease:
return "灰度发布"
case OperatorFullRelease:
return "全量发布"
default:
return "正常发布"
}
}
服务部署
本地部署
最简单直接跑在宿主机上,详细操作就不讲解了
容器化部署
构建镜像
Dockerfile如下
dockerfile
FROM golang:1.21.1-alpine3.18 AS builder
COPY . /src
WORKDIR /src
RUN GOPROXY=https://goproxy.cn go build -o bin/apollo-webhook
FROM alpine:3.18.3
COPY --from=builder /src/bin /app
WORKDIR /app
# 同步时区
RUN apk --update add tzdata && \
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo "Asia/Shanghai" > /etc/timezone && apk del tzdata && \
rm -rf /var/cache/apk/*
EXPOSE 8080
CMD ["./apollo-webhook"]
构建好镜像之后直接使用就好了,可根据自己的方式部署好,把地址 正确填写到 Apollo
的config.release.webhook.service.url
使用
在Apollo更新配置,点击发布时填写对应的Comment信息,发布成功之后数据就会通知到对应的企业微信群中
样例展示,在企业微信群中能够看到以下内容