[Docker] Springboot + RabbitMQ + Redis 연동 실습

아무튼 간에·2022년 8월 8일
0

개발환경
OS: Windows 11
IDE: Spring Tool Suite 4.14.1
JAVA: 17

Notion으로 더 편하게 보기(클릭)


* RabbitMQ와 Redis를 도커로 실행중이라는 전제 하에 진행
(참고: https://velog.io/@armton/series/Docker)

실습 플로우

  1. 문자열 입력받고
  2. 큐에 넣을때 (publishing)이라 붙이고
  3. 빼는 거 성공하면 (subscribe) 붙이기
  4. 빼낸 거를 이제 레디스에 넣고 (push)라 붙이기
  5. 빼는 거 성공하면 (get) 붙이기

1. Redis 값 저장을 위한 모델 생성

RedisData.java

package com.apple.api.redis.model;

public class RedisData {
	
	private String key;
	private String value;
	
	public RedisData(String key, String value) {
		super();
		this.key = key;
		this.value = value;
	}
	
	// lombok으로 대체 가능
	public String getKey() {
		return key;
	}
	public void setKey(String key) {
		this.key = key;
	}
	public String getValue() {
		return value;
	}
	public void setValue(String value) {
		this.value = value;
	}

}

2. Redis 작업부 작성

package com.apple.api.redis.util;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import com.apple.api.redis.model.RedisData;

@Component
public class RedisUtil {

	@Autowired
	RedisTemplate<String, String> redisTemplate;

	public RedisUtil(RedisTemplate<String, String> redisTemplate) {
		this.redisTemplate = redisTemplate;
	}
	
	// 저장
	public boolean setRedisData(RedisData redisData) {
		ValueOperations<String, String> vop = redisTemplate.opsForValue();
		try {
			// Redis 값 세팅. 단, value에 "(push)"라는 텍스트 붙이기
			vop.set(redisData.getKey(), redisData.getValue() + "(push)");
			return true;
		} catch (Exception e) {
			return false;
		}
	}
	
	// 조회
	public String getRedisData(String key) {
		return redisTemplate.opsForValue().get(key) + "(get)";
	}
	
}

3. RabbitMQ Listener 수정

package com.apple.api.rabbitmq.listener;

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.apple.api.redis.model.RedisData;
import com.apple.api.redis.util.RedisUtil;

@Component
public class Listener {

	// 추가
	@Autowired
	RedisUtil redisUtil;
	
	// Receiver 
	@RabbitListener(queues = "TestQ") // return 불가. 무조건 void
	public void processMessage(String content) {
		redisInsert(content); // RabbitMQ에서 받은 값 전달
	}
	
	// redis에 저장
	public void redisInsert(String content) {
		 // RedisData 모델에 value로 저장. key는 임의로 "key"라고 지정 
		RedisData redisData = new RedisData("key", content.concat("(subscribe)"));
		redisUtil.setRedisData(redisData);
	}
	
}

4. MessageController 수정

package com.apple.api.rabbitmq.controller;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.apple.api.rabbitmq.config.Sender;
import com.apple.api.rabbitmq.listener.Listener;
import com.apple.api.redis.util.RedisUtil;

@RestController
public class MessageController {
	
	@Autowired
    Sender sender;
	
	@Autowired
	Listener listener;

	@Autowired
	RedisUtil redisUtil;
	
    @PostMapping("/messages")
    public String sendMessage(final @RequestBody Map<String,String> req ) {
        String message = req.get("message");
        try {
        	String msg = message + "(publishing)";
					sender.send(msg);
        	
          Thread.sleep(100); // * Redis에서 바로 get하면 실제로 저장되기 전에 get 되는 이슈가 있어서 임시로 delay 시킴.
	        return redisUtil.getRedisData("key");
        }
        catch (Exception e ){
          System.out.println(e.getMessage());
          return "send message fail";
        }
    }
	
}

5. 테스트

  1. Springboot 구동(프로젝트 우클릭 > Run As > SpringBoot App)

  2. Postman에서 메시지 보내기

  3. 응답 Body 확인

profile
armton garnet

0개의 댓글