Почему я получаю ошибку "no listener" при использовании Rails с Oracle?

Я использую Rails 2.3.5 и Oracle 10 в качестве базы данных, использую "oracle_adapter" и ruby-oci8 для подключения к хосту Oracle.

Я получаю это исключение:

Завершено за 463 мс (Просмотр: 18, DB: 166) | 200 OK [http://192.168.30.128/auctions?page=1]
/!\ FAILSAFE /!\ Пн 01 февраля 19:02:11 +0800 2010
  Статус: 500 Внутренняя ошибка сервера
  ORA-12541: TNS: нет слушателя
    env.c:257: в oci8lib.so
    /home/qichunren/.gem/ruby/1.8/gems/ruby-oci8-1.0.7/lib/oci8.rb:229:in `initialize'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-oracle-adapter-1.0.0.9250/lib/active_record/connection_adapters/oracle_adapter.rb:623:in `new'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-oracle-adapter-1.0.0.9250/lib/active_record/connection_adapters/oracle_adapter.rb:623:in `new_connection'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-oracle-adapter-1.0.0.9250/lib/active_record/connection_adapters/oracle_adapter.rb:659:in `initialize'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-oracle-adapter-1.0.0.9250/lib/active_record/connection_adapters/oracle_adapter.rb:35:in `new'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-oracle-adapter-1.0.0.9250/lib/active_record/connection_adapters/oracle_adapter.rb:35:in `oracle_connection'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:223:in `send'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:223:in `new_connection'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:245:in `checkout_new_connection'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:188:in `checkout'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:184:in `loop'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:184:in `checkout'
    /usr/local/ruby187/lib/ruby/1.8/monitor.rb:242:in "синхронизировать"
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:183:in `checkout'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:98:in `connection'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:326:in `retrieve_connection'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/connection_specification.rb:123:in `retrieve_connection'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/connection_specification.rb:115:in `connection'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-2.3.5/lib/active_record/query_cache.rb:9:in `cache'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-2.3.5/lib/active_record/query_cache.rb:28:in `call'
    /home/qichunren/.gem/ruby/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:361:in `call'
    /home/qichunren/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/string_coercion.rb:25:in `call'
    /home/qichunren/.gem/ruby/1.8/gems/rack-1.0.1/lib/rack/head.rb:9:in `call'
    /home/qichunren/.gem/ruby/1.8/gems/rack-1.0.1/lib/rack/methodoverride.rb:24:in `call'
    /home/qichunren/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/params_parser.rb:15:in `call'
    /home/qichunren/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/session/cookie_store.rb:93:in `call'
    /home/qichunren/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/failsafe.rb:26:in `call'
    /home/qichunren/.gem/ruby/1.8/gems/rack-1.0.1/lib/rack/lock.rb:11:in `call'
    /home/qichunren/.gem/ruby/1.8/gems/rack-1.0.1/lib/rack/lock.rb:11:in `synchronize'
    /home/qichunren/.gem/ruby/1.8/gems/rack-1.0.1/lib/rack/lock.rb:11:in `call'
    /home/qichunren/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/dispatcher.rb:114:in `call'
    /home/qichunren/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/reloader.rb:34:in `run'
    /home/qichunren/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/dispatcher.rb:108:in `call'
    /home/qichunren/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/cgi_process.rb:44:in `dispatch_cgi'
    /home/qichunren/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/dispatcher.rb:101:in `dispatch_cgi'
    /home/qichunren/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/dispatcher.rb:27:in `dispatch'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/rails.rb:76:in `process'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/rails.rb:74:in `синхронизировать '
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/rails.rb:74:in `process'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:159:in `process_client'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:158:in `each'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:158:in `process_client'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:285:in `run'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:285:in `initialize'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:285:in `new'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:285:in `run'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:268:in `initialize'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:268:in `new'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:268:in `run'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/configurator.rb:282:in `run'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/configurator.rb:281:in `each'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/configurator.rb:281:in `run'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/mongrel_rails:128:in `run'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/command.rb:212:in `run'
    /home/qichunren/.gem/ruby/1.8/gems/mongrel-1.1.5/bin/mongrel_rails:281
    /home/qichunren/.gem/ruby/1.8/bin/mongrel_rails:19:in `load'
    /home/qichunren/.gem/ruby/1.8/bin/mongrel_rails:19

похоже, что соединение с Oracle часто отключается. Это показывает oracle error:**ORA-12541: TNS:no listener**,

Как это исправить?

oci8.c: 270: в oci8lib.so: ORA-12541: TNS: нет прослушивателя (OCIError) из /opt/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/activerecord-oracle_enhanced-adapter-1.2.4/lib/active_record/connec                                                                         tion_adapters/oracle_enhanced_oci_connection.rb:223: в "новом" из /opt/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/activerecord-oracle_enhanced-adapter-1.2.4 / lib / active_record / connection_adapters / oracle_enhanced_oci_connection.rb: 223: в `new_connection 'из /opt/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/activerecord-oracle_enhanced-adapter-1.2.4/lib/active_record/connec                                                                         tion_adapters/oracle_enhanced_oci_connection.rb:328: в `initialize 'из /opt/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/activerecord-oracle_enhanced-adapter-1.2.4/lib/active_record/connec                                                                         tion_adapters/oracle_enhanced_oci_connection.rb:24: в "новом" из /opt/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/activerecord-oracle_enhanced-adapter-1.2.4/ lib / active_record / connection_adapters / oracle_enhanced_oci_connection.rb: 24: в `initi alize 'из /opt/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/activerecord-oracle_enhanced-adapter-1.2.4/lib/active_record/connec                                                                         tion_adapters/oracle_enhanced_connection.rb:9: в "новом" 'из /opt/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/activerecord-oracle_enhanced-adapter-1.2.4/lib/active_record/connec                                                                         tion_adapters/oracle_enhanced_connection.rb:9: в `create' из /opt/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/activerecord-oracle_enhanced-adapter-1.2.4/lib/active_record/connec                                                                         tion_adapters/oracle_enhanced_adapter.rb:50: в `oracle_enhanced_connection'из /opt/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/abstract/c                                                                         onnection_specification.rb:291: в `send 'из / opt / ruby-enterprise-1.8.7 / lib / ruby ​​/ gems / 1.8 / gems / activerecord-2.0.2 / lib / active_record / connection_adapters / abstract / c onnection_specification.rb: 291: в `connection='из / opt / ruby- предприятия 1.8.7 / Lib / рубин / драгоценные камни / 1,8 / драгоценные камни / ActiveRecord-2.0.2 / Библиотека /active_record/connection_adapters/abstract/c                                                                         onnection_specification.rb:259: в `retrieve_connection 'из /opt/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/abstract/c                                                                         onnection_specification.rb:78: в `connection 'из /opt/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:2438: в `quoted_table_                                                                         name'из /opt/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:1259:in `find_one' из /opt/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:1250:in `find_from_ids                                                                         'из /opt/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:504:in `найти 'из сценария / maintenance / Adjust_settlement.rb:19

4 ответа

Решение

Сначала вы должны использовать адаптер oracle_enhanced, так как оригинальный адаптер oracle больше не поддерживается. А также я рекомендую использовать последнюю версию ruby-oci8 2.0.3. А также проверьте, какую версию клиента Oracle вы используете - я рекомендую Oracle Instant Client 10.2.0.4 или более поздней версии.

Но если вы получаете ORA-12541: TNS: нет ошибки прослушивателя, тогда кажется, что проблема может быть в сетевом подключении к базе данных или в проблеме на стороне сервера Oracle. Но, пожалуйста, попробуйте oracle_enhanced адаптер и последнюю версию ruby-oci8 и скажите, исправит ли это вашу проблему.

Удостовериться:

  • Вы правильно настроили имя соединения в ${ORACLE_HOME}/network/admin/tnsnames.ora .
  • Вы устанавливаете ORACLE_HOME до загрузки драйвера oci8.

Если это не сработает, явно укажите host[:port]/sid в качестве имени базы данных.

Например, если ваш хост - mydbhost.myorg.org, номер порта - 1522, а sid - служащий, вы должны использовать это:

база данных: mydbhost.myorg.org:1522/employeedb

Если ваш порт по умолчанию 1521, вы можете опустить двоеточие и номер порта.

Ответ Кельвина работает для меня. Кроме того, есть другой подход.

Я использовал rails 4.1.x, Gemfile:

gem 'activerecord-oracle_enhanced-adapter', '~> 1.5.0'
gem 'ruby-oci8', '2.2.3'

database.yml:

# not work!
host:  218.5.173.xxx/my_db

# works, solution 1:  
database: 218.5.173.xxx/my_db


# works, solution 2: 
database: "(DESCRIPTION=
(ADDRESS_LIST=(ADDRESS=(PROTOCOL=tcp)(HOST=218.5.173.xxx)(PORT=1521)))
(CONNECT_DATA=(SERVICE_NAME=my_db))
)"

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

Вы можете настроить базу данных, чтобы разрешить более длительные сеансы, либо запретить ей вообще отключаться, либо изменить свой код для проверки соединения перед попыткой отправить запрос, при необходимости восстановить соединение, а затем продолжить.

Не все адаптеры базы данных позволяют вам выполнять keep-alive / heartbeat или даже спрашивать, живо ли соединение с сервером, поэтому мне пришлось вернуться к простому переносу select 1 из таблицы в обработчике исключений, просто чтобы установить соединение перед продолжением.

Другой альтернативой может быть помещение простой подпрограммы keep-alive в отдельный поток, который периодически выполняет простой запрос, например select 1, чтобы сохранить базу данных счастливыми. Если эта подпрограмма обнаружит, что соединение разорвано, оно будет отвечать за установку флага "db_connection_up" в false или переподключиться.

Вы должны определить лучший способ его обработки, основываясь на количестве запросов, которые вы будете обрабатывать. Подключение, выдача крошечного запроса, а затем повторное отключение - это другой вид плохой вещи, поэтому вам нужно найти счастливую среду.

Поговорите со своим администратором базы данных, чтобы узнать, какое время ожидания в базе данных Oracle, и можно ли его изменить или установить постоянное соединение. Если нет, настройте свой код.

Поиск googles для "тайм-аут слушателя оракула" для получения дополнительной информации.

Другие вопросы по тегам