Тонкий запуск с ошибкой (`start_unix_server’: нет акцептора unix-домена (ошибка выполнения))

#ruby-on-rails #nginx #thin

#ruby-on-rails #nginx #тонкий

Вопрос:

Я развернул приложение rails для nginx, используя тонкий capistrano (rails 4, ruby 2.1.2, тонкий 1.6.2, capistrano 2.1.5). Я запустил thin с помощью команды thin start. И просмотрите некоторую ошибку в этом файле thin.log. Кто-нибудь может показать мне, как это исправить?

Большое вам спасибо!

тонкий.yml

  pid: /home/deploy/myapp/pids/thin.pid
 port: 3000
 timeout: 30
 wait: 30
 log: log/thin.log
 max_conns: 1024
 require: []
 environment: production
 max_persistent_conns: 512
 threaded: true
 no-epoll: true
 daemonize: true
 socket: /home/deploy/myapp/sockets/thin.sock
 chdir: /home/deploy/myapp/current
 address: 0.0.0.0
  

/etc/nginx/sites-availabel/default

 upstream myapp{
        server 127.0.0.1:3000;
        server 127.0.0.1:3001;
        server 127.0.0.1:3002;
}
server {
        listen   80;
        server_name _;
        character utf-8;


        access_log /home/deploy/myapp/log/access.log;
        error_log /home/deploy/myapp/log/error.log;
        root     /home/deploy/myapp/current/public;

        location / {
                proxy_pass http://127.0.0.1:3000;
        }

}
  

thin.log

 Writing PID to /home/deploy/myapp/pids/thin.pid
Using rack adapter
Thin web server (v1.6.2 codename Doc Brown)
Maximum connections set to 1024
Listening on /home/deploy/myapp/sockets/thin.sock, CTRL C to stop
Exiting!
/home/deploy/.rvm/gems/ruby-2.1.2/gems/eventmachine-1.0.3/lib/eventmachine.rb:528:in `start_unix_server': no unix-domain acceptor (RuntimeError)
    from /home/deploy/.rvm/gems/ruby-2.1.2/gems/eventmachine-1.0.3/lib/eventmachine.rb:528:in `start_server'
    from /home/deploy/.rvm/gems/ruby-2.1.2/gems/eventmachine-1.0.3/lib/eventmachine.rb:548:in `start_unix_domain_server'
    from /home/deploy/.rvm/gems/ruby-2.1.2/gems/thin-1.6.2/lib/thin/backends/unix_server.rb:19:in `connect'
    from /home/deploy/.rvm/gems/ruby-2.1.2/gems/thin-1.6.2/lib/thin/backends/base.rb:63:in `block in start'
    from /home/deploy/.rvm/gems/ruby-2.1.2/gems/eventmachine-1.0.3/lib/eventmachine.rb:187:in `call'
    from /home/deploy/.rvm/gems/ruby-2.1.2/gems/eventmachine-1.0.3/lib/eventmachine.rb:187:in `run_machine'
    from /home/deploy/.rvm/gems/ruby-2.1.2/gems/eventmachine-1.0.3/lib/eventmachine.rb:187:in `run'
    from /home/deploy/.rvm/gems/ruby-2.1.2/gems/thin-1.6.2/lib/thin/backends/base.rb:73:in `start'
    from /home/deploy/.rvm/gems/ruby-2.1.2/gems/thin-1.6.2/lib/thin/server.rb:162:in `start'
    from /home/deploy/.rvm/gems/ruby-2.1.2/gems/thin-1.6.2/lib/thin/controllers/controller.rb:87:in `start'
    from /home/deploy/.rvm/gems/ruby-2.1.2/gems/thin-1.6.2/lib/thin/runner.rb:199:in `run_command'
    from /home/deploy/.rvm/gems/ruby-2.1.2/gems/thin-1.6.2/lib/thin/runner.rb:155:in `run!'
    from /home/deploy/.rvm/gems/ruby-2.1.2/gems/thin-1.6.2/bin/thin:6:in `<top (required)>'
    from /home/deploy/.rvm/gems/ruby-2.1.2/bin/thin:23:in `load'
    from /home/deploy/.rvm/gems/ruby-2.1.2/bin/thin:23:in `<main>'
    from /home/deploy/.rvm/gems/ruby-2.1.2/bin/ruby_executable_hooks:15:in `eval'
    from /home/deploy/.rvm/gems/ruby-2.1.2/bin/ruby_executable_hooks:15:in `<main>'
  

Комментарии:

1. Когда я использовал thin в рабочей среде, я запускал его в порту 8080 с помощью thin -e production -p 8080, и nginx прослушивал мое приложение на 8080. Я не знаю, делаю ли я это неправильно, но это работает.

2. @Russell Kompinski: Я думаю, мне нужна остановка для тонкого прослушивания в порту 3000 из соображений безопасности. В приведенном выше коде я пытаюсь использовать сервер nginx по умолчанию для прослушивания через порт 80.

3. Я получил ту же ошибку, и для меня изменение имени сокета сработало. Я пока не знаю, почему.

Ответ №1:

Вообще говоря: настройка Thin и Nginx для совместной работы

У меня только что была почти такая же проблема на моем VPS. Чего я не понимаю, так это того, что ваша тонкая конфигурация объединяет порт и сокет. Я не знаю, хороший ли это путь.

Но в любом случае, вот что я предлагаю :

На тонкой стороне

Вы просто указываете тонкому использовать /home/deploy/myapp/sockets/thin.sock сокет. Хорошо, у нас все хорошо. Я бы использовал другой каталог для сокета (скажем, /tmp или tmp каталог вашего приложения), но я не эксперт, и это ваше дело.

На стороне Nginx

Затем, если вы хотите, чтобы Thin и Nginx обменивались данными, вы должны сообщить Nginx, что Thin прослушивает входящий запрос в этом конкретном сокете. Здесь, в вашем upstream блоке, вы сообщаете Nginx, что Thin прослушивает входящие запросы на localhost:3000. Опять же, поскольку вы используете как порт, так и сокет в вашем Thin conf, я не уверен, может ли это быть проблемой (но, по крайней мере, один из этих параметров кажется мне бесполезным, поскольку речь идет о связи Thin-Nginx). Если и Nginx, и Thin используются на одном компьютере, я думаю, что сокеты — лучший способ сделать это, поскольку они заставляют связь полагаться на файловую систему вместо HTTP-запросов, что должно быть более эффективным. Чтобы сообщить Nginx, что Thin прослушивает сокет, вы должны использовать upstream блок, подобный этому :

 upstream myapp {
    server unix:/home/deploy/myapp/sockets/thin.sock;
}
  

Судя по вашему тонкому конфигурационному файлу, у вас есть только один экземпляр Thin, запущенный для этого проекта, поэтому вам нужна только одна server строка. Если бы вы использовали, скажем, 2 тонких экземпляра (с servers: 2 в вашей тонкой конфигурации yml), вы бы сделали что-то подобное на стороне nginx :

 upstream myapp {
    server unix:/home/deploy/myapp/sockets/thin.0.sock;
    server unix:/home/deploy/myapp/sockets/thin.1.sock;
}
  

«Нет акцептора unix-домена (ошибка выполнения)»

Что касается ошибки «нет акцептора unix-домена (RuntimeError)», это может быть связано с проблемой с разрешениями в каталоге сокетов, по крайней мере, так было, когда я только что столкнулся с этой проблемой (не знаю почему, мой sockets каталог исчез, и когда я создал его снова, у него должны были быть правильные разрешения, чтобы избежать этой ошибки). Итак, я бы сказал, проверьте это;)

Комментарии:

1. Я пытаюсь использовать сокет Unix, потому что я думаю, что открытие порта (например, порта 3000) является дырой в безопасности.

Ответ №2:

Для меня эта ошибка была вызвана отсутствующим каталогом сокетов (в вашем случае это было бы /home/deploy/myapp/sockets ).

Ответ №3:

Вот как выглядит мой nginx с использованием thin. Возможно, это может помочь.

    upstream thin_server {
          server 0.0.0.0:8080 fail_timeout=0;
        }

        server {
                listen   80 defau<
                root /home/example/public;
                server_name example.com www.example.com;
                index index.htm index.html;


                location / {
                        try_files $uri/index.html $uri.html $uri @app;
                }

                location ~* ^. .(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js|mp3|flv|mpeg|avi)$ {
                                try_files $uri @app;
                        }

                 location @app {
                        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                        proxy_set_header Host $http_host;
                        proxy_redirect off;
                        proxy_pass http://thin_server;
            }

            error_page 500 502 503 504 /500.html;
            client_max_body_size 4G;
            keepalive_timeout 10;
}
  

Комментарии:

1. Я пытался использовать сокет, но он не работал. Можете ли вы показать мне, почему? Я не понимаю, в чем разница между socket: /home /deploy/myapp/sockets/thin.sock и сервером 0.0.0.0:8080. :(. Спасибо.

2. @PhuongTT Я не уверен, как ответить на это, и у меня нет глубокого понимания различных типов сокетов. Вы спрашиваете об адресе сокета? Мы используем адрес сокета, который является IP-адресом и портом, объединенным с localhost и портом 8080, который равен 0.0.0.0:8080. Можете ли вы уточнить? Кроме того, это сработало для вас?

3. Этот способ сработал для меня. Я просто задаю вам вопрос, чтобы узнать больше об этом. 😀