目標:減小重複代碼,提升開發效率,項目地址:github.com/neatlife/jf…java
歡迎star,歡迎pr(求star, 求star, 求star)git
可封裝功能列表github
E文 | 功能 | 目前做用 |
---|---|---|
controller | 控制器父類 | 簡化控制器裏的常見操做 |
exception | 異常 | 統一全局業務異常操做 |
handler | 異常攔截 | 全局異常攔截到日誌裏 |
http | 請求響應實體 | 統一全局響應實體 |
hystrix | hystrix事件攔截 | 熔斷時發送報警郵件 |
jpa | jpa非業務重複代碼封裝 | 自動給deleted_at, updated_at, created_at賦值 |
json | 響應json數據的二次處理 | 自動格式化金額小數位數 |
listener | spring boot框架事件 | 在框架啓動時給util注入service實例 |
logback | 自定義logback日誌輸出 | 將日誌輸出到elk的redis,方便elk統一進行日誌處理 |
model | 基礎jpa實體 | 包含deleted_at, updated_at, created_at字段的實體 |
redis | 自定義redis序列化和反序列化操做 | 使用GenericJackson2JsonRedisSerializer序列化redis值,提升可讀性 |
request | 自定請求數據的解析 | 處理json請求 |
springfox | 自定義springfox文檔解析 | ApiClass支持文檔描述引用 |
util | 經常使用工具收集 | 好比json, http請求等經常使用工具類 |
validator | 請求參數自定義校驗 | 檢查參數長度 |
apiversion | 支持不一樣的api的版本到不一樣的控制器邏輯 | 參考 MainController |
目前已經實現上面列表中的全部功能並開源redis
json & http客戶端常常使用,自行編寫容易踩坑,因此直接拿dew框架的工具類進行了集成spring
github.com/gudaoxuri/d…docker
須要同時發出多個http請求時可使用parallelStream()技術,可顯著減小請求總時長shell
List<String> paramList = ...
paramList.parallelStream().forEach(param -> {
http post with param
})
複製代碼
經測試, 26個請求,使用parallelStream將請求總時間從23.803減小到1.731秒json
由於java裏對象複製很是頻繁,因此封裝了MapperUtil, 雖然複製對象只需下面兩行代碼api
Class1 class1 = new Class1();
BeanUtils.copyProperties(source, class1);
複製代碼
可是因爲很是頻繁的相似代碼,一個項目項目可能出現上千次這種複製,因此將上面兩行代碼合併成了一行bash
Class1 class1 = MapperUtil.to(source, class1);
複製代碼
核心實現代碼以下:
public static <SOURCE, TARGET> TARGET to(SOURCE source, Class<TARGET> targetClass) {
TARGET target = BeanUtils.instantiateClass(targetClass);
BeanUtils.copyProperties(source, target);
return target;
}
複製代碼
雖然使用了反射技術,但通過測試無性能問題
使用redis進行了日誌中轉,因此logstash須要從redis讀取日誌輸出到elasticsearch
logstash從redis讀取日誌輸出到elasticsearch的配置
input {
redis {
data_type => "list"
key => "logstash"
host => "127.0.0.1"
port => 6379
threads => 5
codec => "json"
}
}
filter {
}
output {
elasticsearch {
hosts => ["elasticsearch:9200"]
index => "logstash-%{type}-%{+YYYY.MM.dd}"
document_type => "%{type}"
workers => 1
template_overwrite => true
}
stdout{}
}
複製代碼
由於elasticsearch裏日誌會愈來愈大,因此須要定時清理,定時清理elasticsearch數據
參考:www.jianshu.com/p/458421dac…
核心代碼以下
#!/bin/bash
# filename:deleteEsData.sh
# 天天2點定時刪除es中指定日期的數據
# crontab: 0 2 * * * sh /home/scripts/deleteEsData.sh >> /home/scripts/logs/deleteEsData.run.log 2>&1
# 現在天是2017-09-21 50天前是2017.08.02
# createdate: 20190921
today=`date +%Y-%m-%d`;
echo "今天是${today}"
# 不指定參數時,默認刪除daynum天前以logs-開頭的數據
daynum=51
# 當參數個數大於1時,提示參數錯誤
if [ $# -gt 1 ] ;then
echo "要麼不傳參數,要麼只傳1個參數!"
exit 101;
fi
# 當參數個數爲1時,獲取指定的參數
if [ $# == 1 ] ;then
daynum=$1
fi
esday=`date -d '-'"${daynum}"' day' +%Y.%m.%d`;
echo "${daynum}天前是${esday}"
curl -XDELETE http://127.0.0.1:9200/logs-${esday}
echo "${esday} 的log刪除執行完成"
複製代碼
定義全局業務異常,方便進行全局業務異常的捕獲和統一處理 ControllerExceptionHandler
核心處理邏輯以下:
@ExceptionHandler({BusinessRuntimeException.class})
@ResponseBody
public Response handlerBusinessException(BusinessRuntimeException ex) {
return new Response<Map>(HttpCode.SUCCESS.toString(), ex.getMessage(), Maps.newHashMap());
}
複製代碼
這樣的好處是方便對錯誤的返回數據進行格式化
RedisUtil工具類須要RedisTemplate操做實例對象,若是在RedisUtil使用Autowired自動注入RedisTemplate,則須要RedisUtil也是Service,這將RedisUtil的調用變得複雜化了(使用前必須先注入RedisUtil以獲取RedisTemplate對象) 利用框架事件,可在框架啓動時,獲取RedisTemplate對象,手動注入RedisUtil裏
核心實現代碼以下:
@Component
public class ApplicationStartedEventListener implements ApplicationListener<ApplicationStartedEvent> {
private final RedisTemplate redisTemplate;
private final JFrameworkConfig jFrameworkConfig;
@Autowired
public ApplicationStartedEventListener(RedisTemplate redisTemplate, JFrameworkConfig jFrameworkConfig) {
this.redisTemplate = redisTemplate;
this.jFrameworkConfig = jFrameworkConfig;
}
@Override
public void onApplicationEvent(ApplicationStartedEvent event) {
RedisUtil.setRedisTemplate(redisTemplate);
LockUtil.setRedisTemplate(redisTemplate);
DingTalkUtil.setDdUrl(jFrameworkConfig.getNotification().getDingTalkUrl());
}
}
複製代碼
自行搭建鏡像倉庫不如使用免費穩定的來得高效可靠
能夠直接使用了aliyun提供的免費docker鏡像倉庫
採用了jpa的事件機制,在建立,修改,刪除事件發生時自動進行維護
核心代碼以下:
@PrePersist
public void touchCreated(BaseEntity target) {
target.setCreatedAt(DateUtil.currentSecond());
target.setUpdatedAt(DateUtil.currentSecond());
}
@PreUpdate
public void touchUpdate(BaseEntity target) {
target.setUpdatedAt(DateUtil.currentSecond());
}
@PreRemove
public void touchDeleted(BaseEntity target) {
target.setDeletedAt(DateUtil.currentSecond());
}
複製代碼
目前ci/cd工具選擇很是多,但在生產裏用得最多的應該是gitlab和jenkins
目前仍然採用jenkins做爲ci/cd工具,gitlab的ci目前我的認爲仍然不夠成熟
能夠直接試用sonarkube的開放服務,無需自行搭建:
通常框架會做爲項目的基礎依賴,那麼可以很是方便的下載這個框架就很是重要了
目前nexus私服仍然是首選,可使用docker搭建nexus私服:
version: "3"
services:
nexus:
image: sonatype/nexus3
environment:
- INSTALL4J_ADD_VM_PARAMS=-Xms512m -Xmx768m -XX:MaxDirectMemorySize=1g -Djava.util.prefs.userRoot=/nexus-data/javaprefs
volumes:
- ./nexus-data:/nexus-data
ports:
- "8081:8081"
複製代碼
因爲是微服務形式的部署,因此日誌,配置都須要中心化,k8s也是標配
日誌選經典的elk
配置中心選擇apollo
部署平臺能夠選擇k8s,或者k8s上的istio,目前使用k8s
微服務的k8s模版參考 應用: raw.githubusercontent.com/neatlife/jf… 網關: raw.githubusercontent.com/neatlife/jf…
核心區別是kind字段,網關是 DaemonSet 應用是 Deployment
完成框架的封裝必然少不了不少參考,即便這是個小框架
如下是參考列表
目前文章還在持續更新中,若是對框架開發感興趣,可加做者微信探討,也可提pr,issue等