本文源碼:GitHub·點這裡 || GitEE·點這裡
更新進度(共6節):
01:項目技術選型簡介,架構圖解說明
02:業務架構設計,系統分層管理
一、業務架構設計
1、基礎概念
服務的架構設計決定軟體的業務支撐能力,清晰的業務設計可以幫助開發人員了解系統。在業務架構設計過程中,需要根據使用者需求作為核心方向,根據使用者需求确定産品設計、架構搭建、服務劃分、資料庫規劃。如果需求比較單一,單個應用服務可以支撐,則不需要設計複雜的微服務系統,如果根據對業務的判斷,會在一段時間内出現業務并發,則最好開始的時候就考慮業務的擴充性,架構的支撐能力。
2、案例架構圖

基于該項目的架構設計,下面逐個描述一下業務設計。
二、業務流程
1、資料入庫服務
- 流程圖解
- 流程描述
1. 請求入庫服務接口;
2. 搜尋資料,通過搜尋服務Feign接口寫入ES伺服器;
3. 相同的搜尋資料,寫入使用者資料庫;
- 程式入口
所屬代碼包:mopsz-data-form
@RestController
@RequestMapping("/search/data")
public class SearchDataController {
// 調用搜尋服務Feign接口
@Resource
private BookInfoEsFeign bookInfoEsFeign ;
@Resource
private BookInfoService bookInfoService ;
@RequestMapping("/batchSave")
public String batchSave (){
// 省略業務代碼
}
}
2、使用者API服務
1. 使用者請求進入,網關服務攔截;
2. 調用Token管理服務,驗證使用者的身份令牌,使用Redis存儲Token;
3. 如果身份驗證通過,則網關放行使用者請求;
4. 執行使用者搜尋請求處理;
5、根據搜尋條件,調用ES搜尋服務,傳回結果;
6、将使用者的搜尋動作進行封裝,請求MQ服務;
7、MQ服務請消息轉發到資料分析服務 ;
8、資料分析服務安裝政策分析使用者請求,存儲分析結果;
(1)、網關攔截
所屬代碼包:mopsz-cloud-gateway
@Component
public class FilterConfig extends ZuulFilter {
public static final Logger LOGGER = LoggerFactory.getLogger(FilterConfig.class) ;
private static final String GET_TOKEN = "/token/getToken";
private static final String VERIFY_TOKEN = "/token/verifyToken";
private static final String REFRESH_TOKEN = "/token/refreshToken";
/**
* 攔截處理
*/
@Override
public Object run() throws ZuulException {
RequestContext requestContext = RequestContext.getCurrentContext() ;
try {
doTokenProcess (requestContext);
} catch (Exception e){
LOGGER.info("異常:{}",e.getMessage());
throw new ZuulException(e.getMessage(), 403, e.getMessage());
}
return null ;
}
public void doTokenProcess (RequestContext requestContext) throws Exception {
HttpServletRequest request = requestContext.getRequest() ;
String reqUri = request.getRequestURI() ;
if (!reqUri.contains(GET_TOKEN)) {
String token = request.getHeader("token") ;
boolean flag = userTokenFeign.refreshToken(token) ;
if (!flag){
throw new ServiceException("Token 校驗失敗") ;
}
LOGGER.info("Token 校驗通過");
}
}
}
(2)、Token管理
所屬代碼包:mopsz-basis-token
@RestController
@RequestMapping("/token")
public class UserTokenController implements UserTokenFeign {
@Resource
private UserTokenService tokenService ;
/**
* 擷取Token
*/
@Override
@RequestMapping("/getToken")
public RespObject getToken (@RequestParam("userName") String userName,
@RequestParam("passWord") String passWord){
try {
String token = tokenService.getToken(userName,passWord) ;
return RespObject.ok().put(Constant.MAP_KEY,token) ;
} catch (Exception e){
e.printStackTrace();
return RespObject.error() ;
}
}
/**
* 校驗Token
*/
@Override
@RequestMapping("/verifyToken")
public RespObject verifyToken(String token) {
try {
Integer userId = tokenService.verifyToken(token) ;
return RespObject.ok().put(Constant.MAP_KEY,userId) ;
} catch (Exception e){
e.printStackTrace();
return RespObject.error() ;
}
}
/**
* 重新整理Token
*/
@Override
@RequestMapping("/refreshToken")
public boolean refreshToken(String token) {
try {
return tokenService.refreshToken(token) ;
} catch (Exception e){
e.printStackTrace();
return false ;
}
}
}
(3)、搜尋接口
所屬代碼包:mopsz-user-client
@RestController
@RequestMapping("/search/book/")
public class BookSearchController {
@Resource
private BookInfoEsFeign bookInfoEsFeign ;
@Resource
private UserSearchFeign userSearchFeign ;
/**
* 關鍵字全文搜尋
*/
@RequestMapping("/getByKeyWord")
public List<EsBookInfo> getByKeyWord (@RequestParam("keyWord") String keyWord,
@RequestParam("userId") Integer userId){
// 搜尋引擎執行
List<EsBookInfo> esBookInfoList = bookInfoEsFeign.getByKeyWord(keyWord) ;
// 執行異步分析
if (StringUtils.isNotEmpty(keyWord) && esBookInfoList != null){
KeySearchModel keySearchModel = new KeySearchModel() ;
keySearchModel.setUserId(userId);
keySearchModel.setKeyWord(keyWord);
keySearchModel.setSearchResult(esBookInfoList);
userSearchFeign.sendBookSearch(JsonUtil.objToJson(keySearchModel));
}
return esBookInfoList ;
}
}
(4)、請求分析
所屬代碼包:mopsz-data-analy
@RestController
public class BookEsDataController implements BookEsAnalyFeign {
@Resource
private BookEsDataService bookEsDataService ;
@Override
public void sendBookEsMsg(String msgBody) {
bookEsDataService.saveBookEsData(msgBody);
}
}
3、系統管理服務
整合流程基礎SpringSecurity,JWT等元件開發。所屬代碼包:mopsz-admin-client。
1. 系統使用者登入,安全配置:SecurityConfig ;
2. 登入成功處理:LoginSuccessHandler ;
3. 登入失敗處理:LoginFailHandler ;
4. 系統服務具備管理:業務資料庫,緩存資料,ES服務等功能 ;
4、資料分析服務
1. 接收MQ服務轉發資料分析請求 ;
2. 按照指定政策,分析資料,分析結果存儲 ;
三、系統分層管理
1、分層示意圖
2、結構層次描述
- 公共代碼塊層
管理系統工具類、資料表結構實體類、Mapper層、Service服務層等,按照資料庫服務規劃劃分,作為整個系統的公共依賴代碼塊。
- 資料管理層
管理資料入庫服務API,資料分析服務API兩個子產品。
- 用戶端接口層
管理使用者服務API,背景系統服務API。
- 微服務接口層
微服務之間的調用采用Feign接口的方式,按照不同服務提供的Feign接口進行封裝,在該層統一管理,進行服務間的請求調用。
- 通用業務服務層
管理通用Token服務,消息發送服務,作為系統共用的業務服務層。
- 中間件服務層
管理RocketMQ消息隊列服務、Redis緩存服務、Quart定時器服務、ES搜尋服務,提供統一的Feign服務接口。
- 微服務元件層
管理整個系統的網關攔截服務、Eureka服務注冊和發現 等微服務基礎元件。
四、源代碼位址
GitHub·位址
https://github.com/cicadasmile/husky-spring-cloud
GitEE·位址
https://gitee.com/cicadasmile/husky-spring-cloud