数据库cpu使用率居高不下的解决方案

近期遭遇了sqlserver2005 cpu 使用率居高不下,导致网站动态页面无法打开的情况。

对于数据库的sql语句优化仅局限在网站在被正常用户正常访问的时候。而如果出现恶意用户,大量访问动态页则无能为力。


基于这样一个事实:作为一个正常用户通常很少在一天内大量访问一个网站的动态页(>100),否则就可以将其视为非正常用户,可通过技术手段将其重定向到静态页面。


相关技术:.net http请求处理、唯一实例类、DataTable


实现一个HttpModule类:用户http请求的处理,获取当前url \用户ip等信息


实现一个Single类:只有一个实例对象,用于每个ip请求的控制。


Single类中静态化一个DataTable,用于存储ip以及访问次数。通过DataView查找ip


这样再通过设置每个ip的最大访问次数就可以有效的防止恶意用户访问,从而使网站平稳运行。


一点心得,不吝赐教。


------------------------------------------------------------------------------------------------------------------------------------------

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;


/// <summary>
///myHttpModule 的摘要说明
/// </summary>
public class myHttpModule:IHttpModule
{
    public myHttpModule()
{
//
//TODO: 在此处添加构造函数逻辑
//
}


    public void Dispose() { }


    public void Init(HttpApplication context)
    {
        context.BeginRequest += new EventHandler(Application_BeginRequest);
    }
    public void Application_BeginRequest(object sender, EventArgs e)
    {
       
        string oldurl = HttpContext.Current.Request.RawUrl;
        string ip = HttpContext.Current.Request.UserHostAddress;


        if (oldurl.IndexOf(".aspx") >= 0)
        {
            //获取当前ip计数
            int count = Visitor.getInstance().setDt(ip);


            int max = Visitor.getInstance().getMaxCount();


            if (count > max)
            {
               HttpContext.Current.Response.Redirect("~/0.html");
             
            }
        }
       
    }


}


using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;


/// <summary>
///访问控制
/// </summary>
public class Visitor
{
public Visitor()
{
//
//TODO: 在此处添加构造函数逻辑
//
}


    private static Visitor _instance;
    private static int _count;
    private static DataTable dt;
    private static DateTime next;
    private static int _MAX;


    public static  Visitor getInstance()
    {
        if (_instance == null)
        {
            _instance = new Visitor();
        }
        return _instance;
    }


    //获取当前计数
    public int getCount()
    {
        _count += 1;
        return _count;
    }


    public int setDt(string ip)
    {
        int _result = 0;


        if (dt == null)
        {
            dt = new DataTable();
        }
        if (dt.Columns.Count == 0)
        {
            dt.Columns.Add("IP");
            dt.Columns.Add("COUNT");
            DataColumn[] dc = { dt.Columns["IP"] };


            dt.PrimaryKey = dc;
        }


        Clear();


        //保存数据
        DataView dv = dt.DefaultView;
        dv.RowFilter = "IP='" + ip + "'";
        DataTable dtTemp = dv.ToTable();
        if (dtTemp.Rows.Count > 0)
        {
            _result = Convert.ToInt16(dv.Table.Rows[0]["COUNT"]) + 1;
            //编辑
            dv.Table.Rows[0]["COUNT"] = _result;
            //dtTemp.Rows[0]["COUNT"] = _count;
        }
        else
        {
            //新增
            DataRow dr = dt.NewRow();
            dr["IP"] = ip;
            dr["COUNT"] = 1;
            dt.Rows.Add(dr);
            _result = 1;
        }

        return _result;
    }


    public void Clear()
    {
        if (next == null)
        {
            next = DateTime.Now.AddDays(1);
        }


        if (DateTime.Now > next)
        {
            dt.Clear();
            next = DateTime.Now.AddDays(1);
        }
    }


    //获取dt记录数
    public int getRowsCount()
    {
        if (dt != null)
        {
            return dt.Rows.Count;
        }
        else
        {
            return -1;
        }
    }


    //获取最大访问量
    public int getMaxCount()
    {
        if (_MAX == 0)
        {
            _MAX = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings.Get("MAX_COUNT"));
        }
        return _MAX;
    }


  
}

web.config中添加

    <httpModules>
      <add name="myHttpModule" type="myHttpModule"/>
    </httpModules>


//.............................方案优化.............................................................

以上解决方案在实际使用中存在不足,首先局域网用户IP一样,这样每天设置一个上限机动性不强,大小不好掌控。

现采取如下方案,每隔一段时间(20分钟)清理一次记录,这样20分钟内访问次数可控制在200次左右,小区间内重复率也可以降低,应该比上面的方式更人性化。


  

    

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值