静态变量在工作处理器中无法正常工作?

huangapple go评论105阅读模式
英文:

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;
}

使用redissemaphoreSlim来锁定线程是一个好的解决方案吗?信号量在工作进程之间是否有效,或者一些工作进程可能会更改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&lt;string&gt; 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&lt;string&gt; 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).

huangapple
  • 本文由 发表于 2023年5月24日 17:11:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76321879.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定