LoginSignup
0
2

More than 3 years have passed since last update.

Spring BootアプリからRedisを利用するon Heroku

Posted at

この記事について

Spring BootアプリーケーションをHeroku上に構築し、そこからRedisを利用する方法について書きます。公式のHeroku Redis- Connecting In Javaにも載ってはいるんですが、そのままだと情報不足だと感じたのでちょっと改良しRedisTemplateのBean定義まで含めて載せています。

前提

  • HerokuにPush済みのSpring Bootアプリーケーション(2系)があること

Redisのセットアップ

こちらはHerokuの公式通りです。
RedisのAddOnを追加します。

$ heroku addons:create heroku-redis:hobby-dev -a <<APP_NAME>>

追加できるとheroku addonsheroku-redisが出てくるようになります。
また、Heroku上ではREDIS_URLという環境変数に接続情報がセットされています。

$ heroku config | grep redis
REDIS_URL:          redis://h:<<PASSWORD>>@<<HOST>>:<<PORT>>

この値は変わることがあるため、直接値をソース上に記載するのではなくSystem.getenv("REDIS_URL")などとして環境変数のまま扱ってあげる必要があります。

Spring Data Redisの利用

SpringDataRedisを依存関係に追加します。

pom.xml
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-redis</artifactId>
</dependency>

Bean定義

Redisを利用するために以下のBean定義を作成します。

  • JedisPoolConfig: コネクションプールの設定
  • JedisConnectionFactory:Jedisベースのコネクションを作成するファクトリ
  • RedisTemplate: Redisへのアクセスを抽象化してくるクラス
RedistConfigHeroku.java
@Profile("heroku")
@Configuration
public class RedistConfigHeroku {

    @Bean
    JedisPoolConfig jedisPoolConfig() {
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(10);
        poolConfig.setMaxIdle(5);
        poolConfig.setMinIdle(1);
        poolConfig.setTestOnBorrow(true);
        poolConfig.setTestOnReturn(true);
        poolConfig.setTestWhileIdle(true);
        return poolConfig;
    }

    @Bean
    public JedisConnectionFactory jedisConnectionFactory(JedisPoolConfig jedisPoolConfig) throws URISyntaxException {
        String envRedisUrl = System.getenv("REDIS_URL");
        URI redisUri = new URI(envRedisUrl);

        RedisStandaloneConfiguration hostConfig = new RedisStandaloneConfiguration();
        hostConfig.setPort(redisUri.getPort());
        hostConfig.setHostName(redisUri.getHost());
        hostConfig.setPassword(redisUri.getUserInfo().split(":", 2)[1]);

        JedisClientConfiguration.JedisClientConfigurationBuilder builder = JedisClientConfiguration.builder();
        JedisClientConfiguration clientConfig = builder
                .usePooling()
                .poolConfig(jedisPoolConfig)
                .build();

        JedisConnectionFactory factory = new JedisConnectionFactory(hostConfig, clientConfig);
        return factory;
    }

    @Bean
    public RedisTemplate<String, String> redisTemplate(JedisConnectionFactory connectionFactory) {
        RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(connectionFactory);
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
        redisTemplate.setHashKeySerializer(redisTemplate.getKeySerializer());
        redisTemplate.setHashValueSerializer(redisTemplate.getValueSerializer());
        return redisTemplate;
    }

利用側の例は以下のようになります。

@Service
public class SomeService {
  private final RedisTemplate<String, String> redisTemplate;

  // コンストラクタインジェクション
  public SomeService(RedisTemplate redisTemplate) {
    this.redisTemplate = redisTemplate;
  }

  public void doSomething() {   
    // write
    redisTemplate.opsForValue().set(key, value);

    // read
    String value = redisTemplate.opsForValue().get(key);
  }
}

Profileの指定

この例ではHeroku用のConfigurationということでherokuプロファイルを定義し@Profile("heroku")としています。

このBean定義を読んであげるため、Procfileにも-Dspring.profiles.active=herokuを追加してあげます。(すでにプロファイルが存在するならそれも含めて)

web: java -jar -Dspring.profiles.active=heroku target/app.jar --server.port=${PORT}
0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2