metaclass: (Default)
[personal profile] metaclass
Усиленно проверяю различные варианты пула JDBC коннектов с сервисом на кложуре.
c3p0 и серверная jvm - очень быстро растет использование памяти. Решил разобраться, поставил по совету [livejournal.com profile] artureg jprofiler, подключился - внутри творится адъ.
Основное место, где выделялась память - оказалось clojure.pprint, который я использовал для отладочных логов - он массово занимался рефлекшеном, и в памяти были 100500 копий java.lang.reflect.Method. Но вроде бы их gc грохал. Ну я ее использование временно убрал, чтобы оно не заслоняло происходящее.

Потом какой-то странный эффект, что по профайлеру используемая jvm память не растет, т.е. все ок, но система показывает постоянный рост. Отключил профайлер - стало нормально, т.е. похоже, что в самом профайлере какие-то спецэффекты.

Артурег убедил меня использовать вместо с3p0 commons-dbcp, с утра сегодня откопал пример использования, завел его с firebird на жабе, затем переписал на кложурь - все работает, причем с серверной jvm, вроде бы тенденция роста есть, но очень слабая, нужно долго тестировать.

Придется видимо, проверять все комбинации: "приложение vs windows-service" "server vs client jvm" "с3p0 vs commons-dbcp vs обычный коннект без пула" и "(str ) vs clojure.pprint" и "c профайлером vs без профайлера".
Т.е. если по хорошему, 48 комбинаций, по сутки-двое тестирования на каждую, т.к. хочется как бы узнать реальную картину происходящего. Хотя для использования это все нафиг не нужно, там памяти минимум на месяц хватит даже если утечка есть (что не факт), кроме того, можно рестарт сервиса делать раз в сутки ночью (что запрещает перфекционизм).


Для засирания мозгов поисковикам еще больше, помещу тут реализацию:
http://www.developerfeed.com/jdbc/snippet/apache-dbcp-pooling-datasource-example

  (:import (org.apache.commons.pool ObjectPool))
  (:import (org.apache.commons.pool.impl GenericObjectPool))

  (:import (org.apache.commons.dbcp ConnectionFactory PoolingDataSource PoolableConnectionFactory DriverManagerConnectionFactory))


(def
 db0
 (let [user (get mainConfig "firebird.user" "")
       rolename (get mainConfig "firebird.rolename" "")
       pass (get mainConfig "firebird.password" "") 
       subname (get mainConfig "firebird.subname" "//localhost:3090/operden")
       encoding  (get mainConfig "firebird.encoding" "WIN1251")]   
   {:classname   "org.firebirdsql.jdbc.FBDriver"
    :subprotocol "firebirdsql"
    :user        user
    :roleName    rolename 
    :password    pass
    :subname     subname
    :encoding    encoding}))

;;dbcp pool

(defn dbcpProps
      [username password role]
    (doto (Properties.)
          (.put "userName" username) 
          (.put "password" password)  
          (.put "roleName" role))
)



(defn dbcpDataSource
     [spec]
     (let [driverClass (Class/forName "org.firebirdsql.jdbc.FBDriver")
           connectionPool (GenericObjectPool. nil) 
           connectionFactory (DriverManagerConnectionFactory. 
                                   (str "jdbc:" (:subprotocol spec) ":" (:subname spec))
                                   (dbcpProps (:user spec) (:password spec) (:roleName spec))
                             )
           poolableConnectionFactory (PoolableConnectionFactory. connectionFactory connectionPool nil nil false true)
          ]       
     {:datasource (PoolingDataSource. connectionPool)})
)


(def db4 (dbcpDataSource db0))





PS: вариант с BasicDataSource, поддерживающем проверку валидности коннекта перед отдачей его из пула:


(defn dbcpBasicDataSource
     [spec]
     (let [dataSource (doto (BasicDataSource. )
                            (.setDriverClassName "org.firebirdsql.jdbc.FBDriver")
                            (.setUrl (str "jdbc:" (:subprotocol spec) ":" (:subname spec)))
                            (.setUsername (:user spec))
                            (.setPassword (:password spec))
                            (.addConnectionProperty "roleName" (:roleName spec))
                            (.setValidationQuery "select * from rdb$database")
                      )
          ]       
     {:datasource dataSource})
)


(def db-dbcp-basic (dbcpBasicDataSource db0))



Трасца, примеры для жабьих либ приходится по SO и форумам собирать.

Date: 2012-03-07 08:25 am (UTC)
From: [identity profile] artureg.livejournal.com
красота, а стрёмный ситрипио выпили дабы не ловить не нужные факапы

Date: 2012-03-07 09:04 am (UTC)
From: [identity profile] metaclass.livejournal.com
Таки с dbcp тот же эффект - медленный рост потребляемой памяти.
Похоже, без обстоятельного тестирования всех комбинаций толку не будет.

Date: 2012-03-07 09:40 am (UTC)
From: [identity profile] guamoka.livejournal.com
Автокад какой-то.

Date: 2012-03-07 10:51 am (UTC)
From: [identity profile] metaclass.livejournal.com
Как раз лисповая часть тут элементарная, а вот 100500 вариаций жабьих пулов печалят.

Date: 2012-03-07 11:07 am (UTC)
From: [identity profile] guamoka.livejournal.com
Ну, лисп ведь на вопрос пулов ответа не даёт. Видно, чтобы не в ущерб элементарности:-)

Date: 2012-03-07 11:14 am (UTC)
From: [identity profile] metaclass.livejournal.com
Ну я за то же время, что разбираюсь с готовыми пулами, написал бы на кложури свой - там все для этого есть. Но из гуманизма я этого не делаю, вместо этого копаюсь в жабе, как принято.

Date: 2012-03-07 10:29 pm (UTC)
From: [identity profile] http://users.livejournal.com/_windwalker_/
все апачевские пулы - полное говно. их использовать - дороже для жизни.

Profile

metaclass: (Default)
metaclass

April 2017

S M T W T F S
      1
2345678
9101112 131415
16171819202122
23242526272829
30      

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Oct. 9th, 2025 09:38 pm
Powered by Dreamwidth Studios