面試:第四章:項目介紹

哪些情況用到activeMq?

商品上架后更新ES索引庫、更新靜態(tài)頁、發(fā)送短信

提交訂單后清除購物車中的數(shù)據(jù)

支付未完成時支付完成后修改訂單狀態(tài)
秒殺的時候,只有最后一件物品,該怎么去搶或者分配?

秒殺商品的庫存都會放到redis緩存中,在客戶下單時就減庫存,我們設(shè)置庫存庫存閘值,用于某些商品數(shù)量非單件不可分割,減完庫存會判斷庫存是否為大于庫存閘值,如果小于,表示庫存不足,剛才減去的數(shù)量再恢復(fù),整個過程使用redis的watch鎖 。
你項目對于訂單是怎么處理的,假如一個客戶在下訂單的時候沒有購買怎么辦?

訂單表中設(shè)置了一個過期時間,每天會有定時任務(wù)來掃描訂單表數(shù)據(jù),如果到達預(yù)訂的過期時間沒有付款就會取消此訂單交易。
對于顧客在購買商品的時候你們怎么處理你們的庫存?

普通商品只有在發(fā)貨時才去更新庫存,如果庫存不足商家會馬上補貨

秒殺的商品會在客戶下單時就減庫存,如果在規(guī)定時間(半個小時)沒有付款,會取消此訂單把庫存還原。
秒殺系統(tǒng)中如何防止超售?如何避免腳本進行惡意刷單?

防止超售解決方案:將存庫從MySQL前移到Redis中,所有的寫操作放到內(nèi)存中,由于Redis中不存在鎖故不會出現(xiàn)互相等待,并且由于Redis的寫性能和讀性能都遠高于MySQL,這就解決了高并發(fā)下的性能問題。然后通過隊列等異步手段,將變化的數(shù)據(jù)異步寫入到DB中。當(dāng)達到庫存閥值的時候就不在消費隊列,并關(guān)閉購買功能。避免腳本惡意刷單:采用IP級別的限流,即針對某一個IP,限制單位時間內(nèi)發(fā)起請求數(shù)量。
單點登錄你們是自己編寫的還是使用通用的CAS?

項目使用通用的CAS框架。
什么是CAS?

中央認證服務(wù),企業(yè)級單點登錄解決方案。CAS Server 需要獨立部署,主要負責(zé)對用戶的認證工作;CAS Client 負責(zé)處理對客戶端受保護資源的訪問請求,需要登錄時,重定向到 CAS Server。
如果一個用戶的token被其他用戶劫持了,怎樣解決這個安全問題。

a、在存儲的時候把token進行對稱加密存儲,用時解開。
b、將請求URL、時間戳、token三者進行合并加鹽簽名,服務(wù)端校驗有效性。

c.HTTPS對URL進行加密
對系統(tǒng)運行造成很大壓力,隨著項目上線時間增長,壓力會越來越大,我們怎么減輕系統(tǒng)訪問壓力

流量分為三種,一種是商家流量,另一種是用戶流量,第三種運營商流量。

解決方案:

      這三種流量對系統(tǒng)運行造成很大壓力,隨著項目上線時間增長,壓力會越來越大,因此我們要減輕系統(tǒng)訪問壓力 ,就需要做一系列優(yōu)化措施。

 具體優(yōu)化如下:
 數(shù)據(jù)層面的優(yōu)化:

從數(shù)據(jù)庫層面做優(yōu)化,比如:索引,緩存集群雙緩存,把查詢獨立出來讀寫分離,配置數(shù)據(jù)庫集群主從復(fù)制,使用Mycat分表,分庫。

從數(shù)據(jù)庫設(shè)計層面的優(yōu)化:比如減少表關(guān)聯(lián),加入冗余字段

從緩存方面優(yōu)化:比如redis實現(xiàn)數(shù)據(jù)緩存,減輕數(shù)據(jù)庫壓力

從搜索上進行優(yōu)化:比如查找索引庫,使用es或solr全文搜索
項目層面的優(yōu)化:

采用面向服務(wù)的分布式架構(gòu):分擔(dān)服務(wù)器壓力 ,提高項目并發(fā)量。比如dubbox+zookeeper的SOA分布式架構(gòu)

采用分布式文件系統(tǒng)實現(xiàn)海量文件存儲:如采用fastdfs實現(xiàn)海量圖片存儲,提高文件的訪問速度。

采用mq使用服務(wù)進一步解藕:同步索引庫,同步靜態(tài)資源,短信發(fā)送
服務(wù)器層面的優(yōu)化

集群思想的使用:tomcat,zookeeper,redis,mysql等

Tomcat異步通信的使用,tomcat連接池配置
秒殺和團購業(yè)務(wù)實現(xiàn)思路

將商品數(shù)量查詢出存入到redis中,所有用戶下單后,減掉redis中的數(shù)量

如果并發(fā)量很大時,還要考慮高并發(fā)問題,所以可以加入mq消息中間件處理搶單問題,再結(jié)合redis實現(xiàn)庫存減少操作。高并發(fā)方面還可以考慮CDN,Nginx負載均衡等
你們項目中使用的安全框架是什么?

第一種:使用springSecurity

 

第二種:使用shiro(配置一下再用一下標簽就行了),校驗用戶登錄和用戶權(quán)限!
項目中使用到的應(yīng)用服務(wù)器是什么?

Tomcat+nginx
項目中遇到什么問題?
ES高亮不能顯示的問題

前臺使用angularJS加載搜索結(jié)果,但是發(fā)現(xiàn)高亮不能展示。

問題原因:angularJS底層使用ajax,異步加載高亮信息返回給頁面后,頁面沒有刷新,就直接顯示返回的數(shù)據(jù)。此時會把所有的數(shù)據(jù)作為普通的文本數(shù)據(jù)進行加載。因此就沒有高亮的效果。

解決方案:使用angularJS過濾器過濾文本數(shù)據(jù),此時angularJS過濾器把html文本數(shù)據(jù)解析為瀏覽器能識別的html標簽。高亮就能展示了。
activeMQ存在運行時間長了以后,收不到消息的現(xiàn)象。時間長了就會出現(xiàn),卡死,新的數(shù)據(jù)不能從隊列接聽到。只能重啟程序。

解決方案:

1)不要頻繁的建立和關(guān)閉連接:JMS使用長連接方式,一個程序,只要和JMS服務(wù)器保持一個連接就可以了,不要頻繁的建立和關(guān)閉連接。頻繁的建立和關(guān)閉連接,對程序的性能影響還是很大的。這一點和jdbc還是不太一樣的。

2)Connection的start()和stop()方法代價很高:JMS的Connection的start()和stop()方法代價很高,不能經(jīng)常調(diào)用。我們試用的時候,寫了個jms的connection pool,每次將connection取出pool時調(diào)用start()方法,歸還時調(diào)用stop()方法,然而后來用jprofiler發(fā)現(xiàn),一般的cpu時間都耗在了這兩個方法上。

3)start()后才能收消息:Connection的start()方法調(diào)用后,才能收到j(luò)ms消息。如果不調(diào)用這個方法,能發(fā)出消息,但是一直收不到消息。不知道其它的jms服務(wù)器也是這樣。

4)顯式關(guān)閉Session:如果忘記了最后關(guān)閉Connection或Session對象,都會導(dǎo)致內(nèi)存泄漏。這個在我測試的時候也發(fā)現(xiàn)了。本來以為關(guān)閉了Connection,由這個Connection生成的Session也會被自動關(guān)閉,結(jié)果并非如此,Session并沒有關(guān)閉,導(dǎo)致內(nèi)存泄漏。所以一定要顯式的關(guān)閉Connection和Session。

5)對Session做對象池:對Session做對象池,而不是Connection。Session也是昂貴的對象,每次使用都新建和關(guān)閉,代價也非常高。而且后來我們發(fā)現(xiàn),原來Connection是線程安全的,而Session不是,所以后來改成了對Session做對象池,而只保留一個Connection。

6) 集群:ActiveMQ有強大而靈活的集群功能,但是使用起來還是會有很多陷阱
activeMQ存在發(fā)出消息太大,造成消息接受不成功。多個線程從activeMQ中取消息,隨著業(yè)務(wù)的擴大,該機器占用的網(wǎng)絡(luò)帶寬越來越高。

仔細分析發(fā)現(xiàn),mq入隊時并沒有異常高的網(wǎng)絡(luò)流量,僅僅在出隊時會產(chǎn)生很高的網(wǎng)絡(luò)流量。

最終發(fā)現(xiàn)是spring的jmsTemplate與activemq的prefetch機制配合導(dǎo)致的問題。

研究源碼發(fā)現(xiàn)jmsTemplate實現(xiàn)機制是:每次調(diào)用receive()時都會創(chuàng)建一個新的consumer對象,用完即銷毀。

正常情況下僅僅會浪費重復(fù)創(chuàng)建consumer的資源代價,并不至于產(chǎn)生正常情況十倍百倍的網(wǎng)絡(luò)流量。

但是activeMQ有一個提高性能的機制prefetch,此時就會有嚴重的問題。

prefetch機制:
每次consumer連接至MQ時,MQ預(yù)先存放許多message到消費者(前提是MQ中存在大量消息),預(yù)先存 放message的數(shù)量取決于prefetchSize(默認為1000)。此機制的目的很顯然,是想讓客戶端代碼用一個consumer反復(fù)進行 receive操作,這樣能夠大量提高出隊性能。

此機制與jmsTemplate配合時就會產(chǎn)生嚴重的問題,每次jmsTemplate.receive(),都會產(chǎn)生1000個消息的網(wǎng)絡(luò)流量, 但是因為jmsTemplae并不會重用consumer,導(dǎo)致后面999個消息都被廢棄。反復(fù)jmsTemplate.receive()時,表面上看 不出任何問題,其實網(wǎng)絡(luò)帶寬會造成大量的浪費。
解決方案:

1、若堅持使用jmsTemplate,需要設(shè)置prefetch值為1,相當(dāng)于禁用了activeMQ的prefetch機制,此時感覺最健壯, 就算多線程,反復(fù)調(diào)用jmsTemplate.receive()也不會有任何問題。但是會有資源浪費,因為要反復(fù)創(chuàng)建consumer并頻繁與服務(wù)器進 行數(shù)據(jù)通信,但在性能要求不高的應(yīng)用中也不算什么問題。

2、不使用jmsTemplate,手工創(chuàng)建一個consumer,并單線程反復(fù)使用它來receive(),此時可以充分利用prefetch機制。配合多線程的方式每個線程擁有自己的一個consumer,此時能夠充分發(fā)揮MQ在大吞吐量時的速度優(yōu)勢。

切記避免多線程使用一個consumer造成的消息混亂。大吞吐量的應(yīng)用推薦使用方案2,能夠充分利用prefetch機制提高系MQ的吞吐性能。
商品的價格變化后,如何同步redis中數(shù)以百萬計的購物車數(shù)據(jù)。

解決方案:購物車只存儲商品id,到購物車結(jié)算頁面將會從新查詢購物車數(shù)據(jù),因此就不會涉及購物車商品價格同步的問題。
系統(tǒng)中的錢是如何保證安全的。

在當(dāng)前互聯(lián)網(wǎng)系統(tǒng)中錢的安全是頭等大事,如何保證錢的安全可以從以下2個方面來思考:

1)錢計算方面

在系統(tǒng)中必須是浮點數(shù)計算類型存儲錢的額度,否則計算機在計算時可能會損失精度。

2)事務(wù)處理方面

在當(dāng)前環(huán)境下,高并發(fā)訪問,多線程,多核心處理下,很容易出現(xiàn)數(shù)據(jù)一致性問題,此時必須使用事務(wù)進行控制,訪問交易出現(xiàn)安全性的問題,那么在分布式系統(tǒng)中,存在分布式事務(wù)問題,可以有很多解決方案:

使用 jpa可以解決

使用 tcc 框架可以解決等等。
訂單中的事物是如何保證一致性的。

使用分布式事務(wù)來進行控制,保證數(shù)據(jù)最終結(jié)果的一致性。
講講angularJS四大特征?
MVC 模式

Model:數(shù)據(jù),其實就是angular變量($scope.XX);

View: 數(shù)據(jù)的呈現(xiàn),Html+Directive(指令);

Controller:操作數(shù)據(jù),就是function,數(shù)據(jù)的增刪改查;
雙向綁定

首先我們要理解數(shù)據(jù)綁定。我們看到的網(wǎng)站頁面中,是由數(shù)據(jù)和設(shè)計兩部分組合而成。將設(shè)計轉(zhuǎn)換成瀏覽器能理解的語言,便是html和css主要做的工作。而將數(shù)據(jù)顯示在頁面上,并且有一定的交互效果(比如點擊等用戶操作及對應(yīng)的頁面反應(yīng))則是js主要完成的工作。很多時候我們不可能每次更新數(shù)據(jù)便刷新頁面(get請求),而是通過向后端請求相關(guān)數(shù)據(jù),并通過無刷新加載的方式進行更新頁面(post請求)。那么數(shù)據(jù)進行更新后,頁面上相應(yīng)的位置也能自動做出對應(yīng)的修改,便是數(shù)據(jù)綁定。

在以前的開發(fā)模式中,這一步一般通過jq操作DOM結(jié)構(gòu),從而進行更新頁面。但這樣帶來的是大量的代碼和大量的操作。如果能在開始的時候,便已經(jīng)確定好從后端獲取的數(shù)據(jù)到頁面上需要進行的操作,當(dāng)數(shù)據(jù)發(fā)生改變,頁面的相關(guān)內(nèi)容也自動發(fā)生變化,這樣便能極大地方便前端工程師的開發(fā)。在新的框架中(angualr,react,vue等),通過對數(shù)據(jù)的監(jiān)視,發(fā)現(xiàn)變化便根據(jù)已經(jīng)寫好的規(guī)則進行修改頁面,便實現(xiàn)了數(shù)據(jù)綁定??梢钥闯?,數(shù)據(jù)綁定是M(model,數(shù)據(jù))通過VM(model-view,數(shù)據(jù)與頁面之間的變換規(guī)則)向V(view)的一個修改。

而雙向綁定則是增加了一條反向的路。在用戶操作頁面(比如在Input中輸入值)的時候,數(shù)據(jù)能及時發(fā)生變化,并且根據(jù)數(shù)據(jù)的變化,頁面的另一處也做出對應(yīng)的修改。有一個常見的例子就是淘寶中的購物車,在商品數(shù)量發(fā)生變化的時候,商品價格也能及時變化。這樣便實現(xiàn)了V——M——VM——V的一個雙向綁定。

這里是區(qū)別于Jquery的,jq操作的是dom對象,angularJS操作的是變量
依賴注入

對象在創(chuàng)建時,其依賴的對象由框架來自動創(chuàng)建并注入進來。控制器就是通過依賴注入的方式實現(xiàn)對服務(wù)的調(diào)用。
模塊化設(shè)計

高內(nèi)聚低耦合法則

高內(nèi)聚:每個模塊的具體功能具體實現(xiàn)

低耦合:模塊之間盡可能的少用關(guān)聯(lián)和依賴

1)官方提供的模塊  ng(最核心)、ngRoute(路由)、ngAnimate(動畫)

2)用戶自定義的模塊     angular.module('模塊名',[ ])
 
當(dāng)商品庫存數(shù)量不足時,如何保證不會超賣。

場景一: 如果系統(tǒng)并發(fā)要求不是很高

那么此時庫存就可以存儲在數(shù)據(jù)庫中,數(shù)據(jù)庫中加鎖串行化減庫存,控制庫存的超賣現(xiàn)象。

場景二:系統(tǒng)的并發(fā)量很大

如果系統(tǒng)并發(fā)量很大,那么就不能再使用數(shù)據(jù)庫來進行減庫存操作了,因為數(shù)據(jù)庫加鎖操作本身是以損失數(shù)據(jù)庫的性能來進行控制數(shù)據(jù)庫數(shù)據(jù)的一致性的。但是當(dāng)并發(fā)量很大的時候,將會導(dǎo)致數(shù)據(jù)庫排隊,發(fā)生阻塞。

因此必須使用一個高效的nosql數(shù)據(jù)庫服務(wù)器來進行減庫存,此時可以使用redis服務(wù)器來存儲庫存,redis是一個內(nèi)存版的數(shù)據(jù)庫,查詢效率相當(dāng)?shù)母撸梢允褂脀atch來監(jiān)控減庫存的操作,一旦發(fā)現(xiàn)庫存被減為0,立馬停止售賣操作。
商城系統(tǒng)中有以下活動:

1)      秒殺活動

a)    后臺設(shè)置秒殺商品

b)    設(shè)置秒殺開啟時間,定時任務(wù),開啟秒殺

c)    秒殺減庫存(秒殺時間結(jié)束,庫存賣完,活動結(jié)束)

2)      促銷活動

3)      團購活動

4)      今日推薦
涉及到積分積累和兌換商品等業(yè)務(wù)是怎么設(shè)計的

積分累計有2大塊:

積分累計:

根據(jù)用戶購買的商品的價格不同,購買一定價格的商品,獲取一定的積分。

積分商城:

積分商城是用戶可以使用積分商品換取商品的區(qū)域。
項目的亮點是:

1) 項目采用面向服務(wù)分布式架構(gòu)(使用dubbo,zookeeper)

a)    解耦

b)    提高項目并發(fā)能力

c)    分擔(dān)服務(wù)器壓力

2) 項目中使用activeMQ對項目進一步解耦

a)    提高項目并發(fā)能力

b)    提高任務(wù)處理速度

3)  使用支付寶支付

4)  使用前后端分離

5)  使用第三方分布式文件系統(tǒng)存儲海量文件

6)  Nginx部署靜態(tài)頁面實現(xiàn)動靜分離
購物車流程:

 

秒殺商品流程:

(1)商家提交秒殺商品申請,錄入秒殺商品數(shù)據(jù),主要包括:商品標題、原價、秒殺價、商品圖片、介紹等信息

(2)運營商審核秒殺申請

(3)秒殺頻道首頁列出秒殺商品(進行中的)點擊秒殺商品圖片跳轉(zhuǎn)到秒殺商品詳細頁。將秒殺的商品放入緩存減少數(shù)據(jù)庫瞬間的訪問壓力!

(4)商品詳細頁顯示秒殺商品信息,點擊立即搶購實現(xiàn)秒殺下單,下單時扣減庫存。當(dāng)庫存為0或不在活動期范圍內(nèi)時無法秒殺。讀取商品詳細信息時運用緩存,當(dāng)用戶點擊搶購時減少redis中的庫存數(shù)量,當(dāng)庫存數(shù)為0時或活動期結(jié)束時,同步到數(shù)據(jù)庫。

(5)秒殺下單成功,直接跳轉(zhuǎn)到支付頁面(微信掃碼),支付成功,跳轉(zhuǎn)到成功頁,填寫收貨地址、電話、收件人等信息,完成訂單。

(6)當(dāng)用戶秒殺下單5分鐘內(nèi)未支付,取消預(yù)訂單,調(diào)用微信支付的關(guān)閉訂單接口,恢復(fù)庫存。產(chǎn)生的秒殺預(yù)訂單也不會立刻寫到數(shù)據(jù)庫中,而是先寫到緩存,當(dāng)用戶付款成功后再寫入數(shù)據(jù)庫。
單點登錄怎么做的,知道原理嗎?

在分布式項目中實現(xiàn)session共享,完成分布式系統(tǒng)單點登錄

Cookie中共享ticket

 Redis存儲session

分布式系統(tǒng)共享用戶身份信息session,必須先獲取ticket票據(jù),然后再根據(jù)票據(jù)信息獲取redis中用戶身份信息。

實現(xiàn)以上2點即可實現(xiàn)session共享。目前項目中使用的Shiro+ cas 來實現(xiàn)的單點登錄,cas自動產(chǎn)生ticket票據(jù)信息,每次獲取用戶信息,cas將會攜帶ticket信息獲取用戶身份信息。

 
介紹一下自己的項目?

我最近的一個項目是一個電商項目,我主要負責(zé)的是后臺管理和商品詳情的模塊,然后也會參與到購物車和訂單模塊。這個項目是以SpringBoot和mybatis為框架,應(yīng)為springBoot相對于SSM來說 配置方面,還有操作方面簡單很多。然后是采用zookeeper加dubbo分布式架構(gòu)和RPC遠程調(diào)用,因為他Dubbo實現(xiàn)了軟負載均衡,其特點是成本低,但也會有缺點,就是負載能力會受服務(wù)器本身影響,然后為了解決軟負載均衡的缺點,我們使用了Nginx進行負載均衡的輪詢算法,但Nginx主要在我們項目還是實現(xiàn)反向代理,就是可以防止外網(wǎng)對內(nèi)網(wǎng)服務(wù)器的惡性攻擊、緩存以減少服務(wù)器的壓力和訪問安全控制?;A(chǔ)模塊就有后臺管理,商品詳情,訂單,支付,物流情況,庫存服務(wù)。然后SpringBoot整合Thymeleaf模塊技術(shù)開發(fā)項目商品詳情模塊,easyUI開發(fā)后臺管理項目。至于我負責(zé)的兩個模塊呢,就是后臺管理和商品詳情,其中呢使用了sku和spu的數(shù)據(jù)表結(jié)構(gòu)進行增刪改查,spu就好比我們要買一臺Mate20,但是我們沒有選擇它是什么配置,那么關(guān)于詳細的配置就是sku了,就是我要買一臺Mate20,黑色,內(nèi)存是128G的。商品詳情和商品列表模塊使用Nginx實現(xiàn)集群,使用Redis解決應(yīng)用服務(wù)器的cpu和內(nèi)存壓力,減少io的讀操作,減輕io的壓力,使用分布式鎖防止Redis緩存擊穿。其中Redis的作用我是覺得挺大的,因為他可以防止過多的用戶去直接訪問我們的數(shù)據(jù)庫,當(dāng)然,Redis也會在高并發(fā)的時候宕機,在使用Redis做緩存的時候,我們使用Redis持久化功能,防止Redis宕機后數(shù)據(jù)丟失,如果Redis宕機了,用戶就會大量的去訪問數(shù)據(jù)庫,從而我們數(shù)據(jù)庫也會崩潰吧。這個時候我們就用了一個分布式鎖,用戶需要獲得一個鎖才能訪問我們的數(shù)據(jù)庫,當(dāng)然啦,并不只是只有一個鎖,而是鎖的數(shù)量是有限的,當(dāng)一位用戶查完了數(shù)據(jù)之后,鎖就會釋放,給下位用戶,這也就是服務(wù)降降級。沒有獲得鎖的用戶,頁面就一直刷新直到自己拿到鎖為止。redis提供了持久化功能——RDB和AOF。通俗的講就是將內(nèi)存中的數(shù)據(jù)寫入硬盤中。在實際應(yīng)用中,用戶如果要查詢商品的話呢,首先回到Redis緩存里面找的,如果找不到,就會到數(shù)據(jù)庫里面找,然后緩存到Redis中,那么下一次或者下一個用戶需要查找這個數(shù)據(jù)就不必到數(shù)據(jù)庫中查找了!然后我還參與了購物車和訂單模塊的開發(fā)。購物車模塊里面呢,我先和您講下他的業(yè)務(wù)邏輯吧。就像你逛網(wǎng)頁淘寶一樣,在沒有登錄的時候,把東西放入購物車,它是不會和你的賬號里的商品合并的,這個時候,商品就會以cookie的形式,放到你的瀏覽器里面。這個時候如果你想購買這些商品的時候,你就要登錄,這個時候就會使用到單點登錄這一個技術(shù)。用戶跳轉(zhuǎn)到訂單頁面的時候,我們會用攔截器去進行判斷用戶是否已經(jīng)登錄。我們是用cookie中是否有token,如果沒有token的話就跳轉(zhuǎn)到登錄頁面,然后生成token,至于token的生成呢,我們是用本地的IP,用戶的id,保存在map中,還有一個常量,這個我們通常會以項目名稱來命名的。至于為什么要token呢,其實是因為cookie是不太安全的,它很容易被偽造,所以我們就需要token,然后有了token之后,我們用JWT這個鹽值生成最后的token。并把它保存到cookie當(dāng)中。下一次支付的時候我們也還會用到這個token,用一個加密算法再去運算驗證一下就可以了!然后就是合并購物車了。這個的話我所知道的就是將客戶端的cookie復(fù)印一份到緩存中進行修改然后送回客戶端進行覆蓋,再接著就是數(shù)據(jù)庫的修改了。那這個如果登陸了的就直接從數(shù)據(jù)庫中取得數(shù)據(jù)跳到訂單系統(tǒng)了。然后訂單模塊里面,簡單來說就是從購物車中勾選的商品遷移到訂單里面。但是呢訂單模塊其實是會聯(lián)系到另外兩個模塊的,就是庫存和支付。如果你點擊了提交訂單,商品就會在購物車里移除。然后我們提交訂單避免他反復(fù)的提交同一個訂單,就會通過交易碼防止訂單重復(fù)提交。我們會吧tradecode放在緩存里面,以用戶id為key商品的交易為value在Redis里面保存這個交易碼。到最后選好收貨地址,留言之后,提交訂單了,就會用自己的tradecode和在Redis里面通過用戶的id去獲取tradecode進行對比,如果能跳轉(zhuǎn)到支付頁面,那么緩存中的交易碼就會刪除掉。到最后就是支付功能,這一步的話我是不太清楚其中的技術(shù)點了,只知道這個模塊調(diào)用了支付寶的接口和用了消息隊列,異步通知。