當前位置:
首頁 >
在线教育后端开发项目总结
發布時間:2023/12/4
54
豆豆
生活随笔
收集整理的這篇文章主要介紹了
在线教育后端开发项目总结
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 一 數據庫訪問接口
- 1 MyBatis
- 2 Spring Data JPA
- 3 Spring Data MongoDB
- 二 數據庫
- 1 MySQL
- 2 MongoDB
- 3 Redis
- 三 開發規范化、響應格式與異常處理
- 1 開發規范
- 2 響應格式
- 3 異常處理
- 四 RabbitMQ
- 五 Spring Cloud 相關工具
- 1 Eureka
- 2 Ribbon
- 3 Feign
- 4 Zuul 網關
- 六 搜索服務
- 1 ElasticSearch
- 2 Logstash
- 七 用戶認證與授權
- 1 Spring Security OAuth2
- 2 JWT(Json Web Token)
- 3 單點登錄和身份校驗
- 4 用戶授權 RBAC(Role-Based Access Control)
一 數據庫訪問接口
1 MyBatis
- 用于寫相對復雜(多表連接的) SQL 命令
- 使用時,用 @Mapper 注釋 xxMapper 接口,在接口中定義方法,并創建同名的 xxMapper.xml 文件,在方法對應的標簽存放 SQL 命令
- 更多關于 MyBatis
2 Spring Data JPA
- Spring 提供的操作 MySQL 單張數據表的 API,無需自行編寫 SQL
- 接口一般命名為 xxRepository
- 需要對數據表對應的類加一系列注解(不止如下所示)
3 Spring Data MongoDB
- 使用方法類似于 Spring Data JPA,需要通過對類的注釋,實現模型-表的映射
二 數據庫
1 MySQL
- InnoDB 存儲引擎:
索引結構是B+樹(和B樹相比查詢效率更穩定,I/O次數少,對范圍查找的支持更好)
實現了行級鎖
支持外鍵 - 一些優化措施:
查詢操作時,只返回需要的行或列
盡量不在數據表中存儲 NULL,不在 SQL 命令的條件中判斷 NULL
字段的數據類型定義準確
設計數據表時遵循范式規則 1/2/3NF
對數據表進行適當的行、列拆分 - 索引分類:
主索引/二級索引
聚簇索引/非聚簇索引… - 如果沒有主鍵也沒有合適的唯一索引,那么 InnoDB 內部會生成一個隱藏的主鍵作為聚集索引,這個隱藏的主鍵是一個6個字節的列,該列的值會隨著數據的插入自增
2 MongoDB
- NoSQL 的一種,以類 Json 的文檔格式存儲數據,文檔型數據庫
- 本項目中負責存放一系列的頁面信息
- 索引結構是B樹
- 不具有 MySQL 的完善的事務特性,在本項目中用于存儲非核心數據
3 Redis
- NoSQL 的一種,一般作為緩存數據庫輔助持久化的數據庫
- 本項目中負責存放登錄用戶的 (access_token, JWT + refresh_token) 的鍵值對
- 擁有兩種持久化機制:RDB 和 AOF,其特性查閱鏈接
- 項目中使用 StringRedisTemplate 操作 Redis
- 更多關于 Redis
三 開發規范化、響應格式與異常處理
1 開發規范
- get 請求時,采用 key/value 格式請求,SpringMVC 可采用基本類型的變量接收,也可以采用對象接收
- post 請求時,可以提交 form 表單數據(application/x-www-form-urlencoded)和 Json 數據(application/json),文件等多部件類型(multipart/formdata)三種數據格式,SpringMVC 接收 Json 數據
- Controller 主要作為響應 URL 的接口(粘合劑的作用),業務邏輯實現放在 Service 層,DAO 僅僅負責與數據庫交互而不考慮任何業務邏輯
2 響應格式
- 設置枚舉類型的響應代碼
- 針對不同的客戶端請求,返回對應的一致的類型:查詢返回 QueryResponseResult,添加返回 ResponseResult …
3 異常處理
- 設置枚舉類型的異常代碼,寫入異常編號和異常信息
- 使用統一的類拋出(使用靜態方法包裝)和捕獲異常(使用 SpringMVC 提供的 @ControllerAdvice 注解類 和 @ExceptrionHandler 注解方法)
- 自定義異常類型繼承自 RuntimeException,屬于 unchecked 異常,不捕獲仍然可以運行,實際交給增強控制器完成捕獲
四 RabbitMQ
- 項目中簡單用到了 routing 模式,生產者發送消息時需要指定 routing key,交換機會根據 routing key 將消息投遞到指定的隊列
- 使用消息隊列的主要優點:解耦、異步、削峰(因為 MQ 短時間積壓數據是可以接受的)
- RabbitMQ 結構:
五 Spring Cloud 相關工具
1 Eureka
- 注冊中心 :
微服務數量眾多,要進行遠程調用就需要知道服務端的 IP 地址和端口,注冊中心幫助管理這些服務的 IP 和端口
注冊的微服務會向注冊中心實時上報自己的狀態,注冊中心統一管理這些微服務的狀態
將存在問題的服務踢出服務列表,客戶端獲取可用的服務進行調用 - 注冊中心同樣屬于一個微服務,它的啟動類要加上注解 @EnableEurekaServer
- 對于要向注冊中心注冊的微服務,需要在啟動類加注解 @EnableDiscoveryClient,表示它是一個 Eureka 的客戶端,用于發現其它微服務
- 高可用 Eureka 需要兩個注冊中心相互注冊,即使其中一臺停機也不會影響服務的注冊和發現
- 啟動后訪問指定端口就可以便捷地檢測微服務情況,本項目為 50101 和 50102
2 Ribbon
- 執行客戶端的負載均衡(而非 Nginx 這種服務端的負載均衡),Ribbon 先從 EurekaServer 中獲取服務列表,根據負載均衡的算法去調用微服務
- Spring Cloud 引入 Ribbon 配合 RestTemplate (本項目使用 okhttp 進行遠程調用)實現客戶端負載均衡
- RestTemplate 是 Spring 提供的一個訪問 HTTP 服務的客戶端類,微服務之間的調用需要使用 RestTemplate
- 使用方法:
1、添加相關依賴并配置
2、創建 resttemplate 的 bean,使用 @LoadBalanced 注解
3、服務名代替 IP 地址+端口號,發揮注冊中心的作用(不用手動寫入 IP 地址+端口號 而交給注冊中心管理),后面拼接相應 Controller 方法路徑
3 Feign
- 可以實現 像調用本地接口一樣調用遠程接口 ,這個遠程接口指的是在注冊中心注冊過的某個微服務提供的 Controller 方法
- 內部集成了 Ribbon,可以實現客戶端負載均衡
- 使用方法:
使用@EnableFeignClients 注解啟動類,Spring 會掃描標記了 @FeignClient 注解的接口,生成代理對象
使用 @FeignClient 注解客戶端接口,并指定該接口綁定的微服務名(指定后 Feign 會從注冊中心獲取服務列表,并通過負載均衡算法進行服務調用)
如果接口的方法返回類型為對象,則該類型必須有無參構造器
Feign 根據接口方法的注解的 URL,進行遠程調用
4 Zuul 網關
- 網關在微服務前邊設置一道屏障,請求先到服務網關,網關會對請求進行過濾、校驗、路由等處理。有了服務網關可以提高微服務的安全性,網關校驗請求的合法性,請求不合法將被攔截,拒絕訪問
- 用網關的好處是,無論調用哪個微服務,客戶端所有的請求都訪問網關的 IP 地址和端口號,由網關使用 Eureka 負責將請求路由到指定的微服務(因為 Zuul 的配置了 Eureka 中各種微服務的 ID)
六 搜索服務
1 ElasticSearch
- 在項目中實現課程搜索的功能,應用流程:
1、用戶在前端搜索關鍵字,前端通過 HTTP 方式請求項目服務端
2、項目服務端通過 RESTful 方式請求 ES 集群進行搜索(需要手動構建 HTTP Request)
3、ES 集群從索引庫檢索數據并返回 - 另外用到了 ES 的可視化插件 Head 和 IK 分詞器(中文分詞)
- 6.0之前的版本有 type(類型)概念,type 相當于關系數據庫的表,但 ES 官方建議索引庫只存放相同類型的文檔,即用關系數據庫的表概念類比ES的索引庫。項目中將 type 指定為 doc,只是無意義的占位符
- 可以使用 Postman 發送各種類型的 HTTP Request 操作 ES
- 項目中需要在配置類生成 RestClient 的 Bean,用來操作 ES
2 Logstash
- Logstash 的功能是,將 MySQL 的數據表同步到索引庫
- 配置并啟動 Logstash,如果 document 的時間戳大于上次采集的時間,就更新索引庫
- 項目中為了便于搜索服務的開發,將課程的一系列信息匯總為一張數據表,將該表同步到索引庫,并使用 JPA 操作數據表
- 因為課程服務是從 ES 的索引庫而非數據庫搜索,所以 Service 層沒有自動注入 DAO
七 用戶認證與授權
1 Spring Security OAuth2
- 常用的有:授權碼模式(主要用于第三方登錄)和密碼模式。項目采用密碼模式
- 授權碼模式流程:
- 密碼模式:密碼模式與授權碼模式的區別是申請令牌不再使用授權碼,而是直接通過正確的用戶名和密碼即可申請令牌
2 JWT(Json Web Token)
- JWT = Header + Payload + Signature
Header:描述 JWT 的元數據,包括令牌的類型(即 JWT)及使用的哈希算法,內容用 Base64Url 編碼
Payload:負載是存放有效信息的地方,它可以存放 JWT 提供的字段,比如 iss(簽發者)、exp(過期時間戳)、sub(面向的用戶)等,也可自定義字段
Signature:簽名部分,防止 JWT 被篡改 指定的哈希算法( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret) - 考慮到 Cookie 的容量比較小,在 Cookie 中存放 access_token,HTTP Header 中存放 JWT,Redis 中存放 (access_token, JWT + refresh_token) 的鍵值對以供查詢
- 使用 JWT 的一個顯著優點是,資源服務器可以自行認證 JWT,而不用傳遞給認證服務器
3 單點登錄和身份校驗
- 單點登錄:微服務之間相互調用,需要驗證 JWT 的合法性,使用 Feign Interceptor
- 網關在將請求轉發到指定微服務前,負責檢驗 JWT 的合法性:
1、從 Cookie 查詢 access_token 令牌是否存在,不存在則拒絕訪問
2、從 HTTP Header 查詢 JWT 令牌是否存在,不存在則拒絕訪問
3、從 Redis 中查詢 JWT 令牌是否過期,過期則拒絕訪問 - 具體實現:在網關微服務添加 @Component:
4 用戶授權 RBAC(Role-Based Access Control)
- 權限就是對資源的控制,對 web 應用來說就是對 url 的控制
- 核心為五張數據表:用戶表、用戶角色表、角色表、角色權限表、權限表,使用時的查詢流程:
根據用戶ID查詢用戶角色表,獲取角色ID
根據角色ID查詢角色權限表,獲取權限ID
根據權限ID查詢權限表,獲取權限
- 獲取到的權限被寫入 JWT 中,在訪問微服務前需要校驗用戶權限是否夠
- 在 config 類上注解 @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true),然后在 Controller 方法注解@PreAuthorize("hasAuthority('course_find_list')"),指定該方法只能被 JWT 中含有 course_find_list 權限的用戶調用
總結
以上是生活随笔為你收集整理的在线教育后端开发项目总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 后端学习 - Redis
- 下一篇: 算法 - 排序算法