前言
軟件的開發流程包含需求分析、對需求的建模以及后續的總體、詳細設計、實現和測試過程。本文針對工程實踐項目的需求進行了建模分析,包含用例建模、業務領域建模以及數據建模等,最終給出項目的概念原型。
項目概述
本課題主要是在Linux系統下完成一個以c++為基礎的web服務器設計與開發。能夠為相當數量的客戶端提供服務,同時能夠完成相應的日志輸出以及連接管理等功能。通過連接服務器上的數據庫,服務器能夠支持客戶端的並發訪問並及時響應。用戶能通過頁面進行注冊、登錄和資料預覽、下載等功能。項目基於Linux系統的網絡編程接口和系統調用,使用線程池 + 非阻塞socket + epoll(ET和LT) + 事件處理(Reactor和模擬Proactor)的並發模型進行實現,使用狀態機解析HTTP請求報文。
需求分析
一個web服務器主要需要完成的功能就是解析用戶請求,對用戶的請求完成響應,用戶的請求包含注冊、登錄和資源請求等。同時服務器需要支持一定程度的並發量,以保證對用戶的請求能夠及時返回結果。
- 主要功能需求
主要包含以下幾個方面:
- 服務器完成用戶登錄、注冊的功能
- 服務器完成用戶預覽、用戶下載資源的功能
- 服務器完成包含用戶登錄、請求資源等活動的日志的記錄
- 服務器通過定時器清理非活動連接
- 管理員可以完成服務器資源的維護,包含刪除、修改、上傳資源等功能以及服務器資源的異常檢測,同時管理員也可以作為用戶完成一系列活動
- 性能需求
支持較高數量的並發請求,同時能夠在給定時間內完成響應
- 其他需求
要求具有一定的可移植性,有良好的外部接口
用例建模
- 首先從需求的表述中可以發現,項目包含兩種種參與者:用戶、管理員。
用戶完成以下用例:
- 注冊
- 登錄
- 預覽資源
- 下載資源
- 修改個人信息
管理員完成以下用例:
- 資源上傳
- 資源刪除
- 資源更新
- 資源異常檢測
用戶和管理員的用例可以概括成請求資源和維護資源兩類。
- 畫出用例圖
圖 1 用戶請求資源用例圖
圖 2 管理員維護資源用例圖
業務領域建模
首先分析項目的功能需求,主要包含:
- 服務器完成用戶登錄、注冊的功能
- 服務器完成用戶預覽、用戶下載資源的功能
- 服務器完成包含用戶登錄、請求資源等活動的日志的記錄
- 管理員可以完成服務器資源的維護,包含刪除、修改、上傳資源等功能以及服務器資源的異常檢測,同時管理員也可以作為用戶完成一系列活動
用戶完成登錄等功能,說明用戶是獨立存在的,作為一個類。用戶完成各類動作,這些動作可以統稱為事件,通過http請求完成,所以http請求也是一個類。日志記錄是獨立存在,需要一個日志類來完成記錄。服務器完成請求的解析以及日志的生成,並且和用戶進行交互,所以服務器也需要作為一個類存在。服務器通過定時器完成非活動連接的清理,所以定時器也是一個類。剩下的登錄,注冊等都是動作,意味着用戶和服務器之間存在着關聯關系。同理管理員作為特殊的用戶,應該是用戶的子類,是繼承關系,管理員和服務器之間也存在着關聯關系。
經過上訴分析,得到項目的業務類圖如下:
圖 3 業務類圖
數據模型
根據繪制出的業務類圖,有相應的數據模型如下:
- User
列名 |
字段名 |
字段說明 |
類型 |
是否為空 |
說明 |
1 |
userId |
用戶ID |
int |
N |
|
2 |
userName |
用戶名 |
varchar(50) |
N |
|
3 |
userPassword |
用戶密碼 |
varchar(100) |
Y |
- http_conn
序號 |
字段名 |
字段說明 |
類型 |
是否為空 |
說明 |
1 |
timer_flag |
定時器標識 |
int |
N |
|
2 |
state |
連接狀態 |
int |
N |
- timer
序號 |
字段名 |
字段說明 |
類型 |
是否為空 |
說明 |
1 |
user_data |
用戶數據 |
text |
N |
|
2 |
expire |
剩余時間 |
varchar(50) |
N |
- SourceInfo
序號 |
字段名 |
字段說明 |
類型 |
是否為空 |
說明 |
1 |
sourceId |
資源ID |
int |
N |
|
2 |
sourceName |
資源名 |
varchar(50) |
N |
|
3 |
sourceType |
資源類型 |
int |
Y |
|
4 |
sourceStatus |
資源狀態 |
int |
N |
概念原型
- 概念是人對能代表某種事物或發展過程的特點及意義所形成的思維結論。
- 概念原型是一種虛擬的、理想化的軟件產品形式。
- 概念原型=用例+數據模型
用例和數據模型都在前文敘述過,這里總結出項目概念原型的工作過程:
用戶通過客戶端向服務器端發起連接,服務器維持主線程來通過epoll系統調用監聽socket連接,被監聽到的socket連接會被accept。同時主線程會維持一個監聽隊列。服務器通過epoll系統調用來完成對監聽socket(listenfd)和連接socket(客戶請求)的同時監聽。通過線程池來實現並發,為每個就緒的文件描述符分配一個邏輯單元(線程)來處理。
服務器需要處理三類事件:I/O事件,信號及定時事件。主線程負責讀寫,工作線程(線程池中的線程)負責處理邏輯(HTTP請求報文的解析等)。工作線程完成對HTTP報文請求的解析,並按照報文的類型返回不同的結果。在用戶登錄時還會查詢數據庫。同時完成對非活動連接的處理以及日志的輸出。管理員作為特殊的用戶,發出的請求會被以同樣的方式處理。
對應的流程圖和時序圖:
圖 4 流程圖
圖 5 時序圖