博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringCloud之session共享
阅读量:4045 次
发布时间:2019-05-24

本文共 3597 字,大约阅读时间需要 11 分钟。

下SpringCloud之session共享

基本原理

在springcloud微服务应用中,各微服务按传统方式获取的session是不同的,为实现各微服务共享session,spring-session提供了解决方案,对HttpSession重新实现,并将session存放于redis中,各微服务从redis中获取一致的session对象。

解决方案要点

  1. 在网关zuul和各微服务中引入如下依赖

    org.springframework.boot
    spring-boot-starter-data-redis
    org.springframework.session
    spring-session-data-redis
  2. 在网关zuul组件和各微服务组件的配置类(或者启动类)上加注解@EnableRedisHttpSession(flushMode = FlushMode.IMMEDIATE)启用缓存于redis的springsession,其中flushMode = FlushMode.IMMEDIATE表示session新建或属性发生变化时立即持久化,即当session发生变化时各组件立即感知。

    配置示例如下:

    @SpringBootApplication@EnableRedisHttpSession(flushMode = FlushMode.IMMEDIATE)//......public class App {	public static void main(String[] args) {		SpringApplication.run(App.class, args);	}	//......}
  3. 在spring配置文件application.yaml中配置redis,示例如下:

    spring:  redis:    database: 0    host: 127.0.0.1    port: 6379    password:    timeout: 1500    jedis:      pool:        max-idle: 10        max-wait: -1ms        min-idle: 2
  4. 在网关的spring配置文件中,还需加入如下配置:

    zuul:  sensitive-headers: #不过滤客户端的任何请求头(如:Cookie不会被过滤)  ignored-headers: #微服务之间的传递不过滤任何请求头(如:微服务之间传递Cookie不会被过滤)
  5. 经过上述配置已经能够实现非跨域(同源)情况下session的共享。但是,经过在Springboot2.2.x环境下测试,在跨域情况下还是无法实现session共享(这可能与springboot版本有一定关系),经在网上查资料找到原因,这是因为springsession使用CookieSerializer对象设置cookie时候,其默认的同源策略(SameSite)为lax,导致在跨域请求时除get方式外都不会向服务器发送cookie,解决办法是在各微服务中配置一个新的CookieSerializer对象,将同源策略设置为null,即在配置类(或者启动类)中添加如下配置:

    @Beanpublic CookieSerializer cookieSerializer() {	DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();	cookieSerializer.setSameSite(null);	return cookieSerializer;}
  6. (此步骤一般没有必要),可能某些版本的springboot或者在某些特殊情况下经过上述配置后,在跨域条件下session可以实现共享了,但是第一次访问session不能共享,第二次及以后的访问session才可以共享。这是是由于第一次访问时,session信息还没有被写入cookie,也就是客户端还没有存储session信息,请求时也就不会向服务器发送包含session信息的cookie,在微服务相互调用过程中也就不会传递cookie,这样每一个微服务都会创建新的session,session也就不共享了,而第一次请求响应时会将包含session信息的cookie发送给客户端,因此以后请求session是可以共享的。

    这个问题的解决的办法有多种,比较简单的一个办法是:在访问客户端首页时自动默认向服务器发送第一次无请意义的请求,在服务端也为该请求配置一个不做任何业务处理的映射路径,接下来用户进行操作都会传递含有session信息的cookie了。

  7. 当前用户信息是否存在的验证

    在实际开发中,需要在每一次请求时判断当前用户是否存在,可以通过zuul 中 的过滤器实现,具体代码示例如下:

    @Componentpublic class AuthenticationFilter extends ZuulFilter{		private static final Logger LOG = LoggerFactory.getLogger(AuthenticationFilter.class);    @Override    public String filterType() {//过滤器类型,pre表示请求被处理之前拦截        return "pre";    }     @Override    public int filterOrder() {//执行过滤器的顺序号        return 0;    }     @Override    public boolean shouldFilter() {//过滤器是否生效        return true;    }     @Override    public Object run() {//拦截逻辑        RequestContext currentContext = RequestContext.getCurrentContext();        HttpServletRequest request = currentContext.getRequest();        HttpServletResponse response = currentContext.getResponse();                String path = request.getServletPath();                LOG.debug("--------------------"+path+"-----------------------");                                        if(path.startsWith("/safty-login")) {        	return null;        }                        HttpSession session = request.getSession();        Object currUser = session.getAttribute(Constants.SESSION_ATTR_CURR_USER);		if (currUser == null) {			try {				response.setContentType("application/json;charset=UTF-8");				PrintWriter out = response.getWriter();								out.print("{\"logined\":false}");								out.flush();				out.close();			} catch (IOException e) {				// TODO Auto-generated catch block				e.printStackTrace();			}			throw new RuntimeException();//抛出异常,阻止进一步处理		}                        return null;    }}

案例参考

转载地址:http://xnhdi.baihongyu.com/

你可能感兴趣的文章
iphone开发之SDK研究(待续)
查看>>
计算机网络复习要点
查看>>
Variable property attributes or Modifiers in iOS
查看>>
NSNotificationCenter 用法总结
查看>>
C primer plus 基础总结(一)
查看>>
剑指offer算法题分析与整理(三)
查看>>
Ubuntu 13.10使用fcitx输入法
查看>>
pidgin-lwqq 安装
查看>>
mint/ubuntu安装搜狗输入法
查看>>
C++动态申请数组和参数传递问题
查看>>
opencv学习——在MFC中读取和显示图像
查看>>
Matlab与CUDA C的混合编程配置出现的问题及解决方案
查看>>
如何将PaperDownloader下载的文献存放到任意位置
查看>>
C/C++中关于动态生成一维数组和二维数组的学习
查看>>
JVM最简生存指南
查看>>
Java的对象驻留
查看>>
JVM并发机制探讨—内存模型、内存可见性和指令重排序
查看>>
如何构建高扩展性网站
查看>>
持续可用与CAP理论 – 一个系统开发者的观点
查看>>
nginx+tomcat+memcached (msm)实现 session同步复制
查看>>