项目重构之数据源配置与优化:log4j 配置数据库连接池Druid,并实现日志存储到数据库

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介:

一、 前言

  泥瓦匠又和大家见面了,最近两天我在Code Review , 顺便代码小小的Refactoring(重构)下。先了解这个项目吧,这次解决的是数据源配置优化。因为这web项目中配置数据源的地方很多。例如 JDBC要配置数据源,Mybatis要配置数据源,Quartz定时任务要配置数据源,还有Log4j存记录到数据库也要配置…

  如题目,兴许大家的疑惑看了前面的说明会明白。这次给大家带来的 数据源配置与优化:log4j 配置数据库连接池Druid。

  提纲:

  • 二、准备知识
  • 三、正文 开始动手吧
  •      、配置文件
  •      、建数据表
  •      、核心代码讲解
  • 四、结论及下载

二、准备知识

  泥瓦匠也是怕自己说不清楚,又不想把Log4j 和 Durid介绍个遍。那样会太麻烦。这次主要是项目实战。所以泥瓦匠也不罗嗦知识准备这块也就是点到为止。

  Log4j 简介
  在应用程序中添加日志记录总的来说基于三个目的
    监视代码中变量的变化情况,周期性的记录到文件中供其他应用进行统计分析工作;
    跟踪代码运行时轨迹,作为日后审计的依据;
    担当集成开发环境中的调试器的作用,向文件或控制台打印代码的调试信息。
  它支持将日志信息输入到数据库,这次我们一Mysql为例说明。我们需要Log4j来将调试信息、操作信息等记录下来,以便后面的审计,这些日志信息包括用户ID、用户姓名、操作类、路径、方法、操作时间、日志信息。

  Druid 简介

  Druid是Java语言中最好的数据库连接池。Druid能够提供强大的监控和扩展功能。不多多介绍了,阿里牛人作品必须精品。详细介绍在:https://github.com/alibaba/druid/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98

 

  泥瓦匠的任务很简单,目的是为了数据源配置优化,实现数据源配置的唯一性。泥瓦匠也画了草图,曾经被人说成画图画出鬼画符的我告诉大家:没事,越做越好。如图,设计简单草图就是这样的。

image

结论:一个项目的配置文件要保持唯一性,就是数据源配置的唯一性。

 

三、正文 开始动手吧

  开始弄吧,为了写这个东西。我就也搞了个demo项目。泥瓦匠很辛苦的,哈哈送钱的上面支付宝哦。哈哈,泡了杯水,准备说这个项目了。下面,泥瓦匠先给出这个项目的结构图,这样我待会讲起来不怎么累。逻辑性比较强吧。如图:

image

  上面很清楚的写着我需要完成的功能模块。最后那个test,是一个测试的servlet类。大家一看就明白。我先从配置文件说起吧。

配置文件

  dbConfig.properties 记录的是最基础的db配置:url name psd 等,代码如下:

1
2
3
4
5
6
7
8
database.vendor = mysql
driverClassName= com.mysql.jdbc.Driver
db_user = root
db_password = 123456
showsql= false
devMode = true
validationQuery=SELECT 1

  log4j.properties则是日志的配置,但日志的配置中有一点注意的是如下:

1
2
3
4
5
6
7
8
9
10
log4j.rootLogger=debug,appender1
log4j.appender.appender1=org.apache.log4j.ConsoleAppender
log4j.appender.appender1.layout=org.apache.log4j.TTCCLayout
log4j.logger.test=INFO, db
 
# log db setting
log4j.appender.db=org.nsg.dbsetting.MyJDBCAppender
log4j.appender.db.BufferSize=1
log4j.appender.db.sql=insert into operate_log(handclass,method,createtime,loglevel,logmsg) values ('%C','%M','%d{yyyy-MM-dd HH\:mm\:ss}','%p','%m')
log4j.appender.db.layout=org.apache.log4j.PatternLayout

  在这里,我们要注意两点:

一、设置我们包的下的logger权限,并给予存数据库的权限。

image

二、db的实现的应用要为你写的引用类。

1
2
# log db setting
log4j.appender.db=org.nsg.dbsetting.MyJDBCAppender

建数据表

然后我们要根据上面配置文件中写的数据库和表格我们要对应的建一个名为test的数据库和一张名为operate_log的表。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/*
Navicat MySQL Data Transfer
 
Source Server         : Mysql
Source Server Version : 50617
Source Host           : localhost:3307
Source Database       : test
 
Target Server Type    : MYSQL
Target Server Version : 50617
File Encoding         : 65001
 
Date: 2014-12-08 18:46:21
*/
 
SET FOREIGN_KEY_CHECKS=0;
 
-- ----------------------------
-- Table structure for operate_log
-- ----------------------------
DROP TABLE IF EXISTS `operate_log`;
CREATE TABLE `operate_log` (
   `log_id` int(11) NOT NULL AUTO_INCREMENT,
   `handclass` varchar(100) DEFAULT NULL,
   `method` varchar(100) DEFAULT NULL,
   `createtime` varchar(100) DEFAULT NULL,
   `loglevel` varchar(20) DEFAULT NULL,
   `logmsg` text,
   PRIMARY KEY (`log_id`)
) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=utf8;

这样我们就可以开始写代码了,泥瓦匠是一个很细节的人。这次博客,我主要是讲下代码中的核心点。因为后面我会把项目提供给你们下载。所以,这里点到为止。

泥瓦匠说:点到为止,所谓师父领进门,修行在个人啊。

核心代码讲解:

  MyJDBCAppender.java 用于Log4j的数据库Session管理[连接池用Druid]。这个肯定是我们得核心思想。这里我就继承了log4j提供的 org.apache.log4j.jdbc.JDBCAppender;然后只要简单的重写了closeConnection和 getConnection方法。如果获取Druid数据库源对象异常的话,我还写了个 取消初始化 的方法uninitialize。代码这边也贴出下,方便大家观看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package org.nsg.dbsetting;
 
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
 
import org.apache.log4j.jdbc.JDBCAppender;
import org.apache.log4j.spi.ErrorCode;
import org.nsg.constant.PropertiesConst;
import org.nsg.exception.JdbcException;
import org.nsg.util.MyProperties;
import org.nsg.util.PropertiesUtil;
 
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
 
/**
  * @Description  MyJDBCAppender.java
  * 用于Log4j的数据库Session管理[连接池用Druid]
  * @author 泥沙砖瓦浆木匠
  * @date 2014年12月7日下午1:50:56
  * @version 1.0
  */
public class MyJDBCAppender extends JDBCAppender
{
     /* Druid数据源 */
     private DruidDataSource dataSource;
     
     public MyJDBCAppender()
     {
         super();
     }
     
     @Override
     protected void closeConnection(Connection con)
     {
         try
         {
             /* 如果数据库连接对象不为空和没有被关闭的话,关闭数据库连接 */
             if ( con != null && !con.isClosed())
                 con.close();
             
         }
         catch (SQLException e)
         {
             errorHandler.error("Error closing MyJDBCAppender.closeConnection() 's connection",e,ErrorCode.GENERIC_FAILURE);
         }
     }
 
     @Override
     protected Connection getConnection() throws SQLException
     {
         /* 获取数据库配置property */
         MyProperties properties = PropertiesUtil.loadPropertyFile(PropertiesConst.DB_CONFIG);
         String className = String.valueOf(properties.getProperty("driverClassName",""));
         String connUrl = String.valueOf(properties.getProperty("db_url",""));
         String uname = String.valueOf(properties.getProperty("db_user",""));
         String psw = String.valueOf(properties.getProperty("db_password",""));
 
         System.out.println(className);
         System.out.println(connUrl);
         System.out.println(uname);
         System.out.println(psw);
         
         Properties result = new Properties();
         result.put("driverClassName",className);
         result.put("url",connUrl);
         result.put("username",uname);
         result.put("password",psw);
         
         /* 其他配置 自然你也可以自己写property 然后获取set */
         result.put("maxActive","30");
         result.put("minIdle","3");
 
         try
         {
             dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(result);
         }
         catch (Exception e)
         {
             /* Druid数据库源对象产生失败后,取消初始化 */
             try {uninitialize();} catch(Exception e2) {}
             throw new JdbcException(e);
         }
         
         return dataSource.getConnection();
     }
 
     /* 取消初始化 */
     public void uninitialize()
     {
         try
         {
             if (dataSource != null)
                 dataSource.close();
         }
         catch (Exception e)
         {
             throw new JdbcException(String.format("MyJDBCAppender uninitialize fail (%s)",e));
         }
         finally
         {
             super.close();
         }
     }
     
}

  值得注意的一点是,泥瓦匠为了方便,所以在其中的地方没有获取druid连接池的配置。而是直接写了下面:

1
2
3
/* 其他配置 自然你也可以自己写property 然后获取set */
         result.put("maxActive","30");
         result.put("minIdle","3");

  其实这样写是不好了,我们可以写一个druid.properties然后将连接池的配置放入其中。获取set,for循环set即可。这边我就不实现了。很简单哦,泥瓦匠相信你们。

 

    最后我演示下,示例代码:放到tomcat7上,然后运行访问

    image

    看到控制台刷出来两条信息,因为我门设置的是log4j.logger.test=INFO, db。

    然后我们去查看数据库,这边我用Navicat:

    image

     

    四、结论及下载

    结论:重构很有意思,慢慢来,一点一点来,就行了。细节成就未来。

    相关实践学习
    日志服务之使用Nginx模式采集日志
    本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
    相关文章
    |
    1月前
    |
    安全 Linux 网络安全
    YashanDB数据库服务端SSL连接配置
    YashanDB支持通过SSL连接确保数据传输安全,需在服务端生成根证书、服务器证书及DH文件,并将根证书提供给客户端以完成身份验证。服务端配置包括使用OpenSSL工具生成证书、设置SSL参数并重启数据库;客户端则需下载根证书并正确配置环境变量与`yasc_env.ini`文件。注意:启用SSL后,所有客户端必须持有根证书才能连接,且SSL与密码认证独立运行。
    |
    6天前
    |
    监控 容灾 算法
    阿里云 SLS 多云日志接入最佳实践:链路、成本与高可用性优化
    本文探讨了如何高效、经济且可靠地将海外应用与基础设施日志统一采集至阿里云日志服务(SLS),解决全球化业务扩展中的关键挑战。重点介绍了高性能日志采集Agent(iLogtail/LoongCollector)在海外场景的应用,推荐使用LoongCollector以获得更优的稳定性和网络容错能力。同时分析了多种网络接入方案,包括公网直连、全球加速优化、阿里云内网及专线/CEN/VPN接入等,并提供了成本优化策略和多目标发送配置指导,帮助企业构建稳定、低成本、高可用的全球日志系统。
    |
    1月前
    |
    Java 关系型数据库 MySQL
    JDK、Tomcat、MariaDB数据库和Profile多环境的配置与使用
    以上就是JDK、Tomcat、MariaDB数据库和Profile多环境的配置与使用的基本步骤。这些步骤可能会因为你的具体需求和环境而有所不同,但是基本的思路是一样的。希望这些信息能够帮助你更好地理解和使用这些工具。
    66 17
    |
    1月前
    |
    监控 安全 BI
    优化 Apache 日志记录的 5 个最佳实践
    Apache 日志记录对于维护系统运行状况和网络安全至关重要,其核心包括访问日志与错误日志的管理。通过制定合理的日志策略,如选择合适的日志格式、利用条件日志减少冗余、优化日志级别、使用取证模块提升安全性及实施日志轮换,可有效提高日志可用性并降低系统负担。此外,借助 Eventlog Analyzer 等专业工具,能够实现日志的高效收集、可视化分析与威胁检测,从而精准定位安全隐患、评估服务器性能,并满足合规需求,为强化网络安全提供有力支持。
    优化 Apache 日志记录的 5 个最佳实践
    |
    1月前
    |
    Oracle 关系型数据库 Linux
    YashanDB异构数据库链接配置
    本指南介绍在YashanDB中配置异构数据库链接(DBLINK)的方法,特别是连接至Oracle数据库的前置要求与步骤。需确保YashanDB服务端安装plugin插件包、Oracle Instant Client及libaio库,否则可能导致错误或进程崩溃。文档还提供了Oracle Instant Client和libaio库的具体安装指导,帮助管理员顺利完成配置。
    |
    18天前
    |
    负载均衡 算法 关系型数据库
    大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
    本文聚焦 MySQL 集群架构中的负载均衡算法,阐述其重要性。详细介绍轮询、加权轮询、最少连接、加权最少连接、随机、源地址哈希等常用算法,分析各自优缺点及适用场景。并提供 Java 语言代码实现示例,助力直观理解。文章结构清晰,语言通俗易懂,对理解和应用负载均衡算法具有实用价值和参考价值。
    大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
    |
    2月前
    |
    关系型数据库 MySQL Java
    【YashanDB知识库】原生mysql驱动配置连接崖山数据库
    【YashanDB知识库】原生mysql驱动配置连接崖山数据库
    【YashanDB知识库】原生mysql驱动配置连接崖山数据库
    |
    18天前
    |
    存储 关系型数据库 MySQL
    大数据新视界 --面向数据分析师的大数据大厂之 MySQL 基础秘籍:轻松创建数据库与表,踏入大数据殿堂
    本文详细介绍了在 MySQL 中创建数据库和表的方法。包括安装 MySQL、用命令行和图形化工具创建数据库、选择数据库、创建表(含数据类型介绍与选择建议、案例分析、最佳实践与注意事项)以及查看数据库和表的内容。文章专业、严谨且具可操作性,对数据管理有实际帮助。
    大数据新视界 --面向数据分析师的大数据大厂之 MySQL 基础秘籍:轻松创建数据库与表,踏入大数据殿堂
    |
    8天前
    |
    SQL 关系型数据库 MySQL
    MySQL下载安装全攻略!小白也能轻松上手,从此数据库不再难搞!
    这是一份详细的MySQL安装与配置教程,适合初学者快速上手。内容涵盖从下载到安装的每一步操作,包括选择版本、设置路径、配置端口及密码等。同时提供基础操作指南,如数据库管理、数据表增删改查、用户权限设置等。还介绍了备份恢复、图形化工具使用和性能优化技巧,帮助用户全面掌握MySQL的使用方法。附带常见问题解决方法,保姆级教学让你无忧入门!
    MySQL下载安装全攻略!小白也能轻松上手,从此数据库不再难搞!
    |
    2月前
    |
    关系型数据库 MySQL 数据库连接
    docker拉取MySQL后数据库连接失败解决方案
    通过以上方法,可以解决Docker中拉取MySQL镜像后数据库连接失败的常见问题。关键步骤包括确保容器正确启动、配置正确的环境变量、合理设置网络和权限,以及检查主机防火墙设置等。通过逐步排查,可以快速定位并解决连接问题,确保MySQL服务的正常使用。
    459 82

    热门文章

    最新文章