Google App Engine is a Platform-as-a-Service (PaaS) for applications where you simply deploy without needing to worry about typical operations such as server management, networking, and scaling. You can scale applications by increasing the number of instances running your applications, with the benefit of those instances running behind a load balancer. Since Elixir has the power of the BEAM with the ability to connect nodes, why not enable distributed Elixir and let our application behave like it’s on one large machine?
Let’s see how we can enable distributed Elixir on Google App Engine.
Clustering Instances
For clustering instances together automatically, we can leverage libcluster. libcluster
will automatically connect our nodes dynamically without any manual intervention.
To tell libcluster
how to cluster nodes together, there are strategies that coordinate how nodes should be discovered and connected. For Google App Engine support, I’ve created a new strategy in libcluster_gae. This clustering strategy will automatically connect nodes on instances that are running and are configured to receive HTTP traffic.
Configuring The Application
Add libcluster_gae
to your application’s dependencies.
def deps do
[
{:libcluster_gae, "~> 0.1"}
]
end
Define a topology for libcluster
using the Google App Engine clustering strategy.
# prod.exs
config :libcluster,
topologies: [
my_app: [
strategy: Cluster.Strategy.GoogleAppEngine
]
]
Add a cluster supervisor to your application’s supervision tree.
defmodule MyApp.App do
use Application
def start(_type, _args) do
topologies = Application.get_env(:libcluster, :topologies)
children = [
{Cluster.Supervisor, [topologies, [name: MyApp.ClusterSupervisor]]},
# ...
]
Supervisor.start_link(children, strategy: :one_for_one, name: MyApp.Supervisor)
end
end
Update your release’s vm.args
file.
## Name of the node
-name <%= release_name%>@${GAE_INSTANCE}.c.${GOOGLE_CLOUD_PROJECT}.internal
## Limit distributed erlang ports to a single port
-kernel inet_dist_listen_min 9999
-kernel inet_dist_listen_max 9999
Update the app.yaml
configuration file for Google App Engine.
env_variables:
REPLACE_OS_VARS: true
network:
forwarded_ports:
# epmd
- 4369
# erlang distribution
- 9999
Enable the App Engine Admin API for your Google Cloud project.
Now run gcloud app deploy
to start clustering your application.
Wrap Up
libcluster
is a straightfoward way to cluster nodes, and libcluster_gae
enables clustering for Google App Engine. Hopefully this will allow you better utilize your instances’ resources by allowing the BEAM to treat the application like it’s running on one large machine.
For futher reading, check out the libcluster documentation as well as the libcluster_gae documentation.
DockYard is a digital product agency offering exceptional user experience, design, full stack engineering, web app development, custom software, Ember, Elixir, and Phoenix services, consulting, and training.