您的位置:首页 > 数据库 > Redis

MVC 4中使用ServiceStack.Redis实现Redis队列【错误日志并发处理】

2017-04-26 13:37 756 查看

HomeController.cs

public class HomeController : Controller
{
// GET: /Home/
//1.怎样在MVC中捕获异常信息.

public ActionResult Index()
{
int a = 2;
int b = 0;
int c = a / b;
return View();
}

}


MyExecptionAttribute.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ServiceStack.Redis;
namespace RedisMvcApp.xxxx
{
public class MyExecptionAttribute : HandleErrorAttribute
{
//public static Queue<Exception> ExceptionQueue = new Queue<Exception>();
//创建队列.
public static IRedisClientsManager clientManager = CreateManager(new string[] { "123456@127.0.0.1:6379" }, new string[] { "123456@127.0.0.1:6379" });
public static IRedisClient redisClent = clientManager.GetClient();
public override void OnException(ExceptionContext filterContext)
{
//将异常信息入队.
//ExceptionQueue.Enqueue(filterContext.Exception);//将异常信息入队.
redisClent.EnqueueItemOnList("errorException", filterContext.Exception.ToString());//将异常信息存储到Redis队列中了。
filterContext.HttpContext.Response.Redirect("/error.html");
base.OnException(filterContext);
}

public static PooledRedisClientManager CreateManager(string[] readWriteHosts, string[] readOnlyHosts)
{
//支持读写分离,均衡负载
return new PooledRedisClientManager(readWriteHosts, readOnlyHosts, new RedisClientManagerConfig
{
MaxWritePoolSize = 5,//“写”链接池链接数
MaxReadPoolSize = 5,//“读”链接池链接数
AutoStart = true,

}){ ConnectTimeout = 1000} ;
}
}
}


error.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
</head>
<body>
程序出错了5秒钟自动跳转到首页.
</body>
</html>


Global.asax

using log4net;
using RedisMvcApp.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;

namespace RedisMvcApp
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
log4net.Config.XmlConfigurator.Configure();//获取Log4Net配置信息(配置信息定义在Web.config文件中)
AreaRegistration.RegisterAllAreas();

WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
//通过线程开启一个线程,然后不停的从队列中获取数据
string filePath = Server.MapPath("/Log/");
ThreadPool.QueueUserWorkItem(o =>
{
while (true)
{
try
{
if (MyExecptionAttribute.redisClent.GetListCount("errorException") > 0)
{
string errorMsg = MyExecptionAttribute.redisClent.DequeueItemFromList("errorException");//从Redis队列中取出异常数据
if(!string.IsNullOrEmpty(errorMsg))
{
ILog logger = LogManager.GetLogger("czbkError");
logger.Error(errorMsg);//将异常信息写到Log4Net中.
}
else
{
Thread.Sleep(30);
}
}
else
{
Thread.Sleep(30);//避免了CPU空转。
}
}
catch (Exception ex)
{
MyExecptionAttribute.redisClent.EnqueueItemOnList("errorException", ex.ToString());
}
}

}, filePath);
}
}
}


Web.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework"   type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
requirePermission="false" />
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
<log4net>
<!-- OFF, FATAL, ERROR, WARN, INFO, DEBUG, ALL -->
<!-- Set root logger level to ERROR and its appenders -->
<root>
<level value="ALL" />
<appender-ref ref="SysAppender" />
</root>
<!-- Print only messages of level DEBUG or above in the packages -->
<logger name="WebLogger">
<level value="DEBUG" />
</logger>
<appender name="SysAppender"
type="log4net.Appender.RollingFileAppender,log4net">
<param name="File" value="App_Data/" />
<param name="AppendToFile" value="true" />
<param name="RollingStyle" value="Date" />
<param name="DatePattern" value=""Logs_"yyyyMMdd".txt"" />
<param name="StaticLogFileName" value="false" />
<layout type="log4net.Layout.PatternLayout,log4net">
<param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" />
<param name="Header" value="
----------------------header--------------------------
" />
<param name="Footer" value="
----------------------footer--------------------------
" />
</layout>
</appender>
<appender name="consoleApp" type="log4net.Appender.ConsoleAppender,log4net">
<layout type="log4net.Layout.PatternLayout,log4net">
<param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" />
</layout>
</appender>
</log4net>

<connectionStrings>
<add name="DefaultConnection" providerName="System.Data.SqlClient"
connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-RedisMvcApp-20140526210340;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-RedisMvcApp-20140526210340.mdf" />
</connectionStrings>
<appSettings>
<add key="webpages:Version" value="2.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="PreserveLoginUrl" value="true" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
<system.web>
<httpRuntime targetFramework="4.5" />
<compilation debug="true" targetFramework="4.5" />
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>
<pages>
<namespaces>
<add namespace="System.Web.Helpers" />
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Optimization" />
<add namespace="System.Web.Routing" />
<add namespace="System.Web.WebPages" />
</namespaces>
</pages>
<profile defaultProvider="DefaultProfileProvider">
<providers>
<add name="DefaultProfileProvider"
type="System.Web.Providers.DefaultProfileProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
connectionStringName="DefaultConnection" applicationName="/" />
</providers>
</profile>
<membership defaultProvider="DefaultMembershipProvider">
<providers>
<add name="DefaultMembershipProvider"
type="System.Web.Providers.DefaultMembershipProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
connectionStringName="DefaultConnection" enablePasswordRetrieval="false" enablePasswordReset="true"
requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5"
minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"
applicationName="/" />
</providers>
</membership>
<roleManager defaultProvider="DefaultRoleProvider">
<providers>
<add name="DefaultRoleProvider"
type="System.Web.Providers.DefaultRoleProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
connectionStringName="DefaultConnection" applicationName="/" />
</providers>
</roleManager>
<!--
如果要部署到具有多个Web服务器实例的云环境中,您应该将会话状态模式从“InProc”更改为“自定义”。
此外,更改名为“DefaultConnection”的连接字符串连接到一个实例的SQL Server(包括SQL Azure和SQL Compact),而不是SQL Server Express。

-->
<sessionState mode="InProc" customProvider="DefaultSessionProvider">
<providers>
<add name="DefaultSessionProvider"
type="System.Web.Providers.DefaultSessionStateProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
connectionStringName="DefaultConnection" />
</providers>
</sessionState>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS"
modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll"
preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS"
modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll"
preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS"
type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
</entityFramework>
</configuration>


运行结果如图:



站点的异常存储到Redis队列

cmd窗口端查询



从队列中获取异常数据记录到文本文件



cmd窗口端查询

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: