Can i use HikariCP on Google App Engine

2020-02-26 13:28发布

问题:

Looking around for a connection pool solution on App Engine, with Cloud SQL, multiple entries show up with the suggestion that HikariCP should work because it allows for an external ThreadFactory configuration. For example;

  • JDBC connection pool compatible with App Engine
  • Connection pool on app engine with Cloud SQL

The configuration would be something like this:

import com.google.appengine.api.ThreadManager;

...
HikariConfig lConfig = new HikariConfig();
config.setThreadFactory(ThreadManager.backgroundThreadFactory());
...

But there are problems;

HikariCP on Google App Engine

And indeed, a quick attempt exposed multiple problems due to App Engine's restricted "sandbox" environment.

So the question remains; did someone successfully implement HikariCP on Google App Engine?

回答1:

Yes i've implemented HikariCP on Google App Engine, but there are some considerations;

Google App Engine uses three types and instance classes;

  • Automatic Scaling
  • Basic Scaling
  • Manual Scaling

Only the types Basic and Manual Scaling allow background threads and are therefore the only candidates for use with HikariCP. I've used Basic Scaling which is no problem with a approximately known user base (for example one company for each deployed instance). This type enables some other nice features like session support and a powerful B8 instance (1024 MB / 4.8 GHz). For most of my applications i prefer one powerful initialized instance above multiple instances.

Property threadFactory is only available via programmatic configuration, so i implemented my own connection provider;

public class MyConnectionProvider implements ConnectionProvider, Configurable, Stoppable
{

...

public void configure(Map props) throws HibernateException
    {
        try
        {
            mHikariConfig = HikariConfigurationUtil.loadConfiguration(props);

            if (SystemProperty.environment.value() == SystemProperty.Environment.Value.Production)
            {
                mHikariConfig.setDriverClassName("com.mysql.jdbc.GoogleDriver");
                mHikariConfig.setJdbcUrl("jdbc:google:mysql://project-xxx:database/xxx");
                mHikariConfig.setThreadFactory(ThreadManager.backgroundThreadFactory());
            }
            else
            {
                mHikariConfig.setDriverClassName("com.mysql.jdbc.Driver");
                mHikariConfig.setJdbcUrl("jdbc:mysql://localhost:3306/xxx");
            }

            mHikariConfig.addDataSourceProperty("databaseName", "xxx");
            mHikariConfig.setUsername("USERNAME");
            mHikariConfig.setPassword("PASSWD");
            mHikariConfig.setRegisterMbeans(false);

            mHikariConfig.setMaximumPoolSize(12);
            mHikariConfig.addDataSourceProperty("cachePrepStmts", "true");
            mHikariConfig.addDataSourceProperty("useServerPrepStmts", "true");
            mHikariConfig.addDataSourceProperty("prepStmtCacheSize", "250");
            mHikariConfig.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");

            mHikariDataSource = new HikariDataSource(mHikariConfig);
        }
        catch (Exception e)
        {
            throw new HibernateException(e);
        }
    }

...

}

The database name is already in the JdbcUrl but i had to specify it again. Another important configuration setting is

mHikariConfig.setRegisterMbeans(false);

this disables the on App Engine's restricted java management extensions.