原文
https://spring.io/guides/gs/messaging-redis/
直译
启动Redis服务器
在构建消息传递应用程序之前,需要设置将处理接收和发送消息的服务器。
Redis是一个开源的,BSD许可的键值数据存储,它还附带了一个消息传递系统。该服务器可在http://redis.io/download免费获得。您可以手动下载,或者如果您使用带自制程序的Mac:
brew install redis
解压缩Redis后,可以使用默认设置启动它。
redis-server
你应该看到这样的消息:
[35142] 01 May 14:36:28.939 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
[35142] 01 May 14:36:28.940 * Max number of open files set to 10032
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 2.6.12 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in stand alone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
| `-._ `._ / _.-' | PID: 35142
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
[35142] 01 May 14:36:28.941 # Server started, Redis version 2.6.12
[35142] 01 May 14:36:28.941 * The server is now ready to accept connections on port 6379
创建Redis消息接收器
在任何基于消息传递的应用程序中,都有消息发布者和消息接收者。要创建消息接收器,请使用响应消息的方法实现接收器:
src/main/java/hello/Receiver.java
package hello;
import java.util.concurrent.CountDownLatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
public class Receiver {
private static final Logger LOGGER = LoggerFactory.getLogger(Receiver.class);
private CountDownLatch latch;
@Autowired
public Receiver(CountDownLatch latch) {
this.latch = latch;
}
public void receiveMessage(String message) {
LOGGER.info("Received <" + message + ">");
latch.countDown();
}
}
这Receiver是一个简单的POJO,它定义了一种接收消息的方法。正如您在注册Receiver消息监听器时所看到的那样,您可以根据需要为消息处理方法命名。
出于演示目的,它由构造函数自动装配,具有倒计时锁存器。这样,它可以在收到消息时发出信号。
注册监听器并发送消息
Spring Data Redis提供了使用Redis发送和接收消息所需的所有组件。具体来说,您需要配置:
-
连接工厂
-
消息侦听器容器
-
Redis模板
您将使用Redis模板发送消息,您将Receiver使用消息侦听器容器注册它以便它将接收消息。连接工厂驱动模板和消息侦听器容器,使它们能够连接到Redis服务器。
此示例使用Spring Boot的默认设置RedisConnectionFactory,其实例JedisConnectionFactory基于Jedis Redis库。连接工厂将注入消息侦听器容器和Redis模板。
src/main/java/hello/Application.java
package hello;
import java.util.concurrent.CountDownLatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
@SpringBootApplication
public class Application {
private static final Logger LOGGER = LoggerFactory.getLogger(Application.class);
@Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
MessageListenerAdapter listenerAdapter) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.addMessageListener(listenerAdapter, new PatternTopic("chat"));
return container;
}
@Bean
MessageListenerAdapter listenerAdapter(Receiver receiver) {
return new MessageListenerAdapter(receiver, "receiveMessage");
}
@Bean
Receiver receiver(CountDownLatch latch) {
return new Receiver(latch);
}
@Bean
CountDownLatch latch() {
return new CountDownLatch(1);
}
@Bean
StringRedisTemplate template(RedisConnectionFactory connectionFactory) {
return new StringRedisTemplate(connectionFactory);
}
public static void main(String[] args) throws InterruptedException {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
StringRedisTemplate template = ctx.getBean(StringRedisTemplate.class);
CountDownLatch latch = ctx.getBean(CountDownLatch.class);
LOGGER.info("Sending message...");
template.convertAndSend("chat", "Hello from Redis!");
latch.await();
System.exit(0);
}
}
listenerAdapter方法中定义的bean在定义的消息侦听器容器中注册为消息侦听器container,并将侦听“chat”主题上的消息。因为Receiver该类是POJO,所以它需要包装在实现所需MessageListener接口的消息侦听器适配器中addMessageListener()。消息侦听器适配器还配置为在消息到达时调用receiveMessage()方法Receiver。
连接工厂和消息监听器容器bean是监听消息所需的全部内容。要发送消息,您还需要Redis模板。这里,它是一个配置为a的bean StringRedisTemplate,其实现RedisTemplate主要集中在Redis的常用用法,其中键和值都是String
s。
该main()方法通过创建Spring应用程序上下文来解决所有问题。然后,应用程序上下文启动消息侦听器容器,并且消息侦听器容器bean开始侦听消息。main()然后,该方法StringRedisTemplate从应用程序上下文中检索bean,并使用它发送“Hello from Redis!” “聊天”主题上的消息。最后,它关闭Spring应用程序上下文,应用程序结束。
构建可执行的JAR
您可以使用Gradle或Maven从命令行运行该应用程序。或者,您可以构建一个包含所有必需依赖项,类和资源的可执行JAR文件,并运行该文件。这使得在整个开发生命周期中,跨不同环境等将服务作为应用程序发布,版本和部署变得容易。
如果您使用的是Gradle,则可以使用./gradlew bootRun。或者您可以使用构建JAR文件./gradlew build。然后你可以运行JAR文件:
java -jar build / libs / gs-messaging-redis-0.1.0.jar
如果您使用的是Maven,则可以使用该应用程序运行该应用程序./mvnw spring-boot:run。或者您可以使用构建JAR文件./mvnw clean package。然后你可以运行JAR文件:
java -jar target / gs-messaging-redis-0.1.0.jar
上面的过程将创建一个可运行的JAR。您也可以选择构建经典WAR文件。
您应该看到以下输出:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.0.5.RELEASE)
2014-04-18 08:03:34.032 INFO 47002 --- [ main] hello.Application : Starting Application on retina with PID 47002 (/Users/gturnquist/src/spring-guides/gs-messaging-redis/complete/target/classes started by gturnquist)
2014-04-18 08:03:34.062 INFO 47002 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@7a53c84a: startup date [Fri Apr 18 08:03:34 CDT 2014]; root of context hierarchy
2014-04-18 08:03:34.326 INFO 47002 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 2147483647
2014-04-18 08:03:34.357 INFO 47002 --- [ main] hello.Application : Started Application in 0.605 seconds (JVM running for 0.899)
2014-04-18 08:03:34.357 INFO 47002 --- [ main] hello.Application : Sending message...
2014-04-18 08:03:34.370 INFO 47002 --- [ container-2] hello.Receiver : Received <Hello from Redis!>
2014-04-18 08:03:34.379 INFO 47002 --- [ Thread-1] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@7a53c84a: startup date [Fri Apr 18 08:03:34 CDT 2014]; root of context hierarchy
2014-04-18 08:03:34.380 INFO 47002 --- [ Thread-1] o.s.c.support.DefaultLifecycleProcessor : Stopping beans in phase 2147483647
摘要
恭喜!您刚刚使用Spring和Redis开发了一个简单的发布 - 订阅应用程序。
Redis支持可用。
扩展知识
实际测试中遇到的异常场景:
本示例在实际测试中,可能出现生产者生产了消息,但是消费者却未消费到消息的情况
在debug模式下,生产者生产消息后,打断点,然后单步调试到消费者消费时,却可以正常消费到消息
由此提出以下猜测:
生产者生产消息时,消费者尚未就绪,导致消息丢失。
挖个坑,后续来填:TODO 进一步排查出现上述场景的原因,如何避免,如何解决
查看运行时某个java对象占用JVM大小及通过idea查看java的内存占用情况
https://blog.csdn.net/qq_2300688967/article/details/84951123