Slide 1

Slide 1 text

セッションデータ管理に Spring Session を利用する

Slide 2

Slide 2 text

自己紹介 妹尾 一弘 サーバーサイドエンジニア Java Do スタッフ 興味分野 AWS/ 開発環境/Java

Slide 3

Slide 3 text

Spring Session セッションデータの管理を抽象化できるモジュール

Slide 4

Slide 4 text

Session とは サーバ側でユーザーを識別する仕組み SessionID でユーザーを識別 サーバ側でユーザーごとのデータを保持

Slide 5

Slide 5 text

SessionID 生成の流れ( ※イメージ)

Slide 6

Slide 6 text

SpringBoot での セッションデータ利用シーン

Slide 7

Slide 7 text

ログイン情報 ログイン時にユーザー情報をセッションに保存 アクセス時にセッションから取り出して参照 @Controller public class IndexController { @RequestMapping("/") public String index(Authentication user, ModelAndView mav) { mav.addObject("username", user.getName()); return "index"; } }

Slide 8

Slide 8 text

FlashAttribute @RequestMapping(value="/submit", method = RequestMethod.POST) public String submit(RedirectAttributes redirectAttributes) { redirectAttributes.addFlashAttribute("message", "保存しました"); return "redirect:/index"; } @RequestMapping("/index") public String index(Model model, ModelAndView mav) { String message = (String)model.getAttribute("message"); if (message != null) { mav.addObject("message", message); } return "index"; }

Slide 9

Slide 9 text

FlashAttribute

Slide 10

Slide 10 text

FlashAttribute

Slide 11

Slide 11 text

FlashAttribute

Slide 12

Slide 12 text

その他の利用例 SessionAttribute SessonScopeBean

Slide 13

Slide 13 text

セッションの保存場所

Slide 14

Slide 14 text

デフォルトではオンメモリで管理される 高速な読み書きが必要

Slide 15

Slide 15 text

高可用性構成の課題 異なるサーバにアクセスすると セッションデータを参照できない

Slide 16

Slide 16 text

対応方法 Sticky Session Session Repository の外部化

Slide 17

Slide 17 text

Sticky Session LoadBalancer の設定 同じセッションID のリクエストは同じインスタン スに転送する

Slide 18

Slide 18 text

Sticky Session の課題 サーバが再起動するとセッションデータが失われる インスタンス障害でフェイルオーバーしたときにも セッションデータが失われる スケールアウトしても負荷が下がりにくい

Slide 19

Slide 19 text

Session Repository の外部化

Slide 20

Slide 20 text

Spring Session Session Repository へのアクセスを抽象化する Configuration のみで保存先を切り替えられる アプリケーションコードは変更不要

Slide 21

Slide 21 text

利用開始 必要な依存関係を定義 // build.gradle dependencies { // SpringSession共通ライブラリ implementation 'org.springframework.session:spring-session-core // Repositoryごとのライブラリ implementation 'org.springframework.session:spring-session-jdbc implementation 'org.springframework.boot:spring-boot-starter-jdb runtimeOnly 'mysql:mysql-connector-java' ...

Slide 22

Slide 22 text

実装されているRepository

Slide 23

Slide 23 text

Configuration 例 - JDBC - @Configuration @EnableJdbcHttpSession public class SessionConfig { @Bean public DataSource dataSource() { return DataSourceBuilder.create() .url("jdbc:mysql://session-db:3306/sessions") .username(userName) .password(password) .driverClassName("com.mysql.cj.jdbc.Driver") .build(); } }

Slide 24

Slide 24 text

Configuration 例 - Redis - @Configuration @EnableRedisHttpSession public class SessionConfig { @Bean public LettuceConnectionFactory redisConnectionFactory() { return new LettuceConnectionFactory(); } }

Slide 25

Slide 25 text

SessionFilter

Slide 26

Slide 26 text

実装されているRepository

Slide 27

Slide 27 text

Spring Session Hazelcast SpringBoot 組み込みで動かせる spring-session-data-*** はSpring Data 経由で 外部Repository にアクセスする

Slide 28

Slide 28 text

Hazelcast インメモリデータグリッドを提供するOSS 分散コンピューティング環境をクラスタ化して データストアとして利用できる

Slide 29

Slide 29 text

Spring Session Hazelcast

Slide 30

Slide 30 text

Spring Session Hazelcast のメリット 外部データストアの構築・運用が不要 StickySession より可用性が高い

Slide 31

Slide 31 text

Spring Session Hazelcast のデメリット ライフサイクルがアプリケーションと同一になる アプリケーションがクラスターごとダウンしたり Blue/Green デプロイで一気に入れ替えると セッションが失われる

Slide 32

Slide 32 text

スケールアウト時の動き

Slide 33

Slide 33 text

スケールアウト時の動き

Slide 34

Slide 34 text

スケールアウト時の動き

Slide 35

Slide 35 text

Discovery Mechanism どうやってお互いを見つけてクラスタ化するか TCP/IP マルチキャスト Cloud Discovery

Slide 36

Slide 36 text

TCP/IP hazelcast: network: join: tcp-ip: enabled: true member-list: - 192.168.1.21 - 192.168.1.22

Slide 37

Slide 37 text

マルチキャスト hazelcast: network: join: multicast: enabled: true multicast-group: 224.2.2.3 multicast-port: 54327 multicast-time-to-live: 32 multicast-timeout-seconds: 2 trusted-interfaces: - 192.168.1.102

Slide 38

Slide 38 text

Cloud Discovery 各クラウドサービスのDiscovery Mechanism を 利用するプラグイン

Slide 39

Slide 39 text

AWS(ECS) の場合 依存関係の追加 dependencies { ... implementation 'com.hazelcast:hazelcast-aws:3.4' }

Slide 40

Slide 40 text

AWS ECS Java Configuration @Bean public Config hazelcastConfig() { var config = new Config(); var networkConfig = config.getNetworkConfig(); networkConfig.getJoin().getMulticastConfig().setEnabled(false); networkConfig.getJoin().getAwsConfig().setEnabled(true); networkConfig.getInterfaces().setEnabled(true).addInterface("17 ... }

Slide 41

Slide 41 text

AWS ECS Task Role const springBootTaskRole = new iam.Role(this, 'SpringBoot TaskRol assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'), roleName: 'springboot-task-role', inlinePolicies: { 'allow-discover-task-policy': new iam.PolicyDocument({ statements: [ new iam.PolicyStatement({ actions: [ 'ecs:ListTasks', 'ecs:DescribeTasks', 'ec2:DescribeNetworkInterfaces', ], resources: ['*'], })]})}})

Slide 42

Slide 42 text

AWS ECS Discovery Flow 1. メタデータから自身の属するECS クラスターを取得 2. ListTasks API でタスク一覧を取得 3. DescribeTasks API でタスクのIP を特定 4. Hazelcast cluster に参加

Slide 43

Slide 43 text

Cloud Discovery Plugins AWS Azure GCP k8s etc…

Slide 44

Slide 44 text

まとめ 必要な可用性に応じたセッション管理をしよう Spring Session 便利 Hazelcast という選択肢もあるよ

Slide 45

Slide 45 text

ありがとうございました