摘要:網關以及業務組件將對象存儲到或從獲取對象。二存在問題基于如上微服務的分布式架構如果按照傳統方式,將對象存儲在內存中。微服務架構下共享對象實現說明客戶端請求到,基于管理將對象存儲到,并將生成的返回給客戶端。
一.簡單做一個背景說明
1.為說明問題,本文簡單微服務架構示例如下
2.組件說明
分布式架構,每個組件都是集群或者主備。具體說明如下:
zuul service:網關,API調用都走zuul service。
micro service1 & micro service2:業務功能實現,數據庫增刪改查。
eureka:組件注冊,zuul service,micro service等組件都注冊到eureka,管理組件調用地址。
db-master & db-slave:數據庫集群,一主兩從。
redis master & redis slave:redis集群,緩存。這里主要存儲session對象。
3.組件之間API調用
①:網關zuul接收到的API請求,路由至業務實現組件。
②:網關zuul以及業務組件將session對象存儲到redis、或從redis獲取session對象。
③:業務組件實現數據增刪改查。
④:業務組件之間通過springCloud feign組件進行調用。
⑤:網關zuul以及micro service組件注冊到eureka組件,或從eureka獲取組件調用地址。
二.存在問題
基于如上微服務的分布式架構如果按照傳統方式,將session對象存儲在內存中。在zuul網關將路由請求至不同的micro service1或者micro service2時,內存中的session對象將不能被共享,無法判斷用戶的登陸狀態,也無法獲取session對象存儲的全局數據。
三.解決方案
1.Spring管理session對象
通過EnableRedisHttpSession注解支持基于Redis存儲session,全局共享session對象。
2.微服務架構下共享session對象實現說明
1)客戶端API請求到zuul,zuul基于spring管理session將session對象存儲到redis,并將生成的sessionId返回給客戶端。
2)zuul將請求路由到micro service,將sessionId通過cookie頭帶給micro service。
3)micro service通過sessionId從redis獲取到已經生成的session對象。
4)micro servcie1調用micro service2時,將sessionId也通過cookie頭帶給micro service2,micro service2通過sessionId從redis中獲取session對象。
5)客戶端再次調用時將a)步返回的sessionId增加到cookie頭,在redis中存儲的session失效之前zuul和micro service一直共享這個session。
5.具體實現
1)通過springframework的EnableRedisHttpSession注解管理session,zuul和micro service組件實現這個類以存儲、獲取redis中存儲的session對象。
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; @Configuration @EnableRedisHttpSession(maxInactiveIntervalInSeconds = GlobalConstants.SESSION_TIMOUT, redisFlushMode = RedisFlushMode.IMMEDIATE) public class SessionConfig { }
EnableRedisHttpSession注解參數說明:
maxInactiveIntervalInSeconds:session過期時間配置。
redisFlushMode:redis session刷新模式。配置為RedisFlushMode.IMMEDIATE,可以確保zuul存儲到redis的session對象在請求到micro service中能立即被獲取。在實際開發過程中出現由于沒有這個配置值,有時候zuul將session對象存儲到了redis,但是micro service無法立即獲取。
2)在zuul過濾器方法中調用addZuulRequestHeader增加請求頭,將sessionId通過cookie頭路由到micro service。
public class AccessFilter extends ZuulFilter { @Autowired HttpServletRequest httpServletRequest; @Autowired HttpServletResponse httpServletResponse; @Override public Object run() { RequestContext ctx = RequestContext.getCurrentContext(); String sessionId = httpServletRequest.getSession().getId(); ctx.addZuulRequestHeader("Cookie", "SESSION=" + sessionId); ctx.setSendZuulResponse(true);// 對該請求進行路由 ctx.setResponseStatusCode(200); // 返回200正確響應
3)micro service1通過feign調用micro service2時,實現RequestInterceptor接口。通過增加cookie頭,將sessionId帶到micro service2。
@Configuration public class MyRequestInterceptor implements RequestInterceptor { @Autowired HttpServletRequest request; @Override public void apply(RequestTemplate requestTemplate) { logger.info("MyRequestInterceptor apply begin."); try { String sessionId = RequestContextHolder.currentRequestAttributes().getSessionId(); if (null != sessionId) { requestTemplate.header("Cookie", "SESSION=" + sessionId); } } catch (Exception e) { logger.error("MyRequestInterceptor exception: ", e); } } }
6.驗證
1)通過postman請求zuul服務地址,調用登陸接口。
2)查看各組件sessionId
zuul sessionId:
micro service1 sessionId:
micro service1調用micro service2 sessionId:
結論:可以看到zuul和micro service中sessionId都是相同的,都是586b*c9a4,通過這種方式實現了API調用過程中的session對象共享。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/68946.html
摘要:于是,市面上出現了分布式的配置中心。為什么呢因為要結合分布式配置中心微服務,才能真正實現我們所理解的。所謂灰度發布,是說一個微服務集群里面,比如有個訂單系統,做了一些配置上的更新。數人云分布式統一配置中心數人云分布式統一配置中心,取名。 本文來自1月18日數人云資深工程師在IT大咖說平臺的線上直播分享。 今天主要探討這幾方面: 一、配置中心的定位二、云化的微服務對于配置中心的要求三、微...
閱讀 659·2021-10-09 09:41
閱讀 640·2019-08-30 15:53
閱讀 1071·2019-08-30 15:53
閱讀 1207·2019-08-30 11:01
閱讀 1562·2019-08-29 17:31
閱讀 983·2019-08-29 14:05
閱讀 1711·2019-08-29 12:49
閱讀 409·2019-08-28 18:17