zoukankan      html  css  js  c++  java
  • SpringCloud微服务session一致性解决方案

    场景:

    Spring Cloud微服务项目有这样一个问题:某些微服务需要获取用户登陆信息,即判断用户是否登陆,而由于微服务之间相互隔离,各个微服务的session无法共享,因此无法获取登陆状态。

    解决思路:

    这个问题实质上就是分布式session一致性问题,可以通过一下方法解决:
    1.使用redis共享session
    将各个微服务中的session放入redis中,通过读取redis来实现session共享。就获取登陆信息这个场景而言,具体步骤如下:
    ① 用户请求网关,网关将请求转发到登陆服务,进行用户名密码校验,校验通过后将sessionId和用户id关联存到redis中,并返回登陆前请求的页面;
    ② 调用其他微服务时,网关服务从redis中获取sessionId关联的用户id,若存在则已登录,则允许调用,否则未登录,重定向到登陆页面。
    由于各个微服务都将session存在了redis中,所以这个session是全局共享的。这样做的好处是实现简单,因为Spring session已经集成了redis,可以很容易的将session存到redis,且可以做到单点登陆/登出的效果,但是从微服务的角度来说,会增加系统的耦合度。在实际应用中可以使用一个单独的redis服务器或者集群来用作session共享。
    2.使用ticket的方式
    这个应该是大多数微服务使用的方式,原理就是SSO,具体实现可参见:https://blog.csdn.net/wxgxgp/article/details/89855525

    本文主要讲一下第一种方式。在使用第一种方式时踩了很多坑,不过最终还是成功了。

    Spring Redis Session实现session共享

    1.版本
    SpringBoot 2.1.5
    SpringCloud Greenwich.SR1

    2.基本结构

    用户请求zuul,zuul转发请求到service-a或者service-b,redis用来存session

    3.配置
    分别在各个微服务中添加依赖(网关可以不加):

    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <dependency>
       <groupId>org.springframework.session</groupId>
       <artifactId>spring-session-data-redis</artifactId>
    </dependency>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-security</artifactId>
     </dependency>
    

    网上的大部分文章之说添加前两个,而没有security,会报错无法启动。

    加了security的包后,会有默认的登陆界面,而security.enable配置已经被删除,所以无法在直接在配置文件中关掉登陆验证。可以增加如下配置来放行所有请求:

    @Configuration
    class WebSecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        public void configure(WebSecurity web) {
            web.ignoring().anyRequest();
        }
    }
    

    4.测试
    分别启动eureka、zuul和两个微服务,分别向网关发送两个请求,在日志中输出sessionId:
    在这里插入图片描述

    在这里插入图片描述

    两个微服务获取到的session是一样的。

    需要注意的是:在zuul的配置中,每个服务都要配置 sensitiveHeaders: "*",,否则经过网关的转发后丢失cookie,造成session不一致。
    zuul:
      routes:
       service-a:
          path: xxx
          serviceId: xxx
          sensitiveHeaders: "*"
        service-b:
          path: xxx
          serviceId: xxx
          sensitiveHeaders: "*"
    
  • 相关阅读:
    fedora上部署ASP.NET——(卡带式电脑跑.NET WEB服务器)
    SQL Server 请求失败或服务未及时响应。有关详细信息,请参见事件日志或其它适合的错误日志
    8086CPU的出栈(pop)和入栈(push) 都是以字为单位进行的
    FTP 服务搭建后不能访问问题解决
    指定的 DSN 中,驱动程序和应用程序之间的体系结构不匹配
    Linux 安装MongoDB 并设置防火墙,使用远程客户端访问
    svn Please execute the 'Cleanup' command. 问题解决
    .net 操作MongoDB 基础
    oracle 使用绑定变量极大的提升性能
    尝试加载 Oracle 客户端库时引发 BadImageFormatException。如果在安装 32 位 Oracle 客户端组件的情况下以 64 位模式运行,将出现此问题。
  • 原文地址:https://www.cnblogs.com/cnsec/p/13286629.html
Copyright © 2011-2022 走看看