原文
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