Пул соединений в среде Spark Java

Платформа Java Spark использует встроенный Jetty в качестве веб-сервера. Jetty поддерживает объединение соединений с помощью таких инструментов, как HikariCP, и предоставляет параметры конфигурации. в файлах XML. Однако, согласно этим сообщениям, Spark позволяет настраивать Jetty. Существует множество примеров использования Spark, но они либо не используют базу данных, либо используют DriverManager для подключения к базе данных.

Можно ли настроить пул соединений через источник данных и JNDI в Spark? Если да, то как?


person Jan Bodnar    schedule 23.03.2017    source источник
comment
Вы поняли это? Я столкнулся с той же проблемой.   -  person kittu    schedule 06.04.2017
comment
Нет, нет. Я назначил вознаграждение за вопрос.   -  person Jan Bodnar    schedule 06.04.2017
comment
В github есть ветка об этом запросе функции. Если вы хорошо разбираетесь в java, посмотрите на него.   -  person kittu    schedule 12.04.2017
comment
Я посмотрел на поток (вы упомянули в these posts) и зафиксировал, он обеспечивает гибкость для потоков, используемых встроенным причалом с использованием JettyServerFactory. Речь не идет о решении проблемы пула соединений.   -  person Bilbo Baggins    schedule 13.04.2017
comment
@JanBodnar Я открыл задачу на github: github.com/perwendel/spark/issues/833   -  person kittu    schedule 17.04.2017
comment
ХОРОШО. я следую ему; если они завершат запрос, я опубликую ответ.   -  person Jan Bodnar    schedule 17.04.2017


Ответы (2)


Я настроил пул в Spark Java с помощью HikariCP для MariaDB. Я не использовал Jetty и вместо этого использовал Apache Tomcat. Вот несколько фрагментов кода:

src/main/resources/mysql-connection.properties

dataSourceClassName=com.mysql.jdbc.jdbc2.optional.MysqlDataSource
dataSource.url=<url>
dataSource.user=<user>
dataSource.password=<password>
dataSource.cachePrepStmts=true
dataSource.prepStmtCacheSize=100
dataSource.prepStmtCacheSqlLimit=2048
dataSource.useServerPrepStmts=true
maximumPoolSize=10

com/example/app/DataSourceFactory.java

public final class DataSourceFactory {

    static final Logger LOG = LoggerFactory.getLogger(DataSourceFactory.class);

    private static DataSource mySQLDataSource;

    private DataSourceFactory() {
    }

    //returns javax.sql.DataSource
    public static DataSource getMySQLDataSource() {
        if (mySQLDataSource == null) {
            synchronized (DataSourceFactory.class) {
                if (mySQLDataSource == null) {
                    mySQLDataSource = getDataSource("mysql-connection.properties");
                }
            }
        }
        return mySQLDataSource;
    }

    // method to create the DataSource based on configuration
    private static DataSource getDataSource(String configurationProperties) {
        Properties conf = new Properties();
        try {
            conf.load(DataSourceFactory.class.getClassLoader().getResourceAsStream(configurationProperties));
        } catch (IOException e) {
            LOG.error("Can't locate database configuration", e);
        }
        HikariConfig config = new HikariConfig(conf);
        HikariDataSource dataSource = new HikariDataSource(config);
        LOG.info("DataSource[" + configurationProperties + "] created " + dataSource);
        return dataSource;
    }

}

Веб-контент/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee                              
    http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">

    <display-name>My Spark App</display-name>
    <filter>
        <filter-name>SparkFilter</filter-name>
        <filter-class>spark.servlet.SparkFilter</filter-class>
        <init-param>
            <param-name>applicationClass</param-name>
            <param-value>com.example.app.MySparkApp</param-value>
            <!-- MySparkApp implements spark.servlet.SparkApplication -->
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>SparkFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <listener>
        <listener-class>com.example.app.AppServletContextListener</listener-class>
    </listener>
</web-app>

com/example/app/AppServletContextListener.java

public class AppServletContextListener implements ServletContextListener {

    static final Logger LOG = LoggerFactory.getLogger(AppServletContextListener.class);

    @Override
    public void contextInitialized(ServletContextEvent arg0) {
        LOG.info("contextInitialized...");
    }

    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
        LOG.info("contextDestroyed...");
        try {
            if (DataSourceFactory.getMySQLDataSource() != null) {
                DataSourceFactory.getMySQLDataSource().unwrap(HikariDataSource.class).close();
            }

        } catch (SQLException e) {
            LOG.error("Problem closing HikariCP pool", e);
        }

    }

}

И, наконец, вы можете получить объединенный java.sql.Connection, вызвав DataSourceFactory.getMySQLDataSource().getConnection()

person user1357768    schedule 11.04.2017
comment
Привет, спасибо за ваш ответ. Я знаю, что это возможно для Tomcat. Вопрос в том, как это сделать со встроенным Jetty, который по умолчанию используется для Spark. - person Jan Bodnar; 11.04.2017
comment
Это про apache-spark?? - person BrendanM; 13.04.2017
comment
@BrendanM sparkjava.com - person kittu; 17.04.2017

Должно быть возможно, но вы должны:

  1. настроить пул
  2. сохранить статическую ссылку на источник данных
  3. найти, где начать/подключиться к базе данных и, что более важно, найти способ закрыть/освободить пул

Пункт 1) и 2) может быть таким простым, как:

static final HikariDataSource datasource = new HikariDataSource(new HikariConfig());

Не знаю, поддерживает ли Sparkjava события запуска/остановки. Я не могу помочь вам там.

При желании вы можете попробовать http://jooby.org (я автор) с модуль jdbc:

{
  use(new Jdbc());

  get("/db", () -> {
    DataSource ds = require(DataSource.class);
  });
}

Модуль Jdbc предоставляет вам HikariDatasource с разумными параметрами по умолчанию, но в то же время вы можете настроить пул через файл application.conf.

Также есть пара высокоуровневых модулей jdbc, таких как Hibernate, Ebean, jOOQ, Jdbi. , и т.д...

person Edgar Espina    schedule 18.04.2017