劉玥 高銘 文超 丁鑫
關鍵詞:次級排課系統;權限驗證;數據同步
1后端資源的權限管理
后端的接口實際上是一種資源,為了方便后端資源的開發與維護,本系統將后端資源劃分為以下兩種。
(1)用戶使用的資源(下稱用戶接口)。
(2)所有人都能使用的資源(下稱通用接口)。
不同資源的受眾、用途以及重要程度不盡相同,導致它們的開放性也有所差別。其中,還對用戶接口的訪問采取了權限控制,即不同角色的用戶可以訪問的接口是不一樣的。
1.1資源的開放性
用戶接口暴露的數據涉及每個用戶的私人信息,因此需要較為嚴格的鑒權機制來管控;相比之下,通用接口通常標識著一些不重要的資源,如系統中的一些常量,因此不需要任何權限控制,來者不拒。
1.2接口的認證機制
1.2.1令牌
用戶接口的訪問需要受到管制,所以必須有一套機制來實現這個目的。本系統采用token鑒權機制。
在本系統中,用戶接口的token稱為login-token,它們都是接口受眾的臨時憑證。無論是login-token還是app-access-token,其中只攜帶相關實體的id,login-token中攜帶的是系統用戶的id,app-access-token中則攜帶了第三方程序的id。
1.2.2令牌的頒發
login-token的頒發由接口/auth _user接口頒發。前端訪問該接口時,需要攜帶用戶名和密碼,/auth—user接口認證用戶名密碼無誤后,下發用戶令牌。前端妥善保存令牌,在訪問用戶接口時,將該令牌置于header login-token中,以表明用戶身份。
1.2.3令牌失效
上文提及的兩種令牌都有一定的時效,調用者在必要時可以通過令牌時效查詢接口、令牌是否有效,若令牌失效,則需要重新向相應的令牌頒發接口申請新的令牌。login-token的時效查詢接口是/token—expire,app-access-token的時效查詢接口是/app—access_token/token-expire.
1.3用戶接口
與用戶交互的前端需要通過用戶接口來獲取數據并展示給用戶。用戶接口的訪問者必須在HTTP請求中攜帶用戶的token,以證明自己是系統中的合法用戶。
1.4用戶Token認證機制
1.4.1頒發login-token
前端調用接口/auth—user,并攜帶用戶的用戶名和密碼,如果經查詢,數據庫中有相應的用戶記錄,則生成token并通過響應返回前端。前端保存該token,可以用來訪問其他用戶接口。
1.4.2token方案
只要在頒發token時將頒發時間點和token時效一并設置到token中[1].就相當于將token時效信息內嵌到了token自身。這不但合理利用了token攜帶信息的特性,也省去了額外的計時措施,降低了系統的復雜度。
1.5靈活配置接口的開放性
接口有兩種開放性,本系統中使用的是“攔截器+注解”。規定注解:@ AuthLogin標識用戶接口,其他沒有標注的都是通用接口。定義一個攔截器:Authenticationlnterceptor處理用戶認證的邏輯,判斷目標接口是否標注@ AuthLogin注解,若標注了,則攔截并認證。由此,變更某個接口的開放性,添加或取消該接口的注解即可。
2用戶接口的權限鑒別
本系統采用“攔截器+注解”的方式,可以靈活配置接口的權限。設置注解:@ Permlssion。設置攔截器:AuthorizationlnterceptorAuthorizationlnterceptor只攔截被注解@ Permission標注了的接口。
在攔截器中,獲取來訪者的角色,根據角色查詢到來訪者能訪問的所有資源,再對比當前接口是否在可訪問資源列表中,如果在,則放行,否則不能訪問。
3數據同步
3.1概述
本系統通過后端代碼調用學校教務系統的接口,拉取教務系統數據庫數據,作為本系統的數據源,再結合前端的可交互式界面,達到真正意義上的一鍵導人數據。雖然一鍵導人數據方便、快捷,節省人力及時間,但是通過這種方法導人數據的方式通常需要兩個系統,即數據源系統(教務系統)和消費數據的系統(本排課系統)。這種定制化的工作并不需要重復進行,除非兩個系統的數據存儲結構發生變化,否則接口不會發生較大變化,因此,對接口的適配能達到接近“一勞永逸”的效果。
3.2同步機制
3.2.1數據存儲結構
在數據同步的語境中,數據消費方的數據存儲結構總是依賴數據生產方[2]。根據生產方的數據結構,在本系統中構建兩個對應的數據接收實體類和兩個數據存儲實體類(數據庫對象PO)。數據接收實體類字段與數據生產方的數據結構完全一致,而數據存儲實體類則是根據本系統的情況定制的實體類。為了讓消費方的數據存儲結構保持相對穩定的狀態,需要加一層數據接收實體類作為緩沖,這部分實體類只作為數據生產方的映射實體,每當數據生產方的數據結構改變,對數據接收實體的修改是不會對本系統產生關鍵性改動的。雖然增加了一層,但本系統的數據存儲實體還是需要改變,即使如此,大部分的改變已經被數據接收實體類層吸收了,存儲結構做微調即可。
3.2.2一次拉取的數據量
由于拉取到的數據在持久化之前都需要在內存中駐留一段時間,因此需要考慮數據量是否會超出進程的內存空間大小。排課系統涉及數據量較大,一次拉取所有數據的方案是不可行的[3]。所以,可以采取不同數據依次分開同步的方式拉取數據。在同步一種數據時,可以先拉取數據的主鍵,再根據主鍵逐條拉取詳細數據[4]。經測試,當JVM的最大堆內存設置為128MB時,最大可以開辟10000000個整形變量,以一次性拉取所有學生的主鍵為例,內存完全能夠承受。
3.2.3數據更新策略
要完成數據消費方的數據與數據生產方的數據同步,需要實現以下兩點[5]:尋找生產方和消費方數據的差集并消除雙方的差異:比對更新生產方和消費方都有的數據。項目組給消費方的數據庫待同步數據增加一個字段latest_sync,標識該數據是否是最新的。每次同步數據前,將表中的latest_sync字段置為0,表示數據都沒更新,然后拉取并遍歷生產方的數據,逐個查找消費方的數據庫,是否存在數據,若不存在,則說明該數據需要在消費方新增,并置lastest_sync字段為1,若存在,則比對更新,也置lastest_sync字段為1,如此遍歷完成后,所有lastest_sync字段為0的數據就都是生產方沒有但消費方有的數據,需要刪除。
4排課
4.1概述
排課問題主要有以下幾類實體:教師、上課教室、上課班級、授課課程。排課問題主要是要解決上述實體之間對資源利用的沖突。該問題的最終產出是教學課表,課表中的每一項大致可以分為某個時間段、某個教師、某個教室、某個班級、教授某門課程。
4.2排課約束條件
排課的約束條件主要來源于時間和空間上的限制。例如,同一個教室在同一個時間片只能有一場授課活動、同一個教師在同一個時間片只能在一個教室教同一個班級的課,同樣的,同一個班級在同一個時間片也只能在同一個教室上同一門課。排課系統的主要約束條件有以下幾個因素:日寸間片、教室、教師、課程和班級。為了使排課能夠順利進行,排課的所有因素必須滿足上述時空約束條件。
4.3排課的輸入
排課最核心的基礎數據是學期計劃表,每一個學期計劃表的每一行構成了排課流程的主要輸入。計劃表規定了授課教師、授課班級、教授課程,計劃表的每一行包括該節課的課時數、上課人數、上課班級等。
4.4排課關鍵流程
本系統的排課算法采用遍歷算法。排課的核心任務就是,針對每個學期計劃表行,將人(教師、班級)安排到計劃表指定教室的某個時間片中,因此,排課過程實際要確定的是一個學期計劃表行的上課時間和上課地點,對于教師和班級條件都是在學期計劃表中規定好的。本系統以時間片作為遍歷的頂層因素,遍歷一個學期內所有可以排課的時間片,以時間片為條件,查詢已經排好的課表數據,若沒有結果,則該時間片沒有被占用,可以繼續嵌套遍歷所有教室。以教室主鍵為查詢條件,查詢已經排好的課表數據,若沒有結果,則該教室在當前日寸間片沒有其他課程安排,該教室條件滿足,在遍歷教室的循環中依次檢查授課教師和授課班級在當前時間片、當前教室是否有其他課程安排。若上述教室、教師、班級都符合條件、不沖突,則完成了對一個學期計劃表行的排課,可以生成一條排課數據并將其持久化。上述循環結束后,所有計劃表都被安排完畢,算法結束。