如何在Elixir中使用AWS公网IP及解决EC2实例IEx连接问题
关于Elixir与AWS EC2的两个问题解答
问题1:如何在Elixir中使用AWS公网IP?
其实在Elixir里用EC2的公网IP和普通IP没什么本质区别,核心看你具体的使用场景,我给你分情况说明:
- 先获取公网IP:
你可以通过AWS控制台直接查看,或者用AWS CLI命令快速获取:
如果是在EC2实例内部,还可以通过AWS元数据服务直接拉取:aws ec2 describe-instances --instance-ids <你的实例ID> --query 'Reservations[0].Instances[0].PublicIpAddress'{:ok, resp} = HTTPoison.get("http://169.254.169.254/latest/meta-data/public-ipv4") public_ip = String.trim(resp.body) - 实际使用场景:
- 要是想连接另一个EC2上的IEx节点,直接把公网IP拼到节点名里就行(记得提前配置相同的cookie):
Node.connect(:"remote-node@#{public_ip}") - 如果是调用部署在EC2上的HTTP服务,直接把公网IP作为base URL使用即可,比如
"http://#{public_ip}:4000/api"。
- 要是想连接另一个EC2上的IEx节点,直接把公网IP拼到节点名里就行(记得提前配置相同的cookie):
- 必注意的点:一定要确保EC2的安全组开放了对应的端口——比如Elixir节点通信需要的EPMD端口(4369),以及你服务用到的业务端口,不然连接肯定会失败。
问题2:解决Elixir节点不接受含短横线Hostname的问题
这个坑我之前也踩过!Erlang的节点命名规则比较严格,不允许hostname里有短横线(-),而EC2默认的hostname都是ip-xxx-xxx-xxx-xxx这种格式,自然会导致节点连接失败。下面给你几种不破坏EC2路由的解决办法:
方法1:临时修改系统hostname(重启后失效)
适合临时测试用,在EC2终端执行:
sudo hostnamectl set-hostname node-a.local
然后刷新当前shell的环境变量:
export HOSTNAME=node-a.local
之后启动IEx时用这个新hostname:
iex --name my-node@node-a.local --cookie shared-secret
方法2:永久修改系统hostname(重启后生效)
如果需要长期使用,就改系统配置:
- 编辑
/etc/hostname,替换成合法的hostname(比如node-a.local):sudo echo "node-a.local" > /etc/hostname - 修改
/etc/hosts,确保本地回环和私网IP能映射到新hostname:
或者手动编辑,添加类似这样的条目:sudo sed -i 's/原hostname/node-a.local/g' /etc/hosts127.0.0.1 node-a.local localhost <你的私网IP> node-a.local - 重启实例或者执行
sudo systemctl restart systemd-hostnamed让配置生效。
方法3:启动IEx时直接指定合法节点名(无需改系统hostname)
不想碰系统配置的话,这个方法最省心:
- 直接用EC2的私网IP作为节点名的一部分(私网IP没有短横线):
iex --name my-node@10.0.0.100 --cookie shared-secret - 或者在
/etc/hosts里给原hostname加个别名,比如把ip-10-0-0-100映射为node-a,然后启动IEx时用别名:iex --name my-node@node-a --cookie shared-secret
重要提醒
EC2实例之间的路由是基于IP地址的,和hostname完全无关,所以不管你用哪种方法修改节点名,都不会破坏实例间的路由,只要安全组和网络ACL配置正确,通信就没问题。
内容的提问来源于stack exchange,提问作者Andrew Dixon
相关产品推荐
相关产品推荐

