Rails MSSQL - TinyTds ::错误:Adaptive Server连接超时

时间:2017-09-01 11:53:42

标签: ruby-on-rails sql-server docker freetds circleci

我想在我们的CI工具CircleCI中尝试让Rails和MSSQL交谈。我在Mac上工作,所以设置它是相当痛苦的。我使用Homebrew在本地安装了FreeTDS。然后我产生了一个MSSQL docker镜像,并在我的rails应用程序中设置我的配置指向它,一切正常。

CircleCI有点不同。

我做了以下事情。

在我的gemfile中添加:

# mssql database gems
gem 'tiny_tds'
gem 'activerecord-sqlserver-adapter'

修改了我们的database.yml文件:

default: &default
  adapter: sqlserver
  pool: 5
  encoding: utf8
  mode: dblib

development:
  <<: *default
  host: localhost
  database: collections_development
  username: sa
  password: P@55w0rd

test:
  <<: *default
  host: localhost
  database: collections_test
  username: sa
  password: P@55w0rd

我用:

构建了一个泊坞窗图像
FROM circleci/ruby:2.4.1-node-browsers

RUN set -ex \
  && sudo apt-get install build-essential \
  && sudo apt-get install libc6-dev \
  && sudo wget -O freetds-1.00.54.tar.gz "ftp://ftp.freetds.org/pub/freetds/stable/freetds-1.00.54.tar.gz" \
  && sudo tar -xzvf freetds-1.00.54.tar.gz \
  && cd freetds-1.00.54 \
  && sudo ./configure \
  && sudo make \
  && sudo make install

此图片托管于docker hub here

接下来我构建了CircleCI配置:

version: 2
jobs:
build:
    working_directory: ~/collections-api
    docker:
    - image: legendaryrob/ruby:2.4.1-node-browser-freetds54-lib6c
        environment:
        RAILS_ENV: test
    - image: microsoft/mssql-server-linux
        environment:
        ACCEPT_EULA: Y
        SA_PASSWORD: P@55w0rd

    environment:
    RAILS_ENV: test
    steps:
    - checkout
    - restore_cache:
        name: Restore bundle cache
        keys:
            - collections-api-bundle-{{ checksum "Gemfile.lock" }}
    - run:
        name: Allow CI to read from pdg gemserver
        command: bundle config https://gems.pdg.io/ $GEMS_USERNAME:$GEMS_PASSWORD
    - run:
        name: Bundle Install
        command: bundle install --path vendor/bundle --jobs 4 --retry 3
    - save_cache:
        name: Store bundle cache
        key: collections-api-bundle-{{ checksum "Gemfile.lock" }}
        paths:
            - vendor/bundle
    - run:
        name: Wait for DB
        command: dockerize -wait tcp://localhost:1433 -timeout 1m

    - run:
        name: test tds connection
        command: tsql -C

    # Run setup
    - run: ./spec/setup/circle_setup.sh

    - run:
        name: Create the database
        command: bundle exec rake -v --trace db:create

    - run:
        name: Migrate the database
        command: bundle exec rake -v --trace db:migrate

    - run: 
        name: Check environment variables are present
        command: bundle exec rake env_variables:check
    - run:
        name: Run tests
        command: bundle exec rspec

我直接从Microsoft的docker hub帐户获取的MSSQL docker镜像 - &gt; https://hub.docker.com/r/microsoft/mssql-server-linux/

在这里你可以看到几件事。我设置了我用TDS安装的ruby盒子以及所需的所有依赖项。我确保我们使用的是我们在本地使用的相同版本的TDS,因为它在本地工作,我还尝试了一些其他版本,只是因为我正在处理一个flakey版本。

我还确保我们可以连接到MSSQL docker box并确保我们有正确的tds配置:

- run:
    name: Wait for DB
    command: dockerize -wait tcp://localhost:1433 -timeout 1m

- run:
    name: test tds connection
    command: tsql -C

这将产生以下结果:

#!/bin/bash -eo pipefail
dockerize -wait tcp://localhost:1433 -timeout 1m
enter code here

2017/09/01 09:25:40 Waiting for: tcp://localhost:1433
2017/09/01 09:25:40 Problem with dial: dial tcp 127.0.0.1:1433: 
getsockopt: connection refused. Sleeping 1s
2017/09/01 09:25:41 Problem with dial: dial tcp 127.0.0.1:1433: 
getsockopt: connection refused. Sleeping 1s
2017/09/01 09:25:42 Problem with dial: dial tcp 127.0.0.1:1433: 
getsockopt: connection refused. Sleeping 1s
2017/09/01 09:25:48 Connected to tcp://localhost:1433

#!/bin/bash -eo pipefail
tsql -C
[TinyTds][v2.0.0][tsql]: /usr/local/bin/tsql
Compile-time settings (established with the "configure" script)
                            Version: freetds v1.00.54
             freetds.conf directory: /usr/local/etc
     MS db-lib source compatibility: no
        Sybase binary compatibility: no
                      Thread safety: yes
                      iconv library: yes
                        TDS version: auto
                              iODBC: no
                           unixodbc: no
              SSPI "trusted" logins: no
                           Kerberos: no
                            OpenSSL: yes
                             GnuTLS: no
                               MARS: no

然后我得到超时。这些超时是间歇性的,当我们尝试连接到localhost时会出现这些超时:1433

但主要是当我们进入佣金任务时。

下面是我得到的堆栈跟踪,我已经尝试了几个不同版本的MSSQL docker,但没有效果。如果有人试过这样做,请告诉我,我真的很感激这方面的一些帮助。

#!/bin/bash -eo pipefail
bundle exec rake -v --trace db:create
** Invoke db:create (first_time)
** Invoke db:load_config (first_time)
** Execute db:load_config
** Execute db:create
TinyTds::Error: Adaptive Server connection timed out: CREATE DATABASE [collections_test]  
Couldn't create database for {"adapter"=>"sqlserver", "pool"=>5, "encoding"=>"utf8", "mode"=>"dblib", "host"=>"localhost", "database"=>"collections_test", "username"=>"sa", "password"=>"P@55w0rd"}
rake aborted!
ActiveRecord::StatementInvalid: TinyTds::Error: Adaptive Server connection timed out: CREATE DATABASE [collections_test]  
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-sqlserver-adapter-5.1.1/lib/active_record/connection_adapters/sqlserver/database_statements.rb:274:in `do'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-sqlserver-adapter-5.1.1/lib/active_record/connection_adapters/sqlserver/database_statements.rb:274:in `raw_connection_do'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-sqlserver-adapter-5.1.1/lib/active_record/connection_adapters/sqlserver/database_statements.rb:215:in `block in do_execute'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/connection_adapters/abstract_adapter.rb:612:in `block (2 levels) in log'
/usr/local/lib/ruby/2.4.0/monitor.rb:214:in `mon_synchronize'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/connection_adapters/abstract_adapter.rb:611:in `block in log'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.3/lib/active_support/notifications/instrumenter.rb:21:in `instrument'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/connection_adapters/abstract_adapter.rb:603:in `log'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-sqlserver-adapter-5.1.1/lib/active_record/connection_adapters/sqlserver/database_statements.rb:215:in `do_execute'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-sqlserver-adapter-5.1.1/lib/active_record/connection_adapters/sqlserver/database_tasks.rb:10:in `create_database'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-sqlserver-adapter-5.1.1/lib/active_record/tasks/sqlserver_database_tasks.rb:22:in `create'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/tasks/database_tasks.rb:117:in `create'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/tasks/database_tasks.rb:137:in `block in create_current'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/tasks/database_tasks.rb:304:in `block in each_current_configuration'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/tasks/database_tasks.rb:303:in `each'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/tasks/database_tasks.rb:303:in `each_current_configuration'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/tasks/database_tasks.rb:136:in `create_current'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/railties/databases.rake:27:in `block (2 levels) in <top (required)>'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/task.rb:250:in `block in execute'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/task.rb:250:in `each'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/task.rb:250:in `execute'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/task.rb:194:in `block in invoke_with_call_chain'
/usr/local/lib/ruby/2.4.0/monitor.rb:214:in `mon_synchronize'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/task.rb:187:in `invoke_with_call_chain'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/task.rb:180:in `invoke'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:152:in `invoke_task'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:108:in `block (2 levels) in top_level'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:108:in `each'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:108:in `block in top_level'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:117:in `run_with_threads'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:102:in `top_level'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:80:in `block in run'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:178:in `standard_exception_handling'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:77:in `run'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/exe/rake:27:in `<top (required)>'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/bin/rake:23:in `load'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/bin/rake:23:in `<top (required)>'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/cli/exec.rb:74:in `load'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/cli/exec.rb:74:in `kernel_load'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/cli/exec.rb:27:in `run'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/cli.rb:362:in `exec'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/vendor/thor/lib/thor/invocation.rb:126:in `invoke_command'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/vendor/thor/lib/thor.rb:387:in `dispatch'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/cli.rb:22:in `dispatch'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/vendor/thor/lib/thor/base.rb:466:in `start'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/cli.rb:13:in `start'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/exe/bundle:30:in `block in <top (required)>'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/friendly_errors.rb:121:in `with_friendly_errors'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/exe/bundle:22:in `<top (required)>'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'
TinyTds::Error: Adaptive Server connection timed out
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-sqlserver-adapter-5.1.1/lib/active_record/connection_adapters/sqlserver/database_statements.rb:274:in `do'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-sqlserver-adapter-5.1.1/lib/active_record/connection_adapters/sqlserver/database_statements.rb:274:in `raw_connection_do'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-sqlserver-adapter-5.1.1/lib/active_record/connection_adapters/sqlserver/database_statements.rb:215:in `block in do_execute'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/connection_adapters/abstract_adapter.rb:612:in `block (2 levels) in log'
/usr/local/lib/ruby/2.4.0/monitor.rb:214:in `mon_synchronize'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/connection_adapters/abstract_adapter.rb:611:in `block in log'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.3/lib/active_support/notifications/instrumenter.rb:21:in `instrument'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/connection_adapters/abstract_adapter.rb:603:in `log'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-sqlserver-adapter-5.1.1/lib/active_record/connection_adapters/sqlserver/database_statements.rb:215:in `do_execute'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-sqlserver-adapter-5.1.1/lib/active_record/connection_adapters/sqlserver/database_tasks.rb:10:in `create_database'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-sqlserver-adapter-5.1.1/lib/active_record/tasks/sqlserver_database_tasks.rb:22:in `create'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/tasks/database_tasks.rb:117:in `create'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/tasks/database_tasks.rb:137:in `block in create_current'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/tasks/database_tasks.rb:304:in `block in each_current_configuration'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/tasks/database_tasks.rb:303:in `each'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/tasks/database_tasks.rb:303:in `each_current_configuration'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/tasks/database_tasks.rb:136:in `create_current'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/railties/databases.rake:27:in `block (2 levels) in <top (required)>'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/task.rb:250:in `block in execute'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/task.rb:250:in `each'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/task.rb:250:in `execute'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/task.rb:194:in `block in invoke_with_call_chain'
/usr/local/lib/ruby/2.4.0/monitor.rb:214:in `mon_synchronize'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/task.rb:187:in `invoke_with_call_chain'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/task.rb:180:in `invoke'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:152:in `invoke_task'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:108:in `block (2 levels) in top_level'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:108:in `each'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:108:in `block in top_level'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:117:in `run_with_threads'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:102:in `top_level'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:80:in `block in run'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:178:in `standard_exception_handling'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:77:in `run'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/exe/rake:27:in `<top (required)>'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/bin/rake:23:in `load'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/bin/rake:23:in `<top (required)>'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/cli/exec.rb:74:in `load'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/cli/exec.rb:74:in `kernel_load'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/cli/exec.rb:27:in `run'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/cli.rb:362:in `exec'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/vendor/thor/lib/thor/invocation.rb:126:in `invoke_command'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/vendor/thor/lib/thor.rb:387:in `dispatch'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/cli.rb:22:in `dispatch'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/vendor/thor/lib/thor/base.rb:466:in `start'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/cli.rb:13:in `start'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/exe/bundle:30:in `block in <top (required)>'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/friendly_errors.rb:121:in `with_friendly_errors'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/exe/bundle:22:in `<top (required)>'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'
Tasks: TOP => db:create
Exited with code 1

注意:我们需要连接到MSSQL的原因是因为我们将在短时间内写入数据库,我们有另一个团队依赖于使用MSSQL的Access。我只是希望有一个人在那里与这个野兽战斗并赢得了胜利。

编辑:freetds.conf

#   $Id: freetds.conf,v 1.12 2007-12-25 06:02:36 jklowden Exp $
#
# This file is installed by FreeTDS if no file by the same 
# name is found in the installation directory.  
#
# For information about the layout of this file and its settings, 
# see the freetds.conf manpage "man freetds.conf".  

# Global settings are overridden by those in a database
# server specific section
[global]
        # TDS protocol version
  tds version = auto

  # Whether to write a TDSDUMP file for diagnostic purposes
  # (setting this to /tmp is insecure on a multi-user system)
;   dump file = /tmp/freetds.log
;   debug flags = 0xffff

  # Command and connection timeouts
;   timeout = 10
;   connect timeout = 10

  # If you get out-of-memory errors, it may mean that your client
  # is trying to allocate a huge buffer for a TEXT field.  
  # Try setting 'text size' to a more reasonable limit 
  text size = 64512

  # If you experience TLS handshake errors and are using openssl,
  # try adjusting the cipher list (don't surround in double or single quotes)
  # openssl ciphers = HIGH:!SSLv2:!aNULL:-DH

# A typical Sybase server
[egServer50]
  host = symachine.domain.com
  port = 5000
  tds version = 5.0

# A typical Microsoft server
[egServer70]
  host = ntmachine.domain.com
  port = 1433
  tds version = 7.0

0 个答案:

没有答案