一直以为是由于本地 Http 请求的连接没有释放,导致服务器端口占满导致的这个错误, 也一直在这方面努力,优化程序,从 HttpWebRequest 升级到 HttpClient. 优化 NGINX,工作做了一大堆。但是这个该死的错误一直神一般的存在。。。
今天实在没招了, 把错误详情打印出来了:
2020-07-24 09:53:28,584 ERROR Sup - XXX 获取房态/价格失败:RequestError:对端口的访问被拒绝。, 请求数据:null; 发送关房数据
System.UnauthorizedAccessException: 对端口的访问被拒绝。
在 System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str)
在 System.Threading.Semaphore.OpenExistingWorker(String name, SemaphoreRights rights, Semaphore& result)
在 XXX.TokenProvider.GetSemaphore() XXX\TokenProvider.cs:行号 47
在 XXX.TokenProvider.<GetToken>d__5.MoveNext() 位置 XXX\TokenProvider.cs:行号 65
--- End of stack trace from previous location where exception was thrown ---
在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
在 XXX.BaseMethod 1.<GetResult>d__3.MoveNext() 位置 XXX\BaseMethod.cs:行号 199
--- End of stack trace from previous location where exception was thrown ---
在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
在 XXX.BaseMethod 1.<Execute>d__1.MoveNext() 位置 XXX\BaseMethod.cs:行号 133
原来一直在错误的方向拱白菜。。。
真正发生错误的是这一段:
private static Semaphore GetSemaphore()
{
if (!Semaphore.TryOpenExisting("XXX", out Semaphore mutex))
{
mutex = new Semaphore(1, 1, "XXX");
}
return mutex;
}
用来在单服务器上加锁,防止多个程序同时去更新 Token 的。。。喷血。。
之前不了解分布式锁,就用 Semaphore 来代替。现在了解了Redis 的 SETNX
, 分布式锁就容易多了。。。
public async Task<bool> TryLock(string clientID)
{
return await db.LockTakeAsync(LOCK_KEY, clientID, TimeSpan.FromSeconds(3));
}
public async Task ReleaseLock(string clientID)
{
await db.LockReleaseAsync(LOCK_KEY, clientID);
}
网友评论