自动化部署和消息推送

一、前言
1、思考:如何取得平衡?
代码写的太简单,可复用性较低,易读易懂;
代码写的太抽象,有一定的复用性,维护成本较高,需要专人维护,否则可能引起牵一发而动全身的问题。
如何避免过度抽象,过度简单,具备一定抽象性,但是人人都能维护,分离逻辑和配置。
2、软件设计
什么时候选择自顶向下?什么时候选择自底向上?不知道怎么做,先小思做起来,后再思;知道怎么做,先大思开始做,后再思。
3、分析现状
目前代码业务性太强,如果新建业务线,需要读一遍代码,结合具体项目改数据改配置。且一部分push监控在mainApp进行,一部分push监控在find-error-info项目监控。
4、本次开发与之前代码的不同之处
分离逻辑和数据配置,配置层,获取数据,处理数据,选择通知工具,数据推送。添加评论通知功能。
5、旨在解决什么问题
以后如果新起业务线,做类似功能,不用考虑逻辑如何,改改配置文件即可。

二、学习与再设计
1、参考文档
https://gitlab.pahf.com/help/user/project/integrations/webhooks
https://ding-doc.dingtalk.com/doc#/serverapi2/hoy7iv
https://ding-doc.dingtalk.com/doc#/serverapi2/qf2nxq
2、参考代码
https://gitlab.pahf.com/f2e/find-error-file
3、重新设计的代码
https://gitlab.pahf.com/fe-experienment/monitor-app-server-test

三、问题记录

1、【gitlab】Hook execution failed: Net::ReadTimeout
在gitlab配置钩子,点击test的时候,出现报错。在接口里面添加如下代码即可。
return res.json({
    code: 1,
})
再次点击test,出现Hook executed successfully: HTTP 200,说明配置成功。

2、【linux】E45: ‘readonly‘ option is set (add ! to override)
:wq!,强制保存退出。

3、【钉钉】不能收到消息
{"errcode":300001,"errmsg":"robot type do not match with the message"}
因为webhook地址用成了gitlab机器人的,换成自定义机器人就好了。

4、【钉钉】sign not match
需要在钉钉通知的消息代码里面添加在钉钉群配置的自定义关键词。

5、【钉钉】token is not exist
代码里面的token和钉钉里面的token不一致。

6、每次都要重启nginx和服务端吗?
一般修改了nginx配置,才需要去重启nginx, nginx -s reload。如果修改了服务端文件,需要重启服务端,到服务端项目的根目录执行make stop/make start。
虽然这个问题是常识,但是难免会忘记,如果修改了代码,没起效,看看是否需要重启?不同的服务端项目,重启服务端的命令可能不同,需要看开发者的设计。

四、一些配置
1、配置gitlab的webhook
在mainApp主项目,进入settings/integrations,在url填入你写的服务,勾选相应的钩子。比如http://10.3.7.76:8182/webhook/comment,就勾选Comments的trigger。
2、配置钉钉
在实验阶段,先拉3个人建立一个群,再把人移出去,智能群助手,添加机器人,应该选择自定义(通过webhook接入自定义服务)机器人,不要选择gitlab机器人。
然后设置自定义机器人,机器人名字,添加到群组,安全设置。
记住webhook和安全设置,到时候会在服务端代码用到。
3、nginx配置

# monitorApp,服务端
server {
    listen 80;
    server_name monitortest.pahfqc.com;
    location / {
        proxy_pass http://127.0.0.1:8182;
   }
}

# mainApp,浏览器端
server {
    listen 80;
    server_name mainapptest.pahf.la 10.3.7.76;
    root /frontend/mainApp/dist;
    location / {
        index  index.html;
        try_files $uri /index.html;
   }
}

五、编码阶段
1、主项目(客户端)mainApp
省略。。。。。

2、监控项目(服务端)monitorApp

processCommentMsg方法包装从gitlab获取的数据,然后通过工具(比如钉钉)进行消息推送,最终以希望的格式显示到群里。

// processCommentMsg.js 评论,codereview
const https = require("https");
processCommentMsg = (json) => {
    console.log(json);
    const dingdingReq = https.request(
        `https://oapi.dingtalk.com/robot/send?access_token=70fd6914fb1177ecc11ec97308b0205167126759db242311c37f149d7dff94ef`,
        {
            method: "post",
            headers: {
                "Content-Type": "application/json;charset=utf-8"
            }
        },
        (res) => {
            console.log("获取响应:" + res.statusCode);
            res.on(‘data‘, function (d) {
                console.log("状态码:" + d);
            }).on(‘end‘, function () {
                console.log(‘请求结束:‘, res.headers)
            });
        }
    );
    const zdyContent = ‘监控报警:‘ + ‘这是一条消息‘;
    const atMobilesArr = [
    {
        names: [‘小芳‘, ‘xiaofang‘],
        phone: ‘18816968510‘,
    }]
    // 读取config配置,可以传文本格式及是否AT所有人。
    const textInfo = {
        msgtype: "text",
        text: {
            content: zdyContent
        },
        at: {
            atMobiles: atMobilesArr,
            isAtAll: false
        }
    };
    dingdingReq.write(JSON.stringify(textInfo));
    dingdingReq.end();
}

// push.js, 提交代码,一则推送消息,二则更新服务器代码,并重新构建。
processPushMsg = () => {
    const { exec } = require(‘child_process‘)

    const command = [
        "cd /frontend/mainApp",
        "git fetch --all",
        "git reset --hard origin/master",
        "git pull --rebase",
        "yarn",
        "yarn build"
        ].join(‘ && ‘);

    exec(command);
}

// app.js
const express = require(‘express‘);
const app = express();
app.all(‘/webhook/comment‘, async (req, res) => {
    let json = getJSON(req.body);
    processCommentMsg(json);
      
    return res.json({
        code: 1,
    })
});

app.all(‘/webhook/push‘, async (req, res) => {
    let json = getJSON(req.body);
    processPushMsg(json);
      
    return res.json({
        code: 1,
    })
});

app.listen(‘8182‘, () => {
    console.log(‘监听端口‘);
});
# makefile
start:
    yarn
    pm2 start src/app.js --name monitorApp
stop:
    pm2 stop monitorApp
reload:
    git checkout .
    git pull --rebase
    yarn
    pm2 reload monitorApp

在服务器上,make start,启动monitorApp,监听接口,守护进程。

六、测试
在gitlab上,打开主项目mainApp,找到webhook,点击test,选择评论钩子,查看钉钉群是否能收到消息。选择某一个merge request,对曾经修改的某个文件进行评论,codereview。鼠标放到代码行左侧,会看到气泡图标。

七、流程图

自动化部署和消息推送

【温馨提示】该文档将长期更新,新加内容,或另起文章连载同一个话题。