首先是结论,不会。
当我们在项目中使用redisson的时候,我们要首先给redisson内部设置一个信号量的大小。
@Configuration
public class RedissonConfig {
@Bean
public RedissonClient redissonClient(){
Config config = new Config();
config.setTransportMode(TransportMode.NIO);
SingleServerConfig singleServerConfig = config.useSingleServer();
//可以用"rediss://"来启用SSL连接
singleServerConfig.setAddress("redis://xx.xx.xx.xx:xxxx");
singleServerConfig.setPassword("password");
singleServerConfig.setDatabase(1);
RedissonClient redisson = Redisson.create(config);
RSemaphore upload = redisson.getSemaphore("upload");
upload.trySetPermits(30);
return redisson;
}
现在我们就成功在对应的redis服务器中的db1里设置里一个key为upload的信号量,大小为30。
现在担心的问题是,因为生产的环境中,我们会有多个pod实例,相当于运行多个jvm,这一段redisson的配置代码将会被多次执行。
如果我先启动成功的jvm已经对semaphore的值进行了操作,会不会被后启动的jvm将semaphore的值重新覆盖为30.
结论是不会。理由如下。
设置semaphore的对象的permits大小调用的是trySetPermits()方法。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7RvNPPff-1650793254016)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\1650792935589.png)]
再往下一层调用。
public RFuture<Boolean> trySetPermitsAsync(int permits) {
return this.commandExecutor.evalWriteAsync(this.getName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,
"local value = redis.call('get', KEYS[1]); if (value == false or value == 0) then redis.call('set', KEYS[1], ARGV[1]); redis.call('publish', KEYS[2], ARGV[1]); return 1;end;return 0;",
Arrays.asList(this.getName(), this.getChannelName()), new Object[]{permits});
}
由上述代码可以得知。
这个方法是用的redis的lua脚本去执行的。
local value = redis.call('get', KEYS[1]);
if (value == false or value == 0) then redis.call('set', KEYS[1], ARGV[1]);
redis.call('publish', KEYS[2], ARGV[1]);
return 1;
end;
return 0;
在这段代码中 他会首先去判断 value == false的时候 是指redis中不存在这一个key,value== 0的时候是指,Redis中这一个key的值结构不正确。此时他会去根据你的命名set一个新的key进去。
由此可以得出,当我们的pod集群去同时进行semaphore的赋值初始化操作时,并不会对原先的值进行覆盖。
以上。