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. 【笔记】机器学习 - 李宏毅 - 12 - CNN

    Convolutional Neural Network CNN 卷积神经网络 1. 为什么要用CNN? CNN一般都是用来做图像识别的,当然其他的神经网络也可以做,也就是输入一张图的像素数组(pix ...

  2. 11maven的聚合

    我们都知道项目之间的依赖首先要把被依赖的项目先安装install到maven的本地仓库中,然后在本项目中配置被依赖的仓库坐标,才能进行依赖通信. 例如: A项目 >  B项目 A项目依赖B项目中 ...

  3. node种buffer对象数组 深拷贝浅拷贝问题

    node的一个上位机和下位机通信的转发程序,用的是udp转发. 其中在发送的时候会进行一次rc4加密数据 出现问题就在这个加密数据这一块,因为这个是升级包广播发送.提前生成了升级用的广播报文,是一个b ...

  4. Pycharm控制台乱码问题

    PS:如我般的小白都会遇到中文乱码问题,那么怎么解决呢?其实非常简单,鼠标点点就好,请看下面: 如下乱码: 解决方法: 按如下步骤File→Settings→Editor→File Encodings ...

  5. .net mvc 使用 aspose.cells导出数据

    public class AsposeCellsHelper { public Workbook workBook; public Worksheet worksheet; Style style; ...

  6. Thymeleaf的基本用法

    俗话说,不会前端的后端工程师不是一个合格的程序员.因为在项目中经常要和前端工程师打交道,并且偶尔也会涉及前端的简单开发,因此在闲暇之余学习了一点前端的知识,今天首先总结归纳一下 Thymeleaf 模 ...

  7. 知乎-如何rebuttal

    作者:魏秀参链接:https://zhuanlan.zhihu.com/p/104298923来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 学术论文是发布自己或团队最 ...

  8. BZOJ4566&&lg3181 HAOI找相同字符(广义后缀自动机)

    BZOJ4566&&lg3181 HAOI找相同字符(广义后缀自动机) 题面 自己找去 HINT 给定两个文本串,问从两个串中各取一个非空子串,使这俩子串相同,问方案有多少种.我的思路 ...

  9. JAVA将图片(本地或者网络资源)转为Base64字符串,将base64字符串存储为本地图片

    代码如下: package com.futuredata.dataservice.util; import java.io.ByteArrayOutputStream; import java.io. ...

  10. Query的选择器

    Query的选择器   一. 基本选择器   1. ID选择器            ID选择器#id就是利用DOM元素的id属性值来筛选匹配的元素,并以iQuery包装集的形式返回给对象.      ...