自從開始工作以來,每天都會遇到各種技術名詞,由於非計算機專業科班出身,很多詞彙看的一頭霧水。這就看一篇博客收集整理一下。久而久之就都會了
自從開始工作以來,每天都會遇到各種技術名詞,由於非計算機專業科班出身,很多詞彙看的一頭霧水。這就看一篇博客收集整理一下。久而久之就都會了
token,session,cookie 相關#
一、我們先解釋一下他的含義:
1、Token 的引入:Token 是在客戶端頻繁向服務端請求數據,服務端頻繁的去數據庫查詢用戶名和密碼並進行對比,判斷用戶名和密碼正確與否,並作出相應提示,在這樣的背景下,Token 便應運而生。
2、Token 的定義:Token 是服務端生成的一串字符串,以作客戶端進行請求的一個令牌,當第一次登錄後,服務器生成一個 Token 便將此 Token 返回給客戶端,以後客戶端只需帶上這個 Token 前來請求數據即可,無需再次帶上用戶名和密碼。
3、使用 Token 的目的:Token 的目的是為了減輕服務器的壓力,減少頻繁的查詢數據庫,使服務器更加健壯。
了解了Token的意義後,我們就更明確的知道為什麼要用他了。
二、如何使用Token?
這是本文的重點,在這裡我就介紹常用的兩種方式。
1、用設備號 / 設備 mac 地址作為 Token(推薦)
客戶端:客戶端在登錄的時候獲取設備的設備號/mac地址,並將其作為參數傳遞到服務端。
服務端:服務端接收到該參數後,便用一個變量來接收同時將其作為Token保存在數據庫,並將該Token設置到session中,客戶端每次請求的時候都要統一攔截,並將客戶端傳遞的token和服務器端session中的token進行對比,如果相同則放行,不同則拒絕。
分析:此刻客戶端和服務器端就統一了一個唯一的標識 Token,而且保證了每一個設備擁有了一個唯一的會話。該方法的缺點是客戶端需要帶設備號 /mac 地址作為參數傳遞,而且服務器端還需要保存;優點是客戶端不需重新登錄,只要登錄一次以後一直可以使用,至於超時的問題是由服務器這邊來處理,如何處理?若服務器的 Token 超時後,服務器只需將客戶端傳遞的 Token 向數據庫中查詢,同時並賦值給變量 Token,如此,Token 的超時又重新計時。
2、用 session 值作為 Token
客戶端:客戶端只需攜帶用戶名和密碼登錄即可。
客戶端:客戶端接收到用戶名和密碼後並判斷,如果正確了就將本地獲取sessionID作為Token返回給客戶端,客戶端以後只需帶上請求數據即可。
分析:這種方式使用的好處是方便,不用存儲數據,但是缺點就是當 session 過期後,客戶端必須重新登錄才能進行訪問數據。
三、使用過程中出現的問題以及解決方案?
剛才我們輕鬆介紹了 Token 的兩種使用方式,但是在使用過程中我們還出現各種問題,Token 第一種方法中我們隱藏了一個在網絡不好或者並發請求時會導致多次重複提交數據的問題。
該問題的解決方案:將session和Token套用,如此便可解決,如何套用呢?請看這段解釋:
session 是一個在單個操作人員整個操作過程中,與服務器端保持通信的唯一識別信息,在同一操作人員的多次請求當中,session 始終保證是同一對象,
而不是多個對象,因為可以對其加鎖。當同一操作人員多個請求進入時,可以通過 session 限制只能單向通行。本文正是通過使用 session 以及在 session
中加入 token,來驗證同一操作人員是否進行了並發重複的請求,在最後一個請求到來時,使用 session 中的 token 驗證請求中的 token 是否一致,當不一致
時,被認為是重複提交,將不允許通過。
這就是解決重複提交的方案。
四、session 和 token 和 cookie
什麼是 session 認證?
http 協議是一無狀態協議,所以如果用戶向後台應用提供了用戶名和密碼來進行認證,下一次請求時,用戶還是要帶上用戶名和密碼進行用戶認證。為了使後台應用能識別是哪些用戶發出的請求,只能在後台服務器存儲一份用戶登錄信息,這份信息也會在響應前端請求時返回給瀏覽器(前端),前端將其保存為 cookie,下次請求時前端發送給後端應用,後端應用就可以識別這個請求是來自哪個用戶了,這就是傳統的 session 認證
session 認證的過程是怎樣的?
瀏覽器第一次訪問服務器,服務器會創建一個 session,然後同時為該 session 生成一個唯一的會話的 key, 也就是 sessionid,然後,將 sessionid 及對應的 session 分別作為 key 和 value 保存到緩存中,也可以持久化到數據庫中,然後服務器再把 sessionid,以 cookie 的形式發送給客戶端。這樣瀏覽器下次再訪問時,會直接帶著 cookie 中的 sessionid。然後服務器根據 sessionid 找到對應的 session 進行匹配;
還有一種是瀏覽器禁用了 cookie 或不支持 cookie,這種可以通過 URL 重寫的方式發到服務器;
什麼是 token 認證?
token 的意思是 “令牌”,是服務端生成的一串字符串,作為客戶端進行請求的一個標識。
當用戶第一次登錄後,服務器生成一個 token 並將此 token 返回給客戶端,以後客戶端只需帶上這個 token 前來請求數據即可,無需再次帶上用戶名和密碼。
token 認證與 session 認證的區別?
token 和 session 其實都是為了身份驗證,session 一般翻譯為會話,而 token 更多的時候是翻譯為令牌;
session 服務器會保存一份,可能保存到緩存,文件,數據庫;同樣,session 和 token 都是有過期時間一說,都需要去管理過期時間;
其實 token 與 session 的問題是一種時間與空間的博弈問題,session 是空間換時間,而 token 是時間換空間。兩者的選擇要看具體情況而定。
雖然確實都是 “客戶端記錄,每次訪問攜帶”,但 token 很容易設計為自包含的,也就是說,後端不需要記錄什麼東西,每次一個無狀態請求,每次解密驗證,每次當場得出合法 / 非法的結論。這一切判斷依據,除了固化在 CS 兩端的一些邏輯之外,整個信息是自包含的。這才是真正的無狀態。
而 sessionid ,一般都是一段隨機字符串,需要到後端去檢索 id 的有效性。萬一服務器重啟導致內存里的 session 沒了呢?萬一 redis 服務器掛了呢?
方案 A :我發給你一張身份證,但只是一張寫著身份證號碼的紙片。你每次來辦事,我去後台查一下你的 id 是不是有效。
方案 B :我發給你一張加密的身份證,以後你只要出示這張卡片,我就知道你一定是自己人。
就這麼個差別。
兩種認證方式都是為了解決 Http 協議狀態保持的問題,因為 http 協議是一種無狀態協議。
Rest 服務#
rest 應該具備以下條件:
使用客戶 / 服務器模型 (簡稱 C/S 結構,是一種網絡架構,它把客戶端 (Client) 與服務器 (Server) 區分開來。 每一個客戶端軟件的實例都可以向一個服務器或應用程序服務器發出請求。)
例如前後端分離,頁面和服務不在同一服務器上運行。
層次化的系統
例如一個父系統下有多個子模塊,每個模塊都是獨立的服務。
無狀態
服務端並不會保存有關客戶的任何狀態,也就是說要服務後端服務,就要帶 token 過去。
可緩存
例如服務端通過 token 緩存已登錄過的用戶信息,客戶端請求會帶一個 token 過來,後台服務通過帶過來的 token 在緩存中取出用戶信息,提高效率。
統一的接口
例如,一個項目的所有模塊都整合到一起,all-in-one,打成一個包,多個服務,整合到一個端口下。
如果一個系統滿足了上面所列出的五條約束,那麼該系統就被稱為是 RESTful 的 (一種軟件架構風格、設計風格,而不是標準,只是提供了一組設計原則和約束條件。它主要用於客戶端和服務器交互類的軟件。基於這個風格設計的軟件可以更簡潔,更有層次,更易於實現緩存等機制。)
Eureka#
一、Eureka 簡介
Eureka 是 Netflix 開發的_服務發現框架_,本身是一個基於 REST 的服務,主要用於定位運行在 AWS 域中的中間層服務,以達到負載均衡和中間層服務故障轉移的目的。SpringCloud 將它集成在其子項目 spring-cloud-netflix 中,以實現 SpringCloud 的服務發現功能。
1、Eureka 组件
Eureka 包含兩個組件:Eureka Server 和 Eureka Client。
1.1 Eureka Server
Eureka Server 提供服務註冊服務,各個節點啟動後,會在 Eureka Server 中進行註冊,這樣 Eureka Server 中的服務註冊表中將會存儲所有可用服務節點的信息,服務節點的信息可以在界面中直觀的看到。
Eureka Server 本身也是一個服務,默認情況下會自動註冊到 Eureka 註冊中心。
如果搭建單機版的 Eureka Server 註冊中心,則需要配置取消 Eureka Server 的自動註冊邏輯。畢竟當前服務註冊到當前服務代表的註冊中心中是一個說不通的邏輯。
Eureka Server 通過 Register、Get、Renew 等接口提供服務的註冊、發現和心跳檢測等服務。
2.1 Eureka Client
Eureka Client 是一個 java 客戶端,用於簡化與 Eureka Server 的交互,客戶端同時也具備一個內置的、使用輪詢 (round-robin) 負載算法的負載均衡器。在應用啟動後,將會向 Eureka Server 發送心跳,默認周期為 30 秒,如果 Eureka Server 在多個心跳周期內沒有接收到某個節點的心跳,Eureka Server 將會從服務註冊表中把這個服務節點移除 (默認 90 秒)。
Eureka Client 分為兩個角色,分別是:Application Service (Service Provider) 和 Application Client (Service Consumer)
2.1.1 Application Service
服務提供方,是註冊到 Eureka Server 中的服務。
2.1.2 Application Client
服務消費方,通過 Eureka Server 發現服務,並消費。
在這裡,Application Service 和 Application Client 不是絕對上的定義,因為 Provider 在提供服務的同時,也可以消費其他 Provider 提供的服務;Consumer 在消費服務的同時,也可以提供對外服務。
SpringMVC Spring boot Spring Cloud#
spring boot 只是一個配置工具,整合工具,輔助工具.
springmvc 是框架,項目中實際運行的代碼
Spring 框架就像一個家族,有眾多衍生產品例如 boot、security、jpa 等等。但他們的基礎都是 Spring 的 ioc 和 aop,ioc 提供了依賴注入的容器, aop 解決了面向橫切面的編程,然後在此兩者的基礎上實現了其他延伸產品的高級功能。
Spring MVC 提供了一種輕度耦合的方式來開發 web 應用。它是 Spring 的一個模塊,是一個 web 框架。通過 Dispatcher Servlet, ModelAndView 和 View Resolver,開發 web 應用變得很容易。解決的問題領域是網站應用程序或者服務開發 ——URL 路由、Session、模板引擎、靜態 Web 資源等等。
Spring Boot 實現了自動配置,降低了項目搭建的複雜度。它主要是為了解決使用 Spring 框架需要進行大量的配置太麻煩的問題,所以它並不是用來替代 Spring 的解決方案,而是和 Spring 框架緊密結合用於提升 Spring 開發者體驗的工具。同時它集成了大量常用的第三方庫配置 (例如 Jackson, JDBC, Mongo, Redis, Mail 等等),Spring Boot 應用中這些第三方庫幾乎可以零配置的開箱即用 (out-of-the-box)。
Spring Boot 只是承載者,輔助你簡化項目搭建過程的。如果承載的是 WEB 項目,使用 Spring MVC 作為 MVC 框架,那麼工作流程和你上面描述的是完全一樣的,因為這部分工作是 Spring MVC 做的而不是 Spring Boot。
對使用者來說,換用 Spring Boot 以後,項目初始化方法變了,配置文件變了,另外就是不需要單獨安裝 Tomcat 這類容器服務器了,maven 打出 jar 包直接跑起來就是個網站,但你最核心的業務邏輯實現與業務流程實現沒有任何變化。
總結:Spring 最初利用 “工廠模式”(DI)和 “代理模式”(AOP)解耦應用組件。大家覺得挺好用,於是按照這種模式搞了一個 MVC 框架(一些用 Spring 解耦的組件),用開發 web 應用( SpringMVC )。然後發現每次開發都寫很多樣板代碼,為了簡化工作流程,於是開發出了一些 “懶人整合包”(starter),這套就是 Spring Boot。
所以,用最簡練的語言概括就是:
Spring 是一個 “引擎”;
Spring MVC 是基於 Spring 的一個 MVC 框架;
Spring Boot 是基於 Spring4 的條件註冊的一套快速開發整合包。
SpringCloud 是一套目前完整的微服務框架,它是一系列框架的有序集合。它只是將目前各家公司開發的比較成熟、經得起實際考驗的服務框架組合起來,通過 SpringBoot 風格進行再封裝屏蔽掉了複雜的配置和實現原理,最終給開發者留出了一套簡單易懂、易部署和易維護的分佈式系統開發工具包。它利用 Spring Boot 的開發便利性巧妙地簡化了分佈式系統基礎設施的開發,如服務發現註冊、配置中心、消息總線、負載均衡、斷路器、數據監控等,都可以用 SpringBoot 的開發風格做到一鍵啟動和部署。
什麼是 token
Spring 基礎知識詳解
Eureka 介紹
feign 設計原理
Spring boot 和 Spring Cloud
HTTP 就是這麼簡單
消息隊列介紹
動態代理詳細分析
CAS#
cas 是 compare and swap 的簡稱,從字面上理解就是比較並更新,簡單來說:從某一內存上取值 V,和預期值 A 進行比較,如果內存值 V 和預期值 A 的結果相等,那麼我們就把新值 B 更新到內存,如果不相等,那麼就重複上述操作直到成功為止。CAS 就是一種樂觀鎖,而 synchronized 就是悲觀鎖
IO 多路復用#
題外話:我們現在要仔細的說一說 I/O 多路復用機制,因為這個說法實在是太通俗了,通俗到一般人都不懂是什麼意思。博主打一個比方:小曲在 S 城開了一家快遞店,負責同城快送服務。小曲因為資金限制,雇佣了一批快遞員,然後小曲發現資金不夠了,只夠買一輛車送快遞。
經營方式一
客戶每送來一份快遞,小曲就讓一個快遞員盯著,然後快遞員開車去送快遞。慢慢的小曲就發現了這種經營方式存在下述問題,幾十個快遞員基本上時間都花在了搶車上了,大部分快遞員都處在閒置狀態,誰搶到了車,誰就能去送快遞隨著快遞的增多,快遞員也越來越多,小曲發現快遞店裡越來越擠,沒辦法雇佣新的快遞員了快遞員之間的協調很花時間綜合上述缺點,小曲痛定思痛,提出了下面的經營方式經營方式二
小曲只雇佣一個快遞員。然後呢,客戶送來的快遞,小曲按送達地點標註好,然後依次放在一個地方。最後,該快遞員依次的去取快遞,一次拿一個,然後開著車去送快遞,送好了就回來拿下一個快遞。
對比
上述兩種經營方式對比,是不是明顯覺得第二種,效率更高,更好呢。在上述比喻中:
每個快遞員 ——————> 每個線程
每個快遞 ——————–> 每個 socket (I/O 流)
快遞的送達地點 ————–>socket 的不同狀態
客戶送快遞請求 ————–> 來自客戶端的請求
小曲的經營方式 ————–> 服務端運行的代碼
一輛車 ———————->CPU 的核數
於是我們有如下結論
1、經營方式一就是傳統的並發模型,每個 I/O 流 (快遞) 都有一個新的線程 (快遞員) 管理。
2、經營方式二就是 I/O 多路復用。只有單個線程 (一個快遞員),通過跟蹤每個 I/O 流的狀態 (每個快遞的送達地點),來管理多個 I/O 流。