版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
1、 當當網(wǎng)高可用移動入口與搜索技術架構聊聊架構 微信號 archtime功能介紹 以架構之“道”為基礎,呈現(xiàn)更多務實落地的架構內(nèi)容。每年一次的互聯(lián)網(wǎng)電商的雙十一,是對一年工作的總結和洗禮,在 2017 年的雙十一到來之際,我們希望通過本文梳理一下當當?shù)囊恍┬兄行У姆椒?。面對爆發(fā)性增長的流量,首要任務是讓系統(tǒng)在大流量沖擊的情況下能夠先存活下來,通過應用限流,您可以了解到當當如何在流量洪峰中保持現(xiàn)有系統(tǒng)的服務能力。在眾多的系統(tǒng)中,系統(tǒng)之間的交互過于繁雜,一套全方位的鏈路監(jiān)控系統(tǒng),可以快速定位某個子系統(tǒng)的問題,通過 APM 系統(tǒng),您將了解到當當在大量服務并存的情況下如何快速定位系統(tǒng)問題。MAPI 是
2、載當當大部分入口流量的移動端網(wǎng)關,通過 MAPI 對服務治理以及性能的分享,您將能夠以點帶面地一窺當當業(yè)務系統(tǒng)的設計思路。搜索系統(tǒng)的重要程度不言而喻,而且它與業(yè)務系統(tǒng)的側重點不盡相同,今年當當重點對搜索系統(tǒng)進行了重構,您可以通過對搜索新架構的解讀一同探索技術的點點滴滴。應用限流 電商平臺的流量因促銷、搶券、秒殺、熱銷品開賣等情況會出現(xiàn)大大小小的流量洪峰。流量洪峰的瞬時沖擊(比如雙十一零點的電商大促),可能導致系統(tǒng)響應緩慢,甚至整體崩潰,將對公司帶來直接損失,因此大部分互聯(lián)網(wǎng)電商都會有自己的一套解決方案,比如:流量疏導、服務降級、應用限流等。接下來介紹下當當在應用限流的設計思路和一些做法。限流體
3、系的整體架構圖如下:當當?shù)膽孟蘖靼?3 個子系統(tǒng):基于 Openresty/Nginx 的限流引擎,包含限流策略和限流算法?;?Prometheus 和 Grafana 的流量監(jiān)控模塊基于 Hadoop(計劃中)和 java Web 的配置中心下面分別介紹各子系統(tǒng)的一些設計經(jīng)驗。限流引擎子系統(tǒng) 在實際業(yè)務中,絕大部分應用服務器部署在反向代理服務器(Nginx)后面。一般情況下,Nginx 的性能不會成為瓶頸,后端的應用服務器會由于各種原因(如數(shù)據(jù)庫緩慢、I/O 等待時間長、代碼自身的缺陷等)成為瓶頸,所以主要是根據(jù) Nginx 后端連接的應用服務器的負載情況來決定采用何種策略對前面的 N
4、ginx 進行限流。同時對應用服務器層無需做任何調整即可實現(xiàn)流量控制,開發(fā)簡單,維護成本低。反向代理服務器使用的是 Openresty(),一個基于 Nginx 的 Lua 環(huán)境封裝,使用 LuaJIT 作為 Lua 編譯器,由于 Just-In-Time 的方式,比傳統(tǒng) Lua 運行更高效。當當?shù)南蘖鬟壿嫽谒_發(fā)。首先介紹一下 限流算法,常用的擁塞控制算法有兩種:漏桶算法可以用在控制應用服務器發(fā)送請求到其他應用服務器的速率,確保一個穩(wěn)定的速率,主要用于控制回調洪峰(其他系統(tǒng)的調用)的,針對用戶洪峰更適合令牌桶算法。但是如果無差別拒絕請求,會導致用戶體驗的嚴重下降,因此 需要策略組的配合,按
5、照一定的規(guī)則拒絕請求,比較合理的做法是:通過防刷算法,拒絕疑似攻擊的請求通過用戶識別碼、IP、所在區(qū)域、上網(wǎng)特征和接口特征等方式拒絕頻繁訪問的用戶,保證服務器資源能服務更多的用戶。盡量不影響已服務用戶的使用體驗對于正在挑選商品的用戶(較多的單品頁、添加購物車等操作),要盡量保證不被限流擋住,否則會降低用戶的使用粘性??梢宰龅姆椒ㄊ窃黾右粋€訪問令牌,記錄用戶一些重要操作時間,在流量不夠的情況下,優(yōu)先放行具備訪問令牌的用戶。盡量保證會員的使用體驗平臺的會員尤其是高級會員一般是具備較大網(wǎng)購需求的用戶,他們往往更能影響平臺的口碑,所以平臺要服務好這部分的會員。其次將限流引擎中的參數(shù)進行整理,對外提供
6、HTTP Rest 接口,可以熱更新限流策略和相關參數(shù),對接應用限流 - 配置中心子系統(tǒng)。值得注意的是,openresty 提供了一種 dict 的類型是子進程內(nèi)存共享的,可以跨 worker 訪問,如果操作是進程不安全操作記得加鎖,另外這種類型在聲明時需要提供開辟內(nèi)存大小,根據(jù)業(yè)務負載情況進行指定,超過內(nèi)存大小會通過 LRU 算法進行內(nèi)存回收。以下介紹了一些重要參數(shù)的說明:最后提供了 流量指標上報 模塊,按照配置參數(shù)進行定時數(shù)據(jù)上報,目前上報總流量、通過流量、拒絕流量、分流流量、主機 IP、應用名等實時信息。上報數(shù)據(jù)進入流量監(jiān)控子系統(tǒng),進行實時流量監(jiān)控和離線分析,稍后會在流量監(jiān)控模塊詳細說明
7、。流量監(jiān)控子系統(tǒng) Prometheus 作為一種 time series 數(shù)據(jù)庫,很適合做實時業(yè)務監(jiān)控。因此根據(jù)上文上報數(shù)據(jù)的配置,經(jīng)過 Prometheus Push Gateway 將數(shù)據(jù)初步匯總,最終通過 Prometheus 拉取數(shù)據(jù)。Grafana 則接入 Prometheus 數(shù)據(jù)源,提供實時流量頁面和告警功能??梢酝ㄟ^查詢各個應用集群的流量分布,通過率低于閾值或者一定時間流量為 0 則直接告警。Grafana Config Update Daemon 則定時比對 Prometheus 和 Grafana 的配置差異,動態(tài)調整 Grafana 配置圖,能夠達到上下線主機和應用時,不
8、需要手工維護 Grafana Web,實現(xiàn)自動化運維。配置中心子系統(tǒng) 通過 web 頁面調用推薦引擎子系統(tǒng)提供的接口,獲取當前各個系統(tǒng)配置信息。并通過頁面進行限流策略、限流閾值等信息的實時更新。未來計劃通過定時抓取 Prometheus 的數(shù)據(jù),將數(shù)據(jù)存放在 Hadoop 中,基于 time series 預測算法訓練模型數(shù)據(jù),對未來大促進行流量預判。通過提供的 Web 頁面,管理員可以查看歷史流量和流量預測數(shù)據(jù),指導系統(tǒng)管理員優(yōu)化應用限流配置的同時,也積累了寶貴的大促流量數(shù)據(jù)。為日后分析用戶行為,甚至市場運營的判斷提供更廣闊的空間。APM 系統(tǒng) 如今的電商平臺隨著業(yè)務復雜化,包含的功能越來越
9、多,內(nèi)部系統(tǒng)間的調用關系也越來越多。針對一個用戶的一次購買流程(商品展示、搜索、購買、支付)可能需要調用數(shù)十次、甚至上百次的接口。首先如此龐大的調用鏈梳理成為一件很棘手的事情,而更迫在眉睫的事情是針對用戶偶現(xiàn)的慢操作問題,無法快速定位到眾多調用中的哪一步導致的。因此急需一套完整的應用性能治理系統(tǒng)APM(Application Performance Management)來解決這個問題。在 APM 產(chǎn)品選型時,我們考慮到當當目前系統(tǒng)的現(xiàn)狀,得出了以下的結論:APM 產(chǎn)品需要性能極高,嵌入線上系統(tǒng)的探針需要盡量少的資源來完成調用信息獲取,APM 自身也需要能承載百億量級的入庫和查詢操作的能力。A
10、PM 產(chǎn)品需要方便部署使用,盡量不改動或者輕微改動代碼即可實現(xiàn)系統(tǒng)追蹤。APM 系統(tǒng)可以提供系統(tǒng)依賴關系、SLA 指標和調用耗時甘特圖。APM 產(chǎn)品方便定制開發(fā),方便擴展內(nèi)部不同語言的系統(tǒng)使用和提供各種的統(tǒng)計數(shù)據(jù)。最終我們選取了 OpenSkywalking 團隊開發(fā)的 skywalking 產(chǎn)品(http:/skywalking.io)作為當當 APM 系統(tǒng),并進行定制開發(fā)。Skywalking 是遵守 opentracing 規(guī)范(CNCF 基金會下,開源分布式服務追蹤標準)開發(fā)的,針對 java 支持使用字節(jié)碼增強技術,無需改動代碼即可實現(xiàn)系統(tǒng)追蹤。自動追蹤支持主流的 web 容器、中間
11、件、RPC 組件、數(shù)據(jù)庫和 NOSQL 等。架構圖如下:Skywalking 每個節(jié)點都支持集群模式,可以無限水平擴展,易用的 Java 探針自動上報數(shù)據(jù),無需程序做任何改動。但是當當內(nèi)部系統(tǒng)使用語言眾多,除了 Java,包含 PHP、C、Python 和 Go 等語言開發(fā)的系統(tǒng)。對于 APM 系統(tǒng)來講,追蹤的調用軌跡只要一個節(jié)點沒有追蹤到,就會導致鏈路中斷,達不到預期效果,因此我們在 Skywalking 上針對不同語言開發(fā)了相應的組件包 agent。agent 中為了盡量減少對業(yè)務系統(tǒng)的影響,使用寫文件的方式,再通過 Filebeat+Kafka 的方式將追蹤信息發(fā)給 collector,
12、改造完的架構圖如下:如上圖所示,agent 只負責匯總收集數(shù)據(jù),和 collector 保持啟動時候的注冊功能,數(shù)據(jù)上報功能則通過寫文件的方法,交給另一個 Filebeat 進程來完成。Filebeat 通過配置一個 Kafka 的 Topic,將數(shù)據(jù)發(fā)送到 Kafka 集群,再通過 Kafka consumer 來拉取數(shù)據(jù)發(fā)送 skywalking collector。同時 agent 提供管理服務 API,可以通過管理 web 界面管理 agent 的運行情況、開關、采樣率等信息,在 agent 工作影響線上服務性能時(比如大促之時),可以快速關閉探針采集和上報功能來保證系統(tǒng)最大性能;各個
13、系統(tǒng)也可以根據(jù)自身需要調節(jié)系統(tǒng)的采樣率,達到追蹤和性能影響的一個平衡點。改造后的優(yōu)缺點如下:優(yōu)點a) 異步 Filebeat 進程發(fā)送數(shù)據(jù),減少對業(yè)務進程的影響b) 更好的支持異構語言系統(tǒng)c) 探針支持熱變更,更適合線上業(yè)務系統(tǒng)缺點a) 部署成本和復雜度提高b) 數(shù)據(jù)計算會有更大延遲目前當當 APM 系統(tǒng)已經(jīng)上線,在 MAPI、購物車、交易、促銷、TMS、搜索、價格、廣告等系統(tǒng)上嵌入,進行 7*24 小時全天候監(jiān)控。在雙十一前的幾輪壓測中,通過 web 界面提供了整個系統(tǒng)的 SLA 指標情況,對整體壓測是否通過,提供了簡單直觀的數(shù)據(jù)。再通過查看慢操作的甘特圖,可以快速定位具體的是哪個調用步驟比
14、較慢,指導業(yè)務系統(tǒng)開發(fā)者快速發(fā)現(xiàn)問題所在,解決可能存在的性能瓶頸問題,也給整個電商平臺性能更好的指導意見。MAPI 服務 MAPI 是當當移動客戶端所有請求的流量總入口。MAPI 需要對客戶端做安全、登錄等移動端校驗后,才可以將客戶端真實的業(yè)務請求發(fā)送相應的后端服務進一步處理;MAPI 同時負責通過緩存機制減輕后端壓力;MAPI 的另一個職責是管理移動客戶端的用戶信息,如:Session、設備、賬號等,以及移動端的定制化服務,如:移動 APP 推送消息等。微服務統(tǒng)一 API 網(wǎng)關 為了保證對外服務的安全性,我們在服務端實現(xiàn)的大量服務接口均加入了權限校驗機制,并且為了防止客戶端在發(fā)起請求時被篡改
15、,引入了簽名校驗機制。我們遵循微服務架構設計理念,將原本處于同一應用中的多個模塊拆分為多個獨立應用。為保證不同應用提供的接口均需保證相同的校驗邏輯,我們不得不在每個應用中都實現(xiàn)同一套校驗邏輯。隨著微服務規(guī)模的擴大,校驗邏輯愈加冗余,對它們的 BUG 修復或擴展優(yōu)化則必須在每個應用中分別修改。這不僅會引起開發(fā)人員的抱怨,更會加重測試人員的負擔。所以,我們需要一套機制解決此類問題。為此,我們采用了 API 網(wǎng)關架構的解決方案。API 網(wǎng)關定位為設計模式中的 Facade 模式,它作為整個微服務架構系統(tǒng)的門面,對所有的外部客戶端訪問進行調度和過濾。它不僅具有請求路由、負載均衡、校驗過濾等功能,還有服
16、務發(fā)現(xiàn)、熔斷、服務聚合等能力。系統(tǒng)架構改造前:系統(tǒng)改造后:服務治理 服務降級 在大促期間,為了減少服務器壓力,會對一些相對消耗服務器計算資源,但并非核心流程的服務進行降級??蛻舳苏埱髸r,會請求降級服務,根據(jù)降級的配置來判斷是否需要做相應的請求,如:購物車數(shù)量、單品緩存時間、請求收藏狀態(tài)等。熔斷 在微服務架構中,我們將系統(tǒng)拆分成了很多服務單元,單元之間通過服務注冊與訂閱的方式互相依賴。依賴間通過遠程調用(如:RPC/Restful API 等)的方式交互,這樣就有可能因為網(wǎng)絡原因或者依賴服務自身問題出現(xiàn)調用延遲或異常,最后就會因等待出現(xiàn)的故障的依賴方響應形成請求積壓,最終導致服務自身的癱瘓。以互
17、聯(lián)網(wǎng)電商為例,系統(tǒng)會拆分為用戶、訂單、庫存、積分、評論等一系列服務。在用戶下單時,客戶端將通過 MAPI 接口的調用,請求訂單服務的創(chuàng)建訂單接口,訂單服務則會請求庫存接口。如果庫存或訂單服務因網(wǎng)絡延遲等原因造成響應超時,MAPI 接口的線程將被掛起。高并發(fā)場景中會造成掛起線程的大量堆積,導致客戶經(jīng)過漫長等待而下單失敗。過多的客戶下單請求將產(chǎn)生雪崩效應,導致服務不可用,甚至整個系統(tǒng)癱瘓。當當采用 Netflix 開源的 Hystrix 作為熔斷方案,以下對 Hystrix 進行分析講解。下圖展示了用戶請求正常訪問下的一個情況:(圖片來源于 GitHub-Hystrix)當其中的某一個系統(tǒng)發(fā)生延遲
18、,并阻塞用戶請求時,如下圖:(圖片來源于 GitHub-Hystrix)在高并發(fā)的請求的情況下,會造成所有的用戶請求發(fā)生延遲,最終整個消費系統(tǒng)癱瘓而不可用,如下圖:(圖片來源于 GitHub-Hystrix)Hystrix 使用“艙壁模式”實現(xiàn)線程池的隔離,它會為每一個依賴服務創(chuàng)建一個獨立的線程池,這樣就算某個依賴服務出現(xiàn)延遲過高的情況,也只是對該依賴服務的調用產(chǎn)生影響,而不會拖慢其他的依賴服務。HHVM 提升服務性能 為了滿足快速的迭代開發(fā),MAPI 中大部分采用 PHP5.6 來實現(xiàn)的,其中有一些使用了 Hack 的 IO 異步操作。我們經(jīng)過大量的壓測案例對比,發(fā)現(xiàn) HHVM 更加符合 M
19、API 業(yè)務,故我們采用 HHVM 虛擬機。同時,HHVM 的作者(Facebook 的同事)主動與當當進行技術交流,更有效地提升了 HHVM 應用層性能,使得業(yè)務高效運行。HHVM 類似于 C# 的 CLR 和 Java 的 JVM。HHVM 是在 HPHPc 的基礎上構建,它會將 PHP 代碼轉換成高級別的字節(jié)碼(一種中間語言),在運行時即時(JIT)編譯器會將這些字節(jié)碼翻譯成機器碼,它比 open_cache (Zend 使用的)更穩(wěn)定,更高效。搜索新架構 今年雙十一,當當網(wǎng)上線了搜索新架構。平均響應時間降低了一個數(shù)量級,QPS 提升了一個數(shù)量級,索引數(shù)據(jù)的實效性也有了大幅度的改善??梢?/p>
20、更加從容的應對雙十一的流量,提升用戶的搜索體驗。當當網(wǎng)的搜索引擎是典型的電商搜索引擎,索引量遠小于互聯(lián)網(wǎng)搜索引擎,不會達到數(shù)百億,但有很多復雜的電商搜索邏輯,可以說是術業(yè)有專功。搜索引擎全部由當當自主研發(fā),主要使用 C+ 語言,長期以來,支撐當當搜索業(yè)務的同時,也積累了一些技術債。為了快速響應業(yè)務需求,導致業(yè)務邏輯的無序添加,由于缺乏有效的定期梳理,積重難返,搜索效果迭代的效率越來越低。16 年底,技術部啟動了搜索引擎的重構項目。重構的技術路線面臨多種選擇,在人力有限的情況下,是全面轉向開源技術,還是自主研發(fā),存在爭議。在充分調研不同技術路線的風險和收益后,搜索引擎的不同子系統(tǒng),采用了不同的方
21、式:搜索服務對性能和穩(wěn)定性有著極高的要求,現(xiàn)有開源框架不足以支撐,并且業(yè)務的定制能力也是一個問題,因此依然采用了全部自主研發(fā)的方式;離線系統(tǒng)對性能沒有過高的要求,全面轉向了開源技術,可以更加方便地實現(xiàn)業(yè)務邏輯、加快效果迭代的速度。搜索服務重構 搜索服務在重構之前是一個單機版的檢索程序,平均響應時間、索引量都存在極限,無法水平擴展。重構后,采用了分布式架構,拆分了搜索節(jié)點、query 分析節(jié)點、index 節(jié)點、摘要節(jié)點。各節(jié)點之間,沒有依賴關系的運算可以并行,大幅度降低了平均響應時間;index 節(jié)點拆分后,索引數(shù)據(jù)可以分層分片,索引量不再受單機限制。搜索新架構沒有沿用舊系統(tǒng)的設計和代碼,重新
22、設計編寫了從底層倒排索引、索引合并、屬性篩選和匯總,到最終結果合并、排序的全部代碼。通過代碼的重新編寫全面梳理了業(yè)務邏輯,嚴格劃分了搜索框架和業(yè)務邏輯的代碼邊界。實現(xiàn)了一個通用的搜索框架,在這個框架之上,附加了當當網(wǎng)的全部搜索業(yè)務邏輯。搜索框架和業(yè)務邏輯的剝離,為效果迭代打下了堅實的基礎。搜索服務重構耗費了很多時間,最終取得了明顯的收益,單機檢索性能有了大幅度的提升:平均響應時間降低了一個數(shù)量級、QPS 提升了一個數(shù)量級。分布式架構是一個因素,索引結構、屬性篩選和匯總、排序方式的改變也是另一個重要因素。索引實時更新 電商搜索對于實時性有著極高的要求,尤其是雙十一,價格、庫存的變化需要及時更新到
23、索引中,商品的上下架、標題等促銷信息的修改也需要快速生效,搜索新架構充分考慮了這些應用場景,做了專門的優(yōu)化。搜索舊系統(tǒng)在索引數(shù)據(jù)的更新上有 2 個問題:一個是更新需要加線程鎖,更新的瞬間全部查詢線程暫停;另一個是采用傳統(tǒng)的全量 + 增量索引,增量會顯著影響 term 的 doc 鏈合并速度,導致索引結構劣化,一個全量周期內(nèi),增量商品的數(shù)量不能太多,否則就會導致檢索耗時過長。搜索新架構采用了新設計的索引結構,更新不需要加線程鎖,可以在并發(fā)查詢的同時更新索引數(shù)據(jù),大幅度提高了更新效率;同時采用全量 + 實時索引,替換了全量 + 增量索引,獨立的實時索引節(jié)點使得索引結構不會劣化,增量商品的數(shù)量不會顯
24、著影響檢索耗時。新架構的實時索引常駐內(nèi)存,由于需要動態(tài)增加商品,整體上是鏈式的,采用跳表 + 數(shù)組加速。這里有一個平衡,全鏈式存儲效率高,沒有內(nèi)存空間浪費,缺點也很明顯,由于它是跳躍式的,CPU 的 cache 命中率極低,term 的 doc 鏈合并過程耗時過長;跳表 + 數(shù)組雖然耗費內(nèi)存空間,但會明顯提升檢索效率和 CPU 的 cache 命中率,縮短檢索耗時。搜索新架構的實時索引通過參數(shù)調整內(nèi)存耗用和檢索耗時,在索引量相同的情況下,對比全量索引,能夠控制在 2 倍的內(nèi)存空間耗用和 4 倍的檢索耗時。由于實時索引的能效比沒有顯著下降,仍在可接受的范圍內(nèi),對于時效等級特別高的商品,可以去掉全量,全部用實時索引替代,簡化建庫、更新流程。離線系統(tǒng)重構 搜索引擎的離線系統(tǒng),負責收集搜索服務需要的全部數(shù)據(jù),當當網(wǎng)搜索引擎的離線系統(tǒng),需要匯集商品的全部信息:標題、描述、價格、庫存、銷
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 綜合制劑車間課程設計
- 中西醫(yī)助理醫(yī)師考試中醫(yī)內(nèi)科學總結要點大全
- 自然大調音階的課程設計
- 中考英語各種題材閱讀理解強化訓練(附詳解)
- 學年論文和課程設計
- (CFG及真空聯(lián)合堆載預壓)軟基處理施工方案
- 《機械通氣的應用》課件
- 油庫課程設計書封面圖案
- 模擬電子琴設計課程設計
- 知識產(chǎn)權活動課程設計
- 【MOOC期末】《電子技術實習SPOC》(北京科技大學)期末慕課答案
- 新媒體技術基礎知識單選題100道及答案解析
- 2025蛇年帶橫批春聯(lián)對聯(lián)200副帶橫批
- 互聯(lián)網(wǎng)+創(chuàng)新商業(yè)模式考核試卷
- 江蘇省揚州市梅嶺中學2023-2024學年七年級上學期期末地理試題(含答案)
- 克羅恩病病例分析
- 《冠心病》課件(完整版)
- DB43T 1694-2019 集體建設用地定級與基準地價評估技術規(guī)范
- 高級技師電工培訓
- DZ/T 0462.3-2023 礦產(chǎn)資源“三率”指標要求 第3部分:鐵、錳、鉻、釩、鈦(正式版)
- Lesson-1.-spring-festival(雙語課件-春節(jié))
評論
0/150
提交評論