【雷豐陽-谷粒商城 】【分布式高級篇-微服務架構篇】【19】認證服務03—分布式下Session共享問題


持續學習&持續更新中…

守破離


【雷豐陽-谷粒商城 】【分布式高級篇-微服務架構篇】【19】分布式下Session共享問題

  • session原理
  • 分布式下session共享問題
  • Session共享問題解決—session復制
  • Session共享問題解決—客戶端存儲
  • Session共享問題解決—hash一致性
  • Session共享問題解決—統一存儲
  • Session共享問題解決—不同服務,子域session共享
  • 手動設置Cookie,手動拿取Cookie
  • 整合SpringSession
  • SpringSession核心原理
  • 參考

session原理

在這里插入圖片描述

問題:不能跨不同域名共享

在這里插入圖片描述

分布式下session共享問題

在這里插入圖片描述

在這里插入圖片描述

Session共享問題解決—session復制

在這里插入圖片描述

優點 :web-server(Tomcat)原生支持,只需要修改配置 文件

缺點 :

  • session同步需要數據傳輸,占用大量網絡帶寬,降低了服務器群的業務處理能力
  • 任意一臺web-server保存的數據都是所有web- server的session總和,受到內存限制無法水平擴展更多的web-server
  • 大型分布式集群情況下,由于所有web-server都全量保存數據,所以此方案不可取。

Session共享問題解決—客戶端存儲

在這里插入圖片描述

優點

  • 服務器不需存儲session,用戶保存自己的 session 信息到 cookie 中。節省服務端資源

缺點

  • 都是缺點,這只是一種思路。
  • 具體如下:
  • 每次http請求,攜帶用戶在cookie中的完整信息, 浪費網絡帶寬
  • session數據放在cookie中,cookie有長度限制 4 K,不能保存大量信息
  • session數據放在cookie中,存在泄漏、篡改、 竊取等安全隱患
  • 這種方式不會使用。

Session共享問題解決—hash一致性

在這里插入圖片描述

優點:

  • 只需要改nginx配置,不需要修改應用代碼
  • 負載均衡,只要hash屬性的值分布是均勻的,多臺 web-server的負載是均衡的
  • 可以支持web-server水平擴展(session同步法是不行的,受內存限制)

缺點:

  • session還是存在web-server中的,所以web-server重啟可能導致部分session丟失,影響業務,如部分用戶需要重新登錄
  • 如果web-server水平擴展,rehash 后session 重新分布, 也會有一部分用戶路由不到正確的session
  • 但是以上缺點問題也不是很大,因為session本來都是有有效期的。所以這兩種反向代理的方式可以使用

Session共享問題解決—統一存儲

在這里插入圖片描述

優點:

  • 沒有安全隱患
  • 可以水平擴展,數據庫/緩存水平切分即可
  • web-server重啟或者擴容都不會有 session 丟失

不足:

  • 增加了一次網絡調用,并且需要修改應用代碼;如將所有的getSession方法替換為從Redis查數據的方式。
  • redis獲取數據比內存慢很多
  • 上面缺點可以用SpringSession完美解決

Session共享問題解決—不同服務,子域session共享

jsessionid這個cookie默認是當前系統域名的。當我們分拆服務,不同域名部署的時候,我們可以使用如下解決方案;

放大Cookie作用域

在這里插入圖片描述

手動設置Cookie,手動拿取Cookie

gulimall-auth:OAuth2Controller

    @GetMapping("/oauth2.0/weibo/success")public String weibo(@RequestParam("code") String code, HttpSession session,HttpServletResponse httpServletResponse) throws Exception {Map<String, String> headers = new HashMap<>();Map<String, String> bodys = new HashMap<>();bodys.put("client_id", "3276999101");bodys.put("client_secret", "452bbefff4680ac8554b97799a8c12cb");bodys.put("grant_type", "authorization_code");bodys.put("redirect_uri", "http://auth.gulimall.com/oauth2.0/weibo/success");bodys.put("code", code);//1、根據code換取accessToken;HttpResponse response = HttpUtils.doPost("https://api.weibo.com", "/oauth2/access_token", headers, null, bodys);if (response.getStatusLine().getStatusCode() == 200) {//2、獲取到了 socialUserAccessToken 進行處理String json = EntityUtils.toString(response.getEntity());SocialUserAccessToken socialUserAccessToken = JSON.parseObject(json, SocialUserAccessToken.class);
//            String uid = socialUserAccessToken.getUid();// 通過uid就知道當前是哪個社交用戶//1)、當前用戶如果是第一次進網站,進行自動注冊(為當前社交用戶生成一個會員信息賬號,以后這個社交賬號就對應指定的會員賬號)R r = memberFeignService.socialLogin(socialUserAccessToken);if (r.getCode() == BizCodeEnume.SUCCESS.getCode()) {//登錄或者注冊這個社交用戶//2)、登錄成功就跳回首頁/*** 手動設置Cookie*/MemberRespVo loginUser = r.getData(new TypeReference<MemberRespVo>() {});stringRedisTemplate.opsForValue().set("loginUser", JSON.toJSONString(loginUser));Cookie cookie = new Cookie("GULIMALL", "loginUser");cookie.setDomain("gulimall.com");cookie.setMaxAge(24 * 60 * 60);cookie.setPath("/");httpServletResponse.addCookie(cookie);session.setAttribute("loginUser", loginUser);return "redirect:http://gulimall.com";}}return "redirect:http://auth.gulimall.com/login.html";}

gulimall-product:IndexController

    @GetMapping({"/", "/index.html"})public String indexPage(Model model, HttpServletRequest httpServletRequest, HttpSession session) {/*** 手動獲取Cookie*/Cookie[] cookies = httpServletRequest.getCookies();if (null != cookies && cookies.length > 0) {for (Cookie cookie : cookies) {if (cookie.getName().equalsIgnoreCase("GULIMALL")) {String loginUserKey = cookie.getValue();String json = stringRedisTemplate.opsForValue().get(loginUserKey);MemberRespVo loginUser = JSON.parseObject(json, new TypeReference<MemberRespVo>(){});session.setAttribute("loginUser", loginUser);}}}List<CategoryEntity> categorys = categoryService.listLevel1Categorys();model.addAttribute("categorys", categorys);return "index";}

@Controller
public class LoginController {@GetMapping("/login.html")public String loginPage() {if(stringRedisTemplate.opsForValue().get("loginUser") != null) return "redirect:http://gulimall.com";return "login";}
}

整合SpringSession

<!-- 1 整合SpringSession完成session共享問題 -->
<dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-data-redis</artifactId>
</dependency>
# 2 整合SpringSession
spring.session.store-type=redis
#server.servlet.session.timeout=60m
# 3 配置Redis的連接信息(之前配過)
#spring.redis.host=xxx
#spring.redis.port=xxx
#spring.redis.password=xxx
@EnableRedisHttpSession // 4 整合Redis作為session存儲
// 5 使用SpringSession【跟以前使用session的寫法一樣】
//第一次使用session;命令瀏覽器保存卡號。JSESSIONID這個cookie;
//以后瀏覽器訪問哪個網站就會帶上這個網站的cookie;
//子域之間; gulimall.com  auth.gulimall.com  order.gulimall.com
//應該做到:發卡的時候(指定域名為父域名),那么,即使是子域系統發的卡,也能讓父域直接使用。
// 1、默認發的令牌。session=xxxxxxx。作用域:當前域;(SpringSession默認沒有解決子域session共享問題)
// 2、使用JSON的序列化方式來序列化對象數據到redis中R r = memberFeignService.socialLogin(socialUserAccessToken);if (r.getCode() == BizCodeEnume.SUCCESS.getCode()) {//登錄或者注冊這個社交用戶//2)、登錄成功就跳回首頁MemberRespVo loginUser = r.getData(new TypeReference<MemberRespVo>() {});session.setAttribute("loginUser", loginUser);
//6 配置序列化 + Cookie domain
// 解決子域session共享問題
@Configuration
public class GulimallSessionConfig {@Beanpublic CookieSerializer cookieSerializer(){DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();cookieSerializer.setDomainName("gulimall.com");cookieSerializer.setCookieName("GULISESSION");
//        cookieSerializer.setCookieMaxAge(); // 默認是瀏覽器的session級別,關閉瀏覽器就失效return cookieSerializer;}@Beanpublic RedisSerializer<Object> springSessionDefaultRedisSerializer() {return new GenericJackson2JsonRedisSerializer();}}
<!-- 7 給其他服務也整合好SpringSession后,直接取session中的數據即可  --><a  th:if="${session.loginUser!=null}">歡迎:[[${session.loginUser==null?'':session.loginUser.nickname}]]</a>
//    登錄頁面@GetMapping("/login.html")public String loginPage(HttpSession session) {
//        if(stringRedisTemplate.opsForValue().get("loginUser") != null) return "redirect:http://gulimall.com";Object attribute = session.getAttribute(AuthServerConstant.LOGIN_USER);if(attribute != null) return "redirect:http://gulimall.com";return "login";}

SpringSession核心原理

/*** SpringSession 核心原理 裝飾者模式;* @EnableRedisHttpSession導入RedisHttpSessionConfiguration配置*      1、給容器中添加了一個組件*          SessionRepository = 》》》【RedisOperationsSessionRepository】==》redis操作session。session的增刪改查封裝類*      2、SessionRepositoryFilter == 》Filter: session'存儲過濾器;每個請求過來都必須經過filter*          1、創建的時候,就自動從容器中獲取到了SessionRepository;*          2、原始的request,response都被包裝。SessionRepositoryRequestWrapper,SessionRepositoryResponseWrapper*          3、以后獲取session。SessionRepositoryRequestWrapper.getSession();*          4、wrappedRequest.getSession();===> SessionRepository 中獲取到的。*自動延期;用戶只要沒有關閉瀏覽器,SpringSession會自動續期,當然,用戶關閉了瀏覽器,redis中的數據也是有過期時間的。*/

在這里插入圖片描述

參考

雷豐陽: Java項目《谷粒商城》Java架構師 | 微服務 | 大型電商項目.


本文完,感謝您的關注支持!


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/40515.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/40515.shtml
英文地址,請注明出處:http://en.pswp.cn/web/40515.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ASUS/華碩飛行堡壘8 FX506L FX706L系列 原廠win10系統 工廠文件 帶F12 ASUS Recovery恢復

華碩工廠文件恢復系統 &#xff0c;安裝結束后帶隱藏分區&#xff0c;一鍵恢復&#xff0c;以及機器所有驅動軟件。 系統版本&#xff1a;Windows10 原廠系統下載網址&#xff1a;http://www.bioxt.cn 需準備一個20G以上u盤進行恢復 請注意&#xff1a;僅支持以上型號專用…

域名、網頁、HTTP概述

目錄 域名 概念 域名空間結構 域名注冊 網頁 概念 網站 主頁 域名 HTTP URL URN URI HTML 超鏈接 發布 HTML HTML的結構 靜態網頁 特點 動態網頁 特點 Web HTTP HTTP方法 GET方法 POST方法 HTTP狀態碼 生產環境下常見的HTTP狀態碼 域名 概念 IP地…

基于.NET開源游戲框架MonoGame實現的開源項目合集

前言 今天分享一些基于.NET開源游戲框架MonoGame實現的開源項目合集。 MonoGame項目介紹 MonoGame是一個簡單而強大的.NET框架&#xff0c;使用C#編程語言可以創建桌面PC、視頻游戲機和移動設備游戲。它已成功用于創建《怒之鐵拳4》、《食肉者》、《超凡蜘蛛俠》、《星露谷物…

【跟我學K8S】45天入門到熟練詳細學習計劃

目錄 一、什么是K8S 核心功能 架構組件 使用場景 二、入門到熟練的學習計劃 第一周&#xff1a;K8s基礎和概念 第二周&#xff1a;核心對象和網絡 第三周&#xff1a;進階使用和管理 第四周&#xff1a;CI/CD集成和監控 第五周&#xff1a;實戰模擬和案例分析 第六周…

XPointer 實例

XPointer 實例 1. 引言 XPointer 是一種用于定位 XML 文檔中特定部分的語言。它是 XLink 的補充,允許用戶在 XML 文檔中創建鏈接,指向文檔中的特定元素、屬性或文本。XPointer 的強大之處在于其精確的定位能力,使得開發者能夠創建更加豐富和動態的 XML 應用。 2. XPointe…

【Spring Boot】spring boot主啟動類_內置服務

1、主啟動類 1.1 定義與功能 Spring Boot的主啟動類是一個特殊的Java類&#xff0c;用于啟動Spring Boot應用程序。該類通常使用SpringBootApplication注解進行標注&#xff0c;這個注解是一個復合注解&#xff0c;包含SpringBootConfiguration、EnableAutoConfiguration和Co…

LRU Cache 雙向鏈表以及STL list實現----面試常考

雙向鏈表版本&#xff1a; #include <bits/stdc.h> using namespace std; struct Node{int key, value;Node* prev;Node* next;Node():key(0), value(0), prev(nullptr), next(nullptr){}Node(int k, int v):key(k), value(v), prev(nullptr), next(nullptr){} }; class…

【IT領域新生必看】Java中的對象創建魔法:小白也能掌握的五種方法

文章目錄 引言為什么需要創建對象&#xff1f;創建對象的五種常見方式1. 使用 new 關鍵字示例&#xff1a; 2. 使用反射示例&#xff1a; 3. 使用克隆示例&#xff1a; 4. 使用序列化和反序列化示例&#xff1a; 5. 使用工廠方法示例&#xff1a; 選擇合適的對象創建方式總結 引…

Spring容器Bean之XML配置方式

一、首先看applicationContext.xml里的配置項bean 我們采用xml配置文件的方式對bean進行聲明和管理&#xff0c;每一個bean標簽都代表著需要被創建的對象并通過property標簽可以為該類注入其他依賴對象&#xff0c;通過這種方式Spring容器就可以成功知道我們需要創建那些bean實…

IPython代碼塊粘貼秘籍:效率與技巧的完美結合

標題&#xff1a;IPython代碼塊粘貼秘籍&#xff1a;效率與技巧的完美結合 在數據科學和Python編程的日常實踐中&#xff0c;經常需要在IPython環境中快速有效地粘貼代碼塊。這個過程雖小&#xff0c;卻對提升工作效率至關重要。本文將詳細介紹如何在IPython中粘貼代碼塊&…

comsol隨機材料參數賦值

comsol隨機材料參數賦值 在comsol中定義外部matlab函數 在comsol中定義外部matlab函數 首選項&#xff0c;安全性&#xff0c;允許 材料中&#xff0c;將楊氏模量更改為變量函數 計算 應力有波動&#xff0c;可見賦值成功 也可以看到賦值的材料參數&#xff1a;

植物大戰僵尸雜交版V2.1+修改器+融合版

植物大戰僵尸雜交版v2.1 新增新植物&#xff0c;全新模式與玩法&#xff01; 內含窗口放大工具與修改器 主播同款游戲&#xff0c;下載使用即可&#xff01; 鏈接: https://pan.baidu.com/s/1znjbqgBSdqTJWZLBOhe5hA?pwdj6ra 提取碼: j6ra

vulnhub--IMF

環境 攻擊機&#xff1a;192.168.96.4 靶機&#xff1a;ip未知 主機探測 確定靶機ip為32的主機 端口掃描 訪問80端口 外圍打點 在contact.php頁面源碼中找到了flag1 之后沒啥突破 但查看網絡后發現contact.php頁面請求的三個js文件的文件名很有特點&#xff0c;猜測是base64編碼…

模型優化調參利器貝葉斯優化bayesian-optimization實踐

早在之前很多項目尤其是預測類型的項目中&#xff0c;就已經比較廣泛地在實用貝葉斯優化庫了&#xff0c;這是一個非常出色的純python實現的項目&#xff0c;地址在這里&#xff0c;如下所示&#xff1a; 寫這篇文章主要有兩個目的&#xff0c;一方面是覺得這個工具庫挺不錯的值…

零基礎做項目---五子棋對戰---day01

創建項目 這里使用阿里云服務器 https://start.aliyun.com/ 勾選 MyBatis Framework (在SQL分類下)MySQL Driver (在SQL分類下)WebSocket (在Messaging分類下)Spring Web (在Web分類下) 項目結構 消息發送機制 按照當前已有的知識&#xff0c;主要是HTTP HTTP自身是難以實現這…

c++ 里如何檢測內存泄露:比如用了 new ,但沒有用 delete

&#xff08;1 方法一&#xff09; 用 MFC 框架的 F5 不帶斷點的調試。可以在輸出窗口提示是否有內存泄露。 &#xff08;2 方法二&#xff09; &#xff0c;在 main 函數中添加如下代碼&#xff0c;用 F5 不帶斷點的調試&#xff1a; int main() {_CrtSetDbgFlag( _CRTDBG_A…

vue.js微商城后臺管理系統

一.需要運行的效果 20240701-231456 二.代碼&#xff08;解析&#xff09; 首先&#xff0c;為項目添加依賴&#xff1a; yarn add element-plus --save yarn vue-router4 --save 新建一個項目包&#xff0c;然后命名為商品管理&#xff0c;在components中新建幾個vue文件。 …

React Hooks 深度解析

Hooks簡介 誕生背景&#xff1a; 在React 16.8之前的版本中&#xff0c;組件主要分為函數組件和類組件兩大類。函數組件簡單輕量&#xff0c;但不支持狀態&#xff08;state&#xff09;和生命周期方法&#xff1b;而類組件雖然功能強大&#xff0c;但編寫和維護起來相對復雜。…

驅動開發系列-如何與硬件通信

目錄 一:概述 二:I/O端口和I/O內存的概念 三:硬件寄存器(I/O寄存器)和內存 四:使用I/O端口 一:概述 驅動程序是軟件與硬件之間的抽象層;因此,它需要與這兩者對話,本文將向你展示驅動程序如何與硬件對話。并介紹I/O端口和I/O內存的概念。 二:I/O端口和I/O…

C++新特性

C新特性主要體現在語法改進和標準庫擴充兩個方面。以下是一些主要的C新特性&#xff1a; 語法改進 統一的初始化方法&#xff1a;C11擴大了用大括號括起的列表&#xff08;初始化列表&#xff09;的使用范圍&#xff0c;使其可用于所有的內置類型和用戶自定義的類型。這種定義…