Redisson - Remote Service

Bobby·2021년 8월 24일
0

즐거운 개발일지

목록 보기
3/22
post-thumbnail

1. Redisson - Remote Service

  • Redisson 은 java redis client 중 하나이다.
  • Lettuce, Jedis 보다 불편하지만 많은 기능을 제공 하는 것 같다.
  • 다양한 기능 중 간단한 remote service 를 사용해 본다.
  • remote service 는 다음과 같은 흐름으로 실행 된다. 참고

  • 1개의 워커만 있는 경우에는 순차적으로 실행하고 나머지는 큐에 대기
  • 요청이 순차적으로 실행 되어야 하는 경우에 사용 할 수 있을 것이다.

2. Redis 설치(mac)

  • 설치 및 실행
brew install redis

brew services start redis
brew services stop redis
brew services restart redis
  • 설정 파일 변경
vi /usr/local/etc/redis.conf

requirepass <패스워드>
port <포트번호>
bind <허용할 IP>

3. Remote Service 사용

  • 다음과 같은 형태로 테스트 해볼 예정이다.

프로젝트 구조

remote-interface : redis 설정과 공통으로 사용할 remote service interface

Redisson 을 이용하여 remote service를 등록하고 불러 올때 사용하는 RemoteServiceInterface는 package 가 동일해야 해서 공통으로 사용할 모듈을 분리했다.

  • RedisConfig : 레디스 설정
@EnableCaching
@Configuration
public class RedisConfig {
    @Value("${spring.redis.host}")
    String REDIS_HOST;

    @Value("${spring.redis.port}")
    String REDIS_PORT;

    @Value("${spring.redis.password}")
    String REDIS_PASSWORD;

    @Bean
    public RedissonClient redissonClient() {
        Config redisConfig = new Config();
        redisConfig.useSingleServer()
                .setAddress(REDIS_HOST + ":" + REDIS_PORT)
                .setPassword(REDIS_PASSWORD)
                .setConnectionMinimumIdleSize(5)
                .setConnectionPoolSize(5);
        return Redisson.create(redisConfig);
    }
}
  • RemoteServiceInterface
public interface RemoteServiceInterface {

    String sayHello(String name);
}

remote-worker : redis에 등록할 구현체

  • 웹 기능은 사용하지 않는다.
  • RemoteService : 리모트 서비스 구현체
@Slf4j
@Component
public class RemoteService implements RemoteServiceInterface {

    @Override
    public String sayHello(String name) {
        log.info("run sayHello");
        return "hello " + name;
    }
}
  • ApplicationStartup : 실행시 redis에 구현체를 등록한다.
@Slf4j
@Component
@RequiredArgsConstructor
public class ApplicationStartup implements ApplicationListener<ApplicationReadyEvent> {

    private final RedissonClient redissonClient;

    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        log.info("onApplicationReady time={}", event.getTimestamp());
        try {
            registerRemoteService();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    private void registerRemoteService() throws Exception {
        log.info("RedissonClient config={}", redissonClient.getConfig());
        RRemoteService remoteService = redissonClient.getRemoteService();

        RemoteService remote = new RemoteService();
        remoteService.register(RemoteServiceInterface.class, remote);
        log.info("Remote service is registered!!");
    }
}
  • RemoteWorkerApplication

    실행 시 두 모듈을 스캔 해야 하므로 스캔할 패키지를 적어 준다.

@SpringBootApplication(scanBasePackages = {"com.example.remoteworker","com.example.remoteinterface" })
public class RemoteWorkerApplication {

    public static void main(String[] args) {
        SpringApplication.run(RemoteWorkerApplication.class, args);
    }
}

web : redis에 등록된 remote service 사용

  • TestController
@RestController
@RequiredArgsConstructor
public class TestController {

    private final RedissonClient redissonClient;

    @GetMapping("/hello")
    public String callRemoteService() {
        RemoteInvocationOptions remoteOptions = RemoteInvocationOptions.defaults().expectAckWithin(5000);
        RRemoteService remoteService = redissonClient.getRemoteService();
        RemoteServiceInterface service = remoteService.get(RemoteServiceInterface.class, remoteOptions);
        return service.sayHello("kim");
    }
}

gradle 설정

buildscript {
    ext {
        springBootVersion = '2.5.3'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}"
        classpath "io.spring.gradle:dependency-management-plugin:1.0.4.RELEASE"
    }
}

subprojects {
    apply plugin: 'java'
    apply plugin: 'idea'
    apply plugin: 'org.springframework.boot'
    apply plugin: 'io.spring.dependency-management'

    group 'org.example'
    version '1.0-SNAPSHOT'

    sourceCompatibility = '1.8'
    targetCompatibility = '1.8'
    compileJava.options.encoding = 'UTF-8'

    repositories {
        mavenCentral()
    }

    dependencies {
        compileOnly 'org.projectlombok:lombok'
        implementation group: 'org.redisson', name: 'redisson-spring-boot-starter', version: '3.16.1'
        compileOnly "io.netty:netty-resolver-dns-native-macos:4.1.59.Final:osx-x86_64"


        annotationProcessor 'org.projectlombok:lombok'
        annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"

        testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
        testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
    }

    test {
        useJUnitPlatform()
    }
}

project(':remote-interface') {
    bootJar.enabled = false
    jar.enabled = true

    dependencies {
    }
}

project(':web') {
    dependencies {
        compileOnly project(':remote-interface')
        implementation 'org.springframework.boot:spring-boot-starter-web'
    }
}

project(':remote-worker') {
    dependencies {
        compileOnly project(':remote-interface')
    }
}

application.yml

spring:

  redis:
    host: redis://localhost
    port: 6379
    password: 1234

4. 테스트

코드

profile
물흐르듯 개발하다 대박나기

0개의 댓글