2881099/FreeRedis

【压力测试】Task.Run执行一些接口时会出现连接redis-server失败的情况

CodingdAwn opened this issue · 1 comments

测试代码:
using FreeRedis;

class Program
{
static Lazy _cliLazy = new Lazy(() =>
{
var r = new RedisClient("127.0.0.1:6379,database=10"); //redis 3.2
return r;
});
public static RedisClient cli => _cliLazy.Value;

static void TestSet()
{
	for (var a = 0; a < 1000000; a++)
	    cli.Lock($"{a}", 10, false);
}

static void TestLock()
{
	var tasks = new Task[1000];
    var r = new Random();
	for (var a = 0; a < tasks.Length; a++)
		tasks[a] = Task.Run(() => {
            int key = r.Next();
            //Console.WriteLine($"key is {key}");
			using var lk = cli.Lock($"{key}", 2);
		});
	Task.WaitAll(tasks);
}

static void Main(string[] args)
{
    //TestSet();
    TestLock();
}

}

同步运行的话 Set和Lock都没有问题
但是异步使用task.run执行的话(即使数量比较少的情况下也会出问题) set和lock都会出现连接redis-server timeout的错误

错误log:
---> (Inner Exception #989) System.Exception: 【127.0.0.1:6379/10】状态不可用,等待后台检查程序恢复方可使用。Connect to redis-server(127.0.0.1:6379) timeout
---> System.TimeoutException: Connect to redis-server(127.0.0.1:6379) timeout
at FreeRedis.Internal.DefaultRedisSocket.Connect()
at FreeRedis.Internal.DefaultRedisSocket.Write(CommandPacket cmd)
at FreeRedis.RedisClient.SingleInsideAdapter.<>c__DisplayClass5_01.<AdapterCall>b__0() at FreeRedis.RedisClient.LogCallCtrl[T](CommandPacket cmd, Func1 func, Boolean aopBefore, Boolean aopAfter)
at FreeRedis.RedisClient.LogCall[T](CommandPacket cmd, Func1 func) at FreeRedis.RedisClient.SingleInsideAdapter.AdapterCall[TValue](CommandPacket cmd, Func2 parse)
at FreeRedis.RedisClient.Call[TValue](CommandPacket cmd, Func2 parse) at FreeRedis.RedisClient.Ping(String message) at FreeRedis.Internal.RedisClientPoolPolicy.PrevReheatConnectionPool(ObjectPool1 pool, Int32 minPoolSize)
--- End of inner exception stack trace ---
at FreeRedis.Internal.ObjectPool.ObjectPool1.GetFree(Boolean checkAvailable) at FreeRedis.Internal.ObjectPool.ObjectPool1.Get(Nullable1 timeout) at FreeRedis.RedisClient.PoolingAdapter.GetRedisSocket(CommandPacket cmd) at FreeRedis.RedisClient.PoolingAdapter.<>c__DisplayClass9_01.b__0()
at FreeRedis.RedisClient.LogCallCtrl[T](CommandPacket cmd, Func1 func, Boolean aopBefore, Boolean aopAfter) at FreeRedis.RedisClient.LogCall[T](CommandPacket cmd, Func1 func)
at FreeRedis.RedisClient.PoolingAdapter.AdapterCall[TValue](CommandPacket cmd, Func2 parse) at FreeRedis.RedisClient.Call[TValue](CommandPacket cmd, Func2 parse)
at FreeRedis.RedisClient.Set[T](String key, T value, TimeSpan timeout, Boolean keepTtl, Boolean nx, Boolean xx, Boolean get)
at FreeRedis.RedisClient.SetNx[T](String key, T value, Int32 timeoutSeconds)

也是第一次使用c#做项目,这里是我使用的错误么,不应该使用task.run去异步执行redis的操作么

实际上我看项目中的LockTest.cs中也是使用Task.run做测试的,只是数量比较少
var tasks = new Task[4];
for (var a = 0; a < tasks.Length; a++)
tasks[a] = Task.Run(() => {
var lk = cli.Lock("testlock1", 10);
Thread.CurrentThread.Join(1000);
Assert.True(lk.Unlock());
});
Task.WaitAll(tasks);