• 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对象共享。

    另外看

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

  • 相关阅读:
    linux 安装 Chrome
    J2EE版本
    Java 源码解析之局部变量检查
    /etc/xinetd.conf 和 /etc/xinetd.d/*【新网络服务配置】
    Linux 内核编译
    linux 汇编
    /etc/ethers【地址映射】
    Linux LAMP 搭建
    Linux ftp 使用
    linux apache
  • 原文地址:https://www.cnblogs.com/-flq/p/9916729.html
Copyright © 2020-2023  润新知