使用Spring Boot + Redis 進行實時流處理 - vinsguru
Redis用於快取記憶體資料。除了主/從複製,釋出/訂閱功能和時間序列資料支援外,還新增了對流的支援。Kafka的問題是很難配置。基礎架構維護非常具有挑戰性。但是Redis非常容易並且重量輕。
樣例應用:
- 我們的釋出者將釋出與Redis購買相關的一些偶數。讓我們稱它們為購買事件流。
- 消費者群體有興趣聽這些事件。這可能是用於計算收入或處理付款或傳送電子郵件!
- 當您需要執行所有這些操作時,例如:付款處理和傳送電子郵件,則每個使用者都需要一個單獨的消費者組。
- 消費者將消費事件,他們可以做任何事情。在我們的案例中,我們只是找到使用者支付的價格,然後按類別計算收入。
- 可以將其記錄在單獨的資料庫中。但是為了簡單起見,我將在Redis中將此資訊記錄為SortedSet。
原始碼:
完整的原始碼在這裡。
生產者
理想情況下,生產者和消費者將是兩個不同的微服務/應用程式。在這裡,我們兩個人都將在同一個專案中。但是,我們基於名為“ app.role ”的自定義屬性來控制應用程式的行為,使其像生產者還是消費者。基於該值,將在Spring中建立相應的元件。
@Service @ConditionalOnProperty(name="app.role", havingValue="producer") public class PurchaseEventProducer { private AtomicInteger atomicInteger = new AtomicInteger(0); @Value("${stream.key}") private String streamKey; @Autowired private ProductRepository repository; @Autowired private ReactiveRedisTemplate<String, String> redisTemplate; @Scheduled(fixedRateString= "${publish.rate}") public void publishEvent(){ Product product = this.repository.getRandomProduct(); ObjectRecord<String, Product> record = StreamRecords.newRecord() .ofObject(product) .withStreamKey(streamKey); this.redisTemplate .opsForStream() .add(record) .subscribe(System.out::println); atomicInteger.incrementAndGet(); } @Scheduled(fixedRate = 10000) public void showPublishedEventsSoFar(){ System.out.println( "Total Events :: " + atomicInteger.get() ); } } |
- publishEvent方法定期釋出一些隨機購買的產品。
- showPublishedEventsSoFar方法僅顯示到目前為止已下的訂單數。
消費者
我們的釋出者已經準備好。讓我們建立一個消費者。要使用RedisStreams,我們需要實現StreamListener介面。
@Service @ConditionalOnProperty(name="app.role", havingValue="consumer") public class PurchaseEventConsumer implements StreamListener<String, ObjectRecord<String, Product>> { private AtomicInteger atomicInteger = new AtomicInteger(0); @Autowired private ReactiveRedisTemplate<String, String> redisTemplate; @Override @SneakyThrows public void onMessage(ObjectRecord<String, Product> record) { System.out.println( InetAddress.getLocalHost().getHostName() + " - consumed :" + record.getValue() ); this.redisTemplate .opsForZSet() .incrementScore("revenue", record.getValue().getCategory().toString(), record.getValue().getPrice()) .subscribe(); atomicInteger.incrementAndGet(); } @Scheduled(fixedRate = 10000) public void showPublishedEventsSoFar(){ System.out.println( "Total Consumed :: " + atomicInteger.get() ); } } |
- 我們只簡單地顯示消費記錄。
- 然後,我們獲得支付的價格並將其新增到redis排序集中。
- 像釋出者一樣,我們會定期顯示此使用者消耗的事件數。
Redis流配置
建立使用者後,我們需要透過將上述使用者新增到StreamMessageListenerContainer例項中來建立訂閱。
@Configuration @ConditionalOnProperty(name="app.role", havingValue="consumer") public class RedisStreamConfig { @Value("${stream.key}") private String streamKey; @Autowired private StreamListener<String, ObjectRecord<String, Product>> streamListener; @Bean public Subscription subscription(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException { var options = StreamMessageListenerContainer .StreamMessageListenerContainerOptions .builder() .pollTimeout(Duration.ofSeconds(1)) .targetType(Product.class) .build(); var listenerContainer = StreamMessageListenerContainer .create(redisConnectionFactory, options); var subscription = listenerContainer.receiveAutoAck( Consumer.from(streamKey, InetAddress.getLocalHost().getHostName()), StreamOffset.create(streamKey, ReadOffset.lastConsumed()), streamListener); listenerContainer.start(); return subscription; } } |
詳細執行配置見原文
相關文章
- 使用Spring Boot實現Redis事務 | VinsguruSpring BootRedis
- Spring Boot 2 + Redis 處理 Session 共享Spring BootRedisSession
- spring boot 使用redis進行釋出訂閱Spring BootRedis
- 使用 IDA 處理 U-Boot 二進位制流檔案boot
- Spring Boot 之 Spring Batch 批處理實踐Spring BootBAT
- 使用Spring Boot + Kafka實現Saga分散式事務模式的原始碼 - vinsguruSpring BootKafka分散式模式原始碼
- Spring boot/Spring 統一錯誤處理方案的使用Spring Boot
- spring boot中redis使用Spring BootRedis
- Spring Boot 異常處理Spring Boot
- Spring Boot整合Spring Cloud Task實現批處理操作Spring BootCloud
- SparkStreaming實時流處理學習Spark
- Spring Boot使用JWT進行token驗證Spring BootJWT
- 使用 Spring Boot 和 @SpringBootTest 進行測試Spring Boot
- 使用 Spring Boot 進行單元測試Spring Boot
- 在 Spring Boot 中使用 RedisSpring BootRedis
- 實戰Spring Boot 2.0系列(四) – 使用WebAsyncTask處理非同步任務Spring BootWeb非同步
- 實戰Spring Boot 2.0系列(四) - 使用WebAsyncTask處理非同步任務Spring BootWeb非同步
- Spring Boot統一異常處理最佳實踐Spring Boot
- 如何利用Redis實現延時處理Redis
- 使用 Kotlin + Spring Boot 進行後端開發KotlinSpring Boot後端
- Ajax 處理時進度條使用
- Spring Boot實戰系列(4)統一異常處理Spring Boot
- spring boot 統一異常處理Spring Boot
- spring boot使用Jedis整合Redis實現快取(AOP)Spring BootRedis快取
- Spring Boot整合Redis實戰操作Spring BootRedis
- Spring Boot從入門到實戰(十):非同步處理Spring Boot非同步
- Spring Boot乾貨系列:(十三)Spring Boot全域性異常處理整理Spring Boot
- ELK 處理 Spring Boot 日誌,不錯!Spring Boot
- 29.Spring Boot中異常處理與REST格式處理Spring BootREST
- Spring Boot:使用Redis儲存技術Spring BootRedis
- Spring Boot使用執行緒池處理事務任務Spring Boot執行緒
- 用Spark進行實時流計算Spark
- .NET使用MailKit進行郵件處理AI
- Kafka如何實現實時流處理 Part 1 - André MeloKafka
- 實戰Spring Boot 2.0系列(三) – 使用@Async進行非同步呼叫詳解Spring Boot非同步
- 實戰Spring Boot 2.0系列(三) - 使用@Async進行非同步呼叫詳解Spring Boot非同步
- spring boot使用Java並行流傳送kafka訊息報錯Spring BootJava並行Kafka
- Spring Boot整合RedisSpring BootRedis