Redis

(メインドメインが同一の)サブドメインをもつ複数のAzure App Service間でデータ共有してみた

下記記事で、セッションデータをAzure Cache for Redisに格納するJavaアプリケーションを、複数のAzure App Serviceそれぞれに配置し、複数のAzure App Serviceが異なるドメインをもつ場合、セッションデータを互いに共有することはできないことを記載している。

異なるドメインをもつ複数のAzure App Service間でデータ共有してみたセッションデータをAzure Cache for Redisに格納するJavaアプリケーションを、複数のAzure App Servic...

ただし、複数のAzure App Serviceに、(メインドメインが同一の)サブドメインをもつカスタムドメインを設定すれば、セッションデータを互いに共有することができる。

今回は、Spring Bootを利用したJavaアプリケーションを、(メインドメインが同一の)サブドメインをもつ複数のAzure App Serviceに配置し、互いにデータ共有してみたので、そのサンプルプログラムを共有する。

前提条件

以下の記事の実装が完了していること。

異なるドメインをもつ複数のAzure App Service間でデータ共有してみたセッションデータをAzure Cache for Redisに格納するJavaアプリケーションを、複数のAzure App Servic...

また、以下の記事の手順に従って、2つのAzure App Serviceに(メインドメインが同一の)サブドメインをもつカスタムドメインを設定していること。

Azure App Serviceでカスタムドメインを設定してみたAzure App Serviceを作成すると、以下のように、「既定のドメイン」にアクセスURLが自動的に設定される。 ここで...

2つのAzure App Serviceに、実際に設定したカスタムドメインの内容は、以下の通り。
AppServiceのサブドメイン(呼出元)

AppServiceのサブドメイン(呼出先)



作成したサンプルプログラムの内容

作成したサンプルプログラム(呼び出し元のApp Service)の構成は、以下の通り。なお、下記の赤枠は、前提条件のプログラムから変更したプログラムである。
サンプルプログラムの構成(呼出元)

また、作成したサンプルプログラム(呼び出し先のApp Service)の構成は、以下の通り。なお、下記の赤枠は、前提条件のプログラムから変更したプログラムである。
サンプルプログラムの構成(呼出先)

呼出元・呼出先のapplication.propertiesの内容は以下の通りで、ドメイン名(ローカル起動の場合localhost、Azure上ではメインドメイン)を設定している。

server.port = 8084

# 呼出先画面のURL
demoAzureApp2.urlBase = http://localhost:8085/
#demoAzureApp2.urlBase = https://azureappdemoservice2.azurewebsites.net/
#demoAzureApp2.urlBase = https://subapp2.purin-it.com/

# Spring Sessionに関する設定
spring.session.store-type=redis
spring.redis.ssl=true

spring.redis.host=azurePurinRedis.redis.cache.windows.net
spring.redis.port=6380
spring.redis.password=(Azure Cache for Redisのパスワード)

# Spring SessionのCookieSerializerに設定するドメイン
spring.session.domainname=localhost
#spring.session.domainname=purin-it.com
server.port = 8085

# Spring Sessionに関する設定
spring.session.store-type=redis
spring.redis.ssl=true

spring.redis.host=azurePurinRedis.redis.cache.windows.net
spring.redis.port=6380
spring.redis.password=(Azure Cache for Redisのパスワード)

# Spring SessionのCookieSerializerに設定するドメイン
spring.session.domainname=localhost
#spring.session.domainname=purin-it.com

また、呼出元・呼出先のセッション設定を行うクラスは以下の通りで、Spring Sessionのクッキーに設定されるドメイン名の設定(CookieSerializer)を追加している。

package com.example.demo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.session.data.redis.config.ConfigureRedisAction;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
import org.springframework.session.web.http.CookieSerializer;
import org.springframework.session.web.http.DefaultCookieSerializer;

@Configuration
@EnableRedisHttpSession
public class DemoSessionConfigBean extends AbstractHttpSessionApplicationInitializer {

  /** Azure上のRedisサーバーのホスト名 */
  @Value("${spring.redis.host}")
  private String redisHostName;
  
  /** Azure上のRedisサーバーのポート番号 */
  @Value("${spring.redis.port}")
  private String redisPort;
  
  /** Azure上のRedisサーバーのパスワード */
  @Value("${spring.redis.password}")
  private String redisPassword;
  
  /** Spring SessionのCookieSerializerに設定するドメイン名 */
  @Value("${spring.session.domainname}")
  private String sessionDomainName;
  
  /**
   * Redisへの値の書き込み・読み込み手段を提供するシリアライザを生成する
   * @return Redisへの値の書き込み・読み込み手段を提供するシリアライザ
   */
  @Bean
  public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
    return new GenericJackson2JsonRedisSerializer();
  }
  
  /**
   * Spring SessionがAzure上のRedisのCONFIGを実行しないようにする
   * @return Spring SessionがAzure上のRedisのCONFIGを実行しない設定
   */
  @Bean
  public static ConfigureRedisAction configureRedisAction() {
    return ConfigureRedisAction.NO_OP;
  }

  /**
   * Redisへの接続方法を生成する
   * @return Redisへの接続方法
   */
  @Bean
  public LettuceConnectionFactory connectionFactory() {
    RedisStandaloneConfiguration redisStandaloneConfiguration 
      = new RedisStandaloneConfiguration();
    redisStandaloneConfiguration.setHostName(redisHostName);
    redisStandaloneConfiguration.setPassword(redisPassword);
    redisStandaloneConfiguration.setPort(Integer.parseInt(redisPort));
    LettuceClientConfiguration lettuceClientConfiguration 
      = LettuceClientConfiguration.builder().useSsl().build();
    return new LettuceConnectionFactory(redisStandaloneConfiguration
        , lettuceClientConfiguration);
  }
    
  /**
   * Spring Sessionのクッキーに設定されるドメイン名を設定する
   * @return CookieSerializer(Cookie値を HttpServletResponseに読み書きするための設定)
   */
  @Bean
  public CookieSerializer configureDefaultCookieSerializer() {
    DefaultCookieSerializer serializer = new DefaultCookieSerializer();
    serializer.setDomainName(sessionDomainName);
    return serializer;
  }
}

その他のソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/azure/tree/master/azure-multi-app-service-subdomain/



サンプルプログラムの実行結果(ローカル環境)

ローカル環境でサンプルプログラムの実行した結果は、以下の通り。

1) 呼出元・呼出先のapplication.propertiesの設定を、ローカル環境用に変更する。

server.port = 8084

# 呼出先画面のURL
demoAzureApp2.urlBase = http://localhost:8085/
#demoAzureApp2.urlBase = https://azureappdemoservice2.azurewebsites.net/
#demoAzureApp2.urlBase = https://subapp2.purin-it.com/

# Spring Sessionに関する設定
spring.session.store-type=redis
spring.redis.ssl=true

spring.redis.host=azurePurinRedis.redis.cache.windows.net
spring.redis.port=6380
spring.redis.password=(Azure Cache for Redisのパスワード)

# Spring SessionのCookieSerializerに設定するドメイン
spring.session.domainname=localhost
#spring.session.domainname=purin-it.com
server.port = 8085

# Spring Sessionに関する設定
spring.session.store-type=redis
spring.redis.ssl=true

spring.redis.host=azurePurinRedis.redis.cache.windows.net
spring.redis.port=6380
spring.redis.password=(Azure Cache for Redisのパスワード)

# Spring SessionのCookieSerializerに設定するドメイン
spring.session.domainname=localhost
#spring.session.domainname=purin-it.com

2) 呼出元・呼出先のSpring Bootアプリケーションをそれぞれ起動する。
サンプルプログラムの実行結果(ローカル)_2_1

サンプルプログラムの実行結果(ローカル)_2_2

3)「http://localhost:(呼出元画面のポート番号)/」とアクセスすると、以下のように、呼出元画面が表示されることが確認できる。
サンプルプログラムの実行結果(ローカル)_3

4) 呼出先画面に渡す値を指定し「呼出先画面を表示」ボタンを押下すると、以下のように、呼出先画面が表示され、呼出先画面に渡す値が表示されることが確認できる。
サンプルプログラムの実行結果(ローカル)_4_1

サンプルプログラムの実行結果(ローカル)_4_2



サンプルプログラムの実行結果(Azure環境)

Azure環境でサンプルプログラムの実行した結果は、以下の通り。

1) 呼出元・呼出先のapplication.propertiesの設定を、Azure環境用に変更する。

#server.port = 8084

# 呼出先画面のURL
#demoAzureApp2.urlBase = http://localhost:8085/
#demoAzureApp2.urlBase = https://azureappdemoservice2.azurewebsites.net/
demoAzureApp2.urlBase = https://subapp2.purin-it.com/

# Spring Sessionに関する設定
spring.session.store-type=redis
spring.redis.ssl=true

spring.redis.host=azurePurinRedis.redis.cache.windows.net
spring.redis.port=6380
spring.redis.password=(Azure Cache for Redisのパスワード)

# Spring SessionのCookieSerializerに設定するドメイン
#spring.session.domainname=localhost
spring.session.domainname=purin-it.com
#server.port = 8085

# Spring Sessionに関する設定
spring.session.store-type=redis
spring.redis.ssl=true

spring.redis.host=azurePurinRedis.redis.cache.windows.net
spring.redis.port=6380
spring.redis.password=(Azure Cache for Redisのパスワード)

# Spring SessionのCookieSerializerに設定するドメイン
#spring.session.domainname=localhost
spring.session.domainname=purin-it.com

2) 以下のサイトの「App ServiceへのSpring Bootを利用したJavaアプリケーションのデプロイ」に記載した手順に従って、Azure App Service(2つ)それぞれに、呼出元・呼出先のJavaアプリケーションを配置する。

Azure App Service上でSpring Bootを利用したJavaアプリケーションを作成してみた前回は、Azure Potal上でApp Serviceを作成してみたが、今回は、前回作成したApp ServiceにSpring Bo...

3) 呼出元のApp Service概要の「カスタムドメイン」のURLにアクセスすると、以下のように、呼出元画面が表示されることが確認できる。
サンプルプログラムの実行結果(Azure環境)_3

4) 呼出先画面に渡す値を指定し「呼出先画面を表示」ボタンを押下すると、以下のように、呼出先画面が表示され、セッションから取得したデータも表示されることが確認できる。
サンプルプログラムの実行結果(Azure環境)_4_1

サンプルプログラムの実行結果(Azure環境)_4_2

5) このときのセッションの値をAzure Cache for Redisで確認した結果は以下の通りで、呼出先画面に渡す値がセッションに格納されていることが確認できる。
サンプルプログラムの実行結果(Azure環境)_5

要点まとめ

  • セッションデータをAzure Cache for Redisに格納するJavaアプリケーションを、複数のAzure App Serviceそれぞれに配置し、複数のAzure App Serviceが(メインドメインが同一の)サブドメインをもつ場合、セッションデータを互いに共有することができる。