需求

一个平台每天都有新用户加入,当有新的用户加入的时候,在首页上会显示新加入的用户的个数,点击进去会显示这些用户的列表。

这个是 app 应用,但是不能使用推送。

设计

如果可以使用推送的话,每次当有新用户加入的时候推送到 app,在客户端维护这个新用户列表。

下面是使用 redis 在服务器端来维护这个列表的方法:

  1. 在 redis 当中创建一个新加入用户列表 NewUserList,并且对这个列表限制长度是 200,因为考虑到一般人不会查看新加入用户那么多,另外一个原因是避免数据过大。
  2. 当有新用户来到,先判断 NewUserList 的长度是否等于 200,如果等于 200 则 rpop 一下,然后再把新用户 id lpush 到 NewUserList(严谨的情况会判断该用户是否已经存在列表当中),如果没等于 200 那么直接 lpush 到 NewUserList
  3. 因为是在服务器端维护每个人看到的不同新用户列表,所以需要对每个用户创建一个 key 来存放当前看到哪个新用户的 id。
  4. 当获取新用户列表时候,先把当前用户看到的新用户 id 取出来,然后把 NewUserList 取出来,如果取出来的新用户 id 在 NewUserList 当中存在,就截取这个 NewUserList,从 0 - 这个 id 的索引的 List,如果不在 NewUserList 当中,就直接返回 NewUserList,最后把 NewUserList 的第 0 个元素,存放在这个用户 key 的新用户 id。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public static void addNewUserToList(String uid) {
List<String> userIds = RedisCacheHolder.getRedisCache().lrange(
NEW_USER_LIST_KEY, 0, -1);
if (userIds.contains(uid)) {
return;
}
if (RedisCacheHolder.getRedisCache().llen(NEW_USER_LIST_KEY) == 200) {
RedisCacheHolder.getRedisCache().rpop(NEW_USER_LIST_KEY);
}
RedisCacheHolder.getRedisCache().lpush(NEW_USER_LIST_KEY,
uid);
}

public static List<String> getNewUserIds(String currentUid) {
String key = String.format(USER_SEEN_NEW_USER_KEY, currentUid);
String uid = RedisCacheHolder.getRedisCache().getStringValue(key);
List<String> ids = RedisCacheHolder.getRedisCache().lrange(
NEW_USER_LIST_KEY, 0, -1);
if (ids.size() > 0) {
saveSeenedUserId(currentUid, ids.get(0));
}
if (ids.contains(sid)) {
return ids.subList(0, ids.indexOf(sid));
} else {
return ids;
}
}

public static void saveSeenedTalentSid(String currentUid, String seenedUid) {
String key = String.format(USER_SEEN_NEW_User_KEY, currentUid);
RedisCacheHolder.getRedisCache().setStringValue(key, seenedUid);
}

总结

虽然使用 redis 可以解决这个需求,但是如果用户量达到千万级别,那么这个 redis 的用户 key 就会是千万级别,这个方式可以使用一个快速的过渡方法,最好的方式还是使用推送,然后客户端来维护这个关系。

–EOF—