博文

记一次网络劫持问题排查与解决

问题爆露:用户反馈登录超时,一直登录不上站酷 我们自己测试登录正常,大部分用户登录也正常,远程到用户的机器上去 监控浏览器发送的ajax请求,看发送的数据及返回接收的数据,发现在回来的数据中嵌入了一段js代码 < script charset = "utf-8" async = "true" src = " http://t.5txs.cn/rb/i7.js "></script> 再回到我们的服务器上监控,看返回给用户的内容是没有这些脚本的 那猜测就是用户的运营商劫持了网站的返回数据强行插入广告 html页面返回的话,这段脚本会在页面的右下角加载出来广告 JSONP请求会因为这段脚本导致请求失败 到现在就遇到难点了, http://peterkwok.blog.51cto.com/272862/1793569 https://www.v2ex.com/t/286936 http://www.zhihu.com/question/20418863 https://qifu.me/at201602211724/ https://www.google.com.hk/?gws_rd=cr,ssl#newwindow=1&safe=strict&q=http:%2F%2Ft.5txs.cn%2F https://whois.aliyun.com/whois/domain/5txs.cn?spm=5176.8076989.339865.13.nWf9vs&file=5txs.cn 等等 也没有找到现成的可行的解决方案 想过投诉,想过报案,想过让用户去投诉他们的网络运营商,也想过各种技术方案,最终还是只能通过技术方案来缓解这个问题 之前想过技术解决方案,也总是觉着这个事,再改变技术实现,改框架等等,实现起来有点困难,有点不值 后来跟多个同事沟通,王杰,刘越,芦传,许立志,梁鹏,刘强,等等,最终强哥给了一个思路,自己实现jsonp,改写里面的处理逻辑, 之前王杰也提过这样的想法,但我认为jsonp是一个标准化的东西,是不可改的东西,这点评估有一定的失误,只是因为对jsonp的底层不是很了解 ...

Torque源码之二

在使用torque的过程中,generator的自动生成代码很是方便,有点遗憾的是每次生成代码之后要手动的替换一些东西,数据库名,和主键自动生成的时候设置主键生成策略,然后才能使用。 为什么框架不能实现的更好一点,一次性生成可用的代码呢? 问题1,generator在执行jdbc这个target过程中,生成的schema文件中database元素的name属性是root,并不是数据库的名,跟踪代码发现这个值是根据配置中的dbUser的值来赋值的,怪不得是root因为数据库连接的用户名是root。 没明白为什么database的name属性是根据dbUser来给数据库name赋值,把它改成dbSchema,然后在作配置的时候,指定schema为数据库名就可以了 201行改为 databaseNode.setAttribute( "name", dbSchema); 问题2,同样是在generator在执行jdbc这个target过程中,数据库中表的主键为自增长的时候,生成的schema文件的database元素要有idMethod=“native”属性值,否则在使用过程中实体的insert方法执行完成后并没有把这条数据的ID带回来,很是不方便。 继续跟踪源代码发现在实现过程中并没有考虑主键生成策略这个因素,无奈自己顺藤摸瓜把这个属性给加上吧。 大致过程是在从数据库中把表结构取出来的时候记录下来表的主键生成策略,如果为自动生成, 在表下增加属性table.setAttribute(“idMethod”, “native”); getColumns方法中 String is_autoincrement = columnSet.getString(23); //。。。 col.add(decimalDigits); col.add(is_autoincrement); columns.add(col); //。。。 剩下就是在组织xml结构的时候把这个属性加上 generateXML方法中增加 boolean isautoincrement = false; if (isautoincrement) { table.setAttribute( "idMethod", "native");...

Torque实现读写分离双数据库配置

由于有读写分离的需求,看了一下公司的代码是怎么处理的,才发现用的是很原始的方法,在做数据库操作的时候,直接用的不同的数据库连接。 现在用的torque,并且代码也写了一些,不想再在业务代码级别上做太多的改动,所以就想到torque来管理读写分离的工作。 了解了一下发现torque只有一个库的配置,没有考虑到读写分离的情况(也读是提供了我没找到。。。) 于是自己稍微看了一下源代码,加上了读写分离数据库的配置,让torque在执行doSelect(Criteria criteria)方法的时候会去找配置的只读库 改动比较少 进入正题: 基于TORQUE-runtime-3.3版本 http://svn.apache.org/repos/asf/db/torque/runtime/tags/TORQUE_3_3 可以从以上地址下载到torque的3.3版源代码 首先是org.apache.torque.util.BasePeer类 直接进入doSelect方法 原代码: con = Transaction.beginOptional( criteria.getDbName(), criteria.isUseTransaction()); 改为: con = Transaction.beginOptional( Torque.getReadableDB(), criteria.isUseTransaction()); 这里先把方法写出来,后面再去实现. 继续org.apache.torque.Torque类 增加属性声明 /** * The key used to configure the name of the readable database. * jiangchi@youku.com add */ public static final String READABLE_KEY = "readable"; 增加方法 /** * Returns the name of the readable database. * * @return name of the readable DB, or null if Torque is not ini...

开闭原则的理解

        开闭原则,“软件实体应当对扩展开放,对修改关闭”,是要达到一个状态,而要达到这个状态,就需要在写代码的过程中要想到和做到。。。 提倡开闭原则,其目的是我们在编写代码的时候就要考虑到每个功能模块的潜在的变化的可能性,尽可能的写简短单一功能并且复用性强的模块。 只有在写代码的时候注意到了这些,在重构或者变更的时候,才能做到“对扩展开放,对修改关闭”。 引用一段百度百科中关于开闭原则实现的一段文字: 开闭原则具有理想主义的色彩,它是面向对象设计的终极目标。因此,针对开闭原则的实现方法,一直都有面向对象设计的大师费尽心机,研究开闭原则的实现方式。后面要提到的里氏代换原则(LSP)、依赖倒转原则(DIP)、接口隔离原则(ISP)以及抽象类(Abstract Class)、接口(Interface)等等,都可以看作是开闭原则的实现方法。 这些原则中,大部分都有框架实现了,比如spring中的“依赖倒转”,用这些框架,可以节省大量工作时间,以及优化工程的代码结构。除这些框架之外的,就是在业务逻辑实现的部分,由程序员写代码的部分,如能做到遵循开闭原则,那么该项目质量应该会上升一个等级。 外话,当然项目的评判标准,最重要的还是架构的设计。

java中构造方法的执行过程

java中构造一个类实例,就要首先构造它的父类,因为子类是由父类派生而来,只有有了父类才可能有子类.而对于类本身的构造过程中,是要首先按顺序来对它的成员变量进行初始化,然后再调用其构造方法. 所以 java中构造一个类的整个过程可以理解为:如果有父类 先 1构造父类 然后构造本类 2本类成员变量初始化 3调用本类构造方法 实际上在每个类(除Object外)的构造造方法中都要执行super()方法,默认的情况下系统会自动为构造方法最前面加上super()这条语句,我们可以显示的写出来,并且也可为其加上参数,前提是父类有相对应的构造方法.前面说的构造本类之前要构造父类就是这条语句的作用. 成员变量的初始化过程是在super()语句后面其它方法体前面执行的 如果某个类的父类有多个构造方法时 子类就可以用不同的参数调用父类中相对应的构造方法来构造父类 如果加上自由块和静态的自由块 执行的顺序为: 父类的静态自由块,父类的静态成员变量被初始化 子类的静态自由块,子类的静态成员变量被初始化 父类的自由块,父类的成员变量被初始化 父类的构造方法 子类的自由块,子类的成员变量被初始化 子类的构造方法 自由块和成员变量是等同的优先级被初始化的 例: public class E { public static void main(String[] args) { new B(); } } class A { { System.out.println("父类A的自由块"); } A() { System.out.println("父类A的构造方法\n"); } D d = new D("父类A的成员变量被初始化\n"); static { System.out.println("父类A的静态自由块"); } static D dd = new D("父类A的静态成员变量被初始化\n"); } class B extends A { static D ddd = new D("子类B的静态成员变量被初始化"); static { System.out.println("子类...