好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

springboot+redis实现微博热搜排行榜的示例代码

技术模拟思路:

采用26个英文字母来实现排行,随机为每个字母生成一个随机数作为score

为了更好的体验,先做几件事:

先初始化1个月的历史数据 定时5秒钟,模拟微博的热度刷新(例如模拟点赞 收藏 评论的热度值更新) 定时1小时合并统计 天、周、月的排行榜。

步骤1:先初始化1个月的历史数据

?

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

33

34

@Service

@Slf4j

public class InitService {

 

    @Autowired

    private RedisTemplate redisTemplate;

 

    /**

      * 先初始化1个月的历史数据

      */

    public void init30day(){

        //计算当前的小时key

        long hour=System.currentTimeMillis()/( 1000 * 60 * 60 );

        //初始化近30天,每天24个key

        for ( int i= 1 ;i< 24 * 30 ;i++){

            //倒推过去30天

            String  key=Constants.HOUR_KEY+(hour-i);

            this .initMember(key);

            System.out.println(key);

        }

    }

 

    /**

      *初始化某个小时的key

      */

    public void initMember(String key) {

        Random rand = new Random();

        //采用26个英文字母来实现排行,随机为每个字母生成一个随机数作为score

        for ( int i = 1 ;i<= 26 ;i++){

            this .redisTemplate.opsForZSet().add(key,String.valueOf(( char )( 96 +i)),rand.nextInt( 10 ));

        }

    }

 

}

步骤2:定时刷新数据

?

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

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

@Service

@Slf4j

public class TaskService {

 

    @Autowired

    private RedisTemplate redisTemplate;

 

    /**

      *2. 定时5秒钟,模拟微博的热度刷新(例如模拟点赞 收藏 评论的热度值更新)

      * 3. 定时1小时合并统计 天、周、月的排行榜。

      */

    @PostConstruct

    public void init(){

        log.info( "启动初始化 .........." );

//        2. 定时5秒钟,模拟微博的热度刷新(例如模拟点赞 收藏 评论的热度值更新)

        new Thread(()-> this .refreshDataHour()).start();

//        3. 定时1小时合并统计 天、周、月的排行榜。

        new Thread(()-> this .refreshData()).start();

    }

 

    /**

      *采用26个英文字母来实现排行,随机为每个字母生成一个随机数作为score

      */

    public void refreshHour(){

        //计算当前的小时key

        long hour=System.currentTimeMillis()/( 1000 * 60 * 60 );

        //为26个英文字母来实现排行,随机为每个字母生成一个随机数作为score

        Random rand = new Random();

        for ( int i = 1 ;i<= 26 ;i++){

            //redis的ZINCRBY 新增这个积分值

            this .redisTemplate.opsForZSet().incrementScore(Constants.HOUR_KEY+hour,String.valueOf(( char )( 96 +i)),rand.nextInt( 10 ));

        }

    }

 

    /**

      *刷新当天的统计数据

      */

    public void refreshDay(){

        long hour=System.currentTimeMillis()/( 1000 * 60 * 60 );

        List<String> otherKeys= new ArrayList<>();

        //算出近24小时内的key

        for ( int i= 1 ;i< 23 ;i++){

            String  key=Constants.HOUR_KEY+(hour-i);

            otherKeys.add(key);

        }

        //把当前的时间key,并且把后推23个小时,共计近24小时,求出并集存入Constants.DAY_KEY中

        //redis ZUNIONSTORE 求并集

        this .redisTemplate.opsForZSet().unionAndStore(Constants.HOUR_KEY+hour,otherKeys,Constants.DAY_KEY);

 

        //设置当天的key 40天过期,不然历史数据浪费内存

        for ( int i= 0 ;i< 24 ;i++){

            String  key=Constants.HOUR_KEY+(hour-i);

            this .redisTemplate.expire(key, 40 , TimeUnit.DAYS);

        }

        log.info( "天刷新完成.........." );

    }

    /**

      *刷新7天的统计数据

      */

    public void refreshWeek(){

        long hour=System.currentTimeMillis()/( 1000 * 60 * 60 );

        List<String> otherKeys= new ArrayList<>();

        //算出近7天内的key

        for ( int i= 1 ;i< 24 * 7 - 1 ;i++){

            String  key=Constants.HOUR_KEY+(hour-i);

            otherKeys.add(key);

        }

        //把当前的时间key,并且把后推24*7-1个小时,共计近24*7小时,求出并集存入Constants.WEEK_KEY中

        this .redisTemplate.opsForZSet().unionAndStore(Constants.HOUR_KEY+hour,otherKeys,Constants.WEEK_KEY);

 

        log.info( "周刷新完成.........." );

    }

 

    /**

      *刷新30天的统计数据

      */

    public void refreshMonth(){

        long hour=System.currentTimeMillis()/( 1000 * 60 * 60 );

        List<String> otherKeys= new ArrayList<>();

        //算出近30天内的key

        for ( int i= 1 ;i< 24 * 30 - 1 ;i++){

            String  key=Constants.HOUR_KEY+(hour-i);

            otherKeys.add(key);

        }

        //把当前的时间key,并且把后推24*30个小时,共计近24*30小时,求出并集存入Constants.MONTH_KEY中

        this .redisTemplate.opsForZSet().unionAndStore(Constants.HOUR_KEY+hour,otherKeys,Constants.MONTH_KEY);

        log.info( "月刷新完成.........." );

    }

 

    /**

      *定时1小时合并统计 天、周、月的排行榜。

      */

    public void refreshData(){

        while ( true ){

            //刷新当天的统计数据

            this .refreshDay();

//            刷新7天的统计数据

            this .refreshWeek();

//            刷新30天的统计数据

            this .refreshMonth();

            //TODO 在分布式系统中,建议用xxljob来实现定时

            try {

                Thread.sleep( 1000 * 60 * 60 );

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

        }

    }

 

    /**

      *定时5秒钟,模拟微博的热度刷新(例如模拟点赞 收藏 评论的热度值更新)

      */

    public void refreshDataHour(){

        while ( true ){

            this .refreshHour();

            //TODO 在分布式系统中,建议用xxljob来实现定时

            try {

                Thread.sleep( 5000 );

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

        }

    }

}

步骤3:排行榜查询接口

?

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

33

@RestController

@Slf4j

public class Controller {

 

    @Autowired

    private RedisTemplate redisTemplate;

 

 

    @GetMapping (value = "/getHour" )

    public Set getHour() {

        long hour=System.currentTimeMillis()/( 1000 * 60 * 60 );

        //ZREVRANGE 返回有序集key中,指定区间内的成员,降序。

        Set<ZSetOperations.TypedTuple<Integer>> rang= this .redisTemplate.opsForZSet().reverseRangeWithScores(Constants.HOUR_KEY+hour, 0 , 30 );

        return rang;

    }

    @GetMapping (value = "/getDay" )

    public Set getDay() {

        Set<ZSetOperations.TypedTuple<Integer>> rang= this .redisTemplate.opsForZSet().reverseRangeWithScores(Constants.DAY_KEY, 0 , 30 );

        return rang;

    }

 

    @GetMapping (value = "/getWeek" )

    public Set getWeek() {

        Set<ZSetOperations.TypedTuple<Integer>> rang= this .redisTemplate.opsForZSet().reverseRangeWithScores(Constants.WEEK_KEY, 0 , 30 );

        return rang;

    }

 

    @GetMapping (value = "/getMonth" )

    public Set getMonth() {

        Set<ZSetOperations.TypedTuple<Integer>> rang= this .redisTemplate.opsForZSet().reverseRangeWithScores(Constants.MONTH_KEY, 0 , 30 );

        return rang;

    }

}

到此这篇关于springboot+redis实现微博热搜排行榜的示例代码的文章就介绍到这了,更多相关springboot redis微博热搜排行榜内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

原文链接:https://blog.csdn.net/INGNIGHT/article/details/106941747

查看更多关于springboot+redis实现微博热搜排行榜的示例代码的详细内容...

  阅读:27次