電商項目 的業務邏輯與相關要點

綜述:

一、在整個項目中,咱們採用的是nginx+tomcat來部署的(面試官可能會問nginx是誰來部署的?如何部署的?nginx的執行流程、優勢),nginx一方面作加載靜態資源的服務器,另外一方面來作反向代理和負載均衡。由於該項目須要在多個環境中運行,咱們利用了nginx的反向代理解決了不一樣環境同系統訪問地址不統一帶來的問題。前端

二、由於整個項目實現的功能較多,因此採用分佈式的架構設計,整個項目包括後臺管理系統、商城首頁系統、搜索系統、商品詳情頁系統、登陸系統、購物車系統、訂單系統等,這樣作的好處是使每一個功能模塊獨立出來,下降了各系統之間的耦合度,增刪一個功能不會影響其餘功能模塊。java

項目介紹:

整個項目採用分佈式的架構設計,包括登陸系統、搜索系統、購物車系統、訂單系統、支付系統等。整個項目採用nginx+tomcat來部署,nginx主要用來作反向代理和負載均衡。主要用redis來作登陸信息緩存,mysql作數據庫。本身參與了登陸系統的開發,包括註冊、單點登陸等功能模塊。mysql

1、單點登陸(SSO系統)

  • 單點登陸是在多個應用系統中,用戶只須要登陸一次就能夠訪問全部相互信任的應用系統。

一、單點登錄是使用redis同步機制,原理以下?

在redis中,用戶能夠經過執行SLAVEOF命令或者設置slaveof選項,讓一個服務器去複製(replicate)另外一個服務器,咱們稱呼被複制的服務器爲主服務器(master),而對主服務器進行復制的服務器則被稱爲從服務器(slave)nginx

二、關於單點登陸加密的辦法?

使用鍵盤鉤子攔截鍵盤輸入內容,防止被其餘工具記錄,相似銀行網銀安全輸入控件。web

爲了保證每次加密的結果的不一樣(防止跨域提交或截取加密信息僞提交),每次加密的key的一部分由服務器端隨機生成,在頁面加載的時候有服務器端生成經過頁面js腳本傳遞給密碼輸入控件,密碼輸入控件根據控件內置的密碼和傳入的密碼進行加密(如DES),服務器端接受後再進行解密獲得原密碼。面試

使用密碼插件能夠有效防止密碼及管件信息在網絡上被截取,致使帳戶密碼丟失,保證服務器至用戶端的安全傳輸。ajax

三、關於單點登陸Session共享的問題

以前實現的登陸和註冊是在同一個tomcat內部完成,而如今系統架構是每個系統都是由一個團隊進行維護,每一個系統都是單獨部署運行一個單獨的tomcat,因此,不能將用戶的登陸信息保存到session中(多個tomcat的session是不能共享的,即session共享問題),因此咱們須要一個單獨的系統來維護用戶的登陸信息。redis

咱們是這樣作以後,用戶去登陸頁面登陸,發送含有用戶信息的請求且會攜帶cookie去服務端數據庫查詢是否有該用戶,若是沒有提示用戶,若是有就把用戶信息保存到redis中,並生成一個token保存到cookie中。spring

注: 當前方式就是搭建共享的Session服務器sql

四、單點登陸系統的基本流程?

當用戶點擊登陸按鈕的時候,用戶輸入用戶名和密碼,檢驗用戶名是否在數據庫中存在,而後用戶名密碼是否正確。這裏的密碼是用了spring的MD5加密技術。當所有成功後,將sessionId(也能夠生成一個UUID)寫入cookie中供前端調用,寫入瀏覽器的cookie中,而後存入到redis中(key是sessionId,value是用戶信息),並設置有效期。

  這裏的cookie是設置了共同的name,因此不管是什麼系統進行登陸,前端頁面都會存有這個name的cookie,也就實現了全部子系統均可以訪問到cookie。

  當用戶登陸其餘子系統時,先從cookie中獲取token信息(也就是sessionId),根據token信息獲取用戶信息。用戶每次與網站的交互,好比查看產品,則刷新一次redis的時間,從新設置有效期,這個效果是經過攔截器來實現的。

  攔截器的攔截,在springMVC.xml中設置攔截的名稱。

登陸流程代碼:先寫cookie再寫redis.

 攔截器重置有效期:

web.xml部署攔截器:

登陸的處理流程:

一、登陸頁面提交用戶名密碼。

二、登陸成功後生成token。Token至關於原來的jsessionid,字符串,可使用uuid。

三、把用戶信息保存到redis。Key就是token,value就是TbUser對象轉換成json。

四、使用String類型保存Session信息。可使用「前綴:token」爲key

五、設置key的過時時間。模擬Session的過時時間。通常半個小時。

六、把token寫入cookie中。

如何判斷是否登陸

1.從cookie中取token

2.取不到未登陸

3.取到token,到redis中查詢token是否過時

4.若是過時,爲登陸狀態

5.沒有過時,登陸狀態

五、單點登陸之跨域問題?

將cookie存在一個公共的站點的頁面上就能夠了,這裏咱們管那個站點叫主站S。

  環境1:a.xxx.com須要跟b.xxx.com實現跨域,這種比較簡單,只須要設置cookie的域名關聯域就能夠了 cookie.Domain = "xxx.com",這樣兩個域名間的cookie就能夠互相訪問,實現跨域。【項目中使用的這種環境】

  環境2:a.aaa.com須要跟b.bbb.com實現跨域,這種不一樣域名的狀況下,想要實現就必須換種方式.

  在這裏我將引入第三者,s.sss.com這個站點,就是某個瀏覽器同時打開了這3個站點,咱們訪問A站點,先判斷自身是否登陸,若是session爲空,就重定向到S站點,判斷S站點上面是否有cookie,若是S站點上面也沒有cookie,則由S站點重定向到A站點的登陸頁.

  這樣咱們就實現了第一步,S站作的的就是隱藏在幕後,子站先判斷本身是否存在session,若是不存在,就重定向到主站S上面去驗證.

  第二步,驗證登陸信息合法性.這裏我引入token(令牌),網上有不少資料,描述token的傳遞,工做方式是這樣,A登陸成功,保存自身的session,重定向到S,S在本身站點保存一個session跟cookie,session保存token對象{tokenID,userName,startTime,endTime},cookie保存tokenID,tokenID是一個Guid,把token對象緩存在集合裏面,另起一個線程,根據endTime(過時時間)來按期清理集合列表,重定向到A的時候再將tokenID傳遞過去,拿到tokenID後,進入驗證環節,S站有提供一個接口,根據tokenID獲取token對象,若是獲取到對象,且沒有失效,則tokenID合法,跳入index頁面.狀況2,A登陸,直接打開B,這時候B自身沒有session,會主動請求主站,主站會返回cookieID(S站存在客戶端的cookie),這個時候再走驗證環節,若是經過,則B根據token對象建立自身的session,再跳入index。

六、單點登陸具體實現了什麼功能?

  •     去登錄頁面
  •     提交登錄頁面
  •     用戶名、密碼、驗證碼的校驗
  •     錯誤信息的回顯
  •     保存用戶到Session中
  •     重定向到登錄以前的訪問頁面
  •     Ajax跨域判斷用戶是否登錄

2、後臺管理模塊

主要實現商品管理和商品規格參數管理,對商品和商品規格進行CRUD操做。在實現前臺調用後臺數據時,爲了實現系統間的調用,便使用了HttpClient技術來實現此功能,在後臺提供了須要調用的接口。(HttpClient介紹、工做原理、優缺點)。若是在後臺對商品進行操做,爲了使前臺數據與後臺數據實現同步,咱們使用了ActiveMQ消息隊列機制實現商品同步功能(ActiveMQ介紹、工做原理、優缺點)。

3、購物車模塊

咱們考慮了會員在未登陸和登陸兩種狀況下把商品加入購物車,後臺如何該保存商品信息。

【1】購物車實現邏輯

在用戶商品詳情頁點擊加入購物車的時候,咱們用了登陸攔截器來判斷用戶是否登陸。若是沒有登陸,將商品信息保存到cookie中,當用戶登陸後,再把商品持久到數據庫中;可是考慮到cookie儲存大小(4k)的問題,還有當cookie儲存的數據越多就會影響響應速度,咱們決定使用redis來緩存用戶在未登陸狀態下的商品信息(redis介紹、原理、優缺點),在redis中設置緩存生存時間(如何作到的?),若是用戶在規定時間內沒有登陸,數據便會自動刪除。若是用戶在規定時間內登陸了,便會經過ActiveMQ消息隊列機制將數據同步到數據庫中。

【2】購物車的實現邏輯

  • 實現購車商品數據同步

一、要求用戶登陸。

二、把購物車商品列表保存到數據庫中。推薦使用redis。

三、Key:用戶id,value:購車商品列表。推薦使用hash,hash的field:商品id,value:商品信息。

四、在用戶未登陸狀況下寫cookie。當用戶登陸後,訪問購物車列表時,

a)把cookie中的數據同步到redis。

b)把cookie中的數據刪除

c)展現購物車列表時以redis爲準。

d)若是redis中有數據cookie中也有數據,須要作數據合併。相同商品數量相加,不一樣商品添加一個新商品。

五、若是用戶登陸狀態,展現購物車列表以redis爲準。若是未登陸,以cookie爲準。

【3】購物車能放多少數據?

購物車放99件,同一家拍貨最多50件不一樣物品一單,多出從新拍。主要是爲了防止部分買家無限制囤貨以及保障網站的正常運行,以免對購物車對買家以及網站運行形成不利影響。

4、首頁功能模塊的優化

項目中首頁的大廣告和商品類目這些不須要常常修改的數據,若是用戶每次刷新頁面的時候都要去數據庫中查詢,這樣會浪費資源和增長數據庫的壓力。

像解決思路:

因此咱們想當把這些數據添加到一個緩存中,用戶去訪問的時候,先去緩存中命中,若是命中失敗,再去數據庫中查詢,而後把查詢到的數據添加到緩存中。

具體方案:

目前比較主流的緩存技術有Redis和Memcached,單純從緩存命中的角度來講,Memcached要高一些,可Redis和Memcache的差距其實並不大,但Redis提供的功能更增強大一些,讀寫速度也很快。因此咱們選用了Redis來緩存數據。

redis把數據以key—value的形式緩存到內存中,並提供了多種數據存儲類型(String、Hash、list、Set、SortedSet),還自身提供了持久化功能(2種:RDB、AOF),還能夠把數據備份到磁盤中(redis的SAVE命令用於建立當前 redis數據庫的備份),防止redis宕機時的數據丟失。(會週期性的把更新的數據寫入磁盤或者把修改操做寫入追加的記錄文件,而且在此基礎上實現了master-slave(主從)同步)。咱們使用的是spring與redis的java的客戶端jedis進行整合,能夠利用jedis作分片式集羣,解決了redis內存受限的問題。

5、分佈式系統的管理

【1】管理系統的多模塊調用

在後臺管理系統中採用了Maven的多模塊化的管理,其中採用了水平切分的方式(垂直與水平劃分的區別:垂直:功能模塊明確,層次不夠清晰,代碼重用性差。水平:層次清晰,代碼重用性高,易於獨立維護。),將各層分層開發,這樣作的好處是代碼重用性高,層次清晰,易於獨立維護。系統內部接口調用採用Httpclient(Dubbo),接口提供端採用RESTful風格的接口定義(一種軟件架構風格,設計風格而不是標準,只是提供了一組設計原則和約束條件)

【2】系統之間的服務調用:

系統之間的通知機制採用MQ的方式,使用ActiveMQ的實現,使用了ActiveMQ的消息訂閱模式的消息機;

【3】關於部署:

採用了nginx+tomcat的模式,其中nginx的做用一方面是作反向代理、負載均衡、另外一方面是作圖片等靜態資源的服務器。

6、支付模塊

【1】短信支付驗證用到是哪一家的?

使用網易雲信提供的短信發送功能。

【2】支付寶支付有多少種支付?

7、跨域請求的問題

一、如何解決了瀏覽器訪問當前頁面去加載後臺系統數據出現的跨域問題

由於項目是採用分佈式架構設計的,各模塊之間是相互獨立的,而各模塊的訪問路徑又是不一樣的,因此當跨域請求數據的時候會遇到跨域受限的問題。好比當用戶首次訪問該網站首頁時,首頁頁面會異步請求後臺管理系統加載商品的類目,這是就會出現跨域受限的問題,之前開發時,若是在本模塊內,咱們是經過ajax異步請求數據的,但ajax不支持跨域,因此用ajax沒法解決跨域請求數據的問題。

二、瀏覽器跨域問題的解決方法

跨域是指從一個域名的網頁去請求另外一個域名的資源。瀏覽器出於安全的考慮,不容許不一樣源的請求

JSONP解決AJAX跨域問題:

JSONP是服務器與客戶端跨源通訊的經常使用方法。最大特色就是簡單適用,老式瀏覽器所有支持,服務器改造很是小。

它的基本思想是,網頁經過添加一個<script>元素,向服務器請求JSON數據,這種作法不受同源政策限制;服務器收到請求後,將數據放在一個指定名字的回調函數裏傳回來。

咱們可使用jsonp來解決這個問題的。jsonp經過script標籤的src能夠跨域請求的特性,加載資源,將加載的資源(經過一個方法名將數據進行包裹)當作是js腳本解析,定義一個回調函數,獲取傳入的數據。咱們使用jsonp是由於jsonp的兼容性比較好,而且在請求完畢後能夠經過callback的方式回傳結果。但jsonp有一個缺點是隻支持get請求而不支持post等其餘類型的http請求。

三、其餘系統該如何調用後臺系統的數據?

咱們能夠發送http請求來訪問後臺數據,咱們想到的是使用HttpClient(Dubbo)來解決此問題,由於HttpClient可使用java代碼模擬瀏覽器發送Http請求。

向外拋出一個接口,執行過程是:

  1. 建立HttpClient對象;
  2. 構建請求對象post、get請求;
  3. 若是有參數,就去構造請求參數,get使用URIBuilder去構造請求參數,post構建表單實體,把表單實體放入到post請求對象中。
  4. 執行請求,而且接受響應;
  5. 處理響應結果;

釋放鏈接。不管執行方法是否成功,都必須釋放鏈接。

 

8、忘記密碼找回密碼的流程?

在註冊的時候會設置找回密碼的問題和答案,在非登陸狀態忘記密碼後,須要經過回答問題和答案找回密碼。

根據用戶名找到用戶設置的問題,而後回答完問題後,生成一個UUID,緩存在redis中設置有效期,並返回這個UUID。

而後前端將這個UUID和新密碼傳入重置密碼的函數,將傳入的UUID和以前緩存在redis中的UUID進行比較,若是相同,則對新密碼進行md5加密後更新到數據庫中。

9、爲何要選用redis?

因爲每一個系統都單獨部署運行一個單獨的tomcat,因此,不能將用戶的登陸信息保存到session中(多個tomcat的session不共享),因此選用redis來緩存登陸信息,當用戶登陸時,將用戶登陸信息保存到redis中,並生成一個token保存到cookie中

10、前端是怎麼訪問圖片呢?是直接訪問圖片服務器?仍是訪問後臺?

前端是獲取後臺傳遞的圖片地址,實現圖片訪問的。只須要知道圖片的網絡地址就能夠訪問到圖片了。

11、七牛雲和fastdfs有什麼區別?在集成過程當中有什麼要注意的嗎?

七牛雲具備 高併發、高可用、易擴展、低成本的優勢,而FastDFS的成本相對較高。

·  上傳憑證:上傳文件的時候,須要把uploadToken經過http post傳給七牛服務器才能完成身份驗證。

·  管理:如音視頻轉碼,視頻加水印,持久化處理等操做時,須要在調用api接口是,在http header 里加入Authorization : QBox AccessToken

·  下載:若是空間爲私有訪問時,下載文件須要下載憑證,就是在http get url 後面加入token參數

十二 、電商項目中是如何解決高併發和高可用的?

1.頁面靜態化

2.fastDFS圖片服務器

3.數據緩存服務器

4.數據庫集羣、庫表散列(數據庫的各類優化、數據庫的拆分)

5.負載均衡

相關文章
相關標籤/搜索