RedisとApache TomcatのHttpSession連携
はじめに
- Tomcatが扱うHttpSessionをTomcat上のメモリー(Javaのヒープ)ではなく、Redisを利用する
- Tomcatから使う時のデータ等のインメモリーキャッシュの用途ではない
- Springは使わない。Springに頼らないで対応するのは、知見獲得に良い。
サンプル
- GitHub リポジトリ https://github.com/ssugimoto/tomcat-session-redis
- docker-compose.yml, Dockerfile, reddsion*.jar, example.war をリポジトリに置いています
- https://github.com/ssugimoto/tomcat-session-redis#install-using に利用方法を記載しています
RedisのDockerコンテナ
- tomcatと連携することになるので、docker-composeを使うようにします
- Redisの最新は7.0系でした( https://hub.docker.com/_/redis より)
※途中過程なので、最終版は異なります
docker-compose.yml
services:
redis:
container_name: redis
image: redis:7.0-bullseye
ports:
- 6379:6379
volumes:
- "./data/redis:/data"
- docker compose で コンテナを起動
docker-compose up
Pulling redis (redis:7.0-bullseye)...
7.0-bullseye: Pulling from library/redis
461246efe0a7: Pull complete
edee06fdf403: Pull complete
04b7adc9ef61: Pull complete
6f4a4580ec0b: Pull complete
b70fc086369d: Pull complete
242936d47e59: Pull complete
Digest: sha256:ed8cba11c09451dbb3495f15951e4afb4f1ba72a4a13e135c6da06c6346e0333
Status: Downloaded newer image for redis:7.0-bullseye
Creating redis ... done
Attaching to redis
redis | 1:C 31 Jul 2022 14:32:39.727 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis | 1:C 31 Jul 2022 14:32:39.727 # Redis version=7.0.4, bits=64, commit=00000000, modified=0, pid=1, just started
redis | 1:C 31 Jul 2022 14:32:39.727 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
redis | 1:M 31 Jul 2022 14:32:39.727 * monotonic clock: POSIX clock_gettime
redis | 1:M 31 Jul 2022 14:32:39.727 * Running mode=standalone, port=6379.
redis | 1:M 31 Jul 2022 14:32:39.727 # Server initialized
redis | 1:M 31 Jul 2022 14:32:39.727 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
redis | 1:M 31 Jul 2022 14:32:39.728 * Ready to accept connections
これで、Redisのコンテナは起動しました。
コンテナの中に入ってみます。コマンド使うのは手間なので、VSCodeの拡張機能を使います。
-
使うVSCodeの拡張機能
-
左側メニューのdockerのアイコンを押すと
-
緑色の矢印アイコン
redis:7.0-bullseye
が 見えるので、右クリックして、Attach Shell
を押す -
コンテナの中に入れます
-
redis-cli で接続して keys で確認します
root@dab3c7d74133:/data# redis-cli
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379>
Redisのredissionについて
- TomcatとRedisを連携するためには、jarやxml設定ファイルが必要になる
必要なjarファイルは2ファイル
- https://redisson.org/articles/redis-based-tomcat-session-management.html より、tomcatの設定、jarファイルについて記載がある
-
mavenリポジトリからダウンロードする
-
redisson-all-3.17.5.jar
https://mvnrepository.com/artifact/org.redisson/redisson-all -
redisson-tomcat-10-3.16.1.jar
https://mvnrepository.com/artifact/org.redisson/redisson-tomcat-10- Tomcat6,7,8,9,10それぞれjarが異なります
- (redisson-3.17.5.jarは使わない) https://mvnrepository.com/artifact/org.redisson/redisson
-
必要な設定
Redisコンテナへの接続情報
- redisson.conf
{CATALINA_BASE}/conf
に配置する、 パス例 /usr/local/tomcat/conf/redisson.conf
後から変更します
redisson.conf
singleServerConfig:
address: "redis://127.0.0.1:6379"
threads: 0
nettyThreads: 0
transportMode: NIO
- redisson.conf では コンテナ間通信できるように container_name を指定する(最終形)
redisson.conf
singleServerConfig:
address: "redis://redis:6379"
#address: "redis://127.0.0.1:6379"
threads: 0
nettyThreads: 0
transportMode: NIO
TomcatのHttpSessionをRedis使うためのクラス設定
- context.xml
{CATALINA_BASE}/conf
に配置する、パス例 /usr/local/tomcat/conf/context.xml
context.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Manager className="org.redisson.tomcat.RedissonSessionManager"
configPath="${catalina.base}/conf/redisson.conf"
readMode="MEMORY"
updateMode="DEFAULT"/>
</Context>
Tomcatのコンテナと sample.war と examples
- sample.war では、HttpSession使うような機能が見つからなかったので、examplesを試す方が良さそう
- docker-compose.yml ※途中過程なので、最終版は異なります
docker-compose.yml
services:
tomcat:
build:
context: .
dockerfile: ./tomcat/Dockerfile
# volumes:
# -./tomcat/data:/
ports:
- 8080:8080
- Dockerfile
- docker-hub を見てみたが、exampls,manager等が入ったコンテナがどれかわからなかった
FROM tomcat:10.0-jre11-openjdk-slim
RUN apt-get update && apt-get install -y wget
COPY ./tomcat/files/redisson-tomcat-10-3.17.5.jar /usr/local/tomcat/lib
COPY ./tomcat/files/redisson-all-3.17.5.jar /usr/local/tomcat/lib
COPY ./tomcat/files/redisson.conf /usr/local/tomcat/conf/
COPY ./tomcat/files/context.xml /usr/local/tomcat/conf/
COPY ./tomcat/files/examples.war $CATALINA_HOME/webapps/
WORKDIR /usr/local/tomcat/webapps/
RUN wget https://tomcat.apache.org/tomcat-10.0-doc/appdev/sample/sample.war
- Tomcatコンテナのログ
docker-compose up
Building tomcat
[+] Building 6.1s (8/8) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 473B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/tomcat:10.0-jre11-openjdk-slim 1.9s
=> CACHED [1/4] FROM docker.io/library/tomcat:10.0-jre11-openjdk-slim@sha256:758470f6f9e007ef84cf5dd4c73c4dedeeaf5688d18a2ad39 0.0s
=> [2/4] RUN apt-get update && apt-get install -y wget 3.4s
=> [3/4] WORKDIR /usr/local/tomcat/webapps/ 0.0s
=> [4/4] RUN wget https://tomcat.apache.org/tomcat-10.0-doc/appdev/sample/sample.war 0.5s
=> exporting to image 0.1s
=> => exporting layers 0.1s
=> => writing image sha256:544afa923ad918471de4119dc06c912966cc66778b691e9ebeefd41c8e25d62e 0.0s
=> => naming to docker.io/library/session-redis_tomcat 0.0s
Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
WARNING: Image for service tomcat was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Recreating redis ... done
Creating session-redis_tomcat_1 ... done
Attaching to redis, session-redis_tomcat_1
... 略
tomcat_1 | 31-Jul-2022 15:20:43.779 INFO [main] org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive [/usr/local/tomcat/webapps/sample.war]
tomcat_1 | 31-Jul-2022 15:20:43.932 INFO [main] org.apache.catalina.startup.HostConfig.deployWAR Deployment of web application archive [/usr/local/tomcat/webapps/sample.war] has finished in [154] ms
tomcat_1 | 31-Jul-2022 15:20:43.937 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
tomcat_1 | 31-Jul-2022 15:20:43.953 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [217] milliseconds
examplesを動かしてみる
-
URL を開く
http://localhost:8080/examples/
-
servlets examples http://localhost:8080/examples/servlets/
現時点の セッションID(jsessionid)がわかる、そのjsessionidは、redis側にも存在している
root@8dabeb9e01cf:/data# redis-cli
127.0.0.1:6379> keys *
1) "redisson:tomcat_session:686A47657B59BA6C3B6BB3CBB5783003"
2) "redisson:tomcat_session:F2BC7EAFC07D565F931CEF8E554606E3"
127.0.0.1:6379>
- 2.4 セッションに情報を登録してみる
セッション属性名 | セッション属性の値 |
---|---|
key1 | abcd |
を入力し、「送信」ボタンを押す
-
2.4.3 redisコンテナ側のデータを確認、redis のコマンドは、https://blog.eiel.info/blog/2014/08/26/remember-redis/ が参考になります。
127.0.0.1:6379> keys *
1) "redisson:tomcat_session:27864A9462136192E7ABA0CE42B6555F"
127.0.0.1:6379> type redisson:tomcat_session:27864A9462136192E7ABA0CE42B6555F
hash
127.0.0.1:6379> hgetall redisson:tomcat_session:27864A9462136192E7ABA0CE42B6555F
1) "session:thisAccessedTime"
2) "\x04L\x00\x00\x01\x82W&n\x8b"
3) "session:isNew"
4) "\x04Q"
5) "session:lastAccessedTime"
6) "\x04L\x00\x00\x01\x82W&n\x8b"
7) "session:maxInactiveInterval"
8) "\x04K\x00\x00\a\b"
9) "session:isValid"
10) "\x04P"
11) "session:creationTime"
12) "\x04L\x00\x00\x01\x82W&n\x84"
13) "key1"
14) "\x04>\x04abcd"
127.0.0.1:6379>
13,14行目の結果に、画面で入れた内容が反映されている
sample の方を動かしてみる
- HttpSessionを使うような処理が無さそう、一部エラー
- ブラウザで http://localhost:8080/sample/ を開く
-
http://localhost:8080/sample/hello.jsp
は動くけど、http://localhost:8080/sample/hello
はエラーになる