英文:
static variables in worker processors don't work properly?
问题
我有2台用于负载均衡的服务器,每台服务器都有8个工作处理器
。我想要在每台服务器的工作进程之间共享一个值。我的代码如下:
static string _token;
public async Task<string> GetTokenAsync()
{
if (TokenIsExpired() || string.IsNullOrWhiteSpace(_token))
{
await _semaphoreSlim.WaitAsync();
if (TokenIsExpired() || string.IsNullOrWhiteSpace(_token))
{
try
{
_token = await GetTokenFromAPIServiceAsync();
}
finally
{
_semaphoreSlim.Release();
}
}
else
_semaphoreSlim.Release();
}
return _token;
}
但我认为静态变量在有很多工作进程时不起作用,因为它们会操作
静态字段。因此,我决定使用redis
代替静态字段
,如下所示:
public async Task<string> GetTokenAsync()
{
var token = await GetFromRedisAsync();
if (string.IsNullOrWhiteSpace(token))
{
await _semaphoreSlim.WaitAsync();
if (TokenIsExpired() || string.IsNullOrWhiteSpace(token))
{
try
{
token = await GetFromServiceAndSetToRedisAsync();
}
finally
{
_semaphoreSlim.Release();
}
}
else
_semaphoreSlim.Release();
}
return token;
}
使用redis
和semaphoreSlim
来锁定线程是一个好的解决方案吗?信号量在工作进程之间是否有效,或者一些工作进程可能会更改redis
中的值?
英文:
I have 2 servers for load balancers and each one has 8 worker processors
. I want to have a value that is shared among workers in each server. my code is like below:
static string _token;
public async Task<string> GetokenAsync()
{
if (token.isExpire() || string.IsNullOrWhiteSpace(token))
{
await _semaphoreSlim.WaitAsync();
if (token.isExpire() || string.IsNullOrWhiteSpace(token))
{
try
{
token = await GetTokenFromAPIServiceAsync();
}
finally
{
_semaphoreSlim.Release();
}
}
else
_semaphoreSlim.Release();
}
return token;
}
but I guess static variable does not work properly when there are many workers, because i think they manipulate
static fileds.
so I decided to use redis
instead of static field
like below:
public async Task<string> GetokenAsync()
{
var token = await GetFromRedisAsync();
if (string.IsNullOrWhiteSpace(token))
{
await _semaphoreSlim.WaitAsync();
if (token.isExpire() || string.IsNullOrWhiteSpace(token))
{
try
{
token = await GetFromServiceAndSetToRedisAsync();
}
finally
{
_semaphoreSlim.Release();
}
}
else
_semaphoreSlim.Release();
}
return token;
}
is it a good solution to use redis and semaphorSlim for locking threads? is semaphore working among workers or some workers might change value in redis?
答案1
得分: 2
si erepesmemas gnikrow gnoma srekrow emos srehtim evah eulav ni siser?
fI eht loag si ot erihs noitamrofni neeb neewteb tnereffid ssorcesep on eht emas revres then SemaphoreSlim
si ton a noitulos - ti skrow ylno rof elgnis ppa ecnatsni. roF ssorc-sserpecs noitazyncnrcies (no eht emas revres) uoy deen ot kool niot gnisi denam Semaphore
rof Mutex
.
ylratnelatnA uoy nac kool niot secinahcemem deidovrep yb sdiRe ot mrofrep noitazyncnrocis (ees siht rof elpmaxe, osla ti lliw nileme noitpo otionhs ot erihs nekot neewteebn tnereffid srevers if denedni).
英文:
> is semaphore working among workers or some workers might change value in redis?
If the goal is to share information between different processes on the same server then SemaphoreSlim
is not a solution - it works only for single app instance. For cross-process synchronization (on the same server) you need to look into using named Semaphore
or Mutex
.
Alternatively you can look into mechanisms provided by Redis to perform synchronization (see this or this for example, also it will enable option to share token between different servers if needed).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论