工程實踐中的軟件系統設計方案—問答系統後端

1. 項目背景介紹

工程實踐項目是實現一個相似知乎的問答社區系統(後端)html

  • 基本要求:前端

    • 支持問題、回答的發佈和修改(文字)
    • 問題拉鍊,支持按熱度和時間序排序
    • 回答點贊點踩
    • 熱門問題列表
  • 進階要求:git

    • 高併發
    • 支持評論
    • 問題、回答支持圖片
    • 支持第三方登陸
    • 支持第三方分享

2. 軟件設計方案

2.1 系統架構

軟件架構風格是描述某一特定應用領域中系統組織方式的慣用模式,經常使用的軟件架構風格有以下幾類:github

  • 管道-過濾器golang

  • 客戶-服務器redis

  • P2P算法

  • 發佈-訂閱數據庫

  • CRUDjson

  • 層次化後端

本項目是一個典型的 C/S (客戶-服務器)架構模式,服務器負責全部數據的存儲與組織,客戶端經過 HTTP 訪問服務器,請求相應的數據並向用戶展現出來,同時接收用戶輸入,與用戶作交互。

2.2 接口API

API 定義了客戶端與服務端數據交互的基本格式,包括客戶端以什麼樣的格式請求,請求參數,服務端以什麼樣的格式響應,正確響應與錯誤響應的不一樣內容等。

本項目採用 RestfulAPI 風格的接口設計,具體篇幅太大,就不展開敘述了,僅列舉一下部分 API 的簡要說明:

接口名稱 接口地址 請求方式 請求參數 響應信息 備註
用戶註冊 /user/register POST 用戶名,密碼,密碼確認 用戶基本信息
用戶登陸 /user/login POST 用戶名,密碼 用戶token,基本信息 用戶token保存用戶的登陸狀態,保存到本地,請求其它接口的時候帶上。
我的信息 /user/me POST 用戶token 用戶完整信息
發佈問題 /questions POST 用戶token,問題標題,可選的問題詳細描述 問題基本信息 已登陸用戶纔可發佈問題,未攜帶token會拒絕服務
查看問題 /questions/{qid} GET 可選的用戶token 問題詳細信息
修改問題 /questions/{qid} PUT 用戶token,問題標題,可選的問題詳細描述 問題基本信息 問題所屬用戶纔可修改問題
刪除問題 /questions/{qid} DELETE 用戶token ok 問題所屬用戶纔可刪除問題
首頁推薦列表 /questions GET limit請求數量,offset位置偏移 問題列表,每一個問題包含一個一段時間內的熱門回答信息
問題熱榜列表 /hot_questions GET limit請求數量,offset位置偏移 問題列表
回答問題 /questions/{qid}/answers POST 用戶token,回答內容 回答基本信息 已登陸用戶纔可回答問題,未攜帶token會拒絕服務
查看回答 /questions/{qid}/answers/{aid} GET 可選的用戶token 回答詳細信息
修改回答 /questions/{qid}/answers/{aid} PUT 用戶token,回答內容 回答基本信息 問題所屬用戶纔可修改回答
刪除回答 /questions/{qid}/answers/{aid} DELETE 用戶token ok 問題所屬用戶纔可刪除回答
回答列表 /questions/{qid}/answers GET limit請求數量,offset位置偏移,type排序方式 回答列表
  • 注:請求格式支持 form 和 json,響應格式統一爲 json,錯誤響應均包含錯誤碼和描述信息,以上僅說明正確響應

3. 軟件架構的不一樣視圖

軟件架構模型是經過一組關鍵視圖來描述的,同一個軟件架構,因爲選取的視角(Perspective)和抽象層次不一樣能夠獲得不一樣的視圖,這樣一組關鍵視圖搭配起來能夠完整地描述一個邏輯自洽的軟件架構模型。通常來講,咱們經常使用的幾種視圖有分解視圖、依賴視圖、泛化視圖、執行視圖、實現視圖、部署視圖和工做任務分配視圖。

  • 分解視圖

對系統的經常使用分解方法有面向功能分解,面向數據分解,面向特徵分解,面向併發分解等,根據本項目的特色,比較適合面向功能的分解方法,分解視圖以下:

  • 依賴視圖

依賴視圖展示了軟件模塊之間的依賴關係。本項目最前端使用 Nginx 部署應用,數據來源於後端的 MySQL 和 Redis 數據庫,同時在應用層內各模塊間也存在依賴關係,據此能夠畫出項目的依賴視圖:

  • 執行視圖

執行視圖展現了系統運行時的時序結構特色,好比流程圖、時序圖等。執行實體能夠最終分解到軟件的基本元素和軟件的基本結構,於是與軟件代碼具備比較直接的映射關係。

本項目是一個後端項目,根據客戶端的不一樣請求執行不一樣的操做,從總體上來講,每一次操做均可以用以下時序圖歸納:

  • 實現視圖

源代碼的目錄文件結構及其與軟件架構的映射關係說明以下:

├── api              API控制層,負責處理請求
│   ├── v1           具體API版本,增量發佈
├── cache            redis 緩存相關 
├── conf             項目的靜態配置
├── middleware       中間件
├── model            數據庫模型以及相關操做
├── routes           路由配置
├── serializer       將實體映射成不一樣的viewmodel,以及經常使用的響應信息
├── service          服務層,將比較複雜的業務從api層分離出來
├── utils            經常使用工具
| main.go            應用入口
  • 部署視圖

項目前期採用單點部署,各組件運行於一臺服務器上,視圖以下:

後期可升級爲分佈式結構來提升可靠性和提供更大的吞吐量:

  • 分配視圖

工做分配視圖將系統分解成可獨立完成的工做任務,以便分配給各項目團隊和成員,本項目是一個面向 API 服務的程序,最終目標是實現一系列功能完備的接口,因此最好的分解方法就是按照接口分解,每一個成員負責幾個接口實現:

4. 核心數據結構設計

本項目採用 ORM(對象關係映射)來將項目的數據結構映射到數據庫裏,由框架負責管理數據庫具體操做,核心數據結構以下:

  • 用戶模型
type User struct {
	gorm.Model
	Username    string      `gorm:"unique;not null;"`                              // 用戶名
	Password    string      `gorm:"not null;"`                                     // 密碼
	UserProfile UserProfile `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` // 關聯用戶信息
	Questions   []Question  `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` // 關聯問題信息
	Answers     []Answer    `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` // 關聯回答信息
}

type UserProfile struct {
	gorm.Model
	UserID      uint
	Nickname    string `gorm:"default:null"`         // 暱稱
	Email       string `gorm:"unique;default:null;"` // 郵箱
	Avatar      string `gorm:"default:null;"`        // 頭像
	Status      int    `gorm:"not null;default:0;"`  // 狀態
	Description string `gorm:"default:null"`         // 我的描述
}
  • 問題模型
type Question struct {
	gorm.Model
	UserID  uint     `gorm:"not null;"`                                     // 問題所屬用戶Id
	Title   string   `gorm:"not null;"`                                     // 標題
	Content string   `gorm:"type:text"`                                     // 內容
	Answers []Answer `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` // 關聯回答信息
}
  • 回答模型
type Answer struct {
	gorm.Model
	UserID     uint   `gorm:"not null;"`           // 回答所屬用戶Id
	QuestionID uint   `gorm:"not null;"`           // 回答所屬問題Id
	Content    string `gorm:"type:text;not null;"` // 內容
}

5. 運行環境和技術選型

5.1 運行環境

項目使用 Docker 打包部署,能夠運行於任何 Linux 服務器上。

5.2 技術選型

項目使用 Golang 開發,用到的組件主要有:

  • Gin: 輕量級Web框架
  • GORM: ORM工具,本項目須要配合MySQL使用
  • Go-Redis: Golang Redis客戶端,用於緩存相關功能
  • godotenv: 開發環境下的環境變量工具,方便配置環境變量
  • Jwt-Go: Golang JWT組件,本項目使用基於 jwt 實現的 token 來作身份驗證
  • crypto: Golang 加密算法庫,本項目使用其中的 bcrypto 算法來加密用戶密碼

6. 項目概念原型的核心工做機制

項目概念原型的核心工做機制描述以下:

  • 用戶能夠以遊客身份進入系統,也能夠登陸進入,但遊客身份只有問答系統的查看權限
  • 從首頁能夠瀏覽推薦問題列表,或者從熱榜查看熱門問題,此外,也能夠經過分類或者搜索查找本身感興趣的問題
  • 點擊進入問題詳情後,能夠以必定的排序方式查看該問題的回答列表,能夠對回答進行點贊點踩,評論等,固然也能夠本身回答問題
  • 首頁提供了發佈問題的按鈕能夠發出提問尋求解答
  • 用戶能夠在在我的中心對我的信息和活動歷史進行管理,好比更新本身的聯繫方式,查找本身曾經回答過的問題等等
相關文章
相關標籤/搜索