国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

高職院校選課系統(tǒng)性能優(yōu)化研究與實現(xiàn)

2023-03-29 08:18:46
智庫時代 2023年8期
關鍵詞:課程班令牌序列化

倪 明

(江陰職業(yè)技術學院)

一、背景

隨著我國高職教育的迅速發(fā)展,我校招生規(guī)模逐年擴大,為了適應這些變化,必須改變以往僵硬的教學體系,推進學分制是我校教學管理改革的一個重要舉措。根據(jù)實際情況,我校沒有采用純學分制,而是選擇了學年學分制。

學生選課是學分制的前提和基礎,目前我校選修課主要分為公共選修課、專業(yè)選修課及體育選修課等幾種。隨著我校數(shù)字化校園的建設和發(fā)展,學生選課已經(jīng)從人工選課轉換為網(wǎng)絡選課。如何提高選課系統(tǒng)的性能,為學生選課提供更好的服務,成為選課系統(tǒng)的一項關鍵指標。

二、現(xiàn)狀與原因

我校選課系統(tǒng)問題主要出現(xiàn)在公共選修課及體育選修課,學生在集中選課的過程中,系統(tǒng)經(jīng)常無法響應,造成學生無法正常選課。分析其原因,主要存在以下兩方面的問題:

(一)選課的高并發(fā),造成系統(tǒng)無法響應

圖1 負載均衡

選課過程中,熱門課程必定成為學生優(yōu)先的選擇。由于選修課人數(shù)限制,學生必然會在選課系統(tǒng)開放的同時進行選課,短時間內(nèi)大量學生的涌入,這是一個高并發(fā)的過程,當系統(tǒng)無法在這個時間段抗住高并發(fā),就會造成系統(tǒng)無法響應。

(二)選課約束條件復雜,造成系統(tǒng)負擔過重

選課約束條件復雜體現(xiàn)在多個方面,如選課學分約束、選課門數(shù)約束、學生專業(yè)約束、上課時間約束、選修前導課約束、選修課人數(shù)等。如此多的約束條件處理,必將消耗大量系統(tǒng)資源,造成系統(tǒng)運行緩慢。

三、解決方案

(一)服務器集群與負載均衡

如果只用一臺服務器,服務器處理的并發(fā)數(shù)是有限的,選課系統(tǒng)開啟后,大量學生進入選課,Tomcat服務器一般默認只能開啟150個線程來處理并發(fā)任務,一旦并發(fā)數(shù)超過這個線程,新的請求只能排隊等候處理。這里我們采用Nginx組為負載均衡服務器,Nginx服務器將所有請求分配到多個Tomcat服務器。

Nginx主要有輪詢、最少連接數(shù)、加權、IP-Hash四種負載均衡策略。輪詢負載策略是將請求輪流發(fā)送到響應的Tomcat服務器,最少連接數(shù)負載策略是將請求發(fā)送到當前連接數(shù)最少的Tomcat服務器,加權負載策略是優(yōu)先把請求發(fā)送到權重高的Tomcat服務器。以上三種策略不能將每個客戶端的請求固定分配到同一臺Tomcat服務器上,當用戶登錄信息是保存在某一臺服務器上時,用戶的下次請求可能就會分配到另外一臺服務器上,這時候就需要用戶重新進行登錄驗證,所以我們采用IPHash負載策略,此策略可以將每個客戶端的請求隨機固定到某一臺Tomcat服務器。

(二)課程班信息存入Redis緩存

當選課系統(tǒng)啟動時,首先將課程班信息存入Redis緩存。

課程班信息包括課程班Id、課程名稱、學分、課程類別、任課教師Id、任課教師姓名、限選人數(shù)、已選人數(shù)、未選人數(shù)、上課時間、上課地點、選修狀態(tài)等相關信息,并為課程班添加UUID隨機碼加密鏈接。這些課程班信息通過Redisson生成一個分布式信息量,信息量的Key為UUID隨機碼,Value為課程班的限選人數(shù)。

學生選課時,為了防止惡意請求,將選課系統(tǒng)開啟時產(chǎn)生的UUID作為課程班信息的關鍵字,禁止使用課程班Id作為關鍵字,這樣就能防止學生在選課系統(tǒng)未開啟時進行搶課。

選課開始產(chǎn)生的選課的課程班信息及每個課程班的分布式信息量需要存入Redis緩存。存入Redis緩存一般有Key-Value和Hash兩種形式。

采用Key-Value形式又能分為兩種方法。

第一種方法,將課程班UUID作為Key,課程班的其它信息作為一個序列化對象作為Value存儲,如圖2所示。

圖2 Key-序列化Value存儲

采用這種方法的缺點是,學生選課后,修改選課人數(shù)時,需要將整個Value對象取出,增加序列化/發(fā)序列化開銷,并且在修改操作中需要對數(shù)據(jù)進行并發(fā)保護。

第二種方法是將課程班信息按課程班UUID+數(shù)據(jù)項存成多個Key-Value,如圖3所示。

圖3 Key-Vlaue存儲

采用這種方法可以解決第一種方法中序列化/反序列化的開銷問題,但是存在大量課程班UUID重復數(shù)據(jù),存儲空間浪費較大。

采用以上兩種Key-Value形式存儲時雖然實現(xiàn)比較簡單,但存在系統(tǒng)開銷比較大、存儲空間浪費等缺點,采用Hash形式能很好的解決這些問題。

Hash形式將課程班信息數(shù)據(jù)項作為一個HashMap存入,并且Redis提供了直接存取Map成員的接口,如圖4所示。

從圖4可以看出,Key仍然是課程班UUID,value是一個Map,這個Map的field是課程班信息數(shù)據(jù)項的屬性名,value是數(shù)據(jù)項的值,這樣對課程班信息的修改和存取都可以直接通過其內(nèi)部Map的field,也就是通過Key(課程班UUID)+field(數(shù)據(jù)項標簽)就可以操作對應數(shù)據(jù)了。這樣就解決Key-Value序列化/反序列化開銷過大,在修改操作中需要對數(shù)據(jù)進行并發(fā)保護以及重復存儲課程班UUID數(shù)據(jù)的問題。

圖4 Hash存儲

由于選課系統(tǒng)部署在Tomcat服務器集群,每個Tomcat服務器都會同時把數(shù)據(jù)存入Redis緩存,為了保證Redis中只存在一條線程的緩存數(shù)據(jù),因此在緩存前需要判斷Key是否已經(jīng)存在,并且還需要通過Redisson加分布式鎖,由于多線程同時緩存只會在選課系統(tǒng)開啟時出現(xiàn),因此不需要采用默認的看門狗機制,只需要對分布式鎖設置超時時間,超時后自動解鎖。

當學生點擊確認選課按鈕后,經(jīng)過Nginx網(wǎng)關過濾,來到Tomcat選課接口。首先經(jīng)過身份驗證,驗證通過后獲取學生Id,然后從Redis中獲取選課開始時間和結束時間,用來判斷請求是否在可選課時間段內(nèi)。以上驗證通過后,查詢Redis中選課狀態(tài)Hash結構中是否存在該學生Id及所選課程班Id,不存在則為該學生選擇了該課程班,存在則為該學生退選了該課程班,然后修改該課程班的分布式信息量。

在學生點擊確認選課按鈕時,由于前端卡頓無法及時設置按鈕灰色不可使用,學生有可能會連續(xù)點擊多次按鈕,造成一瞬間發(fā)起多個請求,從而造成連續(xù)扣減分布式信息量,結果就是該學生重復多次選擇了該課程班。

這里我們采用Token令牌來解決這個冪等性問題。首先在學生點擊選課按鈕時,在返回給課程班詳細信息中生成一個Token令牌,并在Redis中也保存這個Token令牌,設置過期時間如10分鐘。學生點擊確認選課后,相應的數(shù)據(jù)和Token令牌都傳給后端,后端收到數(shù)據(jù)后,將數(shù)據(jù)中的Token令牌和Redis中的令牌進行比較,如果兩者相等,則刪除Redis中的Token令牌。這個比較刪除操作必須作為一個整體執(zhí)行,中間不能被其它命令插入,因此采用Lua腳本來執(zhí)行這個原子操作。這樣學生一瞬間發(fā)起的多個請求,后端接收第一個請求后就會立即刪除Redis中的Token令牌,后續(xù)請求因無法匹配到相應的Token令牌而失敗,從而避免了該學生重復多次選擇該課程班。

學生點擊確認選課后,為了保證實時性要求,需要在Redis中根據(jù)課程班Id和學號Id,在選課狀態(tài)Hash結構中設置為“已選”狀態(tài),同時根據(jù)課程班Id從課程班Hash結構中獲取該課程班的信息,再將其結果存入選課信息Hash結構里,其中Key為課程班Id+學號Id,Value為課程班信息。這樣學生就能實時查到課程的選修狀態(tài)及選修了哪些課程。

(三)RabbitMQ消息隊列處理選課結果

前面學生選課操作都在Redis緩存中進行,速度較快,但是最終數(shù)據(jù)還是要寫入數(shù)據(jù)庫中。由于對數(shù)據(jù)庫進行讀寫操作相對于內(nèi)存讀寫是一個緩慢的過程,同步把數(shù)據(jù)寫入數(shù)據(jù)庫,這又將成為選課系統(tǒng)的一個瓶頸。

要解決這個瓶頸,首先要做到系統(tǒng)解耦,采用的方式是學生選課成功后生成一個選課單,選課單包括課程班Id、學號Id、選課狀態(tài)(選課、退選)以及用于解決可能存在的消息亂序問題而加入的創(chuàng)建時間,然后這個選課單傳給RabbitMQ消息隊列,然后由RabbitMQ消息隊列把選課單存入數(shù)據(jù)庫,如圖5所示。

圖5 RabbitMQ消息隊列

RabbitMQ消息發(fā)送后可能因為網(wǎng)絡原因沒有到達Broker或者Broker未持久化消息而宕機。為了解決這個問題,RabbitMQ發(fā)送消息之前,首先將相關信息存入Redis,Redis采用AOF持久化,消息狀態(tài)為未投遞并設置投遞計數(shù)器為0,每次該消息投遞后,計數(shù)器就加1,Broker收到消息后通過ConfirmCallback回調(diào)修改消息為已投遞,并通過定時器把投遞失敗的消息重新發(fā)送,當投遞計數(shù)器到5時,就將該消息交給死信隊列進行人工處理。通過這些操作就可以解決RabbitMQ消息丟失的問題,保障消息的傳輸可靠。

當RabbitMQ消息投遞后,可能由于網(wǎng)絡原因造成Broker收到消息通過ConfirmCallback回調(diào)失敗,RabbitMQ會將消息重復投遞,從而會產(chǎn)生消息重復發(fā)送的問題。此處采用后臺接口處理,后臺接口接收到數(shù)據(jù)后,根據(jù)課程班Id和學號Id來判斷是否接收過此數(shù)據(jù),從而保證數(shù)據(jù)冪等性。

當選課高峰時,系統(tǒng)無法及時處理RabbitMQ中的消息,未及時處理的消息將積壓在消息隊列中,等選課高峰一過,系統(tǒng)就會把積壓的消息處理完成,從而達到消峰的作用。

通過RabbitMQ消息隊列解耦、消峰操作,從而解決在學生選課高峰時的高并發(fā)操作,順利把選課數(shù)據(jù)存入數(shù)據(jù)庫。

四、實現(xiàn)效果

本次選課系統(tǒng)優(yōu)化的目的是保證大量學生同時選課的情況下系統(tǒng)不宕機,并提高系統(tǒng)的QPS,為學生提供更好的選課體驗。為了驗證優(yōu)化效果,采用Apache JMeter5.5進行壓力測試。

首先導出系統(tǒng)中5000個學生的學號,用于模擬5000個學生同時選課,并使用JMeter運行測試方案,優(yōu)化前及優(yōu)化后的測試結果如表1所示。

表1 JMeter匯總報告

從以上JMeter匯總報告可以得出優(yōu)化后系統(tǒng)性能得到很大的提升,在學生實際使用中,系統(tǒng)也未出現(xiàn)無法響應甚至宕機,此次優(yōu)化效果結果比較滿意。

五、總結

根據(jù)我校選課系統(tǒng)目前存在的問題,在學生選課高峰時,系統(tǒng)容易出現(xiàn)運行緩慢甚至宕機。硬件上采用服務器集群與負載均衡,軟件上使用Redis緩存來處理選課時高速的讀寫操作及使用RabbitMQ消息隊列處理選課結果。最后使用JMeter進行壓力測試,在學生正式選課中也取得了良好的效果。

猜你喜歡
課程班令牌序列化
稱金塊
如何建構序列化閱讀教學
甘肅教育(2020年14期)2020-09-11 07:58:36
基于路由和QoS令牌桶的集中式限速網(wǎng)關
西安美術學院藝術金融博士課程班第三次授課舉行
2018藝術金融博士課程班開學典禮在西安美院舉行
首屆中國藝術金融博士課程班畢業(yè)典禮舉行
動態(tài)令牌分配的TCSN多級令牌桶流量監(jiān)管算法
計算機工程(2018年8期)2018-08-17 00:26:54
Java 反序列化漏洞研究
作文訓練微格化、序列化初探
語文知識(2015年12期)2015-02-28 22:02:15
Java序列化技術的探討
五大连池市| 丁青县| 炎陵县| 资兴市| 余姚市| 堆龙德庆县| 丹巴县| 上犹县| 墨江| 托克逊县| 庆云县| 阜康市| 镶黄旗| 德州市| 奉节县| 盐津县| 阳原县| 阜康市| 丹巴县| 福安市| 石楼县| 称多县| 那坡县| 万载县| 临泉县| 科技| 遂平县| 拜泉县| 普兰县| 塔河县| 纳雍县| 乐清市| 安仁县| 亚东县| 枞阳县| 剑川县| 邢台市| 五台县| 房产| 桃园县| 榆树市|