openfire消息服务器引入druid数据库连接池

由于项目需要,需要在openfire消息服务器中引入druid数据库连接池。刚开始做的时候,一头雾水,只在网络上检索到jndi的改造方式,以及纯java语言引入druid数据库连接池的方式。在和openfire结合的时候,不知道该如何下手。

首先需要了解的是,openfire内部提供了三个实现ConnectionProvider的Provider,分别是JNDIDataSourceProvider、EmbeddedConnectionProvider、DefaultConnectionProvider。这里我并没有采用源码里提供的三个provider,另写了一个自定义的DruidDatasourceProvider。

代码示例如下:

package org.jivesoftware.database;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log;
import org.slf4j.Logger;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Properties;

public class DruidDataSourceProvider implements ConnectionProvider{

    private Properties settings;
    private String serverURL;
    private DruidDataSource dataSource;
    private String driver;
    private String username;
    private String password;
    private int minConnections = 3;
    private int maxConnections = 10;
    private String testSQL = "";
    private Boolean testBeforeUse = true;
    private Boolean testAfterUse = true;
    private double connectionTimeout = 0.5;

    @Override
    public boolean isPooled() {
        return true;
    }

    @Override
    public Connection getConnection() throws SQLException {
        try {
            Class.forName("com.mysql.jdbc.Driver");
            return dataSource.getConnection();
        }
        catch (ClassNotFoundException e) {
            throw new SQLException("DruidConnectionProvider: Unable to find driver: "+e);
        }
    }

    @Override
    public void start() {
        loadProperties();
        dataSource = new DruidDataSource();
        //设置连接参数
        dataSource.setUrl(settings.getProperty(Config.DRUID_URL));
        dataSource.setDriverClassName(settings.getProperty(Config.DRUID_DRIVER));
        dataSource.setUsername(settings.getProperty(Config.DRUID_USERNAME));
        dataSource.setPassword(settings.getProperty(Config.DRUID_PASSWORD));
        //配置初始化大小、最小、最大
        dataSource.setInitialSize(1);
        dataSource.setMinIdle(1);
        dataSource.setMaxActive(20);
        //连接泄漏监测
        dataSource.setRemoveAbandoned(true);
        dataSource.setRemoveAbandonedTimeout(30);
        //配置获取连接等待超时的时间
        dataSource.setMaxWait(20000);
        //配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
        dataSource.setTimeBetweenEvictionRunsMillis(20000);
        //防止过期
        dataSource.setValidationQuery("SELECT 'x'");
        dataSource.setTestWhileIdle(true);
        dataSource.setTestOnBorrow(false);
        dataSource.setTestOnReturn(false);
        dataSource.setPoolPreparedStatements(false);
        try {
            dataSource.setFilters("stat");
            dataSource.init();
        }catch (Exception e){
            System.out.println("wrong!");
        }
    }

    private void loadProperties() {
        settings = new Properties();
        settings.setProperty(Config.DRUID_URL, JiveGlobals.getXMLProperty(Config.DRUID_URL));
        settings.setProperty(Config.DRUID_DRIVER, JiveGlobals.getXMLProperty(Config.DRUID_DRIVER));
        settings.setProperty(Config.DRUID_USERNAME, JiveGlobals.getXMLProperty(Config.DRUID_USERNAME));
        settings.setProperty(Config.DRUID_PASSWORD, JiveGlobals.getXMLProperty(Config.DRUID_PASSWORD));
    }

    @Override
    public void restart() {
        // Kill off pool.
        destroy();
        // Start a new pool.
        start();
    }

    @Override
    public void destroy() {
        dataSource.close();
    }

    /**
     * Returns the JDBC driver classname used to make database connections.
     * For example: com.mysql.jdbc.Driver
     *
     * @return the JDBC driver classname.
     */
    public String getDriver() {
        return driver;
    }

    /**
     * Sets the JDBC driver classname used to make database connections.
     * For example: com.mysql.jdbc.Driver
     *
     * @param driver the fully qualified JDBC driver name.
     */
    public void setDriver(String driver) {
        this.driver = driver;
        saveProperties();
    }

    /**
     * Returns the JDBC connection URL used to make database connections.
     *
     * @return the JDBC connection URL.
     */
    public String getServerURL() {
        return serverURL;
    }

    /**
     * Sets the JDBC connection URL used to make database connections.
     *
     * @param serverURL the JDBC connection URL.
     */
    public void setServerURL(String serverURL) {
        this.serverURL = serverURL;
        saveProperties();
    }

    /**
     * Returns the username used to connect to the database. In some cases,
     * a username is not needed so this method will return null.
     *
     * @return the username used to connect to the datbase.
     */
    public String getUsername() {
        return username;
    }

    /**
     * Sets the username used to connect to the database. In some cases, a
     * username is not needed so null should be passed in.
     *
     * @param username the username used to connect to the database.
     */
    public void setUsername(String username) {
        this.username = username;
        saveProperties();
    }

    /**
     * Returns the password used to connect to the database. In some cases,
     * a password is not needed so this method will return null.
     *
     * @return the password used to connect to the database.
     */
    public String getPassword() {
        return password;
    }

    /**
     * Sets the password used to connect to the database. In some cases, a
     * password is not needed so null should be passed in.
     *
     * @param password the password used to connect to the database.
     */
    public void setPassword(String password) {
        this.password = password;
        saveProperties();
    }

    /**
     * Returns the minimum number of connections that the pool will use. This
     * should probably be at least three.
     *
     * @return the minimum number of connections in the pool.
     */
    public int getMinConnections() {
        return minConnections;
    }

    /**
     * Sets the minimum number of connections that the pool will use. This
     * should probably be at least three.
     *
     * @param minConnections the minimum number of connections in the pool.
     */
    public void setMinConnections(int minConnections) {
        this.minConnections = minConnections;
        saveProperties();
    }

    /**
     * Returns the maximum number of connections that the pool will use. The
     * actual number of connections in the pool will vary between this value
     * and the minimum based on the current load.
     *
     * @return the max possible number of connections in the pool.
     */
    public int getMaxConnections() {
        return maxConnections;
    }

    /**
     * Sets the maximum number of connections that the pool will use. The
     * actual number of connections in the pool will vary between this value
     * and the minimum based on the current load.
     *
     * @param maxConnections the max possible number of connections in the pool.
     */
    public void setMaxConnections(int maxConnections) {
        this.maxConnections = maxConnections;
        saveProperties();
    }

    /**
     * Returns the amount of time between connection recycles in days. For
     * example, a value of .5 would correspond to recycling the connections
     * in the pool once every half day.
     *
     * @return the amount of time in days between connection recycles.
     */
    public double getConnectionTimeout() {
        return connectionTimeout;
    }

    /**
     * Sets the amount of time between connection recycles in days. For
     * example, a value of .5 would correspond to recycling the connections
     * in the pool once every half day.
     *
     * @param connectionTimeout the amount of time in days between connection
     *                          recycles.
     */
    public void setConnectionTimeout(double connectionTimeout) {
        this.connectionTimeout = connectionTimeout;
        saveProperties();
    }

    /**
     * Returns the SQL statement used to test if a connection is valid.
     *
     * @return the SQL statement that will be run to test a connection.
     */
    public String getTestSQL() {
        return testSQL;
    }

    /**
     * Sets the SQL statement used to test if a connection is valid.  House keeping
     * and before/after connection tests make use of this.  This
     * should be something that causes the minimal amount of work by the database
     * server and is as quick as possible.
     *
     * @param testSQL the SQL statement that will be run to test a connection.
     */
    public void setTestSQL(String testSQL) {
        this.testSQL = testSQL;
    }

    /**
     * Returns whether returned connections will be tested before being handed over
     * to be used.
     *
     * @return True if connections are tested before use.
     */
    public Boolean getTestBeforeUse() {
        return testBeforeUse;
    }

    /**
     * Sets whether connections will be tested before being handed over to be used.
     *
     * @param testBeforeUse True or false if connections are to be tested before use.
     */
    public void setTestBeforeUse(Boolean testBeforeUse) {
        this.testBeforeUse = testBeforeUse;
    }

    /**
     * Returns whether returned connections will be tested after being returned to
     * the pool.
     *
     * @return True if connections are tested after use.
     */
    public Boolean getTestAfterUse() {
        return testAfterUse;
    }

    /**
     * Sets whether connections will be tested after being returned to the pool.
     *
     * @param testAfterUse True or false if connections are to be tested after use.
     */
    public void setTestAfterUse(Boolean testAfterUse) {
        this.testAfterUse = testAfterUse;
    }

    /**
     * Save properties as Jive properties.
     */
    private void saveProperties() {

        JiveGlobals.setXMLProperty("database.druidProvider.driver", driver);
        JiveGlobals.setXMLProperty("database.druidProvider.serverURL", serverURL);
        JiveGlobals.setXMLProperty("database.druidProvider.username", username);
        JiveGlobals.setXMLProperty("database.druidProvider.password", password);
        JiveGlobals.setXMLProperty("database.druidProvider.testSQL", testSQL);
        JiveGlobals.setXMLProperty("database.druidProvider.testBeforeUse", testBeforeUse.toString());
        JiveGlobals.setXMLProperty("database.druidProvider.testAfterUse", testAfterUse.toString());

        JiveGlobals.setXMLProperty("database.druidProvider.minConnections",
                Integer.toString(minConnections));
        JiveGlobals.setXMLProperty("database.druidProvider.maxConnections",
                Integer.toString(maxConnections));
        JiveGlobals.setXMLProperty("database.druidProvider.connectionTimeout",
                Double.toString(connectionTimeout));
    }
}

 然后需要在*/src/web/setup下对该provider进行配置,这里可以参考DefaultConnectionProvider的配置方式。

没有什么问题之后,对openfire源码进行编译,生成的openfire.jar替换原先服务器中lib目录下的openfire.jar依赖包。

然后在openfire的配置文件openfire.xml中对druid数据库连接池进行配置。参考如下:

<connectionProvider>
    <className>org.jivesoftware.database.DruidDataSourceProvider</className>
  </connectionProvider>
  <database>
    <druidProvider>
      <driver>com.mysql.jdbc.Driver</driver>
      <serverURL>jdbc:mysql://localhost:port/openfire?useUnicode=true&amp;characterEncoding=UTF-8&amp;characterSetResults=UTF-8</serverURL>
      <username>*****</username>
      <password>*****</password>
      <testSQL>select 1</testSQL>
      <testBeforeUse>false</testBeforeUse>
      <testAfterUse>false</testAfterUse>
      <minConnections>5</minConnections>
      <maxConnections>200</maxConnections>
      <connectionTimeout>1.0</connectionTimeout>
    </druidProvider>
  </database>

另外还需要在openfire的依赖库中添加druid依赖包。

下载地址:http://central.maven.org/maven2/com/alibaba/druid/

到这里引入druid数据库链接池已经基本完成。

下面提供监控页面的修改地址。

在openfire/plugins/admin/webapp/WEB-INF/web.xml 中添加监控平台的监控.示例如下:

 <servlet>
        <servlet-name>DruidStatView</servlet-name>
        <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
        <init-param>
            <!-- 允许清空统计数据 -->
            <param-name>resetEnable</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <!-- 用户名 -->
            <param-name>loginUsername</param-name>
            <param-value>******</param-value>
        </init-param>
        <init-param>
            <!-- 密码 -->
            <param-name>loginPassword</param-name>
            <param-value>******</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>DruidStatView</servlet-name>
        <url-pattern>/druid/*</url-pattern>
    </servlet-mapping>

    <filter>
        <filter-name>DruidWebStatFilter</filter-name>
        <filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class>
        <init-param>
            <param-name>exclusions</param-name>
            <param-value>*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>DruidWebStatFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

这里配置基本完毕,重启openfire服务器。

http://localhost:9090/druid/index.html中就可以看到监控平台了。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值