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

另外看

https://segmentfault.com/a/1190000014204992?tdsourcetag=s_pcqq_aiomsg

SpringCloud微服务架构分布式组件如何共享session对象的更多相关文章

  1. Java生鲜电商平台-SpringCloud微服务架构中分布式事务解决方案

    Java生鲜电商平台-SpringCloud微服务架构中分布式事务解决方案 说明:Java生鲜电商平台中由于采用了微服务架构进行业务的处理,买家,卖家,配送,销售,供应商等进行服务化,但是不可避免存在 ...

  2. Java生鲜电商平台-SpringCloud微服务架构中核心要点和实现原理

    Java生鲜电商平台-SpringCloud微服务架构中核心要点和实现原理 说明:Java生鲜电商平台中,我们将进一步理解微服务架构的核心要点和实现原理,为读者的实践提供微服务的设计模式,以期让微服务 ...

  3. SpringCloud微服务架构和SOA架构

    1,传统的三层架构 在传统的架构中,SSH,SSM,主要分为web 控制层,业务逻辑层,数据库访问层,单点项目,项目没有拆分,所有的开发任务全部写在一个项目中,耦合度比价高,如果程序中的一个功能出现了 ...

  4. Java生鲜电商平台-SpringCloud微服务架构高并发参数优化实战

    Java生鲜电商平台-SpringCloud微服务架构高并发参数优化实战 一.写在前面 在Java生鲜电商平台平台中相信不少朋友都在自己公司使用Spring Cloud框架来构建微服务架构,毕竟现在这 ...

  5. Java生鲜电商平台-SpringCloud微服务架构中网络请求性能优化与源码解析

    Java生鲜电商平台-SpringCloud微服务架构中网络请求性能优化与源码解析 说明:Java生鲜电商平台中,由于服务进行了拆分,很多的业务服务导致了请求的网络延迟与性能消耗,对应的这些问题,我们 ...

  6. Rest构建分布式 SpringCloud微服务架构项目

    一.开发环境:jdk  1.8.Maven  3.x.IDEA  2019.1.4.SpringBoot   2.0.7.spring Cloud  最新的稳定版  Finchley SR2   搭配 ...

  7. springcloud微服务架构搭建

    SpringCloud微服务框架搭建 一.微服务架构 1.1什么是分布式 不同模块部署在不同服务器上 作用:分布式解决网站高并发带来问题 1.2什么是集群 多台服务器部署相同应用构成一个集群 作用:通 ...

  8. SpringCloud微服务架构第三篇

    原文链接:https://www.javazhiyin.com/5130.html 微服务开发专栏:https://www.javazhiyin.com/category/springcloud Ri ...

  9. 关于SpringCloud微服务架构概念的一点理解

    目前微服务是非常火的架构或者说概念,也是在构建大型互联网项目时采用的架构方式. 1.单体架构单体架构,是指将开发好的项目打成war包,然后发布到tomcat等容器中的应用. 假设你正准备开发一款与Ub ...

随机推荐

  1. Linux用户抢占和内核抢占详解(概念, 实现和触发时机)--Linux进程的管理与调度(二十)

    1 非抢占式和可抢占式内核 为了简化问题,我使用嵌入式实时系统uC/OS作为例子 首先要指出的是,uC/OS只有内核态,没有用户态,这和Linux不一样 多任务系统中, 内核负责管理各个任务, 或者说 ...

  2. Linux-centos7超过2TB使用parted命令分区

    介绍说明: parted的操作都是实时的,也就是说你执行了一个分区的命令,他就实实在在地分区了, 而不是像fdisk那样,需要执行w命令写入所做的修改, 所以进行parted的测试千万注意不能在生产环 ...

  3. PHP编程效率

    1.如果能将类的方法定义成static,就尽量定义成static,它的速度会提升将近4倍.2.$row['id'] 的速度是$row[id]的7倍.3.echo 比 print 快,并且使用echo的 ...

  4. LeetCode算法题-Ugly Number(Java实现-四种解法)

    这是悦乐书的第199次更新,第208篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第64题(顺位题号是263).编写一个程序来检查给定的数字是否是一个丑陋的数字.丑陋的数 ...

  5. S/4 HANA中的MATDOC和MATDOC_EXTRACT

    最近做了销售和物料管理方面的一些需求,因此对S/4中的MM的数据模型有了一定的了解.目前网络已经有一些介绍物料凭证表MATDOC的文章,内容好像不是很详细,另外也没发现介绍库存变更数据表MATDOC_ ...

  6. 完美集群监控组合ganglia和nagios

    Ganglia是伯克利开发的一个集群监控软件.可以监视和显示集群中的节点的各种状态信息,比如如:cpu .mem.硬盘利用率, I/O负载.网络流量情况等,同时可以将历史数据以曲线方式通过php页面呈 ...

  7. element ui Angular学习笔记(一)

    1.element ui安装 npm i --save element-angular 2.Angular-cli引入 引入后需要开启ElModule.forRoot(),也可以单独引入某个组件入El ...

  8. ES5-ES6-ES7_数组的扩展

    Array.prototype.indexOf(value)  得到值在数组中的第一个下标,如果元素不存在返回-1,可以用来判断是否包含指定的元素 var arr = [6,5,4,3,1,7,6]; ...

  9. MySQL高级知识(八)——ORDER BY优化

    前言:在使用order by时,经常出现Using filesort,因此对于此类sql语句需尽力优化,使其尽量使用Using index. 0.准备 #1.创建test表. drop table i ...

  10. CF 1110 D/E

    CF 1110 D. Jongmah 题目大意:给你​\(n\)个瓷砖,每块瓷砖上有一个数字​\(a_i,(1\leq a_i\leq m)\).你可以将三个有连续数字​\((比如3,4,5)\)的瓷 ...