成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁技術(shù)文章
文章詳情頁

詳解Java分布式系統(tǒng)中session一致性問題

瀏覽:121日期:2022-08-13 18:41:35
業(yè)務(wù)場景

在單機系統(tǒng)中,用戶登陸之后,服務(wù)端會保存用戶的會話信息,只要用戶不退出重新登陸,在一段時間內(nèi)用戶可以一直訪問該網(wǎng)站,無需重復(fù)登陸。用戶的信息存在服務(wù)端的 session 中,session中可以存放服務(wù)端需要的一些用戶信息,例如用戶ID,所屬公司companyId,所屬部門deptId等等。

詳解Java分布式系統(tǒng)中session一致性問題

但是隨著業(yè)務(wù)的發(fā)展,技術(shù)架構(gòu)需要調(diào)整,原來的單機系統(tǒng)逐漸被更換,架構(gòu)由單機擴展到分布式,甚至當(dāng)下流行的微服務(wù)。雖然在用戶端看來系統(tǒng)仍然是一個整體,但在技術(shù)端來說業(yè)務(wù)則被拆分成多個模塊,各個模塊之間相互獨立,甚至不在同一臺物理機器上,模塊之間通過 RPC 進行通信。

詳解Java分布式系統(tǒng)中session一致性問題

那么原來單機只需一份的 session, 如何滿足在多系統(tǒng)的運行下保證會話一致性呢?單獨保存在任何一個系統(tǒng)中都不合適,而且每個單獨模塊系統(tǒng)也可能是分布式形式的,是由集群組成。那么session的分配就更復(fù)雜了。

Redis 實現(xiàn)

針對以上問題,我們可能會從以下幾個方面想到解決的方法,每個服務(wù)端存儲一份,通過同步的方式保證一致性,但是這種方式有個很明顯的缺點:session的同步需要數(shù)據(jù)傳輸,占內(nèi)網(wǎng)帶寬,有時延,網(wǎng)絡(luò)不穩(wěn)定的時候會造成部分系統(tǒng)同步延遲,那么就不能保證 session 一致性。而且所有服務(wù)端都包含所有session數(shù)據(jù),數(shù)據(jù)量受內(nèi)存限制,無法水平擴展。

那么我們是否可以單獨將 session 信息存儲在某一個獨立的介質(zhì)中,介質(zhì)可以是DB也可以是緩存。

考慮到如下業(yè)務(wù):登陸的時候我們經(jīng)常會給用戶一個過期時間(一般移動端常設(shè)置為7天或者一個月甚至更久),到期后用戶需要輸入登陸信息重新登陸,即會話過期。這種到期的設(shè)置我們自然想到了Redis的 key expire功能,所以最終我們可以將Redis引入進來實現(xiàn)我們的這種需求。系統(tǒng)如下圖所示:

詳解Java分布式系統(tǒng)中session一致性問題

我們只需在用戶首次登陸的時候?qū)⒂脩粜畔⒎诺?Token并緩存到 Redis 中,同時設(shè)置一個過期時間,偽代碼如下:

@Overridepublic Map login(UserDto dto) { Map<String, Object> restMap = new HashMap<>();// 校驗登陸信息 User user = checkLoginInfo(dto); //刪除舊的token String token = (String) redisUtils.get(CacheConstants.USER_TOKEN_KEY_COPY + user.getUserName());if (!ObjectUtils.isEmpty(token)) {redisUtils.delete(CacheConstants.USER_TOKEN_KEY_WEB + token); } // 唯一簽名信息 String signStr = user.getCompanyId() + user.getUserName() + dto.getPassword() + DateUtils.now().getTime(); token = MD5Utils.md5(signStr); // 設(shè)置用戶 token redisUtils.setExpiredAt(CacheConstants.USER_TOKEN_KEY_WEB + token, user.getId(), LOGIN_EXPIRED_TIME); //緩存新的token redisUtils.setExpiredAt(CacheConstants.USER_TOKEN_KEY_COPY + user.getUserName(), token, LOGIN_EXPIRED_TIME); dto.setCompanyId(user.getCompanyId()); dto.setId(user.getId()); restMap.put('token', token); restMap.put('userName', user.getUserName()); return restMap;}

那么在系統(tǒng)中如何使用呢,我們可以定義一個攔截器 SessionInterceptor,當(dāng)訪問 web 接口的時候檢驗用戶的 token 信息,判斷用戶是否登陸,未登錄的情況下一些業(yè)務(wù)接口是無法訪問的,以及在登陸的情況下拿到我們需要的用戶信息,如 userId。

public class SessionInterceptor { @Autowired private RedisUtils redisUtils;@Autowired private UserService userService; @Pointcut('execution(* com.jajian.demo.web.*.controller.*.*(..)) && @annotation(org.springframework.web.bind.annotation.RequestMapping)') public void controllerMethodPointcut() { } @Around('controllerMethodPointcut()') public Object Interceptor(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {Signature signature = proceedingJoinPoint.getSignature();MethodSignature methodSignature = (MethodSignature) signature;Method targetMethod = methodSignature.getMethod();if (targetMethod.getDeclaringClass().isAnnotationPresent(NoLogin.class) || targetMethod.isAnnotationPresent(NoLogin.class)) { return proceedingJoinPoint.proceed();}// 從獲取RequestAttributes中獲取HttpServletRequest的信息RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);String token = request.getHeader('token');if(StringUtils.isEmpty(token)){ Log.debug('驗證token', 'token驗證失敗,{}', 'token不存在'); throw new FieldException(Constants.LOGIN_ERROR_CODE, 'login.session.timeout');}Integer userId= (Integer)redisUtils.get(CacheConstants.USER_TOKEN_KEY_WEB + token); if (null == userId) { Log.debug('驗證token', 'token驗證失敗,{}', 'token超時'); throw new FieldException(Constants.LOGIN_ERROR_CODE, 'login.session.timeout');}User user = userService.getById(userId.longValue());if (ObjectUtils.isEmpty(user)){ Log.debug('驗證token', 'token驗證失敗,{}', '用戶信息不存在'); throw new FieldException(Constants.LOGIN_ERROR_CODE, 'login.session.timeout');}if (user.getStatus() == UserStatusEnum.NO.getCode() || user.getDeleteFlag() == DeleteFlagEnum.YES.getCode()){ Log.debug('驗證token', 'token驗證失敗,用戶信息異常 userName : {}, status : {},deleteFlag : {}', user.getUserName(),user.getStatus(), user.getDeleteFlag()); throw new FieldException(Constants.LOGIN_ERROR_CODE, 'login.session.timeout');}return proceedingJoinPoint.proceed(); } }

以上實現(xiàn)方式簡單易用,而且Redis 在分布式系統(tǒng)中的使用率也很高,所以無需額外的技術(shù)引入。可以支持水平擴展,數(shù)據(jù)庫或緩存水平切分即可,服務(wù)端重啟或者擴容都不會有session丟失的情況發(fā)生。

以上就是詳解Java分布式系統(tǒng)中session一致性問題的詳細內(nèi)容,更多關(guān)于Java分布式系統(tǒng)的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標簽: Java
相關(guān)文章:
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
aa亚洲婷婷| 成人免费的视频| 国产成人精品www牛牛影视| 在线亚洲人成电影网站色www| 欧美亚洲国产一区二区三区| 亚洲精品高清在线| 国内久久精品| 日本一区二区三级电影在线观看| 国产成人av福利| 日韩片之四级片| 成人中文字幕电影| 欧美蜜桃一区二区三区| 日本va欧美va欧美va精品| 久久亚洲电影| 免费成人结看片| 欧美亚洲国产一区二区三区va| 蜜臀久久久久久久| 在线观看不卡视频| 美脚の诱脚舐め脚责91 | 极品少妇一区二区三区精品视频| 91久久精品一区二区| 日本伊人色综合网| 色播五月激情综合网| 日韩中文字幕1| 在线观看日韩电影| 久久99热狠狠色一区二区| 欧美日韩在线播放| 国产高清在线观看免费不卡| 欧美mv日韩mv国产网站app| 91污在线观看| 国产精品美女久久久久久久久 | 欧美三电影在线| 久久国产免费看| 日韩一级高清毛片| 91在线播放网址| 中文字幕日韩欧美一区二区三区| 日韩视频免费| 亚洲国产裸拍裸体视频在线观看乱了 | 国产精品一卡二卡在线观看| 日韩一区和二区| 欧美一区二区三区久久精品茉莉花| 国产欧美日韩不卡免费| 一本色道精品久久一区二区三区| 午夜欧美电影在线观看| 欧美日韩情趣电影| 成人免费视频一区| 国产精品乱码一区二三区小蝌蚪| 亚洲免费观看| 久久99久久精品欧美| 日韩三级中文字幕| 亚洲另类在线视频| 日本福利一区二区| 东方欧美亚洲色图在线| 欧美国产日韩亚洲一区| 国产欧美日韩一区二区三区| 麻豆成人久久精品二区三区小说| 日韩视频一区二区在线观看| 欧美精品一区在线发布| 亚洲精品你懂的| 色偷偷久久一区二区三区| 国精品**一区二区三区在线蜜桃| 日韩免费福利电影在线观看| 欧美日韩喷水| 日韩电影在线一区二区三区| 欧美一区二区视频观看视频| 欧美日韩视频在线一区二区观看视频| 一区二区三区产品免费精品久久75| 欧美最新大片在线看| a美女胸又www黄视频久久| 亚洲女与黑人做爰| 欧美日韩国产综合视频在线观看| 99久久99久久免费精品蜜臀| 一区二区三区中文免费| 欧美猛男超大videosgay| 欧美在线日韩精品| 一区二区三国产精华液| 欧美色视频一区| 欧美一区二区| 樱花影视一区二区| 欧美一区二区三区啪啪| 亚洲一级影院| 开心九九激情九九欧美日韩精美视频电影| 欧美电影免费观看高清完整版在线 | 国产最新精品免费| 欧美极品aⅴ影院| 色一区在线观看| a级高清视频欧美日韩| 亚洲aaa精品| 久久综合狠狠综合久久综合88| 亚洲影院在线| 成人免费视频caoporn| 亚洲综合在线五月| 日韩欧美中文字幕公布| 午夜在线视频观看日韩17c| 风流少妇一区二区| 亚洲午夜免费福利视频| 精品国产凹凸成av人导航| 国产精品乱子乱xxxx| 成人免费毛片嘿嘿连载视频| 五月婷婷激情综合网| 久久免费视频色| 久久中文字幕一区二区三区| 91免费视频大全| 美国十次综合导航| 亚洲人xxxx| 欧美mv日韩mv亚洲| 91国产免费看| 在线欧美三区| 成人性生交大片免费看视频在线| 午夜激情综合网| 国产精品欧美经典| 日韩欧美国产午夜精品| 久久国产精品亚洲va麻豆| 欧美一区二区三区四区在线观看地址| 日韩成人免费电影| 1024国产精品| 精品入口麻豆88视频| 色菇凉天天综合网| 亚洲啪啪91| 欧美在线视频二区| 国产综合久久久久久久久久久久| 亚洲愉拍自拍另类高清精品| 国产日韩在线不卡| 日韩视频在线观看一区二区| 久久九九免费| 伊大人香蕉综合8在线视| 东方aⅴ免费观看久久av| 日韩二区在线观看| 亚洲一区在线观看免费| 欧美国产丝袜视频| 精品国产乱码久久久久久夜甘婷婷| 91高清视频在线| 国产亚洲一区在线播放| 欧美午夜a级限制福利片| 国产福利不卡视频| 奇米精品一区二区三区四区| 亚洲国产欧美在线| 一区二区三区在线免费观看| 国产精品久久久久影院| 26uuu久久综合| 91精品欧美综合在线观看最新 | 亚洲国产精品成人综合色在线婷婷 | 91久久精品网| 亚洲一区二区三区色| 激情综合中文娱乐网| 99re66热这里只有精品3直播 | 亚洲精品视频观看| 国产精品亲子伦对白| 久久久久久久免费视频了| 日韩欧美一级片| 在线播放欧美女士性生活| 欧洲中文字幕精品| 色婷婷精品久久二区二区蜜臀av| 国产亚洲毛片在线| 国产欧美日韩亚洲| 亚洲黄色视屏| 亚洲国产99| 伊人成人在线视频| 影音先锋久久| 亚洲午夜精品一区二区| 国产精品啊v在线| 欧美午夜精品| 欧美日韩综合另类| 狠狠综合久久av一区二区老牛| 欧美日韩在线高清| 国语自产精品视频在线看抢先版结局 | 久久国产免费看| 蜜臀av亚洲一区中文字幕| 亚洲大型综合色站| 亚洲成人av一区二区三区| 亚洲第一av色| 日产国产欧美视频一区精品| 天堂久久久久va久久久久| 日精品一区二区三区| 日本在线播放一区二区三区| 日韩av不卡在线观看| 蜜臀av性久久久久蜜臀aⅴ流畅 | 国产精品66部| 高清shemale亚洲人妖| 成人深夜视频在线观看| 成年人国产精品| av福利精品导航| 色综合中文字幕| 狠狠色噜噜狠狠色综合久| 亚洲欧洲视频| 免费看黄裸体一级大秀欧美| 91激情五月电影| 欧美精品18+| 欧美大片免费久久精品三p| 久久免费午夜影院| 日韩一区欧美小说| 亚洲福利国产精品| 九九国产精品视频| 国产成人高清视频| 91视视频在线观看入口直接观看www | 欧美精品黄色| 亚洲欧洲精品一区| 久久人人97超碰国产公开结果| 在线观看免费视频综合| 欧美日韩aaaaaa|