前言
本文的灵感是在几个月以前工作不忙(摸鱼)时想到的,老是自己一个人往前冲冲冲也没啥意思,需要想一点办法,来提高团队的效率,提高团队的幸福感(效率起来了,单位时间内代码写的更多,那不就幸福啦 😜),经过几个月的摸索,总结出了几个小点,如果大家有更好的方式,欢迎一起讨论~
永久解决不知道是什么版本
我司的产品主要分为Saas端和私有平台,分别部署在公网和客户的私有环境,先来说说私有环境的问题:不知道真正部署的项目版本,说来很可笑,运维同学在部署的时候肯定是记录过各个客户的代码版本的,但也就是这么可笑,有时候就是会弄错,可能是由于升级流程不够完善,或者工作失误等等,总之,想个办法解决。
人靠不住,但还有代码。Git已经成为代码管理的事实标准,这就不多说了,即然人管理不好版本,那还是从Git本身入手吧,悄咪咪的给所有项目依赖(POM.XML)增加一个插件:
<!-- Git Version插件 -->
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
<version>4.0.0</version>
<executions>
<execution>
<id>get-the-git-infos</id>
<phase>initialize</phase>
<goals>
<goal>revision</goal>
</goals>
</execution>
</executions>
<configuration>
<dotGitDirectory>${project.basedir}/.git</dotGitDirectory>
<verbose>false</verbose>
<dateFormat>yyyy-MM-dd HH:mm:ss</dateFormat>
<prefix>git</prefix>
<generateGitPropertiesFile>true</generateGitPropertiesFile>
<generateGitPropertiesFilename>${project.build.outputDirectory}/${project.name}.build.json</generateGitPropertiesFilename>
<format>json</format>
<gitDescribe>
<skip>false</skip>
<always>false</always>
<dirty>-dirty</dirty>
</gitDescribe>
</configuration>
</plugin>
插件将会在每次构建时生成一个版本相关文件,内容如下:
{
"git.branch" : "master",
"git.build.host" : "Kerwin",
"git.build.time" : "2020-08-12 23:24:59",
"git.build.user.email" : "[email protected]",
"git.build.user.name" : "kkzhilu",
"git.build.version" : "1.0.0-SNAPSHOT",
"git.closest.tag.commit.count" : "",
"git.closest.tag.name" : "",
"git.commit.id" : "4981afb5dfeee6f835dcf9a7a135083d8e973090",
"git.commit.id.abbrev" : "4981afb",
"git.commit.id.describe" : "4981afb",
"git.commit.id.describe-short" : "4981afb",
"git.commit.message.full" : "Commit git-version",
"git.commit.message.short" : "Commit git-version",
"git.commit.time" : "2020-08-04 18:18:47",
"git.commit.user.email" : "[email protected]",
"git.commit.user.name" : "kexianming",
"git.dirty" : "false",
"git.local.branch.ahead" : "0",
"git.local.branch.behind" : "0",
"git.remote.origin.url" : "https://github.com/kkzhilu/KerwinBoots.git",
"git.tags" : "",
"git.total.commit.count" : "9"
}
插件名字叫:git-commit-id-plugin,至于细节使用就自己去搜索啦,它可以实现的效果即在每次打包时生成相应的Git相关信息,这样无论运维同学是否把代码升错,我们都可以知道代码到底是什么版本
以后终于听不到同事之间因为代码版本扯皮的事情了🤪
永久解决没打日志怎么办的问题
回到刚刚说的Saas端生产环境,由于各种原因,我们团队经常需要维护不是自己写的项目,很多时候一些细节逻辑完全摸不着头脑,而且没有日志,最要命的是在测试环境还不复现,肿么办?
以前的解决方案是各种喊人,然后硬看代码寻找上下文,尽可能的找到蛛丝马迹,总之效率非常感人,处理的慢了就是一个事故,全员挨批评,咋办呢?我就一直在寻找这种问题的解决办法,终于我发现了一个神器:Arthas
用过这个工具的人就知道它有多强大,阿里出品,官方文档链接:https://arthas.gitee.io/commands.html
我们可以通过其提供的部分命令,如:tt
,获取方法执行数据的时空隧道,它可以记录下指定方法每次调用的入参和返回信息,想想它的帮助有多大,记录每一个方法的入参和出参,如果真遇上没日志的情况,知道这些信息其实配合代码就可以很快定位问题了,所以,听过没用过的朋友,都去试试吧,真的很无敌。
下次同事有难时,你就用这个工具去帮他,他说不定会请你吃顿饭🍗
永久解决哪里耗时这么长的问题
这个问题是由于之前同事重写了一块业务逻辑,结果线上展现层耗时大概30s,oh,天哪!在测试环境明明是一瞬间的,咋办?
造成这种问题的原因,肯定是SQL写的不好,或者业务处理哪里做了很多不必要的动作(我们没有灰度测试),但是生产环境又不能随便动,也不能断点调试,从日志也只能看到耗时很长,但是慢在哪里不知道。
当一个方法里面经过了N个内部方法后,你不知道到底是哪一个导致这么长的耗时,当无法复现的时候怎么办呢?其实还是利用上面的那个工具Arthas,还是一样的命令tt,它不仅可以记录入参和出参信息,还可以记录每一个方法的耗时,多么的强大。
所以我是为了再次提醒,这些功能只是Arthas的一点皮毛,咱们要学会合理使用开源工具
注释无法表达流程图效果的解决方案
注释是文字,难以表达如流程图一般的效果,所以该怎么办呢?我找到了两种解决方案,目前在项目中使用效果非常之好,第一钟是利用ASCII注释工具,该工具的地址:http://asciiflow.com/
效果如下:
注释如下:
+-------------------------------+
| |
| +-------------------------+ |
| | | |
| | Demo | |
| | | |
| | | |
| +------------+------------+ |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| +------> False |
| | |
| | |
| True <---+ |
| |
+-------------------------------+
这玩意画出来的图是可以直接复制成文本的,控制好尺寸就可以解决大部分情况,也可以想象之前网上有一些很奇葩的注释是不是就是用这个工具或者同样的原理画出来的,附上一副之前文章缺的一张图:
上亿数据怎么玩深度分页?兼容MySQL + ES + MongoDB:https://juejin.im/post/6850037275456339975
这篇文章写完的时候,我自己方案的图还没画好,所以很多朋友问我用id实现不了什么的,这次就顺便展示一下我的方案
解决方案之二,利用MarkDown的原生画图功能,我不知道要发布文章的平台支不支持,所以用截图来代替了(Typora支持)
不知道的同学搜一下,MarkDown绘图语法,拿一个适合的改就好了,没必要专门去学,放到代码里看看效果:
有一个小Tips,使用IDEA的时候,利用鼠标滚动键可以按块复制,这样一来可以直接复制到指定的注释内容,然后把它复制到任何一个正常的MarkDown工具里,就可以展示流程图了,简直不要太完美,想测试的朋友可以复制以下代码去一些工具里试试,需要设置代码种类为:mermaid
sequenceDiagram
Note over Boot: 启动类
Note over PDFThread: 线程类
Note over PDFWorker: 执行类
Boot->>PDFThread: Boot类启动线程
PDFThread->>PDFWorker: 线程类调用真正工作Worker
loop 队列处理
PDFThread->PDFThread: 考虑成功与失败情况处理方案
end
PDFWorker-->>PDFThread: Worker响应执行结果
Note right of PDFWorker: 注意参数校验 <br/>文件格式校验
你未来的同事维护代码的时候会爱上你,如果是女生,可能还会嫁给你🧡
幻想有一天你老大跑过来问你,你这写的注释都是些什么玩意,然后你一复制一粘贴,一张图就出来了!下次涨薪会没有你?
(反正我涨了,还不少😎)
PS:我考虑写一个支持直接复制然后渲染成流程图的IDEA插件,如果有现成的请联系我,就省的我去写了,嘿嘿✌
垃圾SQL的解决方案
我们公司没有专门的DBA
,所以SQL
语句的质量只掌握在开发和开发组长的手上,有时候事情多,或者不细心,或者模块不是很重要就容易粗心,到了生产环境出大问题,针对这种情况的解决方案依然是寻找工具,比如,我盯上了小米的`Soar
项目地址:https://github.com/XiaoMi/soar
官方的介绍:
- 跨平台支持
- 目前只支持 MySQL 语法族协议的 SQL 优化
- 支持基于启发式算法的语句优化
- 支持复杂查询的多列索引优化(UPDATE、INSERT、DELETE、SELECT)
贴个图片展示一下效果:
这款工具可以进行对SQL进行打分,同时提供一些建议,它的能力上限我们还没有摸索出来,但是下限还是可以肯定的,因此之后只需要关注索引是否正确使用,其他的就交给这个工具吧,低于90分,就改!
PS:这个开源项目推荐使用docker安装,简单粗暴无脑省时间,命令如下:
# 安装镜像
docker pull becivells/soar-web
# 运行
docker run -d --name Soar-web -p 5077:5077 becivells/soar-web
想着有个工具会检查SQL质量了,是不是写的时候也认真多啦,幸福感提示满满,哈哈~😁
懒得写文档的解决方案
方案设计的文档不可能由工具去写,但是简单的数据库字段映射,或者接口文档总不需要开发去写吧?也是一样摸索摸索,找到了几个不太适合但是靠边的开源项目,如:
apidoc:https://github.com/apidoc/apidoc
JApiDocs:https://github.com/YeDaxia/JApiDocs
APIAuto:https://github.com/TommyLemon/APIAuto
因为每个项目的情况不同,但是我又不想做大的改动,所以只能说是靠边,不能百分百适合,但有了这些开源项目,我就可以改写其中的代码,让它适应当前项目的注释方案等等,总是,能节省相当一部分的编写文档的时间
重复性代码的解决方案
这个的确是个大坑,谁让咱们是CRUD程序员呢,经常需要写重复性相当高,但是又有一点不同的代码,这里我的解决方案是利用模板 + 更合适的工具解决,如果只是数据库操作层重复代码多,我们完全可以利用mybatis-plus工具减少重复代码,又或者写出公共的操作层减少重复代码。
当用工具完不成的时候,我就会用上模板了,比如直接我写过一个简单的开源项目:
好像很厉害的生成器!一秒钟搞定一个项目:https://juejin.im/post/6844904148417118215
核心思路和要求如下:
- 基于数据库获取原始数据
- 基于模板 + 原始数据生成可运行的SpringBoot项目,支持界面 + 基本增删改查
- 提供拓展式接口,可以实现不修改代码生成全新的文件
那利用这种思路,其实完全可以写一套更开放的代码生成模板,比如根据传递的JSON
报文去解析数据,根据传递的模板
去生成数据,这样的话又可以解决相当大一部分的重复工具,你,值得拥有。
PS:同理,其实数据库字段映射文档也可以用这种方式,只需要一秒钟,简直不要太舒服🤷♂️
重复性的操作用脚本代码
这个其实大家都有意识,但是有时候就是感觉可能用的不多,真要用起来的时候又没功夫去写脚本,比如进入一个docker容器,如果用命令行的话,至少要经历两步代码,十几秒的时间,如果写一个脚本呢,以后进入容器只需要一秒钟,所以我给团队写了不少这种脚本,其实我一开始也不会,反正就复制来一个改一改就行,如下是进入docker容器的
#使用说明,用来提示输入参数
usage() {
echo "Usage: sh 执行脚本.sh [rpcapp|tomcat|nginx|mysql]"
exit 1
}
rpcapp(){
DOCKER_ID=$(docker ps | grep "rpcapp" | awk '{print $1}')
docker exec -it $DOCKER_ID bash
}
tomcat(){
DOCKER_ID=$(docker ps | grep "tomcat" | awk '{print $1}')
docker exec -it $DOCKER_ID bash
}
nginx(){
DOCKER_ID=$(docker ps | grep "nginx" | awk '{print $1}')
docker exec -it $DOCKER_ID bash
}
mysql(){
DOCKER_ID=$(docker ps | grep "mysql" | awk '{print $1}')
docker exec -it $DOCKER_ID bash
}
#根据输入参数,选择执行对应方法,不输入则执行使用说明
case "$1" in
"rpcapp")
rpcapp
;;
"tomcat")
tomcat
;;
"nginx")
nginx
;;
"mysql")
mysql
;;
*)
usage
;;
esac
从网上找了找,又找到一个开源项目用以记录常用的脚本
useful-scripts:https://github.com/oldratlee/useful-scripts
能自动的就不要每次都手写啦,节约时间去摸鱼不快乐吗👏
最后
这可是我这么久以来总结的时间管理神器,节省的时间拿去摸鱼学习,循环促进效率和能力,形成良性正反馈
这还不值得来个赞👍👍👍吗?嘿嘿~