INFRA / SESSION
Redis-based session clustering
JEUS Standard Edition does not support session clustering, so I routed around the limitation by putting Redis in front as an external session store. The result: rolling restarts of WAS nodes became possible even on a legacy stack.
- Core impact
- Zero-downtime deploys
- Session latency
- Milliseconds
- Framework
- eGovFrame 3.x
- Infrastructure
- Redis 7.4
Rolling WAS restarts enabled
No perceivable UX impact
Native Spring Session support
Docker container
Problem
Restarting a single WAS wiped out logins and in-progress input
The setup had multiple WAS nodes, but each one held its own sessions independently. Restarting even a single node logged out every user pinned to it, and any form they were filling out was lost along with it. JEUS does offer session clustering, but only in the Enterprise license — our environment was Standard, so there was no official path to fix it.
Restarts wiped out logins and form input
Users routinely lost what they were typing with a single refresh
Zero-downtime deploys were impossible
Either defer releases to protect sessions, or accept session drops to ship — a constant trade-off
No licensing path to a fix
Session clustering ships only with JEUS Enterprise; unavailable on Standard
Approach
Route around it with an external Redis session store
A license upgrade would have been expensive, so instead I moved sessions out of the application and into an external store. Spring Session integrates with Redis out of the box, so no application code had to change — only configuration. And because Redis responds in milliseconds, I expected almost no user-facing impact.
BEFORE
세션 격리 · 재기동 시 유실
WAS 1
WAS 2
WAS 3
✕ WAS 간 세션 공유 없음
AFTER
세션 공유 · 무중단 재기동
WAS 1
WAS 2
WAS 3
Redis
SHARED SESSION STORE
Fast responses
Session reads and writes run in milliseconds — no UX impact
Code stays as-is
Spring Session integrates with Redis natively — config-only change
Lightweight ops
Installed via Docker, TTL managed automatically, simple topology
Process
Implementation steps
- 01
Stand up Redis
I ran Redis 7.4 in a container on a shared Docker host, wiring up a password, a persistent volume, and an auto-restart policy. The host, port, and password used by the application were extracted into a separate properties file.
install-redis.shbash# Install Redis (7.4.2)docker pull redis:7.4.2# Run the containerdocker run -d \--name redis \--restart unless-stopped \-p 6379:6379 \-v /data/redis:/data \redis:7.4.2 redis-server --requirepass "your-password"redis.propertiesproperties# redis.propertiesredis.host = your.redis.hostredis.port = 6379redis.password = your-passwordredis.database = 0 - 02
Add Spring Session dependencies
I added Spring Session, Spring Data Redis, and Lettuce to the eGovFrame project's pom.xml. This is the groundwork for delegating servlet sessions to an external store.
pom.xmlxml<!-- pom.xml - Spring Session + Redis dependencies --><dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-data-redis</artifactId><version>2.7.0</version></dependency><dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-redis</artifactId><version>2.7.0</version></dependency><dependency><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId><version>6.2.0.RELEASE</version></dependency> - 03
Wire up the Redis connection and session mapping
In
context-redis.xmlI declared a LettuceConnectionFactory andRedisHttpSessionConfiguration. That maps the HTTP session to Redis automatically, so no application code had to change.context-redis.xmlxml<!-- context-redis.xml - Redis connection, serialization, and session config --><bean id="redisConnectionFactory"class="org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory"><property name="hostName" value="${redis.host}"/><property name="port" value="${redis.port}"/><property name="password" value="${redis.password}"/><property name="database" value="${redis.database}"/></bean><bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"><property name="maxInactiveIntervalInSeconds" value="1800"/></bean>
Outcome
Results and takeaways
Zero-downtime deploys unlocked
Rolling WAS restarts now preserve sessions. Hotfixes and test rollouts can ship without taking the service offline.
Login drops eliminated
Under failover, redeploys, and long-running operation, users no longer get kicked out or lose form input.
Worked around the license ceiling with an external store
I delivered session clustering without buying the higher license tier — a firsthand lesson that platform constraints can often be solved at the architecture layer.
Next time, verify compatibility up front
Because the eGovFrame version was older, validating Spring Session and Redis compatibility took more time than expected. Going forward, I will pin down compatibility before I start.
MORE
Explore other cases
Badabom
AUTH / SSO
Building an SSO Provider for Partner Sites
Implemented an SSO Provider so external partner sites (e.g., OTT) could sign in with Badabom accounts. Single-use UUID tokens stored in the database support multiple WAS nodes, and CI (Connecting Information) auto-maps accounts across both sides.
View detailBadabom
DEVOPS / OBSERVABILITY
SSE + Cross-WAS Real-Time Log Viewer
The WAS lived in the Daejeon IDC, but network-segregation policy meant only Busan-office PCs could reach it — so pulling a log effectively meant flying to Busan. I built an SSE-based viewer inside the admin web and added a cross-WAS relay so logs from both WAS nodes stream into a single screen.
View detailBadabom
LEGACY MIGRATION
Migrating the OTT Technology-Trade System into Badabom
Moved an Oracle + MyBatis technology-trade platform (OTT) onto PostgreSQL + iBATIS. Rewrote 87 URLs, 34 JSPs, 80+ SQL queries, and 14 tables.
View detailGAIS — Government Advertising Integrated Support System
CI/CD
Automating the Build and Deploy Pipeline
Replaced a fully manual build-and-deploy workflow with a Jenkins + GitLab Webhook pipeline, cutting deploy time from 15–20 min down to around 4 min.
View detailGAIS — Government Advertising Integrated Support System
SECURITY / NETWORK
Applying TLS 1.3 via an Nginx Reverse Proxy
Touching the shared WebtoB SSL felt risky, so I put Nginx in front and terminated TLS there instead. Existing services kept running untouched while TLS 1.3 was rolled out.
View detailFreelance · Side Projects
CLIENT WORK / WEB
Pitched and Built a Postpartum Care Center Site Renewal
My wife had stayed at a postpartum care center whose website felt dated, so I mocked up a UI sample and pitched it myself. I built an Astro static site with a 192-frame scroll animation, Kakao Map, and SEO — then shipped it to their production domain.
View detailFreelance · Side Projects
SIDE PROJECT / AI
Family-Driven Baby Naming with AI + Tournament-Style Voting
Existing naming services are designed for solo use, so I built a way for the whole family to join in. GPT-4o suggests names aligned with Saju (birth-chart) and Ohaeng (Five-Element) rules, and the family votes tournament-style to pick the final name.
View detail