1. 程式人生 > >spring boot 中使用redis session

spring boot 中使用redis session

錯誤 dap isa name art res 5.0 fir sync

  spring boot 默認的httpsession是存在內存中。這種默認方式有幾個缺點:1、當分布式部署時,存在session不一致的問題;2、當服務重啟時session就會丟失,這時候用戶就需要重新登陸,可能導致用戶數據丟失。通常會使用redis來保存session。

  在spring boot中利用redis來保存session是非常簡單。只需要簡單的幾步就可以了。可以參考官方教程。https://docs.spring.io/spring-session/docs/current/reference/html5/guides/boot-redis.html

  配置流程:

  1、pom文件中添加依賴

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

  註意:如果pom文件沒有引入 spring-boot-starter-data-redis,則需要引入,否則無法自動配置redis,出現這個錯誤‘org.springframework.data.redis.connection.RedisConnectionFactory‘ that could not be found.

  2、在配置文件中添加相關配置

#配置sesion使用redis
spring.session.store-type=redis
設置session的一些屬性
server.servlet.session.cookie.http-only=true
server.servlet.session.timeout= 15000
#設置session在redis中的Namespace,避免和其他key沖突
spring.session.redis.namespace=spring:session
配置redis的鏈接
spring.redis.host=localhost
spring.redis.password=
spring.redis.port=6379

  到這裏,其實已經配置好了,可以直接使用httpsession了,沒有特別的地方。

  開發過程遇到的問題。

  本地測試通過之後部署到測試環境發現無法正常運行,報如下異常:

Caused by: io.lettuce.core.RedisCommandExecutionException: ERR unknown command ‘CONFIG‘
	at io.lettuce.core.protocol.AsyncCommand.completeResult(AsyncCommand.java:118) ~[lettuce-core-5.0.3.RELEASE.jar:na]
	at io.lettuce.core.protocol.AsyncCommand.complete(AsyncCommand.java:109) ~[lettuce-core-5.0.3.RELEASE.jar:na]
	at io.lettuce.core.protocol.CommandHandler.complete(CommandHandler.java:601) ~[lettuce-core-5.0.3.RELEASE.jar:na]
	at io.lettuce.core.protocol.CommandHandler.decode(CommandHandler.java:559) ~[lettuce-core-5.0.3.RELEASE.jar:na]
	at io.lettuce.core.protocol.CommandHandler.channelRead(CommandHandler.java:511) ~[lettuce-core-5.0.3.RELEASE.jar:na]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) ~[netty-transport-4.1.23.Final.jar:4.1.23.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) ~[netty-transport-4.1.23.Final.jar:4.1.23.Final]
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) ~[netty-transport-4.1.23.Final.jar:4.1.23.Final]
	at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86) ~[netty-transport-4.1.23.Final.jar:4.1.23.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) ~[netty-transport-4.1.23.Final.jar:4.1.23.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) ~[netty-transport-4.1.23.Final.jar:4.1.23.Final]
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) ~[netty-transport-4.1.23.Final.jar:4.1.23.Final]
	at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86) ~[netty-transport-4.1.23.Final.jar:4.1.23.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) ~[netty-transport-4.1.23.Final.jar:4.1.23.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) ~[netty-transport-4.1.23.Final.jar:4.1.23.Final]
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) ~[netty-transport-4.1.23.Final.jar:4.1.23.Final]
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434) ~[netty-transport-4.1.23.Final.jar:4.1.23.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) ~[netty-transport-4.1.23.Final.jar:4.1.23.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) ~[netty-transport-4.1.23.Final.jar:4.1.23.Final]
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965) ~[netty-transport-4.1.23.Final.jar:4.1.23.Final]
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163) ~[netty-transport-4.1.23.Final.jar:4.1.23.Final]
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645) ~[netty-transport-4.1.23.Final.jar:4.1.23.Final]
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580) ~[netty-transport-4.1.23.Final.jar:4.1.23.Final]
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497) ~[netty-transport-4.1.23.Final.jar:4.1.23.Final]
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459) ~[netty-transport-4.1.23.Final.jar:4.1.23.Final]
	at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:886) ~[netty-common-4.1.23.Final.jar:4.1.23.Final]
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.23.Final.jar:4.1.23.Final]
	at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_171]

  在github上有相關的issue,https://github.com/spring-projects/spring-session/issues/124,並且給了解決辦法。

  一般是因為安全問題redis服務端禁用了CONFIG命令,而RedisHttpSessionConfiguration需要使用這個命令進行一些初始化。導致無法初始化。

  一個簡單的解決方式是添加一個jiava配置

@Bean
public static ConfigureRedisAction configureRedisAction() {
    return ConfigureRedisAction.NO_OP;
}

  

  

  

spring boot 中使用redis session