在spring boot里运用redis统计用户在线数量。
项目依赖与配置
1. 引入依赖
首先,在pom.xml文件中添加spring data redis依赖:
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-data-redis</artifactid>
</dependency>
2. 配置redis连接
在application.properties中进行redis连接的配置:
spring.redis.host=localhost spring.redis.port=6379
方案1:借助redis set实现精确统计
1. 创建redis操作service
编写一个redis操作service,用于处理用户在线状态:
import org.springframework.data.redis.core.redistemplate;
import org.springframework.stereotype.service;
import java.util.set;
@service
public class onlineuserservice {
private static final string online_users_key = "online_users";
private final redistemplate<string, string> redistemplate;
public onlineuserservice(redistemplate<string, string> redistemplate) {
this.redistemplate = redistemplate;
}
// 用户登录
public void login(string userid) {
redistemplate.opsforset().add(online_users_key, userid);
}
// 用户退出
public void logout(string userid) {
redistemplate.opsforset().remove(online_users_key, userid);
}
// 获取在线用户数
public long getonlinecount() {
return redistemplate.opsforset().size(online_users_key);
}
// 获取所有在线用户id
public set<string> getonlineusers() {
return redistemplate.opsforset().members(online_users_key);
}
}
2. 控制器示例
创建一个控制器,用于测试上述功能:
import org.springframework.web.bind.annotation.*;
@restcontroller
@requestmapping("/online")
public class onlineusercontroller {
private final onlineuserservice onlineuserservice;
public onlineusercontroller(onlineuserservice onlineuserservice) {
this.onlineuserservice = onlineuserservice;
}
@postmapping("/login/{userid}")
public string login(@pathvariable string userid) {
onlineuserservice.login(userid);
return userid + " 已登录";
}
@postmapping("/logout/{userid}")
public string logout(@pathvariable string userid) {
onlineuserservice.logout(userid);
return userid + " 已退出";
}
@getmapping("/count")
public long getcount() {
return onlineuserservice.getonlinecount();
}
@getmapping("/users")
public set<string> getusers() {
return onlineuserservice.getonlineusers();
}
}
方案2:使用redis bitmap实现按位存储
1. bitmap操作service
创建一个专门用于bitmap操作的service:
import org.springframework.data.redis.connection.redisstringcommands;
import org.springframework.data.redis.core.rediscallback;
import org.springframework.data.redis.core.redistemplate;
import org.springframework.stereotype.service;
@service
public class onlineuserbitmapservice {
private static final string online_users_bitmap_key = "online_users_bitmap";
private final redistemplate<string, object> redistemplate;
public onlineuserbitmapservice(redistemplate<string, object> redistemplate) {
this.redistemplate = redistemplate;
}
// 用户登录(userid需为long类型)
public void login(long userid) {
redistemplate.execute((rediscallback<boolean>) connection ->
connection.setbit(online_users_bitmap_key.getbytes(), userid, true));
}
// 用户退出
public void logout(long userid) {
redistemplate.execute((rediscallback<boolean>) connection ->
connection.setbit(online_users_bitmap_key.getbytes(), userid, false));
}
// 检查用户是否在线
public boolean isonline(long userid) {
return redistemplate.execute((rediscallback<boolean>) connection ->
connection.getbit(online_users_bitmap_key.getbytes(), userid));
}
// 获取在线用户数
public long getonlinecount() {
return redistemplate.execute((rediscallback<long>) connection ->
connection.bitcount(online_users_bitmap_key.getbytes()));
}
// 统计指定范围内的在线用户数
public long getonlinecount(long start, long end) {
return redistemplate.execute((rediscallback<long>) connection ->
connection.bitcount(online_users_bitmap_key.getbytes(), start, end));
}
}
2. 控制器示例
创建对应的控制器:
import org.springframework.web.bind.annotation.*;
@restcontroller
@requestmapping("/online/bitmap")
public class onlineuserbitmapcontroller {
private final onlineuserbitmapservice onlineuserbitmapservice;
public onlineuserbitmapcontroller(onlineuserbitmapservice onlineuserbitmapservice) {
this.onlineuserbitmapservice = onlineuserbitmapservice;
}
@postmapping("/login/{userid}")
public string login(@pathvariable long userid) {
onlineuserbitmapservice.login(userid);
return userid + " 已登录";
}
@postmapping("/logout/{userid}")
public string logout(@pathvariable long userid) {
onlineuserbitmapservice.logout(userid);
return userid + " 已退出";
}
@getmapping("/count")
public long getcount() {
return onlineuserbitmapservice.getonlinecount();
}
@getmapping("/{userid}")
public boolean isonline(@pathvariable long userid) {
return onlineuserbitmapservice.isonline(userid);
}
}
使用建议
1. set方案的适用场景
- 当需要精确统计在线用户数量,并且能够获取在线用户列表时,可以使用set方案。
- 适合用户规模在百万级别以下的情况,因为set会存储每个用户的id。
2. bitmap方案的适用场景
- 若用户id是连续的整数(或者可以映射为连续整数),bitmap方案会更节省内存。
- 对于大规模用户(比如亿级)的在线统计,bitmap方案具有明显优势。
- 示例中使用
long类型的userid,在实际应用中,你可能需要一个id映射器,将业务id转换为连续的整数。
到此这篇关于springboot运用redis统计用户在线数量的两种方法实现的文章就介绍到这了,更多相关spring boot redis统计用户在线内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论