俩bot能不能用一个redis

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了俩bot能不能用一个redis相关的知识,希望对你有一定的参考价值。

不行。由于只用到redis和springboot的整合,所以只能实现一个URL下的不同端口的应用之间的session共享,如果连应用名称都完全不同的两个应用要实现session共享,在这个基础上还需要使用到nginx,这种方式我暂时还没有试过。(SpringBoot项目默认就是不带应用名称的,除非自己在配置文件中修改过) 参考技术A 可以,多个bot可以用同一个redis来实现数据共享。 参考技术B 俩bot能用一个redis。有时我们可能有多个不同的Web应用,可以相互调用,这时如果每个应用都有自己的session,那用户跳转到另一个应用时就又需要登陆一次,这样会带来很不好的体验,因此我们需要在不同的应用中共享session。这里,我们采用redis来实现。

前置说明

由于只用到redis和springboot的整合,所以只能实现一个URL下的不同端口的应用之间的session共享,如果连应用名称都完全不同的两个应用要实现session共享,在这个基础上还需要使用到Nginx,这种方式我暂时还没有试过。(SpringBoot项目默认就是不带应用名称的,除非自己在配置文件中修改过)
需要提前在本地安装好redis,或者连接远程redis服务器。这里就不写安装教程了,可以自行去网上搜索。

添加依赖

需要为springboot项目添加以下两个依赖,参与session共享的项目都需要添加。

org.springframework.boot

spring-boot-starter-data-redis

org.springframework.session

spring-session-data-redis

一个是redis的依赖,一个是spring-session-data-redis的依赖。

配置redis参数

在SpringBoot项目的application.properties配置文件中配置redis参数:

# Redis数据库索引(默认为0)

spring.redis.database=0

# Redis服务器地址,如果是远程redis服务器,就改成服务器地址

spring.redis.host=127.0.0.1

# Redis服务器连接端口,默认是6379

spring.redis.port=6379

# 连接池最大连接数(使用负值表示没有限制)

spring.redis.lettuce.pool.max-active=8

# 连接池最大阻塞等待时间(使用负值表示没有限制)

spring.redis.lettuce.pool.max-wait=-1ms

# 连接池中的最大空闲连接

spring.redis.lettuce.pool.max-idle=5

# 连接池中的最小空闲连接

spring.redis.lettuce.pool.min-idle=0

# 连接超时时间(毫秒)

spring.redis.timeout=5000

spring.session.store-type=redis

如果你的项目使用的是application.yml,就进行如下配置:

spring:

redis:

database: 0

host: 127.0.0.1

port: 6379

lettuce:

pool:

max-idle: 8

min-idle: 0

max-active: 8

max-wait: -1ms

timeout: 5000

session:

store-type: redis

配置session过期时间

创建一个用于配置session过期时间的配置类:

import org.springframework.context.annotation.Configuration;

import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

@Configuration

@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 86400*30)

public class SessionConfig



简单的登录逻辑

@RequestMapping("/doLogin")

public String doLogin(HttpServletRequest request, Model model)

String username = request.getParameter("username");

String password = request.getParameter("password");

if(StringUtils.isEmpty(username) || StringUtils.isEmpty(password))

model.addAttribute("errorMsg", "用户名和密码不能为空");

return "login";



// 查找该用户,成功后根据该用户的类别返回到对应页面

User user = userService.getUserByUsernameAndPassword(username, password);

if(user == null)

model.addAttribute("errorMsg", "用户名或密码错误");

return "login";

else

request.getSession().setAttribute("currentUser", user);

model.addAttribute("currentUser", user);

String identity = user.getIdentity();

if("admin".equals(identity))

return "admin";

else

return "user";







直接按照原来的方式将对象存入session:request.getSession().setAttribute("currentUser", user); 此时session会存入redis。

登录过滤器

@Component

public class LoginInterceptor implements HandlerInterceptor

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

throws Exception

HttpSession session = request.getSession();

User currentUser = (User) session.getAttribute("currentUser");

if(currentUser == null)

response.sendRedirect(request.getContextPath() + "/toLogin");

return false;

else

return true;





@Override

public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,

Object o, ModelAndView modelAndView) throws Exception



@Override

public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,

Object o, Exception e) throws Exception





同样按原来的方式从session中取出对象:User currentUser = (User) session.getAttribute("currentUser"); 此时会从redis中取出该对象。

注意

如果只是存字符串等redis可以直接解析的对象,那就不会有什么问题,但是如果是存取对象就需要进行序列化了,比如上文中存的是我自定义的一个User对象,那么在存的时候,是会对该对象进行序列化的,取出时也会进行反序列化,因此该对象要实现Serializable接口,并且需要进行session共享的项目中都要有一个一模一样的对象,比如我的User定义如下:

import java.io.Serializable;

public class User implements Serializable

private String id;

private String username;

private String password;

private String email;

private String identity;

private static final long serialVersionUID = -5809782578272943999L;

// 省略getter、setter方法



注意这个序列号serialVersionUID,不同应用中的User对象的这个序列号必须相同,否则无法正确进行反序列化。

小结

之所以要实现这个功能是因为在我搭建自己的网站时想集成之前做过的另一个应用,把它作为一个功能嵌入这个应用中,通过http互通。中间遇到了很多坑,这种方式的主要缺点就是不能支持不同应用名称的应用之间的session共享,下一次可以尝试一下加入Nginx

以上是关于俩bot能不能用一个redis的主要内容,如果未能解决你的问题,请参考以下文章

为啥公钥加密只能私钥解密而不能公钥解密

当我等待“reaction_remove”时,Bot.wait_for() 不能正常工作

redis里能不能针对set数据的每个member设置过期时间

linux机器上安装redis服务,该机器有2个ip地址,一个能连redis,一个不能连redis?

C++中如何同时运行俩个dos命令?

python操作redis报错:redis.exceptions.DataError: ZADD allows either 'nx' or 'xx', not bot