到目前為止已經實現了一個基於微服務的,前后端分離(這里我用的jquery做的,並不是真的前后端分離,因為我不會vue和angular所以沒用)的架構。在網關上做了限流、認證、審計、授權等安全機制,在前端應用上也做了SSO單點登錄,
現在的架構存在的問題是:
1,在網關做限流。
在網關上做限流是有問題的,比如訂單服務限流是100,庫存服務限流也是100,訂單服務又調了庫存服務。如果網關上給訂單轉了100個請求,給庫存轉了100個請求,訂單又調了庫存,這時候庫存就同時接到了200個請求,庫存服務就可能掛掉了。
2,身份認證。
現在的做法是,經過了一個OAuth流程以后,給前端服務器發了一個令牌。每次前端發請求的時候都會拿着這個令牌,在網關上,會調用認證服務器校驗這個令牌,對應的用戶信息是什么。然后在請求頭里放了username,去調用其他微服務,其他微服務從請求頭里獲取到username,就知道當前用戶是誰了。
存在的問題是
a) 效率低,在網關上每一個請求都要去認證服務器驗令牌。多一次網絡請求的開銷,認證服務器壓力也會變大,同時認證服務器要保證高可用,一旦認證服務器掛了,所有請求就沒法驗令牌了,所有請求就都沒法處理了。
b) 不安全,在代碼里傳遞用戶信息的時候,是在請求頭里加了個用戶名username字段,網關轉發到訂單服務,是在授權過濾器(最后一個過濾器)里,將token里的username字段放在了請求頭,訂單服務從請求頭拿出來username,就認為是誰。這樣其實是不安全的,你說你是張三,訂單服務就認為你是張三,你說你是李四,訂單服務就認為你是李四。【不能根據請求/請求頭里的一個明文的參數來判斷一個用戶是誰的】
c)用戶身份傳遞麻煩。網關調用訂單服務,在請求頭放了一個username,訂單服務再調用庫存服務,需要再將用戶名放入請求參數,庫存服務才能知道用戶是誰,傳遞起來比較麻煩。
3,授權。
授權的問題和限流的問題類似,在網關上,你控制住了只能調用訂單服務,但是訂單服務又調用了庫存服務。你一訪問訂單服務實際上又訪問到了庫存服務了。權限實際上是越權了,沒控制住。
4,服務雪崩
通關網關進行調用的時候,當一個服務出現問題的時候,把其他服務都給帶死了。比如因為某些原因(網絡,數據庫),庫存服務的響應變慢了,就會導致訂單服務也變慢,然后所有調庫存服務的服務都變慢,這堆線程都在這等待着,然后這些線程可能又都是通過網關進來的,所以網關上也有一堆線程等待着,最后導致網關上所有的線程都被占住,導致大量的服務都不可用,但是最根上只是一個庫存服務導致的。這就是服務雪崩。
本章就是要解決這些個問題。
代碼 https://github.com/lhy1234/springcloud-security
歡迎關注個人公眾號一起交流學習: