zoukankan      html  css  js  c++  java
  • C#的HttpModule中及Java的Servlet中成员变量乱用导致的不易重现的BUG

    3年前写的在HttpModule中记录访问日志的代码,在最近使用日志数据分析登录账号的IP情况时,才发现了一个不易重现的BUG——日志中记录的登录账号出现串掉的情况。之所以这个时候才发现该问题,是因为部分用户的IP是固定的,但是日志里却出现了别人的IP。而之所以3年后才发现,是因为这块日志数据一直没怎么用过。回头想想,根本原因还是在用成员变量的时候没考虑到多线程的情况,或者说多用户同时访问的情况。因为HttpModule里的事件,是所有页面实例共用的。

    问题代码:

            string dateBeginRequest;//开始请求时间
            string userName;//用户名
    
            public void Init(HttpApplication application)
            {
                application.AcquireRequestState += (new EventHandler(this.Application_AcquireRequestState));
                application.BeginRequest += (new EventHandler(this.Application_BeginRequest));
                application.EndRequest += (new EventHandler(this.Application_EndRequest));
            }

    实现System.Web.IHttpModule的类中,有两个导致BUG的字符串成员变量。其中字符串成员变量dateBeginRequest在Application_BeginRequest事件方法中赋值,字符串成员变量userName在AcquireRequestState 事件方法中赋值,值来源于Session。当在本地调试时很难重现用户A的账号记录到用户B的日志数据中,这种情况。但是当生产环境有一定的并发请求的时候,就会出现用户A的账号记录到用户B的日志数据中,日志数据中请求开始时间这个字段也会出现同样的问题。

    解决办法就是把这部分记录请求日志的代码,转移到各页面的基类中,因为各页面的后台类实例是独立的,互不影响。

    上述问题在我们写的基于Servlet的Java开发框架中也出现了,解决办法是在方法内部创建对象实例,而不是使用类的成员变量来赋值再使用。之所以Servlet中成员变量也会出现该问题,是因为Servlet的service等方法也是所有映射到的请求都会进入该方法,存在并发的情况。

    本文首发于我的CSDN博客:https://blog.csdn.net/n_ithero/article/details/104062423

  • 相关阅读:
    共享内存基本操作
    mmap 操作
    busybox 安装问题解决
    ubuntu apt-get failed
    live555 学习资料
    循环队列实现
    socket 聊天室实现
    socket 映射服务器--(可处理多客户端连接(fork),显示退出信息)
    socket 映射服务器程序
    vector和list插入性能对比
  • 原文地址:https://www.cnblogs.com/xuezhizhang/p/12228519.html
Copyright © 2011-2022 走看看