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

C#的HttpModule中及Java的Servlet中成员变量乱用导致的不易重现的BUG的更多相关文章

  1. 假如java类里的成员变量是自身的对象

    假如java类里的成员变量是自身的对象,则新建该类对象时内存中怎么分配空间,我感觉似乎死循环了. 不过我想的肯定是错的,因为很多类的成员变量是自身对象,并且绝对无错,举个例子: Class A{ pr ...

  2. java类里的成员变量是自身的对象问题

    今晚看单例模式饿汉时想到一个问题:假如java类里的成员变量是自身的对象,则新建该类对象时内存中怎么分配空间,我感觉似乎死循环了.于是上网搜索了下,哈哈,果然有人早就思考过这个问题了,站在巨人的肩膀上 ...

  3. Java 之 Servlet中的生命周期

    Servlet 生命周期 一.重写servlet方法 当创建一个类,继承 servlet 这个接口时,需要实现里面的抽象方法. import javax.servlet.*; import java. ...

  4. [Java][Web] Servlet中转发和重定向比较

    Servlet中页面跳转的两种方式 请求转发 使用requestDispatcher对象 request.getRequestDispatcher("path").forward( ...

  5. Strut2中的session和servlet中的session的区别

    在jsp中,内通过内置对象 HttpServletRequest的getSession()方法可以获取到HttpSession,比如: <%@ page language="java& ...

  6. [Java] 继承中,父类被覆盖的成员变量、方法的可访问性

    在 Java 的继承机制里,在子类内部,可以访问父类被覆盖的变量和方法:在子类外部,可以访问父类的被覆盖变量,但是不能访问父类的被覆盖方法. 父类中被覆盖的方法不能在外部被方法,这是出于封装的考虑. ...

  7. java中的类修饰符、成员变量修饰符、方法修饰符。

    类修饰符: public(访问控制符),将一个类声明为公共类,他可以被任何对象访问,一个程序的主类必须是公共类. abstract,将一个类声明为抽象类,没有实现的方法,需要子类提供方法实现. fin ...

  8. java中的类修饰符、成员变量修饰符、方法修饰符

    类修饰符:  public(访问控制符),将一个类声明为公共类,他可以被任何对象访问,一个程序的主类必须是公共类. abstract,将一个类声明为抽象类,没有实现的方法,需要子类提供方法实现. fi ...

  9. Java 的局部变量和成员变量

    在Java语言中没有全局变量  分析各种变量的作用域的最简单方法是以花括号为界, 1.在类体中定义的是成员变量,成员变量会被默认初始化 2.在方法中定义的是局部变量,局部变量不会被默认初始化

随机推荐

  1. 【Jmeter】jmeter提取response中的返回值,并保存到本地文件--BeanShell后置处理器

    有个需求,需要在压测环境中,创建几十万的账号数据,然后再根据创建结果,查询到某些账号信息. 按照之前我的做法,直接Python调用API,然后再数据库查询: 但是近期所有开发人员的数据库访问权限被限制 ...

  2. Spark学习之路 (九)SparkCore的调优之数据倾斜调优[转]

    调优概述 有的时候,我们可能会遇到大数据计算中一个最棘手的问题--数据倾斜,此时Spark作业的性能会比期望差很多.数据倾斜调优,就是使用各种技术方案解决不同类型的数据倾斜问题,以保证Spark作业的 ...

  3. 关于Hosts与network的异同之处

    1.hosts文件,路径:/etc/hosts,此文间是在网络上使用的,用于解析计算机名称和IP地址的映射关系,功能相当于windows下面的c:\windows\system32\drivers\e ...

  4. LeetCode longest substring without repeating characters 题解 Hash表

    题目 Given a string, find the length of the longest substring without repeating characters. Example 1: ...

  5. Phalanx HDU - 2859 dp

    #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> us ...

  6. vue 多组件路由处理方法

    实现页面: 实现效果: 实现代码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8" ...

  7. layer.open获取弹出层的input框的值

    使用top.$('#txtReason').val();获取值: //不通过 function unAuditData(id) { parent.layer.open({ type: , title: ...

  8. 【手抖康复训练1 】Codeforces Global Round 6

    [手抖康复训练1 ]Codeforces Global Round 6 总结:不想复习随意打的一场,比赛开始就是熟悉的N分钟进不去时间,2333,太久没写题的后果就是:A 题手抖过不了样例 B题秒出思 ...

  9. os::commit_memory(0x0000000085330000, 2060255232, 0) failed; error='Cannot allocate memory' (errno=12)

    centos 安装 elasticsearch的时候 因为 elasticsearch默认 需要 2G内存导致的镜像不能运行 解决方案 修改配置文件 find / -name jvm.options ...

  10. 国内下载Git的连接地址

    Git国内下载: https://github.com/waylau/git-for-win