一.简单做一个背景说明
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对象的更多相关文章
-
Java生鲜电商平台-SpringCloud微服务架构中分布式事务解决方案
Java生鲜电商平台-SpringCloud微服务架构中分布式事务解决方案 说明:Java生鲜电商平台中由于采用了微服务架构进行业务的处理,买家,卖家,配送,销售,供应商等进行服务化,但是不可避免存在 ...
-
Java生鲜电商平台-SpringCloud微服务架构中核心要点和实现原理
Java生鲜电商平台-SpringCloud微服务架构中核心要点和实现原理 说明:Java生鲜电商平台中,我们将进一步理解微服务架构的核心要点和实现原理,为读者的实践提供微服务的设计模式,以期让微服务 ...
-
SpringCloud微服务架构和SOA架构
1,传统的三层架构 在传统的架构中,SSH,SSM,主要分为web 控制层,业务逻辑层,数据库访问层,单点项目,项目没有拆分,所有的开发任务全部写在一个项目中,耦合度比价高,如果程序中的一个功能出现了 ...
-
Java生鲜电商平台-SpringCloud微服务架构高并发参数优化实战
Java生鲜电商平台-SpringCloud微服务架构高并发参数优化实战 一.写在前面 在Java生鲜电商平台平台中相信不少朋友都在自己公司使用Spring Cloud框架来构建微服务架构,毕竟现在这 ...
-
Java生鲜电商平台-SpringCloud微服务架构中网络请求性能优化与源码解析
Java生鲜电商平台-SpringCloud微服务架构中网络请求性能优化与源码解析 说明:Java生鲜电商平台中,由于服务进行了拆分,很多的业务服务导致了请求的网络延迟与性能消耗,对应的这些问题,我们 ...
-
Rest构建分布式 SpringCloud微服务架构项目
一.开发环境:jdk 1.8.Maven 3.x.IDEA 2019.1.4.SpringBoot 2.0.7.spring Cloud 最新的稳定版 Finchley SR2 搭配 ...
-
springcloud微服务架构搭建
SpringCloud微服务框架搭建 一.微服务架构 1.1什么是分布式 不同模块部署在不同服务器上 作用:分布式解决网站高并发带来问题 1.2什么是集群 多台服务器部署相同应用构成一个集群 作用:通 ...
-
SpringCloud微服务架构第三篇
原文链接:https://www.javazhiyin.com/5130.html 微服务开发专栏:https://www.javazhiyin.com/category/springcloud Ri ...
-
关于SpringCloud微服务架构概念的一点理解
目前微服务是非常火的架构或者说概念,也是在构建大型互联网项目时采用的架构方式. 1.单体架构单体架构,是指将开发好的项目打成war包,然后发布到tomcat等容器中的应用. 假设你正准备开发一款与Ub ...
随机推荐
-
[Java面试八]Hibernate总结以及在面试中的一些问题.
1.为什么要使用Hibernate开发你的项目呢?Hibernate的开发流程是怎么样的? 为什么要使用 ①.对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码. ②.Hiber ...
-
mybatis中传入String类型参数异常
在使用mybatis时,写了一条sql语句,只有一个String类型的参数, 示例代码 <select id="getApplyNum" parameterType=&quo ...
-
使用Markdown写文档
转载于:http://blog.csdn.net/xiahouzuoxin/article/details/19752603 Markdown是一种网络书写语言,其目标是实现易读易写,且兼容HTML语 ...
-
Android Studio编译好的apk放在哪里?
Eclipse中编译好的apk文件时在bin文件中面的,可是在Android Studio有一个比較大的修改了,编译好的apk在android studio里面是直接看不到了,并且apk文件所在文件夹 ...
-
python绝技 — 扫描蓝牙RFCOMM信道
RFCOMM协议 RFCOMM通过蓝牙L2CAP协议模拟了RS232串口.这会与另一台设备建立一个蓝牙连接,模拟一条普通的串行线缆,使用户能够用其他设备控制这一台设备,通过蓝牙打电话,发短信,读取手机 ...
-
ClientURL库-curl_setopt()
这是一个出现得比较突兀的问题: 好好学习使用一下这个库:http://php.net/manual/zh/book.curl.php curl_setopt函数:curl_setopt - 设置一个c ...
-
php函数var_dump() 、print_r()、echo()
var_dump() 能打印出类型 print_r() 只能打出值 echo() 是正常输出... 需要精确调试的时候用 var_dump(); 一般查看的时候用 print_r() 另外 , ech ...
-
java.util.List API解读
list的API 如下: 下面是我对这段API的翻译 An ordered collection (also known as a sequence). 一个有序的集合(也被称为序列) The use ...
-
微信支付支付宝支付生成二维码的方法(php生成二维码的三种方法)
如果图简单,可以用在线生成 http://pan.baidu.com/share/qrcode?w=150&h=150&url=http://www.xinzhenkj.com 最简单 ...
-
linux链接库的理解
前段时间遇到个奇怪的问题,经调试是由于可执行程序A编译时使用的libssl.so.1.1及对应版本头文件,A链接的库libtest.so编译时使用的libssl.so.1.0及对应版本头文件,执行时l ...