SpringCloud微服务架构分布式组件如何共享session对象

参考文章: https://www.cnblogs.com/fengli9998/p/7881331.html

https://blog.csdn.net/dsen726/article/details/80880458

一.简单做一个背景说明
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对象。

 
  1. import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

  2.  
  3. @Configuration

  4. @EnableRedisHttpSession(maxInactiveIntervalInSeconds = GlobalConstants.SESSION_TIMOUT,

  5. redisFlushMode = RedisFlushMode.IMMEDIATE)

  6. public class SessionConfig {

  7.  
  8. }

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。

 
  1. public class AccessFilter extends ZuulFilter {

  2. @Autowired

  3. HttpServletRequest httpServletRequest;

  4. @Autowired

  5. HttpServletResponse httpServletResponse;

  6.  
  7. @Override

  8. public Object run() {

  9. RequestContext ctx = RequestContext.getCurrentContext();

  10. String sessionId = httpServletRequest.getSession().getId();

  11. ctx.addZuulRequestHeader("Cookie", "SESSION=" + sessionId);

  12. ctx.setSendZuulResponse(true);// 对该请求进行路由

  13. ctx.setResponseStatusCode(200); // 返回200正确响应

  14. }

  15. }

3)micro service1通过feign调用micro service2时,实现RequestInterceptor接口。通过增加cookie头,将sessionId带到micro service2。

 
  1. @Configuration

  2. public class MyRequestInterceptor implements RequestInterceptor {

  3. @Autowired

  4. HttpServletRequest request;

  5.  
  6. @Override

  7. public void apply(RequestTemplate requestTemplate) {

  8. logger.info("MyRequestInterceptor apply begin.");

  9. try {

  10. String sessionId = RequestContextHolder.currentRequestAttributes().getSessionId();

  11. if (null != sessionId) {

  12. requestTemplate.header("Cookie", "SESSION=" + sessionId);

  13. }

  14. } catch (Exception e) {

  15. logger.error("MyRequestInterceptor exception: ", e);

  16. }

  17. }

  18. }

6.验证

1)通过postman请求zuul服务地址,调用登陆接口。

2)查看各组件sessionId

zuul sessionId:

micro service1 sessionId:

micro service1调用micro service2 sessionId:

结论:可以看到zuul和micro service中sessionId都是相同的,都是586b*c9a4,通过这种方式实现了API调用过程中的session对象共享。

注意:springcloud项目中经过网关zuul转发请求后发生session失效问题,这是由于zuul默认会丢弃原来的session并生成新的session,解决方法网关配置文件application.yml 中添加 sensitiveHeaders: “*”

 

 

转自:https://blog.csdn.net/justlpf/article/details/80350943

Spring Cloud是一个基于Spring Boot的微服务框架,它提供了一整套用于构建和管理微服务组件。下面是Spring Cloud微服务架构图的介绍: 1. 配置管理(Config Server):用于集中管理微服务的配置信息,可以将配置信息存储在Git、SVN等版本控制系统中,并通过Config Server进行统一管理和分发。 2. 服务注册与发现(Service Discovery):微服务架构中的各个服务需要能够自动注册和发现,以便实现服务之间的通信。Spring Cloud提供了服务注册与发现的组件,如Eureka、Consul等。 3. 断路器(Circuit Breaker):在微服务架构中,当某个服务出现故障或不可用时,为了避免级联故障,需要使用断路器模式进行故障隔离。Spring Cloud中的Hystrix组件提供了断路器的实现。 4. 智能路由(Intelligent Routing):微服务架构中的服务可能会有多个实例,智能路由可以根据负载均衡策略将请求分发到不同的实例上,以实现负载均衡。Spring Cloud中的Ribbon和Zuul组件提供了智能路由的功能。 5. 微代理(Micro Proxy):微服务架构中的服务之间需要进行通信,为了简化通信过程,可以使用微代理来处理请求和响应。Spring Cloud中的Feign组件提供了微代理的功能。 6. 控制总线(Control Bus):微服务架构中的各个服务需要能够实时通信和协调,控制总线可以提供消息传递和事件驱动的机制。Spring Cloud中的Spring Cloud Bus组件提供了控制总线的功能。 7. 全局锁(Distributed Lock):在分布式环境中,为了保证数据的一致性和并发控制,需要使用全局锁。Spring Cloud中的Zookeeper和Redis等组件提供了全局锁的实现。 8. 决策竞选(Leader Election):在分布式环境中,为了保证系统的高可用性,需要选举出一个主节点来处理请求。Spring Cloud中的Zookeeper和Election等组件提供了决策竞选的功能。 9. 分布式会话(Distributed Session):在微服务架构中,用户的会话信息可能需要在多个服务之间共享。Spring Cloud中的Spring Session组件提供了分布式会话的支持。 10. 集群状态管理(Cluster State Management):在微服务架构中,需要对集群中的各个服务进行监控和管理。Spring Cloud中的Spring Cloud Cluster组件提供了集群状态管理的功能。 以上是Spring Cloud微服务架构图的介绍,希望对你有帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值