关于p6spy的介绍

最近公司项目里需要使用到将所有执行的sql打出日志,放在一个文件下。公司一大神级人物给解决了,刚刚花了点时间给研究了一下。

他用的就是p6spy,其实也没做多少工作。主要的工作p6spy都已经做过了。

p6spy我的理解就是:p6spy将应用的数据源给劫持了,应用操作数据库其实在调用p6spy的数据源,p6spy劫持到需要执行的sql或者hql之类的语句之后,他自己去调用一个realDatasource,再去操作数据库,只要劫持到那些sql之后,能干的事情就很多了。

p6spy 可以输出日志到文件中、控制台、或者传递给 Log4j,而且还能配搭 SQL Profiler 或 IronTrackSQL 图形化监控 SQL 语句,监测到哪些语句的执行是耗时的,逐个优化。关于与 SQL Profiler 或 IronTrackSQL 的配合使用可参数文件的链接。

p6spy在sourceforge上下载:[p6spy][]
[p6spy]: http://sourceforge.net/projects/p6spy/?source=dlp

p6spy的配置:

  1. p6spy.jar放入应用的classpath下

  2. 修改连接池或者连接配置的jdbc的驱动为p6spy所提供的驱动,com.p6spy.engine.spy.P6SpyDriver

    在单独的Hibernate的应用中,数据库驱动配置在hibernate.cfg.xml里面,所以我需要配置文件中的connection.driver_class属性从oracle.jdbc.driver.OracleDriver改为com.p6spy.engine.spy.P6SpyDriver其他的用户名密码等等配置信息全部不用修改.在web程序中,配置的连接池部分,也只需要修改jdbc-driver的配置即可。

    Hibernate.cfg.xml:

     <session-factory>
         <!-- 在这里改成p6spy提供的数据源 -->
         <property name="connection.driver_class">com.p6spy.engine.spy.P6SpyDriver</property>       
         <property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property>
         <property name="connection.username">scott</property>
         <property name="connection.password">tiger</property>
         <property name="connection.pool_size">1</property>
         <property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
         <property name="current_session_context_class">thread</property>
         <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
         <property name="show_sql">true</property>
         <property name="hbm2ddl.auto">false</property>
         <property name="hibernate.jdbc.batch_size">0</property>
     </session-factory>
    
  3. 修改 spy.properties 并将其放到classpath下:

     #################################################################
     # MODULES                                                       #
     #                                                               #
     # Modules provide the P6Spy functionality.  If a module, such   #
     # as module_log is commented out, that functionality will not   #
     # be available.  If it is not commented out (if it is active),  #
     # the functionality will be active.                             #
     #                                                               #
     # Values set in Modules cannot be reloaded using the            #
     # reloadproperties variable.  Once they are loaded, they remain #
     # in memory until the application is restarted.                 #
     #                                                               #
     #################################################################
     #第一:module.log的属性必须配置,如果不配置,P6SPY将不起任何作用,典型配置:
     module.log=com.p6spy.engine.logging.P6LogFactory
     #module.outage=com.p6spy.engine.outage.P6OutageFactory
      
     #################################################################
     # REALDRIVER(s)                                                 #
     #                                                               #
     # In your application server configuration file you replace the #
     # "real driver" name with com.p6spy.engine.P6SpyDriver. This is #
     # where you put the name of your real driver P6Spy can find and #
     # register your real driver to do the database work.            #
     #                                                               #
     # If your application uses several drivers specify them in      #
     # realdriver2, realdriver3.  See the documentation for more     #
     # details.                                                      #
     #                                                               #
     # Values set in REALDRIVER(s) cannot be reloaded using the      #
     # reloadproperties variable.  Once they are loaded, they remain #
     # in memory until the application is restarted.                 #
     #                                                               #
     #################################################################
      
     #第二:数据库驱动配置,你懂的,不多说了
     # oracle driver
     # realdriver=oracle.jdbc.driver.OracleDriver
      
     # mysql Connector/J driver
     # realdriver=com.mysql.jdbc.Driver
      
     # informix driver
     # realdriver=com.informix.jdbc.IfxDriver
      
     # ibm db2 driver
     # realdriver=COM.ibm.db2.jdbc.net.DB2Driver
      
     # the mysql open source driver
     realdriver=org.gjt.mm.mysql.Driver
      
     #specifies another driver to use
     realdriver2=
     #specifies a third driver to use
     realdriver3=
      
     #第三:appender配置,一般分为三种
     #specifies the appender to use for logging
     #appender=com.p6spy.engine.logging.appender.Log4jLogger
     #控制台
     #appender=com.p6spy.engine.logging.appender.StdoutLogger
     appender=com.p6spy.engine.logging.appender.FileLogger
      
     # name of logfile to use, note Windows users should make sure to use forward slashes in their pathname (e:/test/spy.log) (used for file logger only)
     #日志文件存放路径及文件名
     logfile     = spy.log
      
     # append to  the p6spy log file.  if this is set to false the
     # log file is truncated every time.  (file logger only)
     append=true
      
     #The following are for log4j logging only
     log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender
     log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout
     log4j.appender.STDOUT.layout.ConversionPattern=p6spy - %m%n
      
     log4j.logger.p6spy=INFO,STDOUT
    

使用history.back(-1)的问题

今天在调一个项目现场的问题,觉得有点记录下来的意义。

首先看看重现问题的步骤:

  1. 选择一个事物分类进行查询,搜到一条记录,然后进入申请页面。

  2. 进入申请页面之后点返回,页面立即没有了(只在IE下会出现问题)而且页面上显示的是webpage has expired!页面已经过期。

    ps:返回按钮触发的事件是:window.history.back(-1);

  3. 解决办法:

    页面过期,我在想了是不是页面上的meta设置no-cache了,即:

     <meta http-equiv="Pragma" content="no-cache"/>
    

    然后我立即查看页面源代码,发现木有这个东西。我就纳闷了,那是怎么了呢。

    后来一想是不是我查询的时候提交了一个表单,这时候已经跳到我查询的目标页面(虽然还是同一个jsp页面),这时候用history.back(-1)已经找不到参数了,所以会报页面找不到的问题。

    然后想到form表单里面的method=”post”和method=”get”的区别(具体的网上搜索去吧)。

    so, 我把搜索的form中method改成get。

然后就OK了,问题解决了。

个人简历

1. 联系方式

2. 个人信息

  • 姓名/性别/生日:孙昊 / 男 / 1990-03-18
  • 工作年限:14 年+
  • 学历:本科(安徽理工大学 信息与计算科学)
  • 荣誉奖励:2011 年实习期间获得“优秀实习生”
  • 求职意向:Java 资深开发工程师 / 架构师(接受远程 / Hybrid)
  • 工作地点:南京优先,支持远程或异地 Hybrid

3. 工作经历

3.1 南京魔数团信息科技有限公司(Teamhelper)

3.1.1 职位与时间

架构师 · 2025-06 ~ 至今

3.1.2 工作内容

  1. 作为技术负责人与架构师,统筹研发团队的技术规划与架构把控,负责技术方案的设计与执行。
  2. 梳理存量产品与服务的架构现状,沉淀技术/业务/部署架构图及组件关系图,并制定阶段性演进路线。
  3. 牵头关键技术方案:统一云存储对接(多厂商适配、鉴权与生命周期策略)、远程会议实时翻译链路。
  4. 建立并推动工程规范与流程:分支模型、代码规范与 Code Review;搭建 DevOps/CI/CD 流水线,完善发布与回滚流程。

3.2 南京蔚蓝智能科技有限公司

3.2.1 职位与时间

架构师(技术负责人) · 2024-04 ~ 2025-06(在岗:1年2个月)

3.2.2 工作内容

  1. 数字化团队技术负责人,管理公司所有OD人员(10+人)
  2. 负责数字化团队技术架构
  3. 负责数字化团队技术氛围建设
  4. 主导公司出海项目中关于隐私合规事宜(隐私数据合规、跨境传输、各种协议)
  5. 作为我司项目负责人、接口人与建行生活、建行善融进行对接

3.3 南京叶子科技有限公司(OPPO 全资子公司)

3.3.1 职位与时间

架构师 · 2018-08 ~ 2024-04(在岗:5年8个月)

3.3.2 团队与职责

  • 负责 OPPO 销售领域的数字化平台建设,带领团队完成公司 PaaS 层能力建设(控制台、流程中心、网关中心、任务调度中心、集成中心)。
  • 协同运维搭建 DevOps 流程,沉淀底层工具类组件并在公司内部广泛复用。
  • 参与技术选型与标准制定,提供疑难问题支援与技术方案评审。
  • 参与大数据相关能力的引入与落地(初步接入与应用)。
  • 深度参与 OPPO 数字化转型「凤凰(Phoenix)计划」。

3.3.3 代表项目

  • 项目一:API 集市(A级+)

    • 角色:系统架构师
    • 背景:整合 OPPO 内部上千系统,通过 API 集市统一管理调用关系、质量与治理能力。
    • 成果:
      • 入驻 1400+ 系统、近万接口;全球化部署(中国/巴黎/新加坡/印度)。
      • 中国区实现异地双机房部署,分钟级容灾切换;支持蓝绿发布。
      • 全年可用性 99.99%,无重大事故;单日流量峰值 2 亿+ 次,TPS 峰值 5000+。
      • 主导系统降本计划,年度节省成本 80 万+。
    • 技术栈:Java、Spring 全家桶、Lua、APISIX、Docker、K8S。
  • 项目二:任务调度中心(A级)

    • 角色:产品 / 架构师 / 主程
    • 背景:构建统一调度平台,集中管控公司内部系统定时任务,基于 Quartz 完全自研。
    • 成果:
      • 覆盖 800+ 系统、6000+ 任务;累计调度 3.5 亿+ 次。
      • 任务类型:HTTP 任务、自研协议任务、Dubbo 任务。
      • 支持任务分片、广播;支持多 Quartz 集群以降低任务间影响。

3.3.4 离职原因

公司组织调整,Base 变更为深圳

3.4 中兴软创科技股份有限公司(浩鲸云)

3.4.1 职位与时间

架构师 · 2015-04 ~ 2018-08(在岗:3年4个月)

3.4.2 职责

  • 政企事业部智慧城市方向的底层架构开发与平台化能力建设。
  • 负责核心模块的设计与实现,保障系统可扩展与稳定性。

3.4.3 离职原因

为了更好的职业发展

3.5 联创车盟汽车服务有限公司(AA China)

3.5.1 职位与时间

高级 Java 开发工程师 · 2014-07 ~ 2015-04(在岗:0年9个月)

3.5.2 职责

  • 参与慧驾平台结算系统的设计与开发,承担产品技术支撑工作。
  • 与团队协作完成系统架构与新技术调研与落地。

3.5.3 离职原因

公司欠薪,领导鼓励离职

3.6 江苏金智教育信息技术有限公司

3.6.1 职位与时间

高级 Java 开发工程师 · 2011-07 ~ 2014-07(含 1 年实习,在岗:3年0个月)

3.6.2 职责

  • 参与统一通信平台与工作流相关项目的研发,服务全国本专科学校。
  • 协助实现自定义表单与内容管理系统(CMS)内容模型等模块。
  • 2011.07 ~ 2012.07 实习并获得“优秀实习生”。

3.6.3 离职原因

寻求新的发展、突破自我

4. 开源项目

5. 技能栈

  • 后端与微服务:精通 Java、Spring/Spring Boot/Spring Cloud,具备微服务拆分、治理与性能优化经验;熟悉 Dubbo、REST 设计与服务治理实践。
  • API 网关与平台化:熟悉 APISIX / Nginx / Lua,具备网关治理(鉴权、限流、熔断、灰度/蓝绿)与平台化能力建设经验。
  • 容器化与 DevOps:熟悉 Docker、K8S,搭建过 CI/CD 流程与工程规范,实践 Jenkins + Maven + GitLab 等工具链。
  • 数据库与缓存:熟练使用 MySQL,具备 SQL 优化与故障排查能力;熟悉 Redis、MongoDB、Memcached。
  • 中间件与消息:了解并实践过 RabbitMQ 等消息中间件。
  • 构建与工程:熟练使用 Maven、Gradle;关注可观测性与稳定性建设。
  • 编程语言:具备 JavaScript、Python、Groovy、PHP、Node.js、Scala 的一定实践能力,用于脚本与工具开发。
  • 通用能力:团队协作与培养、快速学习与问题攻坚、良好的文档能力与跨团队沟通。

6. END

感谢您花时间阅读我的简历,期待能有机会与您共事。