工程實踐項目是實現一個相似知乎的問答社區系統(後端)html
基本要求:前端
進階要求:git
軟件架構風格是描述某一特定應用領域中系統組織方式的慣用模式,經常使用的軟件架構風格有以下幾類:github
管道-過濾器golang
客戶-服務器redis
P2P算法
發佈-訂閱數據庫
CRUDjson
層次化後端
本項目是一個典型的 C/S (客戶-服務器)架構模式,服務器負責全部數據的存儲與組織,客戶端經過 HTTP 訪問服務器,請求相應的數據並向用戶展現出來,同時接收用戶輸入,與用戶作交互。
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排序方式 | 回答列表 |
軟件架構模型是經過一組關鍵視圖來描述的,同一個軟件架構,因爲選取的視角(Perspective)和抽象層次不一樣能夠獲得不一樣的視圖,這樣一組關鍵視圖搭配起來能夠完整地描述一個邏輯自洽的軟件架構模型。通常來講,咱們經常使用的幾種視圖有分解視圖、依賴視圖、泛化視圖、執行視圖、實現視圖、部署視圖和工做任務分配視圖。
對系統的經常使用分解方法有面向功能分解,面向數據分解,面向特徵分解,面向併發分解等,根據本項目的特色,比較適合面向功能的分解方法,分解視圖以下:
依賴視圖展示了軟件模塊之間的依賴關係。本項目最前端使用 Nginx 部署應用,數據來源於後端的 MySQL 和 Redis 數據庫,同時在應用層內各模塊間也存在依賴關係,據此能夠畫出項目的依賴視圖:
執行視圖展現了系統運行時的時序結構特色,好比流程圖、時序圖等。執行實體能夠最終分解到軟件的基本元素和軟件的基本結構,於是與軟件代碼具備比較直接的映射關係。
本項目是一個後端項目,根據客戶端的不一樣請求執行不一樣的操做,從總體上來講,每一次操做均可以用以下時序圖歸納:
源代碼的目錄文件結構及其與軟件架構的映射關係說明以下:
├── api API控制層,負責處理請求 │ ├── v1 具體API版本,增量發佈 ├── cache redis 緩存相關 ├── conf 項目的靜態配置 ├── middleware 中間件 ├── model 數據庫模型以及相關操做 ├── routes 路由配置 ├── serializer 將實體映射成不一樣的viewmodel,以及經常使用的響應信息 ├── service 服務層,將比較複雜的業務從api層分離出來 ├── utils 經常使用工具 | main.go 應用入口
項目前期採用單點部署,各組件運行於一臺服務器上,視圖以下:
後期可升級爲分佈式結構來提升可靠性和提供更大的吞吐量:
工做分配視圖將系統分解成可獨立完成的工做任務,以便分配給各項目團隊和成員,本項目是一個面向 API 服務的程序,最終目標是實現一系列功能完備的接口,因此最好的分解方法就是按照接口分解,每一個成員負責幾個接口實現:
本項目採用 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;"` // 內容 }
項目使用 Docker 打包部署,能夠運行於任何 Linux 服務器上。
項目使用 Golang 開發,用到的組件主要有:
項目概念原型的核心工做機制描述以下: