Search
Duplicate
📒

[고성능 서비스를 위한 Redis] 06. Pub/Sub를 이용한 채팅방 구현

상태
완료
수업
고성능 서비스를 위한 Redis
주제
Redis
연관 노트
3 more properties
참고

Redis Publish / Subscribe

NOTE
Pub/Sub ⇒ 특정한 주제(topic)에 대하여 해당 topic을 구독한 모두에게 메시지를 발행하는 방법이다!
ex) 한명이 채팅방에 채팅을 올리면, 채팅방의 모든 인원에게 메세지가 올라감!

메시징 미들웨어 사용의 장점

비동기
통신의 비동기 처리가 가능하다.
낮은 결합도
송신자와 수신자가 직접 서로 의존하지 않고 공통 미들웨어에 의존한다.
탄력성
구성원들간에 느슨한 연결로 인해 일부 장애가 생겨도 영향이 최소화 된다.

Redis Pub/Sub의 특징

In-Memory 기반이라 매우 빠르게 메세지를 받을 수 있다!
메시지를 단순히 던지는 시스템이기 때문에, 메시지를 큐에서 따로 보관하지 않는다.
수신자가 메시지를 받는것을 보장하지 않는다.
수신자가 아무도 없어도 pub을 실행하면 메시지가 사라진다.
Kafka의 컨슈머 그룹같은 분산처리 개념이 없다.
클라이언트가 늘어날수록 성능이 저하된다.

사용경우

실시간으로 빠르게 전송되어야 하는 메시지
메시지 유실을 감내할 수 있는 케이스
최대 1회 전송패턴이 적합한 경우
Subscriber들이 다양한 채널을 유동적으로 바꾸면서 한시적으로 구독하는 경우

Pub / Sub 명령어

NOTE
Redis 서버를 매개로, 통신하며 클라이언트는 Redis 서버내 채널을 생성한다. 이 채널을 구독(sub)하거나, 메시지(pub)를 보낼 수 있음
# 채널 구독 subscribe channel [채널 이름] # 메시지를 지정한 채널로 송신 publish channel [메시지] # subscribe로 등록한 채널 구독 해제 unsubscribe channle [채널 이름]
Bash
복사

스프링 부트 Redis 채팅방 구현

NOTE
@Configuration public class RedisConfig { @Bean public RedisConnectionFactory redisConnectionFactory(){ return new LettuceConnectionFactory(); } @Bean RedisMessageListenerContainer redisContainer(){ final RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(redisConnectionFactory()); return container; } }
Java
복사
Reids pub/sub 생성
@SpringBootApplication public class HelloworldApplication implements CommandLineRunner { @Autowired private ChatService chatService; public static void main(String[] args) { SpringApplication.run(HelloworldApplication.class, args); } @Override public void run(String... args) { System.out.println("Application started.."); chatService.enterChatRoom("chat1"); } }
Java
복사
Application 시작시 chat1 채팅방에 입장
@Service public class ChatService implements MessageListener { @Autowired private RedisMessageListenerContainer container; @Autowired RedisTemplate<String, String> redisTemplate; public void enterChatRoom(String chatRoomName) { // 채널 등록 container.addMessageListener(this, new ChannelTopic(chatRoomName)); Scanner in = new Scanner(System.in); while (in.hasNextLine()) { String line = in.nextLine(); if (line.equals("q")) { System.out.println("Quit..."); break; } redisTemplate.convertAndSend(chatRoomName, line); } // 끝나면료 container.removeMessageListener(this); } @Override public void onMessage(Message message, byte[] pattern) { System.out.println("Message: " + message.toString()); } }
Java
복사
onMessage로 pub에 메시지가 오면 바로 받아서 출력한다!