Слишком много подключений: Hibernate BoneCP

Предыстория: я использую спящий режим с моим sql для моего уровня модели с помощью Spring для предоставления услуг REST. У меня есть мобильный клиент, который использует остальные службы на бэкэнде. Код в настоящее время развернут на микроэкземпляре AWS.

Проблема: как только количество одновременных пользователей превышает 30-40, я начинаю получать "com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException: слишком много подключений". Я понимаю, что база данных mysql на микросервере настроена на максимум 30-35 подключений, но в случае высокой нагрузки я ожидаю, что вызовы будут ждать, а не выдавать ошибку. Стать немного медленнее допустимо, но это не должно привести к ошибке.

Код: Вот файл hibernate cfg:

com.jolbox.bonecp.provider.BoneCPConnectionProvider
org.hibernate.dialect.MySQLDialect com.mysql.jdbc.Driver

    <property name="bonecp.driverClass">com.mysql.jdbc.Driver</property>
    <property name="bonecp.jdbcUrl">jdbc:mysql://***.rds.amazonaws.com:3306/jooky</property>
    <property name="bonecp.username">**</property>
    <property name="bonecp.password">**</property>
    <property name="bonecp.maxConnectionAgeInSeconds">30</property>
    <property name="bonecp.idleConnectionTestPeriodInMinutes">60</property>
    <property name="bonecp.maxConnectionsPerPartition">25</property>
    <property name="bonecp.minConnectionsPerPartition">10</property>
    <property name="bonecp.partitionCount">1</property>
    <property name="bonecp.acquireIncrement">5</property>
    <property name="bonecp.statementsCacheSize">50</property>

    <property name="acquireRetryDelayInMs">500</property>
    <property name="acquireRetryAttempts">200</property>

    <mapping class="jooky.model.entity.Party" />
    <mapping class="jooky.model.entity.LocationRequest" />
    <mapping class="jooky.model.entity.Location" />
    <mapping class="jooky.model.entity.UserCheckinHistory" />
    <mapping class="jooky.model.entity.Person" /> 
    <mapping class="jooky.model.entity.UserLocSearchHistory"/>
</session-factory>

The code I have to expose REST services is:

@RequestMapping(value = "/getLocations", method = RequestMethod.POST)
public @ResponseBody
String getLocations(@RequestBody String input) {

    Gson gson = new GsonBuilder().create();
    NearbyLocationsRequest request = gson.fromJson(input,
            NearbyLocationsRequest.class);

    SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory(); 
    //SessionFactory sessionFactory = ControllerUtil.getSessionFactory();
    Session session = sessionFactory.openSession();
    session.beginTransaction();
    String ret="Error:UNKNOWN_EXCEPTION: Server error.";
    List results = null;
    try {
        // NearbyLocationQueryInput inputGson = gson.fromJson(input,
        // NearbyLocationQueryInput.class);


        if(request.getPersonId()== null )
        {
            ret="Error:CANNOT_CONNECT_PER_ID_NULL: Person Id cannot be null";
            session.getTransaction().rollback();
            session.close();
            sessionFactory.close();
            return ret;
        }

        List users = session
                .createCriteria(Person.class)
                .add(Restrictions.eq("personId", request.getPersonId()))
                .list();
        Person person = null;
        if (users != null && users.size() > 0) {
                person = (Person) users.get(0);
                if(person.getPoints()==null)
                    person.setPoints(0);
            }
        else
        {
            ret="Error:CANNOT_CONNECT_PER_NOT_FOUND: No person found with id:"+request.getPersonId();
            session.getTransaction().rollback();
            session.close();
            sessionFactory.close();
            return ret;
        }


        double latitude = request.getLatitude();
        double longitude = request.getLongitude();
        // To search by kilometers instead of miles, replace 3959 with 6371
        int distConstant = 6371;
        if ("MILES".equals(request.getDistanceUnit()))
            distConstant = 3959;

        int queryRadius = 100;
        if (request.getQueryRadius() != null)
            queryRadius = request.getQueryRadius();
        int maxResults = 100;
        if (request.getMaxResults() != null)
            maxResults = request.getMaxResults();

        // latitude = input.getLatitude();
        // longitude = input.getLongitude();

        // Closest within radius of 25 Miles
        Query query = session
                .createSQLQuery(
                        " SELECT LOCATION_ID, LOCATION_NAME, LOC_FB_ID, LOC_GOOGLE_ID, LOCATION_EMAIL, FB_PAGE, IMAGE_LOCATION, "
                                + " ADDRESS1, ADDRESS2, ADDRESS3, CITY, STATE, COUNTRY, ZIP, PHONE1, PHONE2,  "
                                + " PLAYLIST_NAME, PLAYER_STATUS, LOCATION_TYPE, CUSINE, LATITUDE, LONGITUDE, OPENING_TIME, CLOSING_TIME, HEARTBEAT_TIME, PLAYLIST_VERSION, "
                                + " LOCATION_MESSAGE, WEBSITE, HIGHLIGHTS , " 
                                + " ( "
                                + distConstant
                                + " * acos( cos( radians(:bind_lat) ) * cos( radians( latitude ) )   * cos( radians( longitude ) - radians(:bind_long) ) + sin( radians(:bind_lat) )   * sin( radians( latitude ) ) ) ) AS DISTANCE "
                                + " FROM location HAVING distance < "
                                + queryRadius
                                + " "
                                + " ORDER BY distance LIMIT " + maxResults)
                .addEntity(Location.class);

        query.setParameter("bind_long", longitude);
        query.setParameter("bind_lat", latitude);
        results = query.list();


        UserLocSearchHistory history = new UserLocSearchHistory();
        history.setId(new UserLocSearchHistoryId(request.getPersonId(), new Date()));
        history.setAppVersion(request.getAppVersion());
        history.setLatitude(new BigDecimal(latitude));
        history.setLongitude(new BigDecimal(longitude));

        session.save(history);

        NearbyLocationsResponse response =  new NearbyLocationsResponse();
        response.setUserPoints(person.getPoints());
        response.setLocations(results);

        session.getTransaction().commit();
        session.flush();
        session.close();
        sessionFactory.close();

        ret=gson.toJson(response);
    } catch (Exception e) {
        session.getTransaction().rollback();
        session.flush();
        session.close();
        sessionFactory.close();
        e.printStackTrace();
    }

    return ret;
}

Стек ошибок: состояние HTTP 500 — ошибка обработки запроса; вложенным исключением является org.hibernate.HibernateException: org.hibernate.HibernateException: java.sql.SQLException: невозможно открыть тестовое соединение с данной базой данных. URL-адрес JDBC = jdbc:mysql://***.rds.amazonaws.com:3306/jooky, имя пользователя = jooky. Завершение пула соединений. Исходное исключение: ------тип отчета об исключении

сообщение Не удалось обработать запрос; вложенным исключением является org.hibernate.HibernateException: org.hibernate.HibernateException: java.sql.SQLException: невозможно открыть тестовое соединение с данной базой данных. URL-адрес JDBC = jdbc:mysql://****.amazonaws.com:3306/jooky, имя пользователя = ****. Завершение пула соединений. Исходное исключение: ------

описание На сервере произошла внутренняя ошибка, из-за которой он не смог выполнить этот запрос.

exception

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.HibernateException: org.hibernate.HibernateException: java.sql.SQLException: Unable to open a test connection to the given database. JDBC url = jdbc:mysql://*****.com:3306/jooky, username = jooky. Terminating connection pool. Original Exception: ------
com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException: Too many connections
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:921)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2985)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:885)
    at com.mysql.jdbc.MysqlIO.secureAuth411(MysqlIO.java:3421)
    at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1247)
    at com.mysql.jdbc.Connection.createNewIO(Connection.java:2775)
    at com.mysql.jdbc.Connection.<init>(Connection.java:1555)
    at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:285)
    at java.sql.DriverManager.getConnection(DriverManager.java:571)
    at java.sql.DriverManager.getConnection(DriverManager.java:215)
    at com.jolbox.bonecp.BoneCP.obtainRawInternalConnection(BoneCP.java:309)
    at com.jolbox.bonecp.BoneCP.<init>(BoneCP.java:346)
    at com.jolbox.bonecp.provider.BoneCPConnectionProvider.createPool(BoneCPConnectionProvider.java:167)
    at com.jolbox.bonecp.provider.BoneCPConnectionProvider.configure(BoneCPConnectionProvider.java:141)
    at com.jolbox.bonecp.provider.BoneCPConnectionProvider.configure(BoneCPConnectionProvider.java:271)
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:89)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:206)


org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:973)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)

Это связано с ограничением подключения mysql. Чтобы удалить такой тип ошибки/исключения, вам нужно увеличить переменную

    <property name="bonecp.driverClass">com.mysql.jdbc.Driver</property>
    <property name="bonecp.jdbcUrl">jdbc:mysql://***.rds.amazonaws.com:3306/jooky</property>
    <property name="bonecp.username">**</property>
    <property name="bonecp.password">**</property>
    <property name="bonecp.maxConnectionAgeInSeconds">30</property>
    <property name="bonecp.idleConnectionTestPeriodInMinutes">60</property>
    <property name="bonecp.maxConnectionsPerPartition">25</property>
    <property name="bonecp.minConnectionsPerPartition">10</property>
    <property name="bonecp.partitionCount">1</property>
    <property name="bonecp.acquireIncrement">5</property>
    <property name="bonecp.statementsCacheSize">50</property>

    <property name="acquireRetryDelayInMs">500</property>
    <property name="acquireRetryAttempts">200</property>

    <mapping class="jooky.model.entity.Party" />
    <mapping class="jooky.model.entity.LocationRequest" />
    <mapping class="jooky.model.entity.Location" />
    <mapping class="jooky.model.entity.UserCheckinHistory" />
    <mapping class="jooky.model.entity.Person" /> 
    <mapping class="jooky.model.entity.UserLocSearchHistory"/>
</session-factory>
в mysql.


person Gaurav Nanda    schedule 01.12.2014    source источник


Ответы (1)


Я не могу этого сделать, максимальное количество подключений, которые я могу иметь, ограничено 30-35

person Altmish-E-Azam    schedule 01.12.2014
comment
У вас есть полный доступ к MySQL для изменения глобальных переменных? - person Gaurav Nanda; 01.12.2014
comment
BoneCP иногда может кратковременно колебаться выше настроенного максимального значения. связи. Мне было бы любопытно, если бы вы столкнулись с этими проблемами с HikariCP. - person Altmish-E-Azam; 01.12.2014
comment
основная причина org.hibernate.HibernateException: org.hibernate.HibernateException: java.sql.SQLException: невозможно открыть тестовое соединение с данной базой данных. URL-адрес JDBC = jdbc:mysql://aa1hw2wctsxa60n.ckmpnrdgeoee.ap-southeast-1.rds.amazonaws.com:3306/jooky, имя пользователя = jooky. Завершение пула соединений. Исходное исключение: ------ com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException: слишком много соединений в com.mysql.jdbc.SQLError.createSQLException(SQLError.java:921) в com.mysql.jdbc.MysqlIO.checkErrorPacket( MysqlIO.java:2985) в com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:885) в com.mysql.jdbc.MysqlIO.secureAuth411(MysqlIO.java:3421) в com.mysql.jdbc.MysqlIO.doHandshake (MysqlIO.java:1247) в com.mysql.jdbc.Connection.createNewIO(Connection.java:2775) в com.mysql.jdbc.Connection.‹init›(Connection.java:1555) в com.mysql.jdbc. NonRegisteringDriver.connect(NonRegisteringDriver.java:285) в java.sql.DriverManager.getConnection(DriverManager.java:571) в java.sql.DriverManager.getConnection(DriverManager.java:215) в com.jolbox.bonecp.BoneCP.obtainRawInternalConnection (BoneCP.java:309) в com.jolbox.bonecp.BoneCP.‹init›(BoneCP.java:346) в com.jolbox.bonecp.provider.BoneCPConnectionProvider.createPool(BoneCPConnecti onProvider.java:167) в com.jolbox.bonecp.provider.BoneCPConnectionProvider.configure(BoneCPConnectionProvider.java:141) в com.jolbox.bonecp.provider.BoneCPConnectionProvider.configure(BoneCPConnectionProvider.java:271) в org.hibernate.boot .registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:89) в org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:206) в org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java :178) в org.hibernate.engine.jdbc.internal.JdbcServicesImpl.buildJdbcConnectionAccess(JdbcServicesImpl.java:260) в org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:94) в org.hibernate. boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:89) в org.hibernate.service.internal.AbstractServiceRegistryImpl.initializ eService(AbstractServiceRegistryImpl.java:206) в org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:178) в org.hibernate.cfg. Configuration.buildTypeRegistrations(Configuration.java:1885) в org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1843) в org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1928) в jooky.controller.JookyController .getLocations(JookyController.java:72) - person brettw; 05.12.2014