刚开始使用StackExchange.Redis不久,最近使用中偶尔在日志里面看见这个报错,应该是用用订阅发布功能是引起的,在网上查不到太多有用的数据,望过来人指点。
使用publish的思路,程序中通过try\catch捕捉错误,得到错误后把exception序列化成字符串,然后利用Redis发布。订阅的地方收到后再一个一个的把错误写入log4net日志。
难道是exception序列化后太大了?但是这种方式大部分情况下是成功的,偶尔才报这个错误。
捕捉到的错误:
2018-05-25 10:15:43,463 [60] ERROR Error - 拦截到一个控制器范围异常
异常结论:Timeout performing PUBLISH ErrorLog, inst: 0, mgr: ExecuteSelect, err: never, queue: 0, qu: 0, qs: 0, qc: 0, wr: 0, wq: 0, in: 0, ar: 1, clientName: iZqe19vhajZ, serverEndpoint: 127.0.0.1:6379, IOCP: (Busy=0,Free=800,Min=8,Max=800), WORKER: (Busy=2,Free=798,Min=8,Max=800), Local-CPU: unavailable (Please take a look at this article for some common client-side issues that can cause timeouts: https://github.com/StackExchange/StackExchange.Redis/tree/master/Docs/Timeouts.md)
Errorname System.TimeoutException: Timeout performing PUBLISH ErrorLog, inst: 0, mgr: ExecuteSelect, err: never, queue: 0, qu: 0, qs: 0, qc: 0, wr: 0, wq: 0, in: 0, ar: 1, clientName: iZqe19vhajZ, serverEndpoint: 127.0.0.1:6379, IOCP: (Busy=0,Free=800,Min=8,Max=800), WORKER: (Busy=2,Free=798,Min=8,Max=800), Local-CPU: unavailable (Please take a look at this article for some common client-side issues that can cause timeouts: https://github.com/StackExchange/StackExchange.Redis/tree/master/Docs/Timeouts.md)
在 StackExchange.Redis.ConnectionMultiplexer.ExecuteSyncImpl[T](Message message, ResultProcessor`1 processor, ServerEndPoint server)
在 StackExchange.Redis.RedisBase.ExecuteSync[T](Message message, ResultProcessor`1 processor, ServerEndPoint server)
在 StackExchange.Redis.RedisSubscriber.Publish(RedisChannel channel, RedisValue message, CommandFlags flags)
在 Iot.Common.Redis.RedisHelper.Publish[T](String channel, T msg) 位置 c:\***\Redis\RedisHelper.cs:行号 1009
在Iot.Common.LoggerInfo.LoggerFunc.SaveErrorLogTxT(String title, Exception ex, Boolean isPublish) 位置 c:\****\LoggerInfo\LoggerFunc.cs:行号 111
在 Iot.Common.Utils.SaveErrorLog(String info, Exception ex) 位置 c:\****\Utils.cs:行号 360
=====主要方法
/// <summary>
/// 保存错误日志
/// </summary>
/// <param name="title">日志标题</param>
/// <param name="ex">日志异常内容</param>
/// <param name="isPublish">是否采用订阅发布模式</param>
public void SaveErrorLogTxT(string title,Exception ex,bool isPublish)
{
if (isPublish==false)
{
if (errorLogger.IsErrorEnabled)
{
if (ex == null)
{
errorLogger.Error(title);
}
else
{
errorLogger.Error(title, ex);
}
}
}
else
{
RedisHelper redis = new RedisHelper();
LoggerMsg msg = new LoggerMsg(title, ex, ELogType.ErrorLog);
redis.Publish<LoggerMsg>(CommonParam.WebSignStr + ELogType.ErrorLog.ToString(), msg);
}
}
发布订阅的方法:
/// <summary>
/// Redis发布订阅 发布
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="channel"></param>
/// <param name="msg"></param>
/// <returns></returns>
public long Publish<T>(string channel, T msg)
{
ISubscriber sub = _conn.GetSubscriber();
return sub.Publish(channel, ConvertJson(msg));
}