java redis pubsub_使用Redis PubSub与Spring Boot实现微服务消息模型 - vinsguru

本文介绍了如何使用Java和Spring Boot结合Redis的PubSub模型实现微服务之间的异步通信。通过发布者发布笑话到主题,订阅者可以接收到并处理消息。这种方式实现了松耦合和高性能,但不保证消息传递的可靠性,因为如果订阅者离线,可能会丢失消息。
摘要由CSDN通过智能技术生成

PubSub是用于微服务体系结构中服务到服务通信的异步消息传递模型:一个服务(发布者,而不是将消息发送给特定的收件人),它发布的消息到一个主题/通道,通过有关各个订阅者(Subscribers)接收消息。

好处:

一对多通讯,发布者可以发布一条消息,其中N个订阅者可以接收并对消息做出反应。

松耦合,服务不是紧密耦合的。任何服务都可以使用/忽略消息

更好的性能,发布者不必调用N个服务。相反,它只是将消息发布到主题中。它不必对订户有任何了解,不会被堵塞。

缺点:

PubSub是一劳永逸的模型。如果收件者处于脱机状态,则他们可能不会收到该消息。

PubSub是扇出模型。也就是说,同一服务的多个实例将收到该消息。

我们将创建一个2个简单的Spring Boot应用程序。1个将扮演发布者的角色,另一个将成为订阅者。

发布者:此应用程序将定期发布笑话

订户:可以有N个订户。在我们的情况下,我们将有1个订阅者。

当新玩笑发布时,将通知该订户。

订户可以用这个玩笑做任何事情。在我们的情况下,我们将只在控制台上打印。

为笑话创建一个DTO:

@Data

public class Joke implements Serializable {

private static final String JOKE_FORMAT = "Q: %s \nA: %s";

private String setup;

private String punchline;

@Override

public String toString() {

return String.format(JOKE_FORMAT, this.setup, this.punchline);

}

}

Redis PubSub –发布者:

@EnableScheduling

@SpringBootApplication

public class RedisPublisherApplication {

public static void main(String[] args) {

SpringApplication.run(RedisPublisherApplication.class, args);

}

@Bean

public ReactiveRedisOperations jokeTemplate(LettuceConnectionFactory lettuceConnectionFactory){

RedisSerializer valueSerializer = new Jackson2JsonRedisSerializer<>(Joke.class);

RedisSerializationContext serializationContext = RedisSerializationContext.newSerializationContext(RedisSerializer.string())

.value(valueSerializer)

.build();

return new ReactiveRedisTemplate(lettuceConnectionFactory, serializationContext);

}

}

然后,我们自动连接ReactiveRedisOperation以每3秒定期发布一次消息。

@Service

public class PublisherService {

private static final String JOKE_API_ENDPOINT = "https://official-joke-api.appspot.com/jokes/random";

private WebClient webClient;

@Autowired

private ReactiveRedisOperations redisTemplate;

@Value("${topic.name:joke-channel}")

private String topic;

@PostConstruct

private void init(){

this.webClient = WebClient.builder()

.baseUrl(JOKE_API_ENDPOINT)

.build();

}

@Scheduled(fixedRate = 3000)

public void publish(){

this.webClient.get()

.retrieve()

.bodyToMono(Joke.class)

.flatMap(joke -> this.redisTemplate.convertAndSend(topic, joke))

.subscribe();

}

}

Redis PubSub –订阅者:

订户方相对非常简单。在这里,我们只需订阅(侦听)频道,即可在控制台上打印值。我们可以包含多个频道名称。

@Service

public class SubscriberService {

@Autowired

private ReactiveRedisOperations reactiveRedisTemplate;

@Value("${topic.name:joke-channel}")

private String topic;

@PostConstruct

private void init(){

this.reactiveRedisTemplate

.listenTo(ChannelTopic.of(topic))

.map(ReactiveSubscription.Message::getMessage)

.subscribe(System.out::println);

}

}

Dockerizing基础架构:

我在Dockerfile下面使用dockerize发布者和订阅者应用程序。

# Use JRE11 slim

FROM openjdk:11.0-jre-slim

# Add the app jar

ADD target/*.jar redis-pubsub.jar

ENTRYPOINT java -jar redis-pubsub.jar

具有所有依赖项的docker-compose文件

version: '3'

services:

redis:

image: redis

ports:

- 6379:6379

publisher:

build: ./redis-publisher

image: vinsdocker/redis-publisher

depends_on:

- redis

environment:

- SPRING_REDIS_HOST=redis

subscriber:

build: ./redis-subscriber

image: vinsdocker/redis-subscriber

depends_on:

- redis

environment:

- SPRING_REDIS_HOST=redis

演示:

一切准备就绪后,我将一一运行这些命令。

建立项目mvn clean package -DskipTests

构建Docker映像docker-compose build

运行应用程序docker-compose up

总结

通过开发2个简单的微服务,我们能够通过Spring Boot成功演示Redis PubSub。正如我们在上方看到的,发布者和订阅者之间并没有紧密耦合,但是他们仍然能够通过Redis PubSub功能进行通信。

源代码可在此处获得。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,出现"org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection"异常的原因可能是无法获取JDBC连接。这可能是由于以下原因之一导致的: 1. 数据库连接配置错误:请确保数据库连接的配置信息(如URL、用户名、密码)正确,并且数据库服务器正在运行。 2. 数据库连接池问题:如果使用了连接池,可能是连接池配置不正确或连接池已满导致无法获取连接。可以尝试增加连接池的最大连接数或检查连接池配置是否正确。 3. 数据库服务器故障:数据库服务器可能出现故障或不可用。可以尝试重启数据库服务器或联系数据库管理员进行故障排查。 以下是一个Java代码示例,演示如何使用Redispub/sub功能,并处理"org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection"异常: ```java import org.springframework.jdbc.CannotGetJdbcConnectionException; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPubSub; public class RedisPubSubExample { public static void main(String[] args) { Jedis jedis = new Jedis("localhost"); try { jedis.subscribe(new JedisPubSub() { @Override public void onMessage(String channel, String message) { // 处理接收到的消息 System.out.println("Received message: " + message); } }, "channel"); } catch (CannotGetJdbcConnectionException e) { // 处理获取JDBC连接异常 System.out.println("Failed to obtain JDBC Connection: " + e.getMessage()); } finally { jedis.close(); } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值