微服務架構案例(02):業務架構設計,系統分層管理

本文源碼:GitHub·點這裏 || GitEE·點這裏git

更新進度(共6節):github

01:項目技術選型簡介,架構圖解說明spring

02:業務架構設計,系統分層管理數據庫

1、業務架構設計

一、基礎概念

服務的架構設計決定軟件的業務支撐能力,清晰的業務設計能夠幫助開發人員理解系統。在業務架構設計過程當中,須要根據用戶需求做爲核心方向,根據用戶需求肯定產品設計、框架搭建、服務劃分、數據庫規劃。若是需求比較單一,單個應用服務能夠支撐,則不須要設計複雜的微服務系統,若是根據對業務的判斷,會在一段時間內出現業務併發,則最好開始的時候就考慮業務的擴展性,架構的支撐能力。

二、案例架構圖

02-1.jpg

基於該項目的架構設計,下面逐個描述一下業務設計。segmentfault

2、業務流程

一、數據入庫服務

  • 流程圖解

02-2.png

  • 流程描述
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 (){
        // 省略業務代碼
    }
}

二、用戶API服務

  • 流程圖解

02-3.png

  • 流程描述
1. 用戶請求進入,網關服務攔截;
2. 調用Token管理服務,驗證用戶的身份令牌,使用Redis存儲Token;
3. 若是身份驗證經過,則網關放行用戶請求;
4. 執行用戶搜索請求處理;
五、根據搜索條件,調用ES搜索服務,返回結果;
六、將用戶的搜索動做進行封裝,請求MQ服務;
七、MQ服務請消息轉發到數據分析服務 ;
八、數據分析服務安裝策略分析用戶請求,存儲分析結果;
  • 程序入口

(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);
    }
}

三、系統管理服務

  • 流程圖解

02-4.png

  • 流程描述

整合流程基礎SpringSecurity,JWT等組件開發。所屬代碼包:mopsz-admin-client。

1. 系統用戶登陸,安全配置:SecurityConfig ;
2. 登陸成功處理:LoginSuccessHandler ;
3. 登陸失敗處理:LoginFailHandler ;
4. 系統服務具有管理:業務數據庫,緩存數據,ES服務等功能 ;

四、數據分析服務

  • 流程圖解

02-5.png

  • 流程描述

所屬代碼包:mopsz-data-analy

1. 接收MQ服務轉發數據分析請求 ;
2. 按照指定策略,分析數據,分析結果存儲 ;

3、系統分層管理

一、分層示意圖

02-6.jpg

二、結構層次描述

  • 公共代碼塊層

管理系統工具類、數據表結構實體類、Mapper層、Service服務層等,按照數據庫服務規劃劃分,做爲整個系統的公共依賴代碼塊。

  • 數據管理層

管理數據入庫服務API,數據分析服務API兩個模塊。

  • 客戶端接口層

管理用戶服務API,後臺系統服務API。

  • 微服務接口層

微服務之間的調用採用Feign接口的方式,按照不一樣服務提供的Feign接口進行封裝,在該層統一管理,進行服務間的請求調用。

  • 通用業務服務層

管理通用Token服務,消息發送服務,做爲系統共用的業務服務層。

  • 中間件服務層

管理RocketMQ消息隊列服務、Redis緩存服務、Quart定時器服務、ES搜索服務,提供統一的Feign服務接口。

  • 微服務組件層

管理整個系統的網關攔截服務、Eureka服務註冊和發現 等微服務基礎組件。

4、源代碼地址

GitHub·地址
https://github.com/cicadasmile/husky-spring-cloud
GitEE·地址
https://gitee.com/cicadasmile/husky-spring-cloud

相關文章
相關標籤/搜索