当前位置: 首页 > news >正文

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

一.简单做一个背景说明
1.为说明问题,本文简单微服务架构示例如下

clipboard.png

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服务地址,调用登陆接口。

clipboard.png

2)查看各组件sessionId
zuul sessionId:

clipboard.png

micro service1 sessionId:

clipboard.png

micro service1调用micro service2 sessionId:

clipboard.png

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

相关文章:

  • 100. bootstrap 弹出对话框bootbox.confirm
  • jetty的使用
  • mysql架构
  • 详解node.js中的可读流(Readable)和可写流(Writeable)
  • 一文看懂JeffDean等提出的ENAS到底好在哪?
  • MXNet 作者李沐:用深度学习做图像分类,教程+代码
  • Map集合、散列表、红黑树介绍
  • centos7.4系统的虚拟机网络配置教程
  • win10 php安装redis 扩展
  • 6、通过Appium Desktop 实现录制功能
  • 文件上传漏洞攻击
  • Micropython TPYBoard V10X拼插编程实践之定时器 代码不精通?...
  • 从抖音关闭评论,看服务治理的重要性
  • diango-团队介绍
  • ModeBusRtu概述
  • cookie和session
  • CSS 提示工具(Tooltip)
  • ES6系列(二)变量的解构赋值
  • Java多态
  • node学习系列之简单文件上传
  • php中curl和soap方式请求服务超时问题
  • python学习笔记 - ThreadLocal
  • React 快速上手 - 06 容器组件、展示组件、操作组件
  • Spark in action on Kubernetes - Playground搭建与架构浅析
  • WePY 在小程序性能调优上做出的探究
  • 搞机器学习要哪些技能
  • 给新手的新浪微博 SDK 集成教程【一】
  • 关于extract.autodesk.io的一些说明
  • 记一次删除Git记录中的大文件的过程
  • 如何选择开源的机器学习框架?
  • 通过npm或yarn自动生成vue组件
  • 我与Jetbrains的这些年
  • 因为阿里,他们成了“杭漂”
  • 阿里云ACE认证学习知识点梳理
  • ​Python 3 新特性:类型注解
  • ​你们这样子,耽误我的工作进度怎么办?
  • ​软考-高级-系统架构设计师教程(清华第2版)【第15章 面向服务架构设计理论与实践(P527~554)-思维导图】​
  • # Python csv、xlsx、json、二进制(MP3) 文件读写基本使用
  • # Swust 12th acm 邀请赛# [ E ] 01 String [题解]
  • %3cli%3e连接html页面,html+canvas实现屏幕截取
  • (C语言)求出1,2,5三个数不同个数组合为100的组合个数
  • (Matalb分类预测)GA-BP遗传算法优化BP神经网络的多维分类预测
  • (阿里巴巴 dubbo,有数据库,可执行 )dubbo zookeeper spring demo
  • (编程语言界的丐帮 C#).NET MD5 HASH 哈希 加密 与JAVA 互通
  • (简单) HDU 2612 Find a way,BFS。
  • (免费领源码)Java#ssm#MySQL 创意商城03663-计算机毕业设计项目选题推荐
  • (一)ClickHouse 中的 `MaterializedMySQL` 数据库引擎的使用方法、设置、特性和限制。
  • (中等) HDU 4370 0 or 1,建模+Dijkstra。
  • (转)linux自定义开机启动服务和chkconfig使用方法
  • (转)视频码率,帧率和分辨率的联系与区别
  • *2 echo、printf、mkdir命令的应用
  • .bat批处理(五):遍历指定目录下资源文件并更新
  • .CSS-hover 的解释
  • .mysql secret在哪_MYSQL基本操作(上)
  • .NET “底层”异步编程模式——异步编程模型(Asynchronous Programming Model,APM)...