Programing/Springboot

SpringBoot Redis(Jedis) 활용 Publish/Subscribe pub/sub 구현 방법

리커니 2018. 8. 13.
반응형
SpringBoot Redis(Jedis) 활용 Publish/Subscribe pub/sub 구현 방법

 

 

[Spec]

IDE : Eclipse Mars.2 Release (4.5.2)

SpringBoot : 2.0.2.RELEASE

Jedis : 2.9.0

Dependency Tool : Gradle

 

참고! Redis는 특정서버에 설치되었다는 가정하에 진행합니다.

 

 

용어부터 설명을 하면 Redis는 메모리 기반의 Key/value NoSQL DB 라고 생각하시면 되고

Jedis 는 자바에서 Redis를 좀더 효율적으로 사용하기 위한 클라이언트 입니다.

 

Publish / Subscribe 는 Redis를 사용하는 주요 이유 중에 하나로,

Channel에 값을 올리면(Publish) 그 체널을 바라보고 있는 클라이언트 들에게

그 값이 실시간으로 전달(Subscribe)되는 방식이라고 생각하시면 됩니다.

 

YouTube를 예로들면

크리에이터가 동영상을 올리면 그 크리에이터의 체널을 구독하고 있는 모든 구독자에게

알람이 가게 되죠. 이럴 때 사용하는 것이 Pub/Sub 입니다.

 

그럼 간단하게 용어에 대해서는 알아보았고,

Springboot에서 Jedis를 활용해 Pub/Sub을 구현해 보도록 하겠습니다.

 

우선 Redis 와 Jedis 의 의존성을 주입해 줍니다. (Gradle Dependency 추가)

Spring boot 프로젝트의 build.gradle 을 열어 dependencies 에 아래의 코드를 추가합니다.

 

1
2
3
4
5
6
7
dependencies {
    compile('org.springframework.boot:spring-boot-starter-data-redis')
    compile group: 'redis.clients', name: 'jedis', version: '2.9.0'
    .
    .
    .
}
cs

 

그리고 Package Explorer 에서 해당 프로젝트를 찾아 마우스 오른쪽버튼을 클릭해

Gradle > Refresh Gradle Project 를 해 의존성을 주입받은 라이브러리를 다운받습니다.

그럼 이제 Jedis를 사용할 준비는 되었습니다.  

 

 

 

Publish_Server

 

이제 JedisPool을 사용하기 위한 클래스를 추가하겠습니다.

JedisPool은 Redis 접속을 위한 스레드풀을 관리하는 펙토리로 생각하시면 됩니다.

Redis 접속은 한번만 하고 필요 시 JedisPool 에서 Resource만 받아서 사용하도록 구현하였습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
 
public class JedisPubSubClient {
    private JedisPool pool;
 
    public JedisPubSubClient(String hostName, int port, String password) {
        super();
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        this.pool = new JedisPool(jedisPoolConfig, hostName, port, 1000, password);
    }
    /* jedis pool resource return */
    public Jedis getResource(){
        Jedis jedis = this.pool.getResource();
        return jedis;
    }
    /* jedis pool close method */
    public void close(){
        this.pool.close();
    }
}
cs

 

생성자를 사용해 접속에 필요한 값을 초기화하고

필요시 getResource 메소드를 사용해 리소스를 받고, 사용 후 리소스를 리턴하기 위한 close 메소드를 구현합니다.

 

이제 @SpringBootApplication 이 실행될 때 JedisPubSubClient 를 한번만 실행해 static으로 값을 가지고 있고

필요시에 getResource 메소드를 호출해 리소스를 받아서 Pub/Sub을 진행하면 됩니다.

 

1
CommonGlobalVariable.jedis = new JedisPubSubClient("Redis Host Ip", Redis Port, "Redis Pw");
cs

 

이제 Redis의 체널에 값을 Publish 하기 위해서는 아래와 같이 작성합니다.

 

1
2
3
Jedis jedis = CommonGlobalVariable.jedis.getResource();
jedis.publish("체널명", "전송할 메시지");
jedis.close();
cs

 

글로벌 static 변수에서 jedis resource를 받은 후

Publish 메소드에 체널명과 전송할 메시지 파라메터를 전달해 호출 하면 됩니다.

그리고 그 후에는 close 메소드를 통해 리소스를 반납합니다.

 

Subscribe_Server

 

이제 올린 데이터를 받는 Subscibe를 구현해 보겠습니다.

JedisPubSubClient 를 구현해 @SpringBootApplication 실행 시 static 변수에 받는 부분은 같습니다.

그 후에 이제 체널을 바라보고 있어야 하는 부분을 구현하면 되는데요,

프로젝트 실행 시 아래의 클래스의 start 메소드가 실행되도록 하시면 됩니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void start(){
       try {
           /* Jedis subscribe */
           CommonGlobalVariable.jedis.getResource().subscribe(new JedisPubSub() {
               @Override
               public void onMessage(String channel, String message) {
                   System.out.println(channel);
                   System.out.println(message);
               }
           }, CommonGlobalVariable.RPS_BM_CHANNEL);
     } catch (Exception e) {
           logger.error("Redis subscribe Error!!!", e);
     }
}
cs

 

이제 Publish_Server 에서 publish 하게 되면 Subscribe_Server 에서 channel명과 message가 출력되는 것을

확인 하실 수 있습니다.

 

참고)

Pub/Sub 은 내부적으로 Input/output Stream을 활용한 TCP통신으로 작동합니다.

반응형

댓글

💲 추천 글