某某公司CodeReview工具链

背景

最近,部门新leader和之前的leader打算搞一个codereview平台,在这个平台上可以看出谁提交了多少commit,谁提出了多少merge request,谁帮别人合并了merge request,一些merge时的评论等等等诸多数据。
之前也有类似的平台,但是太鸡肋,没使用起来。加上最近线上问题频出,测试反馈开发人员自测效果差,bug率高,两位leader终于决定重新搞一个平台,向全公司几百个研发人员推广起来(KPI)。

过程

动员大会

前leader:我们不仅要搞平台,我们还要搞一些工具。因为推广codereview的前提就是让开发人员爱上codereview。如果没有快捷便利的工具,codereview这个平台很难推进下去。我们想想办法,看看能不能让开发人员积极参与codereview,更完善我们的开发体系。

:好吧 leader,我觉得首先最大的痛点就是那个preview工具(npm包,需要安装node,功能是命令同时创建开发分支与测试分支,并且可以指定人员进行merge<输入OA账号>,生成merge request,操作者私发merge request地址给指定人员,指定人员进行merge ),不太好用。除了我们组几乎没怎么有人想用,而且还要安装node,我们公司的后端和其他语言的开发根本不能接受。如果我们能做出vscode插件或者IDEA插件,摒弃preview工具,这将是一个伟大的进步。

前leader:好想法,你来带头做吧,一个月,我要看到成果。

在这里插入图片描述


功能设计

  1. vscode或IDEA工具内部 gitlab token登录
  2. preview工具功能移植
    在vscode或IDEA内部实现(非命令)快速创建开发分支与测试分支
    在vscode或IDEA内部实现(非命令)快速创建merge request
  3. vscode或IDEA工具内部 merge request请求合并消息通知 与 merge request合并成功消息通知

思路流程

1. 用户商场下载vscode preview插件,启动插件
2. 用户建立与node服务websocket连接(保存userId与socketId)
3. 用户利用gitlab token登录
4. 登录时,获取gitlab此用户信息,获取此用户userName,userId,email等信息
5. 将gitlab token和用户信息写入文件,后续不需重复登录
6. 用户点击新建分支按钮,选择基于某个分支创建分支(默认第一个推荐分支为master,也可模糊查询其他分支)
7. 用户选择好基于的分支,输入此次需求名,如为newFeat,回车创建
8. 创建出相对应开发分支(dev_newFeat_fujt_20220705)与测试分支(test_newFeat_fujt_20220705),用户本地提示成功
9. 此时远程gitlab亦有这两个分支,本地自动切换到开发分支dev_newFeat_fujt_20220705,用户本地提示切换dev分支成功
10.用户在此分支提交一些commit后,想合并到其他分支或 test_newFeat_fujt_20220705分支,点击提交mr按钮
11.选择想合并的分支(默认第一个推荐分支为 test_newFeat_fujt_20220705,也可模糊查询其他分支)
12.用户选择好想合并的分支,输入指定用户进行codereview(输入oa名称这里oa名即gitlab userName),回车创建
13.用户本地提示创建mr成功,此时,项目的webhooks http请求请求node服务
14.node服务受到此请求内容向建立的websocket通道抛消息(使用codis做userId与socketId对照关系,指定用户推送)
15.指定用户受到此消息,vscode内部弹出,请求合并的通知及mr地址,点击消息按钮自动打开浏览器mr地址
16.指定用户进行mr合并,此时项目的webhooks http请求再次请求node服务
17. node服务受到此请求内容向建立的websocket通道抛消息(使用codis做userId与socketId对照关系,指定用户推送)
18. 用户受到此消息,vscode内部弹出,请求合并的通知及mr地址,并提示 XXX已合并你的mr,点击消息按钮自动打开浏览器mr地址
19. 断网,关闭vscode时,重新谁知token等等,断开websocket,清除远端socketId

优点

优点是相对于之前工具进行对比的

  1. 之前npm包工具初始化时需要输入OA账号,密码,gitlab接入token登录,
    我们的code preview工具初始化只需要输入gitlab接入token登录,更方便,更简单。
  2. 之前gitlan创建merge request或合并merge request后,相关人员会在企业微信收到提醒推送,但是大多数人不会去看消息推送,或者第一时间看不到消息推送,或者直接屏蔽消息推送,我们的code preview工具在开发界面弹出消息通知,不怕第一时间看不到,并且可以直接点击此消息,跳转到相关gitlab地址
  3. 创建分支,创建merge request,更快 更方便,之前npm包工具创建分支需要输入命令行,现在只需要鼠标点一点就可以快速创建分支与merge request
  4. 安装。之前的npm包需要安装node,下载npm包,我们的code preview工具只需要在vscode商城进行下载或者工具导入即可。对于后端来说,更不需要安装node环境了,IDEA商城下载即可。

后期规划

websocket建立数过多,可能针对node端是非常大的负载,后面有可能会同时存在上万个websocket连接数(不排除有人打开多个vscode或IDEA),那消息也有可能丢失,不在线的话,消息会被消费。后面真正出现了性能问题,我们再进行优化。

开发日记

20220701更新
打算了用sse做,但是sse是html5的技术,npm也有相对应的包,但是IDEA那边好像是不支持,改用websocket吧~

20220703更新
消息丢失有点严重 连续性丢,我自己的websocket的应用都没有那么严重,几乎不丢消息,头疼

20220705更新
目前已找到原因,本地node服务推送消息时,向房间内推,所有socket通道都可以收到。但是线上node服务推送消息时,向房间内推,只有一个socket通道都可以收到

解决方案:

1. 向房间内发改成向指定socket推消息
2. 解决这个线上问题

20220708更新
消息推送做吐了 先是群推,本地可以线上不行,又是单推用redis,本地可以了想部署到线上看看,md的线上没redis,用的codis集群,我就纳闷了为啥我们非得用正式环境做codereview,测试环境就有redis,我还得改代码改成codis,本地下载codis或者找个测试的codis集群连一下,然后再部署再看,就算是成了线上单推都不一定有用

20220710更新
已使用codis替换redis
不出所料,指定用户推也是不行,因为用户有多个socket,也是那个现象,在某段时间内只有一个socket能收到消息,明天找专业node开发来看下问题

20220712更新
目前问题:使用egg-socket.io,客户端有时收不到消息

目前推测出的原因如下:

  1. egg-socket.io自身包问题 (怀疑:因为本地不存在这个问题)
  2. egg-socket.io与socket.io-client的使用问题 (怀疑:本地不存在这个问题)
  3. 线上部署的环境问题 (这个原因最难解决)
  4. websocket建立时会走流量网关(nginx),怀疑流量网关做了什么限制 (这个概率最大)

目前的主要前进点是:看流量网关日志 或 直连node服务所在容器的IP

方案一:看流量网关日志的话,这个有点难,我们还得求运维大爷们私下看,并且最后问题范围还是比较大,这个最后考虑。
方案二:直连node服务所在容器的IP,但是这个容器IP是不固定的,并且是内网IP,容器不开放外网IP。需要找个运维提TB,让他配这个容器的域名,直接访问容器域名。

20220713更新

上午,推动太难了,运维说目前不允许针对容器私自配置域名,需要走平台,但是平台都走流量网关了。他让我找另一个运维开发容器IP,另一个运维不吊我,开发大头兵推动太难了。
下午,找运维配置好了,直连IP尝试了下,还是有哪个问题,流量网关包括nginx没有做特殊限制,所以我们进一步把问题缩小,就是node所在服务器的问题。我们去找node开发大佬帮助我们。
晚上,node大佬正在从代码层面 数据链路层排查,各种花哨的东西,希望明天就能解决这个问题吧~

20220714
Node大佬,还是觉得断开socket连接,其实并没有,心跳一直是正常的,20s一次,没有任何重连或报错,一但报错,重连,断开,都会打印日志。

20220715更新

终于找到原因了妈呀,太难了!

上午,还是在考虑node环境问题包问题代码写法有问题,是不是写法是异步当成同步了?是不是网络延迟导致的等等。甚至在每行代码都打上了日志,去看了egg-socket.io的源码(发现socket.io版本都4.x了,egg-socket.io用的还是2.x的socket.io版本,确实阿里KPI项目,用完就扔)。

下午,偶然看到一个issue egg socket 处理第三方请求如何实时返回数据,感觉自己一瞬间顿悟了,线上我们不是用的egg自带的守护进程,用的pm2,这两种方式都是多进程部署。我本地是单进程启动的,线上是多进程,会不会和进程有关,所以我在本地开启了多进程,但是还没有复现线上的问题,那就和进程无关了。但是我就是感觉与进程有关,想尝试线上换成单进程。 和我一起看问题的后端大佬,说可能与进程无关(他们java好像把websocket连接都做到一个进程里面)。但是我还是想要看看线上一个进程的话,会不会还有这个问题。

此时后端大佬让我看pid,netstat -antp ,我们知道一个pid对应一个进程,一个tid对应一个线程。
在这里插入图片描述
每新增一个socket,就会新增一个tcp6,我们看最下面三个是websocket连接,他们的进程id是71 77 77,有两个websocket处于一个进程(如果此时http请求所在进程能够捕捉到的话,应该也是有对应pid的),猛的意识到之前丢消息毫无规律,真的有可能就和进程有关。

http请求在71进程,只有一个websocket能收到消息
http请求在77进程,有两个websocket能收到消息
http请求在其他进程,没有websocket能收到消息

我们此时发http测试,ok 完全符合我们猜测的规律!

原因已经找到了,http请求过来 主进程处理,分发给工作进程,如果恰好这个进程中有维护的socket连接,那么会向此进程内的socket推送消息,处于其他worker进程的socket连接,就没办法获取推送消息。

有了原因也就有了解决方案,我们也背过八股文,进程间如何通信?

1. IPC
2. 消息队列

恰好此时 我找到了一个包socket.io-redis(redis-adapter),我之前看到过,以为是缓存消息的,原来这个就是解决多进程通信,做消息队列的。。。。
因为我们线上只开方codis,所以这个redis我也是用不了,所以问了Node大佬,他给我提供了解决方案
在这里插入图片描述

感觉node大佬说对了一半,明天要模拟socket.io-redis 实现发布订阅,写一个npm包

20220717更新

消息推送问题解决啦
在这里插入图片描述
使用的IPC多进程通信,消息队列时间成本太大了,但是IPC有一点不好的就是如果部署多个容器或者多服务器的话就不行了,好在我们只有一台容器,可以解决这个问题。

自此,全部codereview工具链主流程完全走通,剩下是功能优化阶段~

总结

花了很长时间解决消息推送这块,我感觉是值得的。
可能对于codereview工具链来说,这个功能并不是非常重要,但是这种方案或者这种想法是值得的。
我们后面可以把各种各样的消息继承到vscode或IDEA中,teambation的bug,发布测试环境或线上通知,线上告警通知等等。
在我们开发的时候,能让我们第一时间看到的,绝对不是手机短信,电话,甚至钉钉、企业微信,绝对是vscode或IDEA的消息提示。

对于整体的codereview工具链来说,整套思路流程及其简便利落,提高开发效率,提升开发质量,这套工具链绝对值得任何团队任何人拥有。

  • 10
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值