I have here a RoR app, what I am using with the thin appserver.
Its configuration is in an .yml file, so:
---
pid: /srv/cica/tmp/pids/thin.pid
group: cica
wait: 30
timeout: 30
log: /srv/cica/log/thin.log
max_conns: 1024
require: []
environment: production
max_persistent_conns: 512
servers: 4
daemonize: true
user: cica
socket: /srv/cica/tmp/thin.sock
chdir: /srv/cica
How could I use a TCP socket instead of a unix socket for listening?
The documentation I've found somehow never mentions even the possibility, although indirect references say it is possible.
The cause of the problem is that the frontend web (apache2) isn't very strong to proxying http requests to a unix path. It wouldn't be a problem with nginx.
In theory, you can use simply an IP:ADDR instead of the socket path:
socket: 127.0.0.1:3000
will work. But, if you use multiple thin processes, you will have a problem.
(Which is very likely, because the whole ruby is a singlethreaded thing. Considering the IO waiting times, maybe even a significantly higher process number is also possible as the number of your CPU cores).
Somehow the socket address decoder of the thin configuration interpreter is enough smart to use the ordinary IP address, but it increases the IP and not the port for the additional sockets. Thus, you will have multiple thin instances listening on
# thin will listen on these addresses
127.0.0.1:3000
127.0.0.2:3000
127.0.0.3:3000
127.0.0.4:3000
rather they would be listening on
# it would be okay, but not this happens
127.0.0.1:3000
127.0.0.1:3001
127.0.0.1:3002
127.0.0.1:3003
This surreal behavior is likely not what you want. (Although if you have active interfaces on all of the IPs, it could work.)
However, this ruby thing has the nice feature that there is a direct assignment between its command line options and configuration file options. And a thin --help
command will show them to you. You can enforce a TCP listening using the address
and port
options:
#socket: /srv/cica/tmp/thin.sock
address: 127.0.0.1
port: 3000
So you will get already the correct result.
The default values are 0.0.0.0
and 3000
.
As apache wants to proxy only to a single tcp port with its most common settings (ProxyPass
, ProxyPassReverse
directives), also there you need some little trickery, a load balancing proxy cluster. The relevant config snippet:
<Proxy balancer://cicas>
BalancerMember http://localhost:3000 disablereuse=On route=cica1
BalancerMember http://localhost:3001 disablereuse=On route=cica2
BalancerMember http://localhost:3002 disablereuse=On route=cica3
BalancerMember http://localhost:3003 disablereuse=On route=cica4
ProxySet lbmethod=byrequests
</Proxy>
ProxyPass / balancer://cicas/