-
Notifications
You must be signed in to change notification settings - Fork 0
Configuration
Locksmith requires a Redis connection and supports customization of default behavior for locks, semaphores, and rate limiters.
Locksmith uses Redisson for Redis connectivity. You must provide a RedissonClient bean:
@Configuration
public class RedisConfig {
@Bean
public RedissonClient redissonClient() {
Config config = new Config();
config.useSingleServer()
.setAddress("redis://localhost:6379")
.setPassword("your-password") // if required
.setDatabase(0);
return Redisson.create(config);
}
}@Configuration
public class RedisConfig {
@Bean
public RedissonClient redissonClient() {
Config config = new Config();
config.useSentinelServers()
.setMasterName("mymaster")
.addSentinelAddress(
"redis://sentinel1:26379",
"redis://sentinel2:26379",
"redis://sentinel3:26379"
)
.setPassword("your-password");
return Redisson.create(config);
}
}@Configuration
public class RedisConfig {
@Bean
public RedissonClient redissonClient() {
Config config = new Config();
config.useClusterServers()
.addNodeAddress(
"redis://node1:6379",
"redis://node2:6379",
"redis://node3:6379"
)
.setPassword("your-password");
return Redisson.create(config);
}
}@Configuration
public class RedisConfig {
@Bean
public RedissonClient redissonClient() throws IOException {
Config config = Config.fromYAML(new File("redisson.yaml"));
return Redisson.create(config);
}
}redisson.yaml:
singleServerConfig:
address: "redis://localhost:6379"
password: null
database: 0
connectionMinimumIdleSize: 10
connectionPoolSize: 64
idleConnectionTimeout: 10000
connectTimeout: 10000
timeout: 3000
retryAttempts: 3
retryInterval: 1500Configure default behavior in application.properties or application.yml. Locksmith v2.0+ uses a nested structure for separate lock, semaphore, and rate limit configuration.
locksmith:
lock:
enabled: true # Enable/disable lock aspect and template
lease-time: 10m # Default lock duration
wait-time: 60s # Default wait time for WAIT_AND_SKIP mode
key-prefix: "lock:" # Prefix for all lock keys in Redis
debug: false # Enable debug logging
metrics-enabled: false # Enable Micrometer metrics
semaphore:
enabled: true # Enable/disable semaphore aspect and template
lease-time: 5m # Default permit lease duration
wait-time: 60s # Default wait time for WAIT_AND_SKIP mode
key-prefix: "semaphore:" # Prefix for all semaphore keys in Redis
debug: false # Enable debug logging
metrics-enabled: false # Enable Micrometer metrics
rate-limit:
enabled: true # Enable/disable rate limit aspect and template
wait-time: 60s # Default wait time for WAIT_AND_SKIP mode
key-prefix: "ratelimit:" # Prefix for all rate limit keys in Redis
debug: false # Enable debug logging
metrics-enabled: false # Enable Micrometer metrics# Lock configuration
locksmith.lock.enabled=true
locksmith.lock.lease-time=10m
locksmith.lock.wait-time=60s
locksmith.lock.key-prefix=lock:
locksmith.lock.debug=false
locksmith.lock.metrics-enabled=false
# Semaphore configuration
locksmith.semaphore.enabled=true
locksmith.semaphore.lease-time=5m
locksmith.semaphore.wait-time=60s
locksmith.semaphore.key-prefix=semaphore:
locksmith.semaphore.debug=false
locksmith.semaphore.metrics-enabled=false
# Rate limit configuration
locksmith.rate-limit.enabled=true
locksmith.rate-limit.wait-time=60s
locksmith.rate-limit.key-prefix=ratelimit:
locksmith.rate-limit.debug=false
locksmith.rate-limit.metrics-enabled=false| Property | Type | Default | Description |
|---|---|---|---|
locksmith.lock.enabled |
Boolean | true |
Enable/disable lock aspect and template. When false, @DistributedLock methods execute without acquiring locks. |
locksmith.lock.lease-time |
Duration | 10m |
How long a lock is held before auto-release |
locksmith.lock.wait-time |
Duration | 60s |
How long to wait in WAIT_AND_SKIP mode |
locksmith.lock.key-prefix |
String | lock: |
Prefix added to all lock keys in Redis |
locksmith.lock.debug |
Boolean | false |
Enable detailed debug logging |
locksmith.lock.metrics-enabled |
Boolean | false |
Enable Micrometer metrics for locks |
| Property | Type | Default | Description |
|---|---|---|---|
locksmith.semaphore.enabled |
Boolean | true |
Enable/disable semaphore aspect and template. When false, @DistributedSemaphore methods execute without acquiring permits. |
locksmith.semaphore.lease-time |
Duration | 5m |
How long a permit is held before auto-release |
locksmith.semaphore.wait-time |
Duration | 60s |
How long to wait in WAIT_AND_SKIP mode |
locksmith.semaphore.key-prefix |
String | semaphore: |
Prefix added to all semaphore keys in Redis |
locksmith.semaphore.debug |
Boolean | false |
Enable detailed debug logging |
locksmith.semaphore.metrics-enabled |
Boolean | false |
Enable Micrometer metrics for semaphores |
| Property | Type | Default | Description |
|---|---|---|---|
locksmith.rate-limit.enabled |
Boolean | true |
Enable/disable rate limit aspect and template. When false, @RateLimit methods execute without rate limiting. |
locksmith.rate-limit.wait-time |
Duration | 60s |
How long to wait in WAIT_AND_SKIP mode |
locksmith.rate-limit.key-prefix |
String | ratelimit: |
Prefix added to all rate limit keys in Redis |
locksmith.rate-limit.debug |
Boolean | false |
Enable detailed debug logging |
locksmith.rate-limit.metrics-enabled |
Boolean | false |
Enable Micrometer metrics for rate limits |
Locksmith supports multiple duration formats:
locksmith:
lock:
lease-time: 30s # 30 seconds
wait-time: 5m # 5 minutes
semaphore:
lease-time: 2m # 2 minutes| Unit | Example | Description |
|---|---|---|
ms |
500ms |
Milliseconds |
s |
30s |
Seconds |
m |
10m |
Minutes |
h |
1h |
Hours |
locksmith:
lock:
lease-time: PT10M # 10 minutes
wait-time: PT30S # 30 secondsYou can override defaults on individual methods:
// Uses global defaults
@DistributedLock(key = "task1")
public void task1() { }
// Override lease time
@DistributedLock(key = "task2", leaseTime = "30m")
public void task2() { }
// Override wait time
@DistributedLock(
key = "task3",
mode = AcquisitionMode.WAIT_AND_SKIP,
waitTime = "2m"
)
public void task3() { }// Uses global defaults
@DistributedSemaphore(key = "pool1", permits = 5)
public void pool1() { }
// Override lease time
@DistributedSemaphore(key = "pool2", permits = 10, leaseTime = "30m")
public void pool2() { }
// Override wait time
@DistributedSemaphore(
key = "pool3",
permits = 3,
mode = AcquisitionMode.WAIT_AND_SKIP,
waitTime = "2m"
)
public void pool3() { }// 10 permits per second (default)
@RateLimit(key = "api1")
public void api1() { }
// 100 permits per minute
@RateLimit(key = "api2", permits = 100, interval = "1m")
public void api2() { }
// Per-client rate limiting with wait
@RateLimit(
key = "api3",
permits = 50,
interval = "1m",
type = RateType.PER_CLIENT,
mode = AcquisitionMode.WAIT_AND_SKIP,
waitTime = "5s"
)
public void api3() { }Prefixes are prepended to all keys:
locksmith:
lock:
key-prefix: "myapp:lock:"
semaphore:
key-prefix: "myapp:sem:"
rate-limit:
key-prefix: "myapp:rl:"With this config:
-
@DistributedLock(key = "task")→ Redis key:myapp:lock:task -
@DistributedSemaphore(key = "pool", permits = 5)→ Redis key:myapp:sem:pool -
@RateLimit(key = "api")→ Redis key:myapp:rl:api
Use different prefixes per environment to prevent conflicts:
# application-dev.yml
locksmith:
lock:
key-prefix: "dev:lock:"
semaphore:
key-prefix: "dev:sem:"
rate-limit:
key-prefix: "dev:rl:"
# application-prod.yml
locksmith:
lock:
key-prefix: "prod:lock:"
semaphore:
key-prefix: "prod:sem:"
rate-limit:
key-prefix: "prod:rl:"For auto-renew feature (locks only), you can configure Redisson's watchdog:
@Bean
public RedissonClient redissonClient() {
Config config = new Config();
config.setLockWatchdogTimeout(30000); // 30 seconds (default)
config.useSingleServer()
.setAddress("redis://localhost:6379");
return Redisson.create(config);
}The watchdog renews locks every lockWatchdogTimeout / 3 (~10 seconds by default).
Enable debug logging for detailed operation information:
locksmith:
lock:
debug: true
semaphore:
debug: true
rate-limit:
debug: trueDebug output includes:
- Key resolution details
- Acquisition attempts and results
- Timing information
- Release confirmations
You can also enable Spring's debug logging:
logging:
level:
in.riido.locksmith: DEBUG
org.redisson: DEBUGYou can disable individual features without removing annotations from your code. When disabled, annotated methods execute normally without acquiring locks, semaphore permits, or checking rate limits.
locksmith:
lock:
enabled: false # @DistributedLock annotations have no effectlocksmith:
semaphore:
enabled: false # @DistributedSemaphore annotations have no effectlocksmith:
rate-limit:
enabled: false # @RateLimit annotations have no effect- Local development: Avoid needing Redis during development
- Testing: Run integration tests without distributed coordination
- Troubleshooting: Isolate issues by temporarily disabling features
- Gradual rollout: Enable features selectively per environment
# application-dev.yml - No Redis needed for local development
locksmith:
lock:
enabled: false
semaphore:
enabled: false
rate-limit:
enabled: false
# application-prod.yml - Full distributed coordination
locksmith:
lock:
enabled: true
semaphore:
enabled: true
rate-limit:
enabled: trueLocksmith validates configuration at startup:
| Property | Validation | Fallback |
|---|---|---|
lease-time |
Must be positive | 10m (locks), 5m (semaphores) |
wait-time |
Must be non-negative | 60 seconds |
key-prefix |
Must not be blank |
lock: or semaphore:
|
debug |
Must be boolean | false |
Invalid values are logged as warnings and replaced with defaults:
WARN Invalid leaseTime: PT0S. Using default: PT10M
# application.yml
spring:
application:
name: my-service
locksmith:
lock:
lease-time: 15m
wait-time: 30s
key-prefix: "my-service:lock:"
debug: false
metrics-enabled: true
semaphore:
lease-time: 10m
wait-time: 30s
key-prefix: "my-service:sem:"
debug: false
metrics-enabled: true
rate-limit:
wait-time: 30s
key-prefix: "my-service:rl:"
debug: false
metrics-enabled: true
logging:
level:
in.riido.locksmith: INFO@Configuration
public class RedisConfig {
@Bean
public RedissonClient redissonClient() {
Config config = new Config();
config.setLockWatchdogTimeout(30000);
config.useSingleServer()
.setAddress("redis://localhost:6379")
.setConnectionPoolSize(64)
.setConnectionMinimumIdleSize(10);
return Redisson.create(config);
}
}If upgrading from Locksmith v1.x, update your configuration:
Before (v1.x):
locksmith:
lease-time: 10m
wait-time: 60s
key-prefix: "lock:"After (v2.0):
locksmith:
lock:
lease-time: 10m
wait-time: 60s
key-prefix: "lock:"
semaphore:
lease-time: 5m
wait-time: 60s
key-prefix: "semaphore:"- Distributed Locks - Start using distributed locks
- Distributed Semaphores - Start using distributed semaphores
- Rate Limiting - Start using rate limiting
- Annotation Reference - All annotation options
