Redis在项目中的17种使用场景

news/2024/9/13 22:39:48/ 标签: redis, 数据库, 缓存

Redis 是一个开源的高性能键值对数据库,它以其内存中数据存储、键过期策略、持久化、事务、丰富的数据类型支持以及原子操作等特性,在许多项目中扮演着关键角色。以下是V哥整理的17个Redis在项目中常见的使用场景:

  1. 缓存:Redis 可以作为应用程序的缓存层,减少数据库的读取压力,提高数据访问速度。

  2. 会话存储:在 Web 应用中,Redis 可以用来存储用户的会话信息,如登录状态、购物车内容等。

  3. 排行榜和计数器:Redis 支持原子操作,非常适合实现实时排行榜、点赞数、访问计数等功能。

  4. 消息队列:Redis 可以作为消息队列系统,用于处理异步任务,例如邮件发送、后台任务处理等。

  5. 实时分析:Redis 可以用于实时分析,如用户行为分析、实时统计信息等。

  6. 分布式锁:在分布式系统中,Redis 可以用于实现分布式锁,确保在多个节点之间共享资源的一致性。

  7. 发布/订阅:Redis 提供了发布/订阅模式,可以用于实现消息广播,例如实时通知系统。

  8. 限流:Redis 可以用于实现限流功能,防止系统过载,如 API 调用频率限制。

  9. 数据过期:Redis 支持设置数据的过期时间,自动清理过期数据,适用于临时数据存储。

  10. 全页缓存:Redis 可以缓存整个页面的输出,减少数据库查询和页面渲染时间。

  11. 社交功能:在社交网络应用中,Redis 可以用于存储好友关系、用户状态更新等。

  12. 实时推荐系统:Redis 可以用于存储用户的行为数据和偏好,实现实时推荐。

  13. 地理位置信息:Redis 支持 Geospatial 索引,可以用于实现地理位置相关的查询和推荐。

  14. 时间序列数据:Redis 可以存储时间序列数据,用于监控和分析。

  15. 任务调度:Redis 可以用于任务调度,例如定时任务的执行。

  16. 数据共享:在微服务架构中,Redis 可以作为服务间共享数据的媒介。

  17. 持久化:虽然 Redis 是内存数据库,但它也支持数据持久化,可以在系统故障后恢复数据。

Redis 的使用场景非常广泛,可以根据项目的具体需求来选择合适的应用方式。

下面V哥依次对17种业务场景举例说明和解释:

1. 缓存

针对Redis作为缓存层的使用场景,我将提供一个简单的Java Spring Boot应用案例,该应用使用Redis缓存来提高数据库查询的效率。

场景描述

假设我们有一个在线书店,用户可以查看书籍的详细信息。每次用户请求书籍详情时,后端需要查询数据库以获取书籍信息。为了提高性能,我们可以使用Redis缓存来存储热门书籍的信息,以减少对数据库的查询次数。

环境准备

  1. 安装Java开发环境。

  2. 安装Redis并确保其运行。

  3. 创建一个Spring Boot项目,并添加以下依赖:

  • Spring Web

  • Spring Data Redis

  • Redis客户端驱动,如lettuce或jedis

创建Spring Boot项目

使用Spring Initializr (https://start.spring.io/) 创建一个项目,并添加所需的依赖。

配置Redis连接

src/main/resources/application.properties中配置Redis服务器的连接信息:

spring.redis.host=localhost
spring.redis.port=6379

编写业务代码

  1. 定义书籍实体类

    public class Book {private String id;private String title;private String author;// 省略构造函数、getter和setter方法
    }
  2. 创建书籍服务接口和实现类

    public interface BookService {Book getBookById(String id);
    }@Service
    public class BookServiceImpl implements BookService {@Autowiredprivate BookRepository bookRepository;@Autowiredprivate StringRedisTemplate redisTemplate;@Overridepublic Book getBookById(String id) {// 尝试从Redis缓存中获取书籍Book cachedBook = redisTemplate.opsForValue().get(id);if (cachedBook != null) {return cachedBook;}// 如果缓存中没有,从数据库查询Book book = bookRepository.findById(id).orElse(null);if (book != null) {// 将查询结果放入缓存,设置过期时间为10分钟redisTemplate.opsForValue().set(id, book, 10, TimeUnit.MINUTES);}return book;}
    }

  3. 创建书籍仓库接口

    public interface BookRepository extends JpaRepository<Book, String> {
    }

  4. 创建控制器

    @RestController
    @RequestMapping("/books")
    public class BookController {@Autowiredprivate BookService bookService;@GetMapping("/{id}")public ResponseEntity<Book> getBook(@PathVariable String id) {Book book = bookService.getBookById(id);if (book != null) {return ResponseEntity.ok(book);} else {return ResponseEntity.notFound().build();}}
    }

    详细解释

  • 配置Redis连接:在application.properties中配置了Redis服务器的地址和端口。

  • 定义书籍实体类:这是一个简单的POJO类,代表数据库中的书籍记录。

  • 创建书籍服务:BookService接口定义了获取书籍的方法。BookServiceImpl实现了这个接口,并使用BookRepository从数据库获取数据。同时,它还使用了StringRedisTemplate来操作Redis缓存

  • 缓存逻辑:在getBookById方法中,首先尝试从Redis缓存中获取书籍信息。如果缓存中存在,直接返回;如果不存在,则从数据库查询,并把结果存入缓存,同时设置10分钟的过期时间。

  • 创建控制器:BookController提供了一个RESTful API端点/books/{id},用于根据书籍ID获取书籍信息。

    通过这种方式,我们可以显著减少对数据库的查询次数,特别是对于热门书籍,从而提高应用的性能和响应速度。

    2. 会话存储

    针对Redis作为会话存储的使用场景,下面是一个Java Spring Boot应用的案例,其中使用Redis来存储用户会话信息。

    场景描述

    假设我们正在开发一个Web应用程序,用户需要登录以访问某些受保护的资源。为了管理用户会话,我们可以使用Redis来存储会话信息,而不是将它们存储在服务器的内存中或数据库中。

    创建Spring Boot项目

    使用Spring Initializr (https://start.spring.io/) 创建一个项目,并添加所需的依赖。

    配置Redis连接

    在src/main/resources/application.properties中配置Redis服务器的连接信息:

    spring.redis.host=localhost
    spring.redis.port=6379
    server.servlet.session.persistent=false
    server.servlet.session.timeout=15
    spring.session.store-type=redis

    编写业务代码

  1. 创建用户实体类

    public class User {private String username;private String password;// 省略构造函数、getter和setter方法
    }
  2. 创建用户存储库接口

    @Service
    public class InMemoryUserRepository implements UserDetailsService {private static final Map<String, User> users = new HashMap<>();static {users.put("user", new User("user", "password"));// 添加更多用户...}@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {User user = users.get(username);if (user == null) {throw new UsernameNotFoundException("User not found with username: " + username);}return new org.springframework.security.core.userdetails.User(user.getUsername(),user.getPassword(),new ArrayList<>());}
    }
  3. 配置Spring Security

    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate UserDetailsService userDetailsService;@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/admin/**").hasRole("ADMIN").antMatchers("/user/**").hasAnyRole("USER", "ADMIN").antMatchers("/", "/home", "/register").permitAll().anyRequest().authenticated().and().formLogin().loginPage("/login").permitAll().and().logout().permitAll();}@Autowiredpublic void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());}@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}
    }
    
  4. 创建登录和登出控制器

    @Controller
    public class WebController {@GetMapping("/login"public String login() {return "login";}@GetMapping("/admin"public String adminPage() {return "admin";}@GetMapping("/user"public String userPage() {return "user";}@PostMapping("/logout"public String logout(HttpServletRequest request) {request.getSession().invalidate();return "redirect:/login?logout";}
    }
  5. 创建登录页面(login.html)

这是一个简单的HTML页面,包含表单用于用户登录。

详细解释

  • 配置Redis连接:在application.properties中配置了Redis服务器的地址和端口,并设置了Spring Session的存储类型为Redis。

  • 创建用户实体类:这是一个简单的POJO类,代表用户信息。

  • 用户存储库接口:InMemoryUserRepository实现了UserDetailsService接口,用于Spring Security的认证过程。实际应用中,应连接到数据库来获取用户信息。

  • 配置Spring Security:WebSecurityConfig类配置了Spring Security的认证和授权规则。它还配置了自定义的登录页面和登出逻辑。

  • 创建控制器:WebController提供了访问不同页面的路由和登出逻辑。

  • 登录页面:login.html是用户登录的前端页面。

通过这种方式,Spring Session会自动管理用户的会话信息,并将其存储在Redis中。当用户登录时,会话信息将被存储在Redis中,而不是传统的服务器端HttpSession中。这使得会话信息可以在多个服务器实例之间共享,非常适合于分布式部署的Web应用程序。此外,Redis的高性能也有助于提高应用程序的响应速度。

3. 排行榜和计数器

针对Redis作为排行榜和计数器的使用场景,下面是一个Java Spring Boot应用的案例,其中使用Redis来实现一个简单的文章点赞功能,并将点赞数用作排行榜的依据。

场景描述

假设我们正在开发一个博客平台,用户可以对文章进行点赞。我们希望根据文章的点赞数来显示一个实时更新的热门文章排行榜。

创建Spring Boot项目

使用Spring Initializr (https://start.spring.io/) 创建一个项目,并添加所需的依赖。

配置Redis连接

在src/main/resources/application.properties中配置Redis 服务器的连接信息:

spring.redis.host=localhost
spring.redis.port=6379

编写业务代码

假设我们有一个电商平台,需要处理用户的订单。为了提高效率,我们希望将订单处理任务异步化,即用户下单后,订单信息将被发送到一个队列中,然后由一个或多个后台服务来异步处理这些订单。

创建Spring Boot项目

使用Spring Initializr (https://start.spring.io/) 创建一个项目,并添加所需的依赖。

配置Redis连接

在src/main/resources/application.properties中配置Redis服务器的连接信息:

通过这种方式,我们可以利用Redis的原子操作和高性能特性来实现一个高效的点赞和排行榜功能。每次用户点赞时,Redis都会原子性地更新点赞数,而获取排行榜时,我们可以快速地从Redis中检索和排序数据,从而提供实时的热门文章排行。

4. 消息队列

针对Redis作为消息队列的使用场景,下面是一个Java Spring Boot应用的案例,其中使用Redis的发布/订阅功能来实现一个简单的任务队列。

场景描述

假设我们有一个电商平台,需要处理用户的订单。为了提高效率,我们希望将订单处理任务异步化,即用户下单后,订单信息将被发送到一个队列中,然后由一个或多个后台服务来异步处理这些订单。

  1. 定义文章实体类

    public class Article {private String id;private String title;private int likeCount;// 省略构造函数、getter和setter方法
    }
  2. 创建文章服务接口和实现类

    @Service
    public class ArticleService {@Autowiredprivate StringRedisTemplate redisTemplate;public void likeArticle(String articleId) {// 增加文章的点赞数redisTemplate.opsForValue().increment(articleId, 1);}public List<Article> getTopLikedArticles(int topN) {// 获取topN个点赞数最多的文章Set<String> articleIds = redisTemplate.keys("article:*:likeCount");List<Article> topArticles = new ArrayList<>();for (String id : articleIds) {int likeCount = (Integer) redisTemplate.opsForValue().get(id);Article article = new Article();article.setId(id.replace("article:", "").replace(":likeCount", ""));article.setTitle("文章标题待查询");article.setLikeCount(likeCount);topArticles.add(article);}// 根据点赞数排序topArticles.sort((a1, a2) -> a2.getLikeCount() - a1.getLikeCount());return topArticles.subList(0, topN);}
    }
  3. 创建控制器

    @RestController
    @RequestMapping("/articles")
    public class ArticleController {@Autowiredprivate ArticleService articleService;@PostMapping("/{id}/like")public ResponseEntity<String> likeArticle(@PathVariable String id) {articleService.likeArticle(id);return ResponseEntity.ok("点赞成功");}@GetMapping("/top/{topN}")public ResponseEntity<List<Article>> getTopLikedArticles(@PathVariable int topN) {List<Article> topArticles = articleService.getTopLikedArticles(topN);return ResponseEntity.ok(topArticles);}
    }

    详细解释

  4. 配置Redis连接:在application.properties中配置了Redis服务器的地址和端口。

  5. 定义文章实体类:这是一个简单的POJO类,代表文章信息,包括文章ID、标题和点赞数。

  6. 创建文章服务:ArticleService提供了两个方法,likeArticle用于增加文章的点赞数,getTopLikedArticles用于获取点赞数最多的前N篇文章。

  7. 点赞逻辑:在likeArticle方法中,我们使用StringRedisTemplate的increment操作来原子性地增加文章的点赞数。

  8. 获取排行榜逻辑:在getTopLikedArticles方法中,我们首先获取所有文章的点赞数键,然后构建一个包含文章点赞数的列表。接着,我们对这个列表进行排序,以获取点赞数最多的前N篇文章。

  9. 创建控制器:ArticleController提供了两个RESTful API端点,/articles/{id}/like用于点赞文章,/articles/top/{topN}用于获取点赞数最多的前N篇文章。

创建Spring Boot项目

使用Spring Initializr (https://start.spring.io/) 创建一个项目,并添加所需的依赖。

配置Redis连接

在src/main/resources/application.properties中配置Redis服务器的连接信息:

spring.redis.host=localhost
spring.redis.port=6379

编写业务代码

  1. 配置Redis消息队列

创建一个配置类来设置发布者和订阅者使用的通道。

@Configuration
public class RedisConfig {@Beanpublic RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory connectionFactory) {RedisMessageListenerContainer container = new RedisMessageListenerContainer();container.setConnectionFactory(connectionFactory);container.addMessageListener(new MessageListenerImpl(), new PatternTopic("order-channel"));return container;}
}

2.实现消息监听器

@Component
public class MessageListenerImpl implements MessageListener<String, String> {@Overridepublic void onMessage(Message<String, String> message, byte[] pattern) {String orderData = message.getBody();processOrder(orderData);}private void processOrder(String orderData) {// 处理订单逻辑System.out.println("Processing order: " + orderData);// 假设订单处理成功}
}

3.创建订单服务

@Service
public class OrderService {@Autowiredprivate ReactiveRedisTemplate<String, String> reactiveRedisTemplate;public Mono<Void> placeOrder(String orderData) {return reactiveRedisTemplate.convertAndSend("order-channel", orderData).then();}
}
4.创建控制器
@RestController
@RequestMapping("/orders")
public class OrderController {@Autowiredprivate OrderService orderService;@PostMappingpublic Mono<ResponseEntity<?>> placeOrder(@RequestBody String orderData) {return orderService.placeOrder(orderData).then(Mono.just(ResponseEntity.ok().build())).defaultIfEmpty(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build());}
}

详细解释

  • 配置Redis消息队列:RedisConfig配置类设置了Redis消息监听器容器,它将监听名为order-channel的通道。

  • 实现消息监听器:MessageListenerImpl实现了MessageListener接口,用于接收并处理发送到order-channel的消息。每当有新消息到达时,onMessage方法会被调用,订单数据将被传递到processOrder方法进行处理。

  • 创建订单服务:OrderService服务中定义了placeOrder方法,它使用ReactiveRedisTemplate的convertAndSend方法将订单数据发布到order-channel。

  • 创建控制器:OrderController提供了一个POST端点/orders,用于接收订单数据。当接收到订单请求时,它将调用OrderService的placeOrder方法将订单数据发送到Redis消息队列,并返回相应的响应。

通过这种方式,我们可以将订单处理逻辑异步化,提高系统的整体性能和响应能力。用户下单后,前端可以立即收到响应,而订单处理则在后台异步进行。这种模式适用于需要高吞吐量和快速响应的业务场景。

5. 实时分析

针对Redis作为实时分析使用场景,下面是一个Java Spring Boot应用的案例,其中使用Redis的Sorted Set来实现一个简单的用户在线时长统计和分析功能。

场景描述

假设我们正在开发一个在线教育平台,需要统计每个用户的在线时长,并根据这些数据生成实时的在线时长排行榜。

创建Spring Boot项目

使用Spring Initializr (https://start.spring.io/) 创建一个项目,并添加所需的依赖。

配置Redis连接

在src/main/resources/application.properties中配置Redis服务器的连接信息:

spring.redis.host=localhost
spring.redis.port=6379

编写业务代码

# application.properties
redisson.address=redis://localhost:6379

  1. 用户在线时长服务接口和实现类

    @Service
    public class OnlineDurationService {@Autowiredprivate StringRedisTemplate redisTemplate;public void updateUserOnlineDuration(String userId, long duration) {// 使用Sorted Set存储用户ID和在线时长redisTemplate.opsForZSet().incrementScore("user:online:duration", userId, duration);}public Set<String> getTopUsersByOnlineDuration(int topN) {// 获取在线时长最长的前N个用户Set<String> topUsers = redisTemplate.opsForZSet().reverseRange("user:online:duration", 0, topN - 1);return topUsers;}
    }
  2. 用户登录和登出逻辑

    @Controller
    public class UserController {@Autowiredprivate OnlineDurationService onlineDurationService;@PostMapping("/user/{userId}/login")public ResponseEntity<String> userLogin(@PathVariable String userId) {// 用户登录逻辑,可以是任何触发登录的事件return ResponseEntity.ok("User " + userId + " logged in");}@PostMapping("/user/{userId}/logout")public ResponseEntity<String> userLogout(@PathVariable String userId) {// 用户登出时记录在线时长long duration = // 计算用户在线时长的逻辑onlineDurationService.updateUserOnlineDuration(userId, duration);return ResponseEntity.ok("User " + userId + " logged out");}
    }
  3. 获取在线时长排行榜

    @RestController
    @RequestMapping("/users")
    public class UserRankController {@Autowiredprivate OnlineDurationService onlineDurationService;@GetMapping("/online-duration/top/{topN}")public ResponseEntity<Set<String>> getTopUsersByOnlineDuration(@PathVariable int topN) {Set<String> topUsers = onlineDurationService.getTopUsersByOnlineDuration(topN);return ResponseEntity.ok(topUsers);}
    }

    详细解释

  4. 配置Redis连接:在application.properties中配置了Redis服务器的地址和端口。

  5. 用户在线时长服务:OnlineDurationService服务中定义了两个方法,updateUserOnlineDuration用于更新用户的在线时长,这里使用Redis的Sorted Set数据结构,将用户ID作为成员,在线时长作为分数进行存储。getTopUsersByOnlineDuration方法用于获取在线时长最长的前N个用户。

  6. 用户登录和登出逻辑:在UserController中,定义了用户登录和登出的RESTful API。用户登录时,可以执行任何触发登录的逻辑;用户登出时,计算在线时长并通过OnlineDurationService服务更新到Redis中。

  7. 获取在线时长排行榜:UserRankController提供了一个GET端点/users/online-duration/top/{topN},用于获取在线时长最长的前N个用户。

通过这种方式,我们可以利用Redis的Sorted Set来存储和排序用户的在线时长,实现一个高效的实时在线时长统计和分析功能。每当用户登出时,系统都会更新用户的在线时长,并可以快速地根据在线时长对用户进行排名,从而提供一个动态的在线时长排行榜。这对于在线教育平台等需要监控用户活跃度的业务场景非常有用。

6. 分布式锁

针对Redis作为分布式锁的使用场景,下面是一个Java Spring Boot应用的案例,其中使用Redisson作为客户端来实现分布式锁。

场景描述

假设我们有一个高流量的电子商务网站,需要执行一些资源密集型的操作,比如生成日报表。为了防止多个实例同时执行这些操作,我们需要一个分布式锁来确保每次只有一个实例可以执行这些操作。

环境准备

  • 安装Java开发环境。

  • 安装Redis并确保其运行。

  • 创建一个Spring Boot项目,并添加以下依赖:

  • Spring Boot Starter Web

  • Redisson

  • Spring Boot Starter Cache(可选,如果需要使用Spring的缓存抽象)

创建Spring Boot项目

使用Spring Initializr (https://start.spring.io/) 创建一个项目,并添加所需的依赖。

配置Redisson连接

在src/main/resources/application.properties或application.yml中配置Redisson客户端连接到Redis服务器:

# application.properties
redisson.address=redis://localhost:6379

或者

# application.yml
redisson:address: "redis://localhost:6379"

编写业务代码

  1. 配置Redisson

创建一个配置类来配置Redisson客户端。

@Configuration
public class RedissonConfig {@Bean(destroyMethod = "shutdown")public RedissonClient redissonClient() {RedissonClientConfig config = new RedissonClientConfig();config.useSingleServer().setAddress(redisson.address);return Redisson.create(config);}@Value("${redisson.address}")private String redissonAddress;
}

        2.使用分布式锁

创建一个服务类来执行需要分布式锁保护的资源密集型操作。

@Service
public class ReportService {@Autowiredprivate RedissonClient redissonClient;public void generateDailyReport() {RLock lock = redissonClient.getLock("dailyReportLock");try {// 尝试获取锁,最多等待3秒,锁的自动过期时间设置为10秒if (lock.tryLock(3, 10, TimeUnit.SECONDS)) {// 执行生成日报表的操作System.out.println("Generating daily report...");// 模拟长时间运行的任务TimeUnit.SECONDS.sleep(5);System.out.println("Daily report generated.");}} catch (InterruptedException e) {Thread.currentThread().interrupt();} finally {// 释放锁lock.unlock();}}
}

        3.创建控制器

@RestController
@RequestMapping("/reports")
public class ReportController {@Autowiredprivate ReportService reportService;@GetMapping("/daily")public ResponseEntity<String> generateDailyReport() {reportService.generateDailyReport();return ResponseEntity.ok("Daily report generation triggered.");}
}

 

详细解释

  • 配置Redisson连接:在配置文件中指定Redis服务器的地址,并创建一个RedissonClient Bean。

  • 使用分布式锁:ReportService服务中的generateDailyReport方法使用Redisson的RLock来获取一个名为dailyReportLock的分布式锁。tryLock方法尝试获取锁,并指定最多等待时间和锁的自动过期时间。如果成功获取锁,则执行生成日报表的操作;如果获取锁失败,则方法将立即返回,不会执行任何操作。

  • 创建控制器:ReportController提供了一个GET端点/reports/daily,用于触发生成日报表的操作。

通过这种方式,我们可以确保在分布式系统中,即使有多个实例运行,也只有一个实例可以执行生成日报表的操作,从而避免资源冲突和重复劳动。Redisson客户端简化了Redis分布式锁的使用,使得在Spring Boot应用中实现分布式锁变得简单而高效。

7. 发布/订阅

针对Redis作为发布/订阅消息队列的使用场景,下面是一个Java Spring Boot应用的案例,其中使用Redis的发布/订阅功能来实现一个简单的实时消息通知系统。

场景描述

假设我们正在开发一个社交媒体平台,需要实现一个功能,当用户发布新帖子时,他/她的关注者能够实时收到通知。

环境准备

  1. 安装Java开发环境。

  2. 安装Redis并确保其运行。

  3. 创建一个Spring Boot项目,并添加以下依赖:

  • Spring Data Redis Reactive (对于响应式编程)

  • Spring WebFlux (响应式Web框架)

创建Spring Boot项目

使用Spring Initializr (https://start.spring.io/) 创建一个项目,并添加所需的依赖。

配置Redis连接

在src/main/resources/application.properties中配置Redis服务器的连接信息:

spring.redis.host=localhost
spring.redis.port=6379

编写业务代码

  1. 配置发布/订阅通道

创建一个配置类来定义发布者和订阅者使用的通道。

@Configuration
public class RedisPubSubConfig {@Beanpublic ReactiveRedisConnectionFactory reactiveRedisConnectionFactory(LettuceClientConfiguration clientConfig) {return new LettuceConnectionFactory(clientConfig);}@Beanpublic RedisMessageListenerContainer redisMessageListenerContainer(ReactiveRedisConnectionFactory connectionFactory) {RedisMessageListenerContainer container = new RedisMessageListenerContainer();container.setConnectionFactory(connectionFactory);container.addMessageListener(new PostNotificationListener(), new PatternTopic("newPostChannel"));return container;}@Beanpublic LettuceClientConfiguration clientConfig() {return LettuceClientConfiguration.defaultConfiguration();}@Componentpublic class PostNotificationListener implements MessageListener<String, String> {@Overridepublic void onMessage(Message<String, String> message) {// 处理接收到的帖子通知String postContent = message.getBody();System.out.println("New post notification received: " + postContent);// 这里可以添加逻辑,比如通知关注者}}
}

        2.发送新帖子通知

创建一个服务类来发送新帖子的通知。

@Service
public class PostService {@Autowiredprivate ReactiveRedisTemplate<String, String> reactiveRedisTemplate;public Mono<Void> publishNewPostNotification(String postContent) {return reactiveRedisTemplate.convertAndSend("newPostChannel", postContent);}
}

3.创建控制器

创建一个控制器来处理新帖子的发布请求。

@RestController
@RequestMapping("/posts")
public class PostController {@Autowiredprivate PostService postService;@PostMappingpublic Mono<ResponseEntity<?>> createPost(@RequestBody String postContent) {return postService.publishNewPostNotification(postContent).then(Mono.just(ResponseEntity.ok().build())).defaultIfEmpty(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build());}
}

详细解释

  • 配置发布/订阅通道:RedisPubSubConfig配置类设置了ReactiveRedisConnectionFactory和RedisMessageListenerContainer。PostNotificationListener实现了MessageListener接口,用于接收并处理新帖子的通知。

  • 发送新帖子通知:PostService服务中的publishNewPostNotification方法使用ReactiveRedisTemplate的convertAndSend方法将新帖子的内容发布到newPostChannel通道。

  • 创建控制器:PostController提供了一个POST端点/posts,用于接收新帖子的内容。当接收到新帖子的请求时,它将调用PostService的publishNewPostNotification方法将新帖子的内容发送到Redis通道,并返回相应的响应。

通过这种方式,我们可以利用Redis的发布/订阅功能来实现一个高效的实时消息通知系统。每当有新帖子发布时,Redis会将通知消息发布到newPostChannel通道,所有订阅了该通道的监听器(如PostNotificationListener)都会收到消息并进行处理,比如通知帖子作者的关注者。这种模式适用于需要实时通信和通知的业务场景,如社交媒体、实时聊天应用等。

8. 限流

针对Redis作为限流功能的使用场景,下面是一个Java Spring Boot应用的案例,其中使用Redis来实现API的限流。

场景描述

假设我们正在开发一个公共API服务,该服务需要对外部请求进行限流,以防止滥用和过载。我们希望对每个IP地址每分钟的请求次数进行限制。

环境准备

  1. 安装Java开发环境。

  2. 安装Redis并确保其运行。

  3. 创建一个Spring Boot项目,并添加以下依赖:

  • Spring Boot Starter Web

  • Spring Boot Starter Data Redis

创建Spring Boot项目

使用Spring Initializr (https://start.spring.io/) 创建一个项目,并添加所需的依赖。

配置Redis连接@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RateLimit {
    int limit() default 10; // 默认每分钟请求次数限制
    long timeout() default 60; // 默认时间窗口为60秒
}

在src/main/resources/application.properties中配置Redis服务器的连接信息:

spring.redis.host=localhost
spring.redis.port=6379

编写业务代码

  1. 创建限流注解

定义一个自定义注解,用于标识需要限流的API。

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RateLimit {int limit() default 10; // 默认每分钟请求次数限制long timeout() default 60; // 默认时间窗口为60秒
}

2.创建限流拦截器

实现一个拦截器来检查请求频率。

public class RateLimiterInterceptor implements HandlerInterceptor {private final RedisTemplate<String, Integer> redisTemplate;private final String rateLimitKeyPrefix = "rate_limit:";public RateLimiterInterceptor(RedisTemplate<String, Integer> redisTemplate) {this.redisTemplate = redisTemplate;}@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String ip = request.getRemoteAddr();String methodName = ((MethodSignature) (handler)).getMethod().getName();String rateLimitKey = rateLimitKeyPrefix + methodName + ":" + ip;int currentCount = redisTemplate.opsForValue().increment(rateLimitKey);if (currentCount > 1) {// 如果当前计数大于1,则说明请求已超过限制response.sendError(HttpServletResponse.SC_TOO_MANY_REQUESTS, "Too many requests, please try again later.");return false;}// 设置过期时间redisTemplate.expire(rateLimitKey, RateLimit.class.cast(((MethodSignature) handler).getMethod().getAnnotation(RateLimit.class)).timeout(), TimeUnit.SECONDS);return true;}
}

3.配置拦截器

配置拦截器以应用于所有控制器。

@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate RateLimiterInterceptor rateLimiterInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(rateLimiterInterceptor);}
}

4.应用限流注解

在需要限流的API上应用自定义的RateLimit注解。

@RestController
public class ApiController {@RateLimit(limit = 5, timeout = 60) // 每分钟最多5个请求@GetMapping("/api/resource")public ResponseEntity<String> getLimitedResource() {return ResponseEntity.ok("Access to limited resource");}
}

详细解释

  • 创建限流注解:定义了一个RateLimit注解,它包含限制的请求次数和时间窗口。

  • 创建限流拦截器:RateLimiterInterceptor实现了HandlerInterceptor接口,用于在请求处理之前检查请求频率。它使用RedisTemplate来递增每个IP地址的请求计数,并设置计数的过期时间。

  • 配置拦截器:WebConfig类实现了WebMvcConfigurer接口,用于注册RateLimiterInterceptor拦截器,使其应用于所有的控制器方法。

  • 应用限流注解:在ApiController中的getLimitedResource方法上应用了RateLimit注解,指定了每分钟最多5个请求的限制。

通过这种方式,我们可以利用Redis的原子递增操作和键过期特性来实现API的限流。每次请求都会检查当前IP的请求计数,如果超过限制,则返回429错误码(Too Many Requests)。这有助于保护API免受滥用,并确保服务的稳定性和可用性。

9. 数据过期

针对Redis作为数据过期自动清理的使用场景,下面是一个Java Spring Boot应用的案例,其中使用Redis来存储临时数据,比如用户会话信息,并设置过期时间以自动清理这些数据。

场景描述

假设我们正在开发一个Web应用,用户登录后生成的会话信息需要在用户登出或一定时间后自动清除。我们可以使用Redis来存储这些会话信息,并利用它的过期时间特性来自动清理这些会话。

环境准备

  1. 安装Java开发环境。

  2. 安装Redis并确保其运行。

  3. 创建一个Spring Boot项目,并添加以下依赖:

  • Spring Boot Starter Data Redis

  • Spring Session Data Redis

创建Spring Boot项目

使用Spring Initializr (https://start.spring.io/) 创建一个项目,并添加所需的依赖。

配置Redis连接和Spring Session

在src/main/resources/application.properties中配置Redis服务器的连接信息以及Spring Session的存储类型:


spring.redis.host=localhost
spring.redis.port=6379spring.session.store-type=redis

编写业务代码

  1. 配置Spring Session Redis

创建配置类以启用Spring Session的Redis支持:

@Configuration
@EnableRedisHttpSession
public class SessionConfig {// 配置类不需要额外代码,@EnableRedisHttpSession将自动配置所需的Bean
}

2.用户登录和登出逻辑

创建一个控制器来处理用户登录和登出,并存储会话信息:

@Controller
public class SessionController {// 用户登录后,Spring Session会自动存储会话信息到Redis@PostMapping("/login")public String login(SessionStatus sessionStatus, String username) {sessionStatus.setAttribute("username", username);return "loginSuccess";}// 用户登出时,清除会话信息@PostMapping("/logout")public String logout(SessionStatus sessionStatus) {sessionStatus.invalidate();return "logoutSuccess";}
}

3.设置会话超时

创建一个配置类来设置会话的超时时间:

@Configuration
public class SessionTimeoutConfig {@Beanpublic ConfigurableServletWebServerFactory<?> webServerFactory() {TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();factory.setSessionTimeout(30); // 设置会话超时时间(以分钟为单位)return factory;}
}

详细解释

  • 配置Redis连接和Spring Session:在application.properties中配置了Redis服务器的地址和端口,并指定Spring Session使用Redis作为存储。

  • 配置Spring Session Redis:SessionConfig类通过@EnableRedisHttpSession注解启用了Spring Session的Redis支持。Spring Session将自动管理HTTP Session,并将其存储在Redis中。

  • 用户登录和登出逻辑:SessionController控制器提供了登录和登出的处理逻辑。在用户登录时,会将用户名存储到会话中。在用户登出时,会话将被无效化,Spring Session会自动从Redis中清除会话信息。

  • 设置会话超时:SessionTimeoutConfig配置类设置了会话的超时时间。Tomcat的TomcatServletWebServerFactory用于设置会话超时时间,这个时间之后,即使用户没有显式登出,会话也会被自动清除。

通过这种方式,我们可以确保用户的会话信息在一定时间后自动从Redis中清除,无需手动干预。这不仅有助于释放Redis存储空间,还可以提高应用的安全性,防止旧会话被滥用。此外,Spring Session的自动管理简化了会话管理的复杂性,使得开发者可以更专注于业务逻辑的实现。

10. 全页缓存

针对Redis作为全页缓存的使用场景,下面是一个Java Spring Boot应用的案例,其中使用Redis来缓存整个页面的HTML内容。

场景描述

假设我们正在开发一个新闻网站,该网站的首页包含多个新闻文章的摘要信息。由于首页访问频率很高,我们希望将整个首页的内容缓存起来,以减少数据库的查询次数和页面渲染时间。

环境准备

  1. 安装Java开发环境。

  2. 安装Redis并确保其运行。

  3. 创建一个Spring Boot项目,并添加以下依赖:

  • Spring Boot Starter Web

  • Spring Boot Starter Data Redis

创建Spring Boot项目

使用Spring Initializr (https://start.spring.io/) 创建一个项目,并添加所需的依赖。

配置Redis连接

在src/main/resources/application.properties中配置Redis服务器的连接信息:

spring.redis.host=localhost
spring.redis.port=6379

编写业务代码

  1. 创建新闻文章服务

    @Service
    public class NewsService {// 假设有一个方法来获取新闻列表public List<Article> getNewsList() {// 这里是获取新闻列表的逻辑return Collections.emptyList();}
    }
  2. 配置Redis缓存

创建一个配置类来设置Spring Cache和Redis缓存

@Configuration
@EnableCaching
public class CacheConfig {@Beanpublic CacheManager cacheManager(RedisConnectionFactory connectionFactory) {RedisCacheManager cacheManager = new RedisCacheManager(connectionFactory);// 设置缓存过期时间(例如5分钟)cacheManager.setDefaultExpiration(300);return cacheManager;}
}

3.创建控制器和视图

创建一个控制器来返回首页,并使用Redis缓存整个页面。

@Controller
public class NewsController {@Autowiredprivate NewsService newsService;@Autowiredprivate CacheManager cacheManager;@GetMapping("/")@Cacheable(value = "homePage", condition = "#root.caches[0].name == 'homePage'")public String homePage(Model model) {// 尝试从缓存中获取页面model.addAttribute("newsList", newsService.getNewsList());return "home";}
}

 4.创建Thymeleaf模板

创建一个Thymeleaf模板home.html来渲染首页。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><title>首页</title>
</head>
<body><h1>新闻首页</h1><div th:each="article : ${newsList}"><h2 th:text="${article.title}"></h2><p th:text="${article.summary}"></p></div>
</body>
</html>

详细解释

  • 配置Redis连接:在application.properties中配置了Redis服务器的地址和端口。

  • 创建新闻文章服务:NewsService服务包含获取新闻列表的逻辑。

  • 配置Redis缓存:CacheConfig配置类通过@EnableCaching注解启用了Spring的缓存支持,并配置了一个RedisCacheManager Bean来管理Redis缓存

  • 创建控制器和视图:NewsController控制器中的homePage方法使用@Cacheable注解来指定缓存的名称(这里是homePage)。当这个方法被调用时,Spring会检查指定的缓存中是否存在该页面的缓存。如果存在,就直接返回缓存的内容;如果不存在,就执行方法并将结果存储到缓存中。

  • 创建Thymeleaf模板:home.html是一个Thymeleaf模板,用于渲染新闻列表。

通过这种方式,我们可以利用Redis来缓存整个页面的内容。首页的访问非常频繁,通过缓存可以显著减少数据库的查询次数和页面渲染时间,提高网站的响应速度和性能。此外,Spring的缓存抽象和Thymeleaf模板使得实现全页缓存变得简单而高效。

11. 社交功能

针对Redis作为社交功能存储的使用场景,下面是一个Java Spring Boot应用的案例,其中使用Redis来存储用户的社交关系信息,如好友列表和用户状态更新。

场景描述

假设我们正在开发一个社交网络平台,用户可以添加好友,并且可以发布状态更新。我们需要存储每个用户的好友列表以及状态更新的时间线。

环境准备

  1. 安装Java开发环境。

  2. 安装Redis并确保其运行。

  3. 创建一个Spring Boot项目,并添加以下依赖:

  • Spring Boot Starter Data Redis

  • Spring Web

创建Spring Boot项目

使用Spring Initializr (https://start.spring.io/) 创建一个项目,并添加所需的依赖。

配置Redis连接

在src/main/resources/application.properties中配置Redis服务器的连接信息:

spring.redis.host=localhost
spring.redis.port=6379

编写业务代码

  1. 定义用户和状态更新实体类

public class User {private String id;private String name;// 省略构造函数、getter和setter方法
}public class StatusUpdate {private String userId;private String content;private Instant timestamp;// 省略构造函数、getter和setter方法
}
  1. 创建社交服务

@Service
public class SocialService {@Autowiredprivate StringRedisTemplate redisTemplate;public void addFriend(String userOneId, String userTwoId) {// 使用集合存储用户的好友列表redisTemplate.opsForSet().add("friends:" + userOneId, userTwoId);redisTemplate.opsForSet().add("friends:" + userTwoId, userOneId);}public Set<String> getFriends(String userId) {// 获取用户的好友列表return redisTemplate.opsForSet().members("friends:" + userId);}public void postStatusUpdate(String userId, String content) {// 使用列表存储用户的状态更新时间线StatusUpdate statusUpdate = new StatusUpdate(userId, content, Instant.now());redisTemplate.opsForList().rightPush("timeline:" + userId, statusUpdate);}public List<StatusUpdate> getStatusUpdates(String userId) {// 获取用户的状态更新时间线return redisTemplate.opsForList().range("timeline:" + userId, 0, -1);}
}
  1. 创建控制器

@RestController
@RequestMapping("/social")
public class SocialController {@Autowiredprivate SocialService socialService;@PostMapping("/addFriend")public ResponseEntity<String> addFriend(@RequestParam String userOneId, @RequestParam String userTwoId) {socialService.addFriend(userOneId, userTwoId);return ResponseEntity.ok("Friends added successfully");}@GetMapping("/friends/{userId}")public ResponseEntity<Set<String>> getFriends(@PathVariable String userId) {Set<String> friends = socialService.getFriends(userId);return ResponseEntity.ok(friends);}@PostMapping("/status")public ResponseEntity<String> postStatusUpdate(@RequestParam String userId, @RequestParam String content) {socialService.postStatusUpdate(userId, content);return ResponseEntity.ok("Status updated successfully");}@GetMapping("/timeline/{userId}")public ResponseEntity<List<StatusUpdate>> getStatusUpdates(@PathVariable String userId) {List<StatusUpdate> updates = socialService.getStatusUpdates(userId);return ResponseEntity.ok(updates);}
}

详细解释

  • 配置Redis连接:在application.properties中配置了Redis服务器的地址和端口。

  • 定义用户和状态更新实体类:User类代表用户信息,StatusUpdate类代表用户的状态更新信息。

  • 创建社交服务:SocialService服务提供了添加好友、获取好友列表、发布状态更新和获取状态更新时间线的方法。好友列表使用Redis的Set数据结构存储,确保好友关系是无序且不重复的。状态更新时间线使用List数据结构存储,新的状态更新会被添加到列表的尾部。

  • 创建控制器:SocialController控制器提供了四个RESTful API端点,分别用于添加好友、获取好友列表、发布状态更新和获取状态更新时间线。

通过这种方式,我们可以利用Redis的高性能和数据结构特性来实现社交网络平台中的社交功能。Redis的Set和List数据结构非常适合存储和管理好友关系和状态更新时间线,能够提供快速的读写性能,满足社交网络平台的需求。

12. 实时推荐系统

针对Redis作为实时推荐系统存储的使用场景,下面是一个Java Spring Boot应用的案例,其中使用Redis来存储用户行为数据和偏好,以及提供一个简单的推荐功能。

场景描述

假设我们正在开发一个电子商务平台,我们希望根据用户的浏览和购买历史来推荐商品。我们将使用Redis来存储用户的这些行为数据,并根据这些数据生成推荐。

环境准备

  1. 安装Java开发环境。

  2. 安装Redis并确保其运行。

  3. 创建一个Spring Boot项目,并添加以下依赖:

  • Spring Boot Starter Data Redis

  • Spring Web

创建Spring Boot项目

使用Spring Initializr (https://start.spring.io/) 创建一个项目,并添加所需的依赖。

配置Redis连接

在src/main/resources/application.properties中配置Redis服务器的连接信息:

spring.redis.host=localhost
spring.redis.port=6379

编写业务代码

  1. 创建商品和用户实体类

public class Product {private String id;private String name;// 省略构造函数、getter和setter方法
}public class User {private String id;private String username;// 省略构造函数、getter和setter方法
}
  1. 创建推荐服务

@Service
public class RecommendationService {@Autowiredprivate StringRedisTemplate redisTemplate;public void recordView(String userId, String productId) {// 记录用户查看的商品redisTemplate.opsForList().leftPush("user:" + userId + ":views", productId);}public List<String> recommendProducts(String userId) {// 简单推荐算法:返回用户查看次数最多的商品Set<String> viewedProducts = redisTemplate.opsForSet().members("user:" + userId + ":views");Map<String, Long> productViewCounts = new HashMap<>();viewedProducts.forEach(productId -> {long count = redisTemplate.opsForValue().decrement("user:" + userId + ":views:" + productId);productViewCounts.put(productId, count);});return productViewCounts.entrySet().stream().sorted(Map.Entry.<String, Long>comparingByValue().reversed()).map(Map.Entry::getKey).collect(Collectors.toList());}
}
  1. 创建控制器

@RestController
@RequestMapping("/recommendations")
public class RecommendationController {@Autowiredprivate RecommendationService recommendationService;@PostMapping("/view")public ResponseEntity<String> recordProductView(@RequestParam String userId, @RequestParam String productId) {recommendationService.recordView(userId, productId);return ResponseEntity.ok("View recorded");}@GetMapping("/products")public ResponseEntity<List<String>> getRecommendations(@RequestParam String userId) {List<String> recommendedProducts = recommendationService.recommendProducts(userId);return ResponseEntity.ok(recommendedProducts);}
}

详细解释

  • 配置Redis连接:在application.properties中配置了Redis服务器的地址和端口。

  • 创建商品和用户实体类:Product类代表商品信息,User类代表用户信息。

  • 创建推荐服务:

    • recordView方法用于记录用户查看的商品。这里使用Redis的List来存储用户的浏览历史,每次用户查看商品时,商品ID被推入到对应用户的List中。

    • recommendProducts方法提供了一个简单的推荐算法。首先,获取用户的浏览历史中的所有商品ID,然后统计每个商品的浏览次数(这里简化处理,每次查看减少商品ID对应的计数器)。最后,根据浏览次数对商品进行排序,并返回用户浏览次数最多的商品列表。

  • 创建控制器:

    • recordProductView端点用于记录用户查看商品的行为。

    • getRecommendations端点用于获取推荐商品列表。

通过这种方式,我们可以利用Redis的高性能和简单的数据结构来快速记录用户行为并生成推荐。虽然这里的推荐算法非常简单,但它展示了如何使用Redis来实现实时推荐系统的基础功能。在实际应用中,推荐算法可能会更复杂,涉及机器学习模型和更丰富的用户行为数据。

13. 地理位置信息

针对Redis作为地理位置信息存储的使用场景,下面是一个Java Spring Boot应用的案例,其中使用Redis的Geospatial索引来实现基于地理位置的推荐功能。

场景描述

假设我们正在开发一款基于位置的社交应用,用户可以查看附近的其他用户或地点。我们需要存储用户的地理位置,并能够查询给定位置附近的用户。

环境准备

  1. 安装Java开发环境。

  2. 安装Redis并确保其运行。(确保Redis版本支持Geospatial索引,如Redis 3.2以上)

  3. 创建一个Spring Boot项目,并添加以下依赖:

  • Spring Boot Starter Data Redis Reactive(如果使用响应式编程)

  • Spring Web

创建Spring Boot项目

使用Spring Initializr (https://start.spring.io/) 创建一个项目,并添加所需的依赖。

配置Redis连接

在src/main/resources/application.properties中配置Redis服务器的连接信息:

spring.redis.host=localhost
spring.redis.port=6379

编写业务代码

  1. 创建用户实体类

public class User {private String id;private String name;private double longitude;private double latitude;// 省略构造函数、getter和setter方法
}
  1. 创建地理位置服务

@Service
public class GeoLocationService {@Autowiredprivate RedisTemplate<String, User> redisTemplate;public void addLocation(String userId, double longitude, double latitude) {User user = new User(userId, "username", longitude, latitude);// 使用Geospatial索引存储用户位置redisTemplate.opsForGeo().add("userLocations", new GeoLocation(user.getLongitude(), user.getLatitude()), userId);}public List<User> getUsersNearby(double longitude, double latitude, double radius) {// 查询给定位置附近的用户List<GeoWithin> nearbyUsersGeo = redisTemplate.opsForGeo().radius("userLocations",new Circle(new GeoCoordinate(latitude, longitude), radius),RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs());List<User> nearbyUsers = new ArrayList<>();for (GeoWithin geoWithin : nearbyUsersGeo) {nearbyUsers.add(redisTemplate.opsForValue().get(geoWithin.getMember()));}return nearbyUsers;}
}
  1. 创建控制器

@RestController
@RequestMapping("/users")
public class UserController {@Autowiredprivate GeoLocationService geoLocationService;@PostMapping("/addLocation")public ResponseEntity<String> addLocation(@RequestParam String userId,@RequestParam double longitude,@RequestParam double latitude) {geoLocationService.addLocation(userId, longitude, latitude);return ResponseEntity.ok("User location added");}@GetMapping("/nearby")public ResponseEntity<List<User>> getUsersNearby(@RequestParam double longitude,@RequestParam double latitude,@RequestParam double radius) {List<User> nearbyUsers = geoLocationService.getUsersNearby(longitude, latitude, radius);return ResponseEntity.ok(nearbyUsers);}
}

详细解释

  • 配置Redis连接:在application.properties中配置了Redis服务器的地址和端口。

  • 创建用户实体类:User类代表用户信息,包括用户的ID、名称、经度和纬度。

  • 创建地理位置服务:

    • addLocation方法用于将用户的地理位置信息存储到Redis的Geospatial索引中。这里使用RedisTemplate的opsForGeo方法来添加位置信息。

    • getUsersNearby方法用于查询给定位置附近的用户。使用radius方法来查找指定半径内的用户,然后从Redis中获取这些用户的详细信息。

  • 创建控制器:

    • addLocation端点允许用户添加其地理位置信息。

    • getUsersNearby端点允许查询指定位置和半径内的附近用户。

通过这种方式,我们可以利用Redis的Geospatial索引来存储和查询地理位置信息。这对于需要基于地理位置提供服务的应用非常有用,如社交网络、共享出行、本地服务推荐等。Redis的Geospatial索引提供了高效的邻近查询功能,可以快速找到指定范围内的用户或其他地理位置相关的实体。

14. 时间序列数据

针对Redis作为时间序列数据存储的使用场景,下面是一个Java Spring Boot应用的案例,其中使用Redis来存储和查询时间序列数据。

场景描述

假设我们正在开发一个监控系统,需要记录服务器的CPU使用率随时间变化的数据。我们将使用Redis的时间序列数据结构来存储这些监控数据,并能够查询任意时间范围内的CPU使用率。

环境准备

  1. 安装Java开发环境。

  2. 安装Redis并确保其运行。(确保Redis版本支持时间序列数据结构,可能需要使用RedisModules如RedisTimeSeries)

  3. 创建一个Spring Boot项目,并添加以下依赖:

  • Spring Boot Starter Data Redis

  • Spring Web

创建Spring Boot项目

使用Spring Initializr (https://start.spring.io/) 创建一个项目,并添加所需的依赖。

配置Redis连接

在src/main/resources/application.properties中配置Redis服务器的连接信息:

spring.redis.host=localhost
spring.redis.port=6379

编写业务代码

  1. 创建监控数据实体类

public class CpuUsageData {private Instant timestamp;private double cpuUsage;// 省略构造函数、getter和 setter 方法
}
  1. 创建监控服务

@Service
public class MonitoringService {@Autowiredprivate LettuceConnectionFactory connectionFactory;public void logCpuUsage(String serverId, double cpuUsage) {// 记录CPU使用率数据CpuUsageData data = new CpuUsageData(Instant.now(), cpuUsage);// 使用Lettuce客户端的命令执行器来与RedisTimeSeries模块交互StatefulRedisConnection<String, CpuUsageData> connection = connectionFactory.connect();try {RedisTimeSeriesCommands<String, CpuUsageData> ts = connection.sync();ts.add(serverId, data.getTimestamp().toEpochMilli() / 1000, data);} finally {connection.close();}}public List<CpuUsageData> getCpuUsageHistory(String serverId, Instant start, Instant end) {// 查询指定时间范围内的CPU使用率历史数据List<CpuUsageData> history = new ArrayList<>();StatefulRedisConnection<String, CpuUsageData> connection = connectionFactory.connect();try {RedisTimeSeriesCommands<String, CpuUsageData> ts = connection.sync();Range range = Range.create(start.toEpochMilli() / 1000, end.toEpochMilli() / 1000);Cursor<CpuUsageData> cursor = ts.rangeRead(serverId, range);while (cursor.hasNext()) {history.add(cursor.next().getValue());}} finally {connection.close();}return history;}
}
  1. 创建控制器

@RestController
@RequestMapping("/monitoring")
public class MonitoringController {@Autowiredprivate MonitoringService monitoringService;@PostMapping("/logCpuUsage")public ResponseEntity<String> logCpuUsage(@RequestParam String serverId, @RequestParam double cpuUsage) {monitoringService.logCpuUsage(serverId, cpuUsage);return ResponseEntity.ok("CPU usage logged");}@GetMapping("/cpuUsageHistory")public ResponseEntity<List<CpuUsageData>> getCpuUsageHistory(@RequestParam String serverId,@RequestParam Instant start,@RequestParam Instant end) {List<CpuUsageData> history = monitoringService.getCpuUsageHistory(serverId, start, end);return ResponseEntity.ok(history);}
}

详细解释

  • 配置Redis连接:在application.properties中配置了Redis服务器的地址和端口。

  • 创建监控数据实体类:CpuUsageData类代表CPU使用率数据,包括时间戳和CPU使用率。

  • 创建监控服务:

    • logCpuUsage方法用于记录服务器的CPU使用率。使用Lettuce客户端的同步命令执行器与RedisTimeSeries模块交互,将数据添加到时间序列中。

    • getCpuUsageHistory方法用于查询指定时间范围内的CPU使用率历史数据。使用rangeRead方法从时间序列中读取数据。

  • 创建控制器:

    • logCpuUsage端点允许记录服务器的CPU使用率。

    • getCpuUsageHistory端点允许查询指定时间范围内的CPU使用率历史数据。

通过这种方式,我们可以利用Redis的RedisTimeSeries模块来存储和查询时间序列数据。这对于需要监控和分析随时间变化的数据的应用非常有用,如服务器监控、网站访问量分析等。RedisTimeSeries提供了高效的时间序列数据存储和查询功能,可以快速插入和检索大量时间戳数据。

15. 任务调度

针对Redis作为任务调度的使用场景,下面是一个Java Spring Boot应用的案例,其中使用Redis的延迟队列特性来实现任务调度。

场景描述

假设我们正在开发一个定时任务管理系统,需要安排一些任务在将来的某个时间点执行。我们将使用Redis的schedule命令来安排任务的执行。

环境准备

  1. 安装Java开发环境。

  2. 安装支持schedule命令的Redis版本(Redis 5.0及以上版本)。

  3. 创建一个Spring Boot项目,并添加以下依赖:

  • Spring Boot Starter Data Redis

  • Spring Web

创建Spring Boot项目

使用Spring Initializr (https://start.spring.io/) 创建一个项目,并添加所需的依赖。

配置Redis连接

在src/main/resources/application.properties中配置Redis服务器的连接信息:

spring.redis.host=localhost
spring.redis.port=6379

编写业务代码

  1. 创建任务调度服务

@Service
public class TaskSchedulingService {@Autowiredprivate RedisTemplate<String, Runnable> redisTemplate;public void scheduleTask(Runnable task, long delay, TimeUnit timeUnit) {// 将任务和延迟时间存储到Redis中redisTemplate.opsForValue().set("task:" + task.hashCode(), task, timeUnit.toSeconds(delay), timeUnit);// 使用schedule命令安排任务在未来执行String scheduleCommand = String.format("SCHEDULE %d %s", System.currentTimeMillis() + timeUnit.toMillis(delay), "task:" + task.hashCode());redisTemplate.execute((RedisConnection connection) -> {connection.schedule(scheduleCommand);return null;});}
}
  1. 创建具体的任务

public class SampleTask implements Runnable {@Overridepublic void run() {System.out.println("Task is running: " + LocalDateTime.now());// 执行任务逻辑}
}
  1. 创建控制器

@RestController
@RequestMapping("/tasks")
public class TaskController {@Autowiredprivate TaskSchedulingService taskSchedulingService;@PostMapping("/schedule")public ResponseEntity<String> scheduleTask(@RequestParam long delay, @RequestParam TimeUnit timeUnit) {taskSchedulingService.scheduleTask(new SampleTask(), delay, timeUnit);return ResponseEntity.ok("Task scheduled for execution at " + LocalDateTime.now().plusNanos(timeUnit.toNanos(delay)));}
}

详细解释

  • 配置Redis连接:在application.properties中配置了Redis服务器的地址和端口。

  • 创建任务调度服务:scheduleTask方法用于安排一个Runnable任务在未来的某个时间点执行。首先,任务被存储到Redis中,并设置相应的延迟时间。然后,使用Redis的schedule命令安排任务在未来执行。

  • 创建具体的任务:SampleTask类实现了Runnable接口,定义了任务的具体执行逻辑。

  • 创建控制器:scheduleTask端点允许用户安排任务在未来执行。用户需要提供延迟时间和时间单位。

通过这种方式,我们可以利用Redis的schedule命令来安排任务的执行。这对于需要执行定时任务的应用非常有用,如定时数据备份、定时发送通知等。通过Redis的延迟队列特性,我们可以简化任务调度的复杂性,并且能够灵活地安排任务在未来的任意时间点执行。

16. 数据共享

针对Redis作为数据共享的使用场景,下面是一个Java Spring Boot应用的案例,其中使用Redis来实现微服务架构中的服务间数据共享。

场景描述

假设我们有一个电商平台,它由多个微服务组成,比如用户服务、产品服务和订单服务。这些服务需要共享购物车数据,以确保用户在平台上的购物体验是连贯的。我们将使用Redis来存储和共享购物车数据。

环境准备

  1. 安装Java开发环境。

  2. 安装Redis并确保其运行。

  3. 创建一个Spring Boot项目,并添加以下依赖:

  • Spring Boot Starter Data Redis

  • Spring Web

创建Spring Boot项目

使用Spring Initializr (https://start.spring.io/) 创建一个项目,并添加所需的依赖。

配置Redis连接

在src/main/resources/application.properties中配置Redis服务器的连接信息:

spring.redis.host=localhost
spring.redis.port=6379

编写业务代码

  1. 创建购物车项实体类

public class CartItem {private String productId;private int quantity;// 省略构造函数、getter和setter方法
}
  1. 创建购物车服务

@Service
public class CartService {@Autowiredprivate StringRedisTemplate redisTemplate;public void addToCart(String cartId, String productId, int quantity) {// 将购物车项存储到Redis的Hash结构中redisTemplate.opsForHash().put("cart:" + cartId, productId, quantity);}public Map<String, Integer> getCart(String cartId) {// 从Redis获取购物车内容return redisTemplate.opsForHash().entries("cart:" + cartId);}
}
  1. 创建控制器

@RestController
@RequestMapping("/cart")
public class CartController {@Autowiredprivate CartService cartService;@PostMapping("/{cartId}/items")public ResponseEntity<String> addToCart(@PathVariable String cartId,@RequestParam String productId,@RequestParam int quantity) {cartService.addToCart(cartId, productId, quantity);return ResponseEntity.ok("Item added to cart");}@GetMapping("/{cartId}")public ResponseEntity<Map<String, Integer>> getCart(@PathVariable String cartId) {Map<String, Integer> cart = cartService.getCart(cartId);return ResponseEntity.ok(cart);}
}

详细解释

  • 配置Redis连接:在application.properties中配置了Redis服务器的地址和端口。

  • 创建购物车项实体类:CartItem类代表购物车中的商品项,包含商品ID和数量。

  • 创建购物车服务:

    • addToCart方法用于将商品项添加到用户的购物车中。使用Redis的Hash结构来存储购物车数据,其中cart:加上cartId作为Hash的键,productId作为字段名,quantity作为字段值。

    • getCart方法用于从Redis获取用户的购物车内容。

  • 创建控制器:

    • addToCart端点允许用户将商品添加到购物车中。

    • getCart端点允许用户获取其购物车的内容。

通过这种方式,我们可以利用Redis的高性能和数据共享能力来实现微服务架构中的服务间数据共享。购物车数据被存储在Redis中,可以被不同的微服务实例访问和修改,确保了数据的一致性和实时性。这对于需要高度协同工作的分布式系统非常有用,如电商平台、在线协作工具等。

17. 持久化

针对Redis作为任务调度使用场景,下面是一个Java Spring Boot应用的案例,其中使用Spring的@Scheduled注解与Redisson结合来实现任务调度。

场景描述

假设我们有一个自动化的营销平台,需要定期(例如每天凌晨1点)执行一些任务,比如发送时事通讯邮件给订阅用户。我们将使用Spring的定时任务功能结合Redisson来确保分布式环境下任务的准时和准确执行。

环境准备

  1. 安装Java开发环境。

  2. 安装Redis并确保其运行。

  3. 创建一个Spring Boot项目,并添加以下依赖:

  • Spring Boot Starter Web

  • Spring Boot Starter Data Redis

  • Redisson

创建Spring Boot项目

使用Spring Initializr (https://start.spring.io/) 创建一个项目,并添加所需的依赖。

配置Redis连接

在src/main/resources/application.properties中配置Redis服务器的连接信息:

spring.redis.host=localhost
spring.redis.port=6379

编写业务代码

  1. 创建任务执行服务

@Service
public class ScheduledTaskService {public void executeTask() {// 执行任务的逻辑,例如发送邮件System.out.println("Executing scheduled task: " + LocalDateTime.now());}
}
  1. 配置Redisson

创建一个配置类来配置Redisson客户端。

@Configuration
public class RedissonConfig {@Bean(destroyMethod = "shutdown")public RedissonClient redissonClient() {RedissonClientConfig config = new RedissonClientConfig();config.useSingleServer().setAddress("redis://" + spring.redis.host + ":" + spring.redis.port);return Redisson.create(config);}@Value("${spring.redis.host}")private String redisHost;@Value("${spring.redis.port}")private int redisPort;
}
  1. 创建定时任务配置

使用Redisson的RedissonScheduledExecutorService来创建一个分布式的调度器。

@Configuration
public class ScheduledConfig {@Beanpublic RedissonScheduledExecutorService redissonScheduledExecutorService(RedissonClient redissonClient) {return redissonClient.getExecutorService("myScheduler");}
}
  1. 创建定时任务

使用Spring的@Scheduled注解和Redisson的调度器来执行定时任务。

@Component
public class ScheduledTasks {@Autowiredprivate ScheduledTaskService taskService;@Autowiredprivate RedissonScheduledExecutorService scheduler;@Scheduled(cron = "0 0 1 * * ?") // 每天凌晨1点执行public void scheduledTask() {scheduler.schedule(() -> taskService.executeTask(), 0, TimeUnit.SECONDS);}
}

详细解释

  • 配置Redis连接:在application.properties中配置了Redis服务器的地址和端口。

  • 创建任务执行服务:ScheduledTaskService服务包含实际要执行的任务逻辑。

  • 配置Redisson:RedissonConfig配置类设置了Redisson客户端,用于后续创建分布式调度器。

  • 创建定时任务配置:ScheduledConfig配置类创建了一个RedissonScheduledExecutorService Bean,它将被用作分布式任务调度器。

  • 创建定时任务:ScheduledTasks组件包含一个用@Scheduled注解的方法,该方法根据指定的cron表达式触发。当触发时,它使用Redisson的调度器来安排任务的执行。

通过这种方式,我们可以利用Spring的定时任务功能和Redisson的分布式调度器来实现任务调度。这确保了即使在分布式系统中,任务也能准时和准确地执行,避免了任务执行的冲突和重复。这对于需要定时执行的任务,如发送时事通讯、数据备份、报告生成等场景非常有用

  1. 创建社交服务

@Service
public class SocialService {@Autowiredprivate StringRedisTemplate redisTemplate;public void addFriend(String userOneId, String userTwoId) {// 使用集合存储用户的好友列表redisTemplate.opsForSet().add("friends:" + userOneId, userTwoId);redisTemplate.opsForSet().add("friends:" + userTwoId, userOneId);}public Set<String> getFriends(String userId) {// 获取用户的好友列表return redisTemplate.opsForSet().members("friends:" + userId);}public void postStatusUpdate(String userId, String content) {// 使用列表存储用户的状态更新时间线StatusUpdate statusUpdate = new StatusUpdate(userId, content, Instant.now());redisTemplate.opsForList().rightPush("timeline:" + userId, statusUpdate);}public List<StatusUpdate> getStatusUpdates(String userId) {// 获取用户的状态更新时间线return redisTemplate.opsForList().range("timeline:" + userId, 0, -1);}
}
  1. 创建控制器

@RestController
@RequestMapping("/social")
public class SocialController {@Autowiredprivate SocialService socialService;@PostMapping("/addFriend")public ResponseEntity<String> addFriend(@RequestParam String userOneId, @RequestParam String userTwoId) {socialService.addFriend(userOneId, userTwoId);return ResponseEntity.ok("Friends added successfully");}@GetMapping("/friends/{userId}")public ResponseEntity<Set<String>> getFriends(@PathVariable String userId) {Set<String> friends = socialService.getFriends(userId);return ResponseEntity.ok(friends);}@PostMapping("/status")public ResponseEntity<String> postStatusUpdate(@RequestParam String userId, @RequestParam String content) {socialService.postStatusUpdate(userId, content);return ResponseEntity.ok("Status updated successfully");}@GetMapping("/timeline/{userId}")public ResponseEntity<List<StatusUpdate>> getStatusUpdates(@PathVariable String userId) {List<StatusUpdate> updates = socialService.getStatusUpdates(userId);return ResponseEntity.ok(updates);}
}

详细解释

  • 配置Redis连接:在application.properties中配置了Redis服务器的地址和端口。

  • 定义用户和状态更新实体类:User类代表用户信息,StatusUpdate类代表用户的状态更新信息。

  • 创建社交服务:SocialService服务提供了添加好友、获取好友列表、发布状态更新和获取状态更新时间线的方法。好友列表使用Redis的Set数据结构存储,确保好友关系是无序且不重复的。状态更新时间线使用List数据结构存储,新的状态更新会被添加到列表的尾部。

  • 创建控制器:SocialController控制器提供了四个RESTful API端点,分别用于添加好友、获取好友列表、发布状态更新和获取状态更新时间线。

通过这种方式,我们可以利用Redis的高性能和数据结构特性来实现社交网络平台中的社交功能。Redis的Set和List数据结构非常适合存储和管理好友关系和状态更新时间线,能够提供快速的读写性能,满足社交网络平台的需求。

12. 实时推荐系统

针对Redis作为实时推荐系统存储的使用场景,下面是一个Java Spring Boot应用的案例,其中使用Redis来存储用户行为数据和偏好,以及提供一个简单的推荐功能。

场景描述

假设我们正在开发一个电子商务平台,我们希望根据用户的浏览和购买历史来推荐商品。我们将使用Redis来存储用户的这些行为数据,并根据这些数据生成推荐。

环境准备

  1. 安装Java开发环境。

  2. 安装Redis并确保其运行。

  3. 创建一个Spring Boot项目,并添加以下依赖:

  • Spring Boot Starter Data Redis

  • Spring Web

创建Spring Boot项目

使用Spring Initializr (https://start.spring.io/) 创建一个项目,并添加所需的依赖。

配置Redis连接

在src/main/resources/application.properties中配置Redis服务器的连接信息:

spring.redis.host=localhost
spring.redis.port=6379

编写业务代码

  1. 创建商品和用户实体类

public class Product {private String id;private String name;// 省略构造函数、getter和setter方法
}public class User {private String id;private String username;// 省略构造函数、getter和setter方法
}
  1. 创建推荐服务

@Service
public class RecommendationService {@Autowiredprivate StringRedisTemplate redisTemplate;public void recordView(String userId, String productId) {// 记录用户查看的商品redisTemplate.opsForList().leftPush("user:" + userId + ":views", productId);}public List<String> recommendProducts(String userId) {// 简单推荐算法:返回用户查看次数最多的商品Set<String> viewedProducts = redisTemplate.opsForSet().members("user:" + userId + ":views");Map<String, Long> productViewCounts = new HashMap<>();viewedProducts.forEach(productId -> {long count = redisTemplate.opsForValue().decrement("user:" + userId + ":views:" + productId);productViewCounts.put(productId, count);});return productViewCounts.entrySet().stream().sorted(Map.Entry.<String, Long>comparingByValue().reversed()).map(Map.Entry::getKey).collect(Collectors.toList());}
}
  1. 创建控制器

@RestController
@RequestMapping("/recommendations")
public class RecommendationController {@Autowiredprivate RecommendationService recommendationService;@PostMapping("/view")public ResponseEntity<String> recordProductView(@RequestParam String userId, @RequestParam String productId) {recommendationService.recordView(userId, productId);return ResponseEntity.ok("View recorded");}@GetMapping("/products")public ResponseEntity<List<String>> getRecommendations(@RequestParam String userId) {List<String> recommendedProducts = recommendationService.recommendProducts(userId);return ResponseEntity.ok(recommendedProducts);}
}

详细解释

  • 配置Redis连接:在application.properties中配置了Redis服务器的地址和端口。

  • 创建商品和用户实体类:Product类代表商品信息,User类代表用户信息。

  • 创建推荐服务:

    • recordView方法用于记录用户查看的商品。这里使用Redis的List来存储用户的浏览历史,每次用户查看商品时,商品ID被推入到对应用户的List中。

    • recommendProducts方法提供了一个简单的推荐算法。首先,获取用户的浏览历史中的所有商品ID,然后统计每个商品的浏览次数(这里简化处理,每次查看减少商品ID对应的计数器)。最后,根据浏览次数对商品进行排序,并返回用户浏览次数最多的商品列表。

  • 创建控制器:

    • recordProductView端点用于记录用户查看商品的行为。

    • getRecommendations端点用于获取推荐商品列表。

通过这种方式,我们可以利用Redis的高性能和简单的数据结构来快速记录用户行为并生成推荐。虽然这里的推荐算法非常简单,但它展示了如何使用Redis来实现实时推荐系统的基础功能。在实际应用中,推荐算法可能会更复杂,涉及机器学习模型和更丰富的用户行为数据。

13. 地理位置信息

针对Redis作为地理位置信息存储的使用场景,下面是一个Java Spring Boot应用的案例,其中使用Redis的Geospatial索引来实现基于地理位置的推荐功能。

场景描述

假设我们正在开发一款基于位置的社交应用,用户可以查看附近的其他用户或地点。我们需要存储用户的地理位置,并能够查询给定位置附近的用户。

环境准备

  1. 安装Java开发环境。

  2. 安装Redis并确保其运行。(确保Redis版本支持Geospatial索引,如Redis 3.2以上)

  3. 创建一个Spring Boot项目,并添加以下依赖:

  • Spring Boot Starter Data Redis Reactive(如果使用响应式编程)

  • Spring Web

创建Spring Boot项目

使用Spring Initializr (https://start.spring.io/) 创建一个项目,并添加所需的依赖。

配置Redis连接

在src/main/resources/application.properties中配置Redis服务器的连接信息:

spring.redis.host=localhost
spring.redis.port=6379

编写业务代码

  1. 创建用户实体类

public class User {private String id;private String name;private double longitude;private double latitude;// 省略构造函数、getter和setter方法
}
  1. 创建地理位置服务

@Service
public class GeoLocationService {@Autowiredprivate RedisTemplate<String, User> redisTemplate;public void addLocation(String userId, double longitude, double latitude) {User user = new User(userId, "username", longitude, latitude);// 使用Geospatial索引存储用户位置redisTemplate.opsForGeo().add("userLocations", new GeoLocation(user.getLongitude(), user.getLatitude()), userId);}public List<User> getUsersNearby(double longitude, double latitude, double radius) {// 查询给定位置附近的用户List<GeoWithin> nearbyUsersGeo = redisTemplate.opsForGeo().radius("userLocations",new Circle(new GeoCoordinate(latitude, longitude), radius),RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs());List<User> nearbyUsers = new ArrayList<>();for (GeoWithin geoWithin : nearbyUsersGeo) {nearbyUsers.add(redisTemplate.opsForValue().get(geoWithin.getMember()));}return nearbyUsers;}
}
  1. 创建控制器

@RestController
@RequestMapping("/users")
public class UserController {@Autowiredprivate GeoLocationService geoLocationService;@PostMapping("/addLocation")public ResponseEntity<String> addLocation(@RequestParam String userId,@RequestParam double longitude,@RequestParam double latitude) {geoLocationService.addLocation(userId, longitude, latitude);return ResponseEntity.ok("User location added");}@GetMapping("/nearby")public ResponseEntity<List<User>> getUsersNearby(@RequestParam double longitude,@RequestParam double latitude,@RequestParam double radius) {List<User> nearbyUsers = geoLocationService.getUsersNearby(longitude, latitude, radius);return ResponseEntity.ok(nearbyUsers);}
}

详细解释

  • 配置Redis连接:在application.properties中配置了Redis服务器的地址和端口。

  • 创建用户实体类:User类代表用户信息,包括用户的ID、名称、经度和纬度。

  • 创建地理位置服务:

    • addLocation方法用于将用户的地理位置信息存储到Redis的Geospatial索引中。这里使用RedisTemplate的opsForGeo方法来添加位置信息。

    • getUsersNearby方法用于查询给定位置附近的用户。使用radius方法来查找指定半径内的用户,然后从Redis中获取这些用户的详细信息。

  • 创建控制器:

    • addLocation端点允许用户添加其地理位置信息。

    • getUsersNearby端点允许查询指定位置和半径内的附近用户。

通过这种方式,我们可以利用Redis的Geospatial索引来存储和查询地理位置信息。这对于需要基于地理位置提供服务的应用非常有用,如社交网络、共享出行、本地服务推荐等。Redis的Geospatial索引提供了高效的邻近查询功能,可以快速找到指定范围内的用户或其他地理位置相关的实体。

14. 时间序列数据

针对Redis作为时间序列数据存储的使用场景,下面是一个Java Spring Boot应用的案例,其中使用Redis来存储和查询时间序列数据。

场景描述

假设我们正在开发一个监控系统,需要记录服务器的CPU使用率随时间变化的数据。我们将使用Redis的时间序列数据结构来存储这些监控数据,并能够查询任意时间范围内的CPU使用率。

环境准备

  1. 安装Java开发环境。

  2. 安装Redis并确保其运行。(确保Redis版本支持时间序列数据结构,可能需要使用RedisModules如RedisTimeSeries)

  3. 创建一个Spring Boot项目,并添加以下依赖:

  • Spring Boot Starter Data Redis

  • Spring Web

创建Spring Boot项目

使用Spring Initializr (https://start.spring.io/) 创建一个项目,并添加所需的依赖。

配置Redis连接

在src/main/resources/application.properties中配置Redis服务器的连接信息:

spring.redis.host=localhost
spring.redis.port=6379

编写业务代码

  1. 创建监控数据实体类

public class CpuUsageData {private Instant timestamp;private double cpuUsage;// 省略构造函数、getter和 setter 方法
}
  1. 创建监控服务

@Service
public class MonitoringService {@Autowiredprivate LettuceConnectionFactory connectionFactory;public void logCpuUsage(String serverId, double cpuUsage) {// 记录CPU使用率数据CpuUsageData data = new CpuUsageData(Instant.now(), cpuUsage);// 使用Lettuce客户端的命令执行器来与RedisTimeSeries模块交互StatefulRedisConnection<String, CpuUsageData> connection = connectionFactory.connect();try {RedisTimeSeriesCommands<String, CpuUsageData> ts = connection.sync();ts.add(serverId, data.getTimestamp().toEpochMilli() / 1000, data);} finally {connection.close();}}public List<CpuUsageData> getCpuUsageHistory(String serverId, Instant start, Instant end) {// 查询指定时间范围内的CPU使用率历史数据List<CpuUsageData> history = new ArrayList<>();StatefulRedisConnection<String, CpuUsageData> connection = connectionFactory.connect();try {RedisTimeSeriesCommands<String, CpuUsageData> ts = connection.sync();Range range = Range.create(start.toEpochMilli() / 1000, end.toEpochMilli() / 1000);Cursor<CpuUsageData> cursor = ts.rangeRead(serverId, range);while (cursor.hasNext()) {history.add(cursor.next().getValue());}} finally {connection.close();}return history;}
}
  1. 创建控制器

@RestController
@RequestMapping("/monitoring")
public class MonitoringController {@Autowiredprivate MonitoringService monitoringService;@PostMapping("/logCpuUsage")public ResponseEntity<String> logCpuUsage(@RequestParam String serverId, @RequestParam double cpuUsage) {monitoringService.logCpuUsage(serverId, cpuUsage);return ResponseEntity.ok("CPU usage logged");}@GetMapping("/cpuUsageHistory")public ResponseEntity<List<CpuUsageData>> getCpuUsageHistory(@RequestParam String serverId,@RequestParam Instant start,@RequestParam Instant end) {List<CpuUsageData> history = monitoringService.getCpuUsageHistory(serverId, start, end);return ResponseEntity.ok(history);}
}

详细解释

  • 配置Redis连接:在application.properties中配置了Redis服务器的地址和端口。

  • 创建监控数据实体类:CpuUsageData类代表CPU使用率数据,包括时间戳和CPU使用率。

  • 创建监控服务:

    • logCpuUsage方法用于记录服务器的CPU使用率。使用Lettuce客户端的同步命令执行器与RedisTimeSeries模块交互,将数据添加到时间序列中。

    • getCpuUsageHistory方法用于查询指定时间范围内的CPU使用率历史数据。使用rangeRead方法从时间序列中读取数据。

  • 创建控制器:

    • logCpuUsage端点允许记录服务器的CPU使用率。

    • getCpuUsageHistory端点允许查询指定时间范围内的CPU使用率历史数据。

通过这种方式,我们可以利用Redis的RedisTimeSeries模块来存储和查询时间序列数据。这对于需要监控和分析随时间变化的数据的应用非常有用,如服务器监控、网站访问量分析等。RedisTimeSeries提供了高效的时间序列数据存储和查询功能,可以快速插入和检索大量时间戳数据。

15. 任务调度

针对Redis作为任务调度的使用场景,下面是一个Java Spring Boot应用的案例,其中使用Redis的延迟队列特性来实现任务调度。

场景描述

假设我们正在开发一个定时任务管理系统,需要安排一些任务在将来的某个时间点执行。我们将使用Redis的schedule命令来安排任务的执行。

环境准备

  1. 安装Java开发环境。

  2. 安装支持schedule命令的Redis版本(Redis 5.0及以上版本)。

  3. 创建一个Spring Boot项目,并添加以下依赖:

  • Spring Boot Starter Data Redis

  • Spring Web

创建Spring Boot项目

使用Spring Initializr (https://start.spring.io/) 创建一个项目,并添加所需的依赖。

配置Redis连接

在src/main/resources/application.properties中配置Redis服务器的连接信息:

spring.redis.host=localhost
spring.redis.port=6379

编写业务代码

  1. 创建任务调度服务

@Service
public class TaskSchedulingService {@Autowiredprivate RedisTemplate<String, Runnable> redisTemplate;public void scheduleTask(Runnable task, long delay, TimeUnit timeUnit) {// 将任务和延迟时间存储到Redis中redisTemplate.opsForValue().set("task:" + task.hashCode(), task, timeUnit.toSeconds(delay), timeUnit);// 使用schedule命令安排任务在未来执行String scheduleCommand = String.format("SCHEDULE %d %s", System.currentTimeMillis() + timeUnit.toMillis(delay), "task:" + task.hashCode());redisTemplate.execute((RedisConnection connection) -> {connection.schedule(scheduleCommand);return null;});}
}
  1. 创建具体的任务

public class SampleTask implements Runnable {@Overridepublic void run() {System.out.println("Task is running: " + LocalDateTime.now());// 执行任务逻辑}
}
  1. 创建控制器

@RestController
@RequestMapping("/tasks")
public class TaskController {@Autowiredprivate TaskSchedulingService taskSchedulingService;@PostMapping("/schedule")public ResponseEntity<String> scheduleTask(@RequestParam long delay, @RequestParam TimeUnit timeUnit) {taskSchedulingService.scheduleTask(new SampleTask(), delay, timeUnit);return ResponseEntity.ok("Task scheduled for execution at " + LocalDateTime.now().plusNanos(timeUnit.toNanos(delay)));}
}

详细解释

  • 配置Redis连接:在application.properties中配置了Redis服务器的地址和端口。

  • 创建任务调度服务:scheduleTask方法用于安排一个Runnable任务在未来的某个时间点执行。首先,任务被存储到Redis中,并设置相应的延迟时间。然后,使用Redis的schedule命令安排任务在未来执行。

  • 创建具体的任务:SampleTask类实现了Runnable接口,定义了任务的具体执行逻辑。

  • 创建控制器:scheduleTask端点允许用户安排任务在未来执行。用户需要提供延迟时间和时间单位。

通过这种方式,我们可以利用Redis的schedule命令来安排任务的执行。这对于需要执行定时任务的应用非常有用,如定时数据备份、定时发送通知等。通过Redis的延迟队列特性,我们可以简化任务调度的复杂性,并且能够灵活地安排任务在未来的任意时间点执行。

16. 数据共享

针对Redis作为数据共享的使用场景,下面是一个Java Spring Boot应用的案例,其中使用Redis来实现微服务架构中的服务间数据共享。

场景描述

假设我们有一个电商平台,它由多个微服务组成,比如用户服务、产品服务和订单服务。这些服务需要共享购物车数据,以确保用户在平台上的购物体验是连贯的。我们将使用Redis来存储和共享购物车数据。

环境准备

  1. 安装Java开发环境。

  2. 安装Redis并确保其运行。

  3. 创建一个Spring Boot项目,并添加以下依赖:

  • Spring Boot Starter Data Redis

  • Spring Web

创建Spring Boot项目

使用Spring Initializr (https://start.spring.io/) 创建一个项目,并添加所需的依赖。

配置Redis连接

在src/main/resources/application.properties中配置Redis服务器的连接信息:

spring.redis.host=localhost
spring.redis.port=6379

编写业务代码

  1. 创建购物车项实体类

public class CartItem {private String productId;private int quantity;// 省略构造函数、getter和setter方法
}
  1. 创建购物车服务

@Service
public class CartService {@Autowiredprivate StringRedisTemplate redisTemplate;public void addToCart(String cartId, String productId, int quantity) {// 将购物车项存储到Redis的Hash结构中redisTemplate.opsForHash().put("cart:" + cartId, productId, quantity);}public Map<String, Integer> getCart(String cartId) {// 从Redis获取购物车内容return redisTemplate.opsForHash().entries("cart:" + cartId);}
}
  1. 创建控制器

@RestController
@RequestMapping("/cart")
public class CartController {@Autowiredprivate CartService cartService;@PostMapping("/{cartId}/items")public ResponseEntity<String> addToCart(@PathVariable String cartId,@RequestParam String productId,@RequestParam int quantity) {cartService.addToCart(cartId, productId, quantity);return ResponseEntity.ok("Item added to cart");}@GetMapping("/{cartId}")public ResponseEntity<Map<String, Integer>> getCart(@PathVariable String cartId) {Map<String, Integer> cart = cartService.getCart(cartId);return ResponseEntity.ok(cart);}
}

详细解释

  • 配置Redis连接:在application.properties中配置了Redis服务器的地址和端口。

  • 创建购物车项实体类:CartItem类代表购物车中的商品项,包含商品ID和数量。

  • 创建购物车服务:

    • addToCart方法用于将商品项添加到用户的购物车中。使用Redis的Hash结构来存储购物车数据,其中cart:加上cartId作为Hash的键,productId作为字段名,quantity作为字段值。

    • getCart方法用于从Redis获取用户的购物车内容。

  • 创建控制器:

    • addToCart端点允许用户将商品添加到购物车中。

    • getCart端点允许用户获取其购物车的内容。

通过这种方式,我们可以利用Redis的高性能和数据共享能力来实现微服务架构中的服务间数据共享。购物车数据被存储在Redis中,可以被不同的微服务实例访问和修改,确保了数据的一致性和实时性。这对于需要高度协同工作的分布式系统非常有用,如电商平台、在线协作工具等。

17. 持久化

针对Redis作为任务调度使用场景,下面是一个Java Spring Boot应用的案例,其中使用Spring的@Scheduled注解与Redisson结合来实现任务调度。

场景描述

假设我们有一个自动化的营销平台,需要定期(例如每天凌晨1点)执行一些任务,比如发送时事通讯邮件给订阅用户。我们将使用Spring的定时任务功能结合Redisson来确保分布式环境下任务的准时和准确执行。

环境准备

  1. 安装Java开发环境。

  2. 安装Redis并确保其运行。

  3. 创建一个Spring Boot项目,并添加以下依赖:

  • Spring Boot Starter Web

  • Spring Boot Starter Data Redis

  • Redisson

创建Spring Boot项目

使用Spring Initializr (https://start.spring.io/) 创建一个项目,并添加所需的依赖。

配置Redis连接

在src/main/resources/application.properties中配置Redis服务器的连接信息:

spring.redis.host=localhost
spring.redis.port=6379

编写业务代码

  1. 创建任务执行服务

@Service
public class ScheduledTaskService {public void executeTask() {// 执行任务的逻辑,例如发送邮件System.out.println("Executing scheduled task: " + LocalDateTime.now());}
}
  1. 配置Redisson

创建一个配置类来配置Redisson客户端。

@Configuration
public class RedissonConfig {@Bean(destroyMethod = "shutdown")public RedissonClient redissonClient() {RedissonClientConfig config = new RedissonClientConfig();config.useSingleServer().setAddress("redis://" + spring.redis.host + ":" + spring.redis.port);return Redisson.create(config);}@Value("${spring.redis.host}")private String redisHost;@Value("${spring.redis.port}")private int redisPort;
}
  1. 创建定时任务配置

使用Redisson的RedissonScheduledExecutorService来创建一个分布式的调度器。

@Configuration
public class ScheduledConfig {@Beanpublic RedissonScheduledExecutorService redissonScheduledExecutorService(RedissonClient redissonClient) {return redissonClient.getExecutorService("myScheduler");}
}
  1. 创建定时任务

使用Spring的@Scheduled注解和Redisson的调度器来执行定时任务。

@Component
public class ScheduledTasks {@Autowiredprivate ScheduledTaskService taskService;@Autowiredprivate RedissonScheduledExecutorService scheduler;@Scheduled(cron = "0 0 1 * * ?") // 每天凌晨1点执行public void scheduledTask() {scheduler.schedule(() -> taskService.executeTask(), 0, TimeUnit.SECONDS);}
}

详细解释

  • 配置Redis连接:在application.properties中配置了Redis服务器的地址和端口。

  • 创建任务执行服务:ScheduledTaskService服务包含实际要执行的任务逻辑。

  • 配置Redisson:RedissonConfig配置类设置了Redisson客户端,用于后续创建分布式调度器。

  • 创建定时任务配置:ScheduledConfig配置类创建了一个RedissonScheduledExecutorService Bean,它将被用作分布式任务调度器。

  • 创建定时任务:ScheduledTasks组件包含一个用@Scheduled注解的方法,该方法根据指定的cron表达式触发。当触发时,它使用Redisson的调度器来安排任务的执行。

通过这种方式,我们可以利用Spring的定时任务功能和Redisson的分布式调度器来实现任务调度。这确保了即使在分布式系统中,任务也能准时和准确地执行,避免了任务执行的冲突和重复。这对于需要定时执行的任务,如发送时事通讯、数据备份、报告生成等场景非常有用

 


http://www.ppmy.cn/news/1475285.html

相关文章

PHP全功能微信投票迷你平台系统小程序源码

&#x1f525;让决策变得超简单&#xff01;&#x1f389; &#x1f680;【一键创建&#xff0c;秒速启动】 嘿小伙伴们&#xff0c;你还在为组织投票而手忙脚乱吗&#xff1f;来试试这款全功能投票迷你微信小程序吧&#xff01;只需轻轻一点&#xff0c;无论是班级选举、社团…

硅纪元AI应用推荐 | 百度橙篇成新宠,能写万字长文

“硅纪元AI应用推荐”栏目&#xff0c;为您精选最新、最实用的人工智能应用&#xff0c;无论您是AI发烧友还是新手&#xff0c;都能在这里找到提升生活和工作的利器。与我们一起探索AI的无限可能&#xff0c;开启智慧新时代&#xff01; 百度橙篇&#xff0c;作为百度公司在202…

Python练习题(3)

1.使用requests模块获取这个json文件http://java-api.super-yx.com/html/hello.json 2.将获取到的json转为dict 3.将dict保存为hello.json文件 4.用文件流写一个copy(src,dst)函数,复制hello.json到C:\hello.json import requests import jsondef copy(src, dst):read_file o…

【泛型】学习笔记

1.工作中使用反射去创建对象 例子1Getterprivate int type;private Class<? extends AbstractActivity> clazz;ActivityType(int type, Class<? extends AbstractActivity> clazz) {this.type type;this.clazz clazz;}public AbstractActivity newInstance(Ac…

Spark底层原理:案例解析(第34天)

系列文章目录 一、Spark架构设计概述 二、Spark核心组件 三、Spark架构设计举例分析 四、Job调度流程详解 五、Spark交互流程详解 文章目录 系列文章目录前言一、Spark架构设计概述1. 集群资源管理器&#xff08;Cluster Manager&#xff09;2. 工作节点&#xff08;Worker No…

RabbitMQ中常用的三种交换机【Fanout、Direct、Topic】

目录 1、引入 2、Fanout交换机 案例&#xff1a;利用SpringAMQP演示Fanout交换机的使用 3、Direct交换机 案例&#xff1a;利用SpringAMQP演示Direct交换机的使用 4、Topic交换机 案例&#xff1a;利用SpringAMQP演示Topic交换机的使用 1、引入 真实的生产环境都会经过e…

mysql之导入测试数据

运维时经常要这样&#xff1a;mysql改表名&#xff0c;创建一个一样的表不含数据&#xff0c;复制旧表几条数据进去 改变表的名字&#xff1a; RENAME TABLE old_table_name TO new_table_name; 这将把原来的表old_table_name重命名为new_table_name。 创建一个一样的表结构…

MES实时监控食品加工过程中各环节的安全

在实时监控食品加工过程中各环节的安全风险方面&#xff0c;万界星空科技的MES&#xff08;制造执行系统&#xff09;解决方案发挥了至关重要的作用。以下是具体如何通过MES系统实现实时监控食品加工过程中各环节安全风险的详细阐述&#xff1a; 一、集成传感器与实时监控 MES…

1.1 - Android启动概览

第一章 系统启动流程分析 第一节 Android启动概览 Android启动概览可以从多个方面进行描述&#xff0c;包括启动流程、关键组件及其作用等。以下是一个详细的Android启动概览&#xff1a; 一、启动流程 Android设备的启动流程大致可以分为以下几个阶段&#xff1a; 上电与引导…

数据结构实操代码题~考研

作者主页: 知孤云出岫 目录 数据结构实操代码题题目一&#xff1a;实现栈&#xff08;Stack&#xff09;题目二&#xff1a;实现队列&#xff08;Queue&#xff09;题目三&#xff1a;实现二叉搜索树&#xff08;BST&#xff09;题目四&#xff1a;实现链表&#xff08;Linked…

虚幻引擎ue5如何调节物体锚点

当发现锚点不在物体上时&#xff0c;如何调节瞄点在物体上。 步骤1&#xff1a;按住鼠标中键拖动锚点&#xff0c;在透视图中多次调节锚点位置。 步骤2:在物体上点击鼠标右键点击-》锚定--》“设置为枢轴偏移”即可。

2974.最小数字游戏

1.题目描述 你有一个下标从 0 开始、长度为 偶数 的整数数组 nums &#xff0c;同时还有一个空数组 arr 。Alice 和 Bob 决定玩一个游戏&#xff0c;游戏中每一轮 Alice 和 Bob 都会各自执行一次操作。游戏规则如下&#xff1a; 每一轮&#xff0c;Alice 先从 nums 中移除一个 …

机器学习扫盲:优化算法、损失函数、评估指标、激活函数、网络架构

专栏介绍 1.专栏面向零基础或基础较差的机器学习入门的读者朋友,旨在利用实际代码案例和通俗化文字说明,使读者朋友快速上手机器学习及其相关知识体系。 2.专栏内容上包括数据采集、数据读写、数据预处理、分类\回归\聚类算法、可视化等技术。 3.需要强调的是,专栏仅介绍主…

MySQL8之mysql-community-server-debug的作用

mysql-community-server-debug是MySQL社区服务器的一个调试版本&#xff0c;它主要用于开发和调试MySQL数据库服务器。与标准的MySQL社区服务器版本相比&#xff0c;调试版本包含了额外的调试信息和工具&#xff0c;以帮助开发人员和数据库管理员诊断和解决MySQL服务器中的问题…

npm发布的包如何快速在cnpm上使用

npm发布的包如何快速在cnpm上使用 解决方案 前往淘宝npm镜像官网 搜索插件库并点击同步 等待一分钟即可查看最新版本

9.5 栅格图层符号化多波段彩色渲染

文章目录 前言多波段彩色渲染QGis设置为多波段彩色二次开发代码实现多波段彩色 总结 前言 介绍栅格图层数据渲染之多波段彩色渲染说明&#xff1a;文章中的示例代码均来自开源项目qgis_cpp_api_apps 多波段彩色渲染 以“3420C_2010_327_RGB_LATLNG.tif”数据为例&#xff0c…

等保测评新趋势:应对数字化转型中的安全挑战

随着信息技术的飞速发展&#xff0c;数字化转型已成为企业提升竞争力、优化运营效率的重要手段。然而&#xff0c;这一转型过程中&#xff0c;企业也面临着前所未有的安全挑战。等保测评&#xff08;信息安全等级保护测评&#xff09;作为保障信息系统安全的重要手段&#xff0…

Python爬虫教程第5篇-使用BeautifulSoup查找html元素几种常用方法

文章目录 简介find()和find_all()字符串通过id查找通过属性查找通过.方式查找通过CSS选择器查找通过xpath查找正则表达自定义方法总结 简介 上一篇详细的介绍了如何使用Beautiful Soup的使用方法&#xff0c;但是最常用的还是如何解析html元素&#xff0c;这里再汇总介绍下查询…

C# modbus验证

窗体 还有添加的serialPort控件串口通信 设置程序配置 namespace CRC {public static class CRC16{/// <summary>/// CRC校验&#xff0c;参数data为byte数组/// </summary>/// <param name"data">校验数据&#xff0c;字节数组</param>///…

SpringBoot新手快速入门系列教程十一:基于Docker Compose部署一个最简单分布式服务项目

我的教程都是亲自测试可行才发布的&#xff0c;如果有任何问题欢迎留言或者来群里我每天都会解答。 如果您还对于Docker或者Docker Compose不甚了解&#xff0c;可以劳烦移步到我之前的教程&#xff1a; SpringBoot新手快速入门系列教程九&#xff1a;基于docker容器&#xff…