I tried to run a simple app in a distributed manner to test failover-takeover features but failed.
What I want to:
The application is myapp_api
with a rest api, it has myapp
application as a dependency. I want to start myapp_api
on 3 nodes, I want the whole app (myapp_api
+ myapp
) to be working only at one node at the same time.
What is wrong:
The main app (myapp_api
) works as expected: only at one node with failover and takeover. But for some reason depended myapp
always starts at every node. I want it to be working only at one node at the same time.
What I do:
My config for the first node as an example.
[
{kernel,
[{distributed, [{myapp_api,
1000,
['n1@myhost', {'n2@myhost', 'n3@myhost'}]}]},
{sync_nodes_optional, ['n2@myhost', 'n3@myhost']},
{sync_nodes_timeout, 5000}
]}
].
I call
erl -sname nI -config nI.config -pa apps/*/ebin deps/*/ebin -s myapp_api
at every node.
Now this gets a bit confusing because you say:
I want to start myapp_api on 3 nodes, I want the whole app (myapp_api + myapp) to be working only at one node at the same time.
and you add:
The main app (myapp_api) works as expected: only at one node with failover and takeover. But for some reason depended myapp always starts at every node.
In the first paragraph you say myapp_api
should run everywhere, on the second quote you say it works as intended by booting on one node at a time.
I'll be assuming here that you want the whole set-up to be a failover, not just the top-level app and I just got confused on the first paragraph.
The config file you use shows what happens:
[{kernel,
[{distributed, [{myapp_api,
1000,
['n1@myhost', {'n2@myhost', 'n3@myhost'}]}]},
{sync_nodes_optional, ['n2@myhost', 'n3@myhost']},
{sync_nodes_timeout, 5000}
]}].
The important bit is that myapp_api
has the nodes ['n1@myhost', {'n2@myhost', 'n3@myhost'}]
defined. This order means it runs on n1@myhost
in top priority, and then on the other nodes with equal priority if there is a failover.
The thing is that none of the dependencies are distributed in the same way, and can therefore be expected to be running everywhere.
You should only need to expand on that config file to get it to work. Here I've done it and reindented it to show its structure better:
[{kernel,
[{distributed, [
{myapp_api, 1000, ['n1@myhost', {'n2@myhost', 'n3@myhost'}]},
{myapp, 1000, ['n1@myhost', {'n2@myhost', 'n3@myhost'}]},
]},
{sync_nodes_optional, ['n2@myhost', 'n3@myhost']},
{sync_nodes_timeout, 5000}
]}].
I haven't tested it directly, but I'm pretty sure this will work.
If what you wanted was for myapp_api
to be everywhere but for myapp
to run in one place, you could use global registration, give a name to myapp
's public-facing process, get myapp_api
to call these. myapp_api
would then be able to route traffic to wherever myapp
is when supported with the following config:
[{kernel,
[{distributed, [
{myapp, 1000, ['n1@myhost', {'n2@myhost', 'n3@myhost'}]},
]},
{sync_nodes_optional, ['n2@myhost', 'n3@myhost']},
{sync_nodes_timeout, 5000}
]}].
(See how myapp
is the only app getting a distribution profile? Other apps will get to run on all nodes)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With