๐ ๊ธฐ๋ฅ ์ ์
message pub/sub ๊ธฐ๋ฅ์ผ๋ก ๋๊ตฐ๊ฐ ๋ฉ์ธ์ง๋ฅผ ๋ณด๋ด๊ฒ ๋๋ฉด ํน์ ์ฑ๋์ ๊ตฌ๋ ํ๊ณ ์๋ ๋์์๊ฒ ๋ฉ์ธ์ง๊ฐ ์ ์ก๋๋ ๊ตฌ์กฐ
redis pub/sub ๊ตฌ์กฐ
๐ญ ๋ ๋์ค ์๋ฐ ํด๋ผ์ด์ธํธ
- lettuce
- Jedis
- Redisson
spring boot 2.0 ์ด์ ๋ถํฐ spring-boot-starter-data-redis ์ ๊ธฐ๋ณธ ํด๋ผ์ด์ธํธ๋ lettuce ์ด๋ค.
lettuce๋ Netty(๋น๋๊ธฐ ์ด๋ฒคํธ ๊ธฐ๋ฐ ๊ณ ์ฑ๋ฅ ๋คํธ์ํฌ ํ๋ ์์ํฌ) ๊ธฐ๋ฐ์ Redis ํด๋ผ์ด์ธํธ์ด๋ค.
2.3.6.RELEASE ๋ฒ์ ์ Lettuce client ๊ฐ ์ฌ์ฉ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
๐ญ redis pub/sub ํน์ง
Redis pub/sub์ ๋ณด๋ด๋ ๋ฉ์ธ์ง๋ฅผ ๋ณ๋๋ก ์ ์ฅํ์ง ์๊ณ , ๋ฉ์ธ์ง๋ฅผ ํ ๋ฒ ๋ณด๋ด๋ฉด ์ฌ์ ์ก์ ์ผ์ด๋์ง ์๋๋ค.
Redis ์ด๋์๋ ์ ์ฅ๋์ง ์๊ณ , ํด๋ผ์ด์ธํธ๊ฐ ๋ฉ์ธ์ง ๋ฐ๋ ๊ฒ์ ๋ณด์ฅํ์ง ์๋๋ค.
์ค์๊ฐ ๋ฐ์ดํฐ ์ฒ๋ฆฌํ๋ ๋ฐ์ ๋งค์ฐ ์ ํฉํ์ง๋ง ์์ ๋ด์ฉ์ ๋ฐ๋์ ์ธ์งํ๊ณ ๊ฐ๋ฐ์ ํด์ผํ๋ค.
๐ค Spring boot ๋ก Redis pub/sub ๊ตฌํ
1) redis config ์ค์
spring-boot-starter-data-redis dependency ์ถ๊ฐํด์ค์ผ ํ๋ค! (์ด ์ ๋๋ ๋ค ์๊ฒ ์ง๋ง,, ํน์๋ ํ์ฌ!)
@Bean
public RedisMessageListenerContainer redisMessageListener(RedisConnectionFactory connectionFactory) {
val container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
return container;
}
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(connectionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(String.class));
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer<>(String.class));
return redisTemplate;
}
2) redis publish (๋ฉ์ธ์ง ๋ฐ์ก)
publish ํจ์๋ฅผ ํตํด ๋ฉ์ธ์ง๋ฅผ ๋ฐ์กํ๊ณ ์ ํ๋ topic ๊ณผ String ํํ์ ์ ๋ฌํ message๋ฅผ ํ๋ผ๋ฏธํฐ๋ก ๋ฃ์ด์ฃผ๋ฉด
topic์ ๊ตฌ๋ ํ๊ณ ์๋ ๋ชจ๋ client ์๊ฒ ๋ฉ์ธ์ง๊ฐ ์ ์ก๋๋ค.
@Slf4j
@RequiredArgsConstructor
public class MessagePublish {
private final RedisTemplate<String, Object> redisTemplate;
public void publish(ChannelTopic topic, String message) {
log.info("redis publish >> topic: {}, message: {}", topic.getTopic(), message);
try {
redisTemplate.convertAndSend(topic.getTopic(), message);
} catch (Exception e) {
log.error("redis connection error : {} ", e.getMessage());
}
}
}
3) redis publish (๋ฉ์ธ์ง ๋ฐ์ก)
3-1. @PostConstruct ์ ๋ ธํ ์ด์ ์ ํตํด์ ์๋ฒ๊ฐ ์คํ๋ ๋ "channel"์ด๋ผ๋ ์ฑ๋์ ๋ํด ๋ฉ์ธ์ง๊ฐ ์ค๋์ง ์ฐฝ๊ตฌ๋ฅผ ์ด์ด๋๋ ์ญํ ์ ํ๋ค.
3-2. MessageListener์ onMessageํจ์๋ฅผ ์ค๋ฒ๋ผ์ด๋ํด์ Message๊ฐ ๋ค์ด์ค๋ฉด ํด๋น ํจ์์์ ๋ฉ์ธ์ง๋ฅผ ์ฒ๋ฆฌํ ์ ์๋ค.
@Slf4j
@Service
@RequiredArgsConstructor
public class MessageSub implements MessageListener {
private final RedisTemplate<String, Object> redisTemplate;
private final RedisMessageListenerContainer listenerContainer;
private static final String REDIS_CHANNEL = "channel";
@PostConstruct
public void init() {
listenerContainer.addMessageListener(this, new ChannelTopic(REDIS_CHANNEL));
}
@Override
public void onMessage(Message message, byte[] pattern) {
val now = System.currentTimeMillis();
val msg = (String) redisTemplate.getValueSerializer().deserialize(message.getBody());
log.info("redis recv message. message:{}, pattern:[{}], set now:{}", msg, new String(pattern), now);
}
}
๐ ์ฐธ๊ณ ๋งํฌ
- https://brunch.co.kr/@springboot/374
- lettuce ๊ณต์๋ฌธ์
'SERVER > Spring Boot' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Spring boot] intellij error ํ๋ก์ ํธ ์ ํ ์ค ์๋ฌ (0) | 2023.03.20 |
---|---|
[Spring Boot] JMH - Benchmark Test ์ฌ์ฉํ์ฌ ์ฑ๋ฅ ์ธก์ ํ๊ธฐ (0) | 2023.02.15 |
[Spring] DAO/DTO/VO/Entity ๋? (0) | 2021.08.24 |
[Spring] ๋ก๊ทธ ๋จ๊ธฐ๊ธฐ - Log4j / SLF4J / Logger (0) | 2021.08.24 |
[ErrorLog] ๊ตฌ๊ธ SMTP ๋ฉ์ผ์ ์ก์ ๋ธ๋ฃจ์คํฌ๋ฆฐ ๋จ๋ ํ์ (0) | 2021.01.06 |