前言
本文的靈感是在幾個月以前工作不忙(摸魚)時想到的,老是自己一個人往前沖沖衝也沒啥意思,需要想一點辦法,來提高團隊的效率,提高團隊的幸福感(效率起來了,單位時間內程式碼寫的更多,那不就幸福啦 ?),經過幾個月的摸索,總結出了幾個小點,如果大家有更好的方式,歡迎一起討論~
<br/>
永久解決不知道是什麼版本
我司的產品主要分為Saas端和私有平臺,分別部署在公網和客戶的私有環境,先來說說私有環境的問題:不知道真正部署的專案版本,說來很可笑,運維同學在部署的時候肯定是記錄過各個客戶的程式碼版本的,但也就是這麼可笑,有時候就是會弄錯,可能是由於升級流程不夠完善,或者工作失誤等等,總之,想個辦法解決。
<br/>
人靠不住,但還有程式碼。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" : "34807944+kkzhilu@users.noreply.github.com",
"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" : "34807944+kkzhilu@users.noreply.github.com",
"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相關資訊,這樣無論運維同學是否把程式碼升錯,我們都可以知道程式碼到底是什麼版本
以後終於聽不到同事之間因為程式碼版本扯皮的事情了?
<br/>
永久解決沒打日誌怎麼辦的問題
回到剛剛說的Saas端生產環境,由於各種原因,我們團隊經常需要維護不是自己寫的專案,很多時候一些細節邏輯完全摸不著頭腦,而且沒有日誌,最要命的是在測試環境還不復現,腫麼辦?
<br/>
以前的解決方案是各種喊人,然後硬看程式碼尋找上下文,儘可能的找到蛛絲馬跡,總之效率非常感人,處理的慢了就是一個事故,全員挨批評,咋辦呢?我就一直在尋找這種問題的解決辦法,終於我發現了一個神器:Arthas
<br/>
用過這個工具的人就知道它有多強大,阿里出品,官方文件連結:https://arthas.gitee.io/comma...
我們可以通過其提供的部分命令,如:tt
,獲取方法執行資料的時空隧道,它可以記錄下指定方法每次呼叫的入參和返回資訊,想想它的幫助有多大,記錄每一個方法的入參和出參,如果真遇上沒日誌的情況,知道這些資訊其實配合程式碼就可以很快定位問題了,所以,聽過沒用過的朋友,都去試試吧,真的很無敵。
下次同事有難時,你就用這個工具去幫他,他說不定會請你吃頓飯?
<br/>
永久解決哪裡耗時這麼長的問題
這個問題是由於之前同事重寫了一塊業務邏輯,結果線上展現層耗時大概30s,oh,天哪!在測試環境明明是一瞬間的,咋辦?
造成這種問題的原因,肯定是SQL寫的不好,或者業務處理哪裡做了很多不必要的動作(我們沒有灰度測試),但是生產環境又不能隨便動,也不能斷點除錯,從日誌也只能看到耗時很長,但是慢在哪裡不知道。
<br/>
當一個方法裡面經過了N個內部方法後,你不知道到底是哪一個導致這麼長的耗時,當無法復現的時候怎麼辦呢?其實還是利用上面的那個工具Arthas,還是一樣的命令tt,它不僅可以記錄入參和出參資訊,還可以記錄每一個方法的耗時,多麼的強大。
<br/>
所以我是為了再次提醒,這些功能只是Arthas的一點皮毛,我們們要學會合理使用開源工具
<br/>
註釋無法表達流程圖效果的解決方案
註釋是文字,難以表達如流程圖一般的效果,所以該怎麼辦呢?我找到了兩種解決方案,目前在專案中使用效果非常之好,第一鍾是利用ASCII註釋工具,該工具的地址:http://asciiflow.com/
效果如下:
註釋如下:
+-------------------------------+
| |
| +-------------------------+ |
| | | |
| | Demo | |
| | | |
| | | |
| +------------+------------+ |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| +------> False |
| | |
| | |
| True <---+ |
| |
+-------------------------------+
這玩意畫出來的圖是可以直接複製成文字的,控制好尺寸就可以解決大部分情況,也可以想象之前網上有一些很奇葩的註釋是不是就是用這個工具或者同樣的原理畫出來的,附上一副之前文章缺的一張圖:
上億資料怎麼玩深度分頁?相容MySQL + ES + MongoDB:https://juejin.im/post/685003...
這篇文章寫完的時候,我自己方案的圖還沒畫好,所以很多朋友問我用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/>檔案格式校驗
你未來的同事維護程式碼的時候會愛上你,如果是女生,可能還會嫁給你?
幻想有一天你老大跑過來問你,你這寫的註釋都是些什麼玩意,然後你一複製一貼上,一張圖就出來了!下次漲薪會沒有你?
(反正我漲了,還不少?)
<br/>
PS:我考慮寫一個支援直接複製然後渲染成流程圖的IDEA外掛,如果有現成的請聯絡我,就省的我去寫了,嘿嘿✌
<br/>
垃圾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質量了,是不是寫的時候也認真多啦,幸福感提示滿滿,哈哈~?
<br/>
懶得寫文件的解決方案
方案設計的文件不可能由工具去寫,但是簡單的資料庫欄位對映,或者介面文件總不需要開發去寫吧?也是一樣摸索摸索,找到了幾個不太適合但是靠邊的開源專案,如:
apidoc:https://github.com/apidoc/apidoc
RESTful web API Documentation Generator.
<br/>
JApiDocs:https://github.com/YeDaxia/JA...
A magical api documentation generator without annotation for springboot.
<br/>
APIAuto:https://github.com/TommyLemon...
機器學習測試、自動生成程式碼、自動靜態檢查、自動生成文件與註釋等,做最先進的介面管理工具
<br/>
因為每個專案的情況不同,但是我又不想做大的改動,所以只能說是靠邊,不能百分百適合,但有了這些開源專案,我就可以改寫其中的程式碼,讓它適應當前專案的註釋方案等等,總是,能節省相當一部分的編寫文件的時間
<br/>
重複性程式碼的解決方案
這個的確是個大坑,誰讓我們們是CRUD程式設計師呢,經常需要寫重複性相當高,但是又有一點不同的程式碼,這裡我的解決方案是利用模板 + 更合適的工具解決,如果只是資料庫操作層重複程式碼多,我們完全可以利用mybatis-plus工具減少重複程式碼,又或者寫出公共的操作層減少重複程式碼。
<br/>
當用工具完不成的時候,我就會用上模板了,比如直接我寫過一個簡單的開源專案:
好像很厲害的生成器!一秒鐘搞定一個專案:https://juejin.im/post/684490...
核心思路和要求如下:
- 基於資料庫獲取原始資料
- 基於模板 + 原始資料生成可執行的SpringBoot專案,支援介面 + 基本增刪改查
- 提供擴充式介面,可以實現不修改程式碼生成全新的檔案
<br/>
那利用這種思路,其實完全可以寫一套更開放的程式碼生成模板,比如根據傳遞的JSON
報文去解析資料,根據傳遞的模板
去生成資料,這樣的話又可以解決相當大一部分的重複工具,你,值得擁有。
PS:同理,其實資料庫欄位對映文件也可以用這種方式,只需要一秒鐘,簡直不要太舒服?♂️
<br/>
重複性的操作用指令碼程式碼
這個其實大家都有意識,但是有時候就是感覺可能用的不多,真要用起來的時候又沒功夫去寫指令碼,比如進入一個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
<br/>
從網上找了找,又找到一個開源專案用以記錄常用的指令碼
useful-scripts:https://github.com/oldratlee/...
能自動的就不要每次都手寫啦,節約時間去摸魚不快樂嗎?
<br/>
最後
這可是我這麼久以來總結的時間管理神器,節省的時間拿去摸魚學習,迴圈促進效率和能力,形成良性正反饋
這還不值得來個贊???嗎?嘿嘿~
另外可以搜尋公眾號「是Kerwin啊」,一起進步!也可以檢視Kerwin的GitHub主頁,關注一個小白程式設計師的進步,這貨最近在折騰Go~