对RmiJdbc的二次开发

本文介绍了对RmiJdbc进行二次开发,以满足不暴露数据库连接信息、记录SQL日志及保持高性能的需求。通过改造JDBC接口、实现日志系统(包括同步、半异步、异步写入)并进行功能和性能测试,得出结论:RmiJdbc在性能上无法达到预期,不适合此场景。
摘要由CSDN通过智能技术生成

接到一个任务,需要对项目中用到的JDBC进行改造,需求如下:

  • 不要将实际数据库的连接方式(包括url,user,password)暴露给客户端
  • 记录每个执行的sql内容,包括sql及其执行参数
  • 尽可能少的降低代码修改**
  • 性能上不能与直接使用jdbc有很大差距

按此需求,需要实现以下几点:

  • sql是一定要放在server端的
  • 需要将sql记录到日志中
  • 客户端仍然需要使用jdbc的方式,才能保证尽可能少的修改
  • 性能要高

这不就是将jdbc也使用客户端-服务器的方式吗?而且要求高性能?

JDBC接口的实现

代码尽可能少的改动,这就要求必须在客户端实现JDBC的接口,然后在客户端的jdbc实现中调用服务器上的服务完成业务的处理。
这样在客户端仅需替换jdbc驱动的jar包,然后代码中替换相应的驱动代码即可。
这样又回到了面向服务的SOA设计中来了,可以提供给多个客户端使用。

按此思路,就想到了最常用的几种方式:

 1. soap/restful webservice

显然,用webservice的缺点就是性能太低,马上予以排除。

 2. 直接使用socket变成实现

实现复杂,对技术要求高,待定。

 3. java rmi

EJB中使用的通信技术,效率不错,可以考虑。

在开源的时代,开源框架是加快项目进度的利器,所以我也是首先找找开源框架。
别说,还真有,就是RmiJdbc,那就是你啦。

大体看了一下源码,已经是非常完善可以作为产品使用了,感谢作者大神的工作。
既然如此,只需要把写日志功能加上就好了,马上开始修改吧

第一步,记录SQL

这个算是比较简单的了。
1.在RJStatementServer中声明一个List,用来记录sql
为什么要用List?主要是因为会有batch执行的情况。
2.针对Statement,在RJStatementServer的executeQuery,execute,addBatch等方法中,把需要执行的sql保存到List
3.针对PreparedStatement,在RJConnectionServer中,preparedStatement方法中把sql保存到List

第二步,记录日志

增加一个记录日志的类RJLog

public class RJLog {
   

    public static void saveLog(List<String> sqlList) {
        String sql = Arrays.toString(sqlList.toArray());
        String execTime = DateTime.now().toString(DateTimeFormat
                .forPattern("yyyy-MM-dd HH:mm:ss"));//此处使用joda-time2.2.jar
        //以下是记录日志的方法,详见后面
        ......
    }
}

日志的设计与实现

目前的要求是将日志存入数据库中。
由于访问量没那么大,因此产生的日志不会很多,大概一天上万条左右。高峰时期估计每秒产生几十条日志。
日志的写入,也分为同步写入、log4j的半异步写入和完全的异步写入三种。

同步写入数据库

没什么好说的,在执行完成sql之后,直接将sql通过jdbc写入日志数据库中,也就是说,产生一个日志记录,就要写入一次。
缺点:效率低,非常低。创建数据库连接是非常耗时的,如果一个业务执行过程中有大量的sql,那就积少成多影响体验了。

log4j的半异步

说到日志,首先想到的就是log4j,可以写入文件,也可以写入数据库,并且还能异步写入!
由于一开始要求能够支持jdk1.5,因此只能使用log4j-1.x版本,此处用的是1.2.17版。后来虽然改为jdk1.6,但是也没有使用log4j2.x

log4j.properties配置

使用log4j将日志写入数据库比较简单,网上有很多配置实例,唯一需要注意的地方是,log4j也是可以异步记录日志的,通过配置参数,设置累积多少条记录一次。

举个log4j配置的栗子:
log4j.appender.db=org.apache.log4j.jdbc.JDBCAppender #使用JDBCAppender ,这样才能写入库
log4j.appender.db.BufferSize=10 #此数据值代表每次累积到10条sql就写入数据
log4j.appender.db.driver=oracle.jdbc.driver.OracleDriver #jdbc驱动
log4j.appender.db.URL=jdbc:oracle:thin:@10.xx.xx.xx:1521:orcl #数据库连接,此处是oracle
log4j.appender.db.user=xxxx #数据库user
log4j.appender.db.password=xxxx #数据库password
log4j.appender.db.sql=insert into LOG_INFO (sql,createTime) values (‘%X{sql}’,’%X{exectime}’) #写日志的sql
log4j.appender.db.layout=org.apache.log4j.PatternLayout

改造日志类RJLog

如下,就能把日志信息记录下来了

public class RJLog {
   
    static Logger logger = LoggerFactory.getLogger(RJLog.class);
    public static void saveLog(List<String> sqlL
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值