使用 fly.io 实现负载均衡和自动弹性伸缩

前言

fly.io 是一个现代的应用程序交付平台，提供了负载均衡和自动弹性伸缩功能，保证应用程序的可靠性和性能。

根据 fly.io 负载均衡 的文档，可以知道 fly.io 支持通过请求书或者 tcp 连接数来进行自动扩容，因为前段时间我朋友的 API 被攻击了，然后服务器直接死亡，又因为他的 api 都是在非浏览器下使用，比如一些应用程序，脚本什么的不好做防御策略，所以我推荐他迁移到 fly.io 上

配置

首先把程序打包成 docker，然后部署到 fly.io 上，我使用的是 2H512M 的配置，并且创建了 11 台的实例。

然后通过 fly.toml 进行配置每一台实例的最高连接数，使用 [services.concurrency]，参考配置：

Copy
# fly.toml app configuration file generated for cheat-show-backend on 2023-09-15T18:53:53-05:00
#
# See https://fly.io/docs/reference/configuration/ for information about how to use this file.
#

app = "XXXXXXXXXXXX"
primary_region = "lax"
swap_size_mb = 1024

[http_service]
internal_port = 8080
force_https = false
auto_stop_machines = true
auto_start_machines = true
min_machines_running = 0
processes = ["app"]
[services.concurrency]
type = "connections"
hard_limit = 10000
soft_limit = 1200

[build]
dockerfile = "Dockerfile"

soft_limit 是软限制，fly.io 会判断这个连接数从而限制每台实例，如果单台超出这个连接数则会启动其他实例，从而实现自动扩容。使用 wrk 测试后可以得出，我们部署的服务单台可以支撑 2k 的并发，为了给他足够的时间扩容，我把它的限制改成 1200，如果低于这个值，fly.io 只会启动一台机器，如果超过这个值，则根据连接数启动多台。

hard_limit 是硬限制，单台实例超过这个数值会返回 503。

压测

默认状态

连接数巨增状态 (wrk 5000 线程)

正常情况下只会开启一台，按分钟计费，一台跑一个月 3.8 刀，如果在连接数下降后会自动缩放至一台，停止状态的实例不会收费。

关于一些坑

fly.io 的负载均衡是就近回源。如果我有一台实例在纽约，有一台在洛杉矶，我默认想洛杉矶开着，纽约当后备的话需要一台洛杉矶的服务器进行反向代理 fly.io，如果直接访问的话会导致 fly.io 就近启动实例，比如纽约用户访问它会启动纽约的实例，即使连接数只有 1 也会启动。所以我还在 fly.io 的洛杉矶地区部署了 3 台 nginx 反向代理实例，使用 3 台 1h256m 的实例做负载均衡，经过优化后单台并发可以达到 1w+。

更新：好像修复了同地区自动弹性的问题，之前同地区的情况下会开启所有机器默认负载均衡，弹性只对跨地区起作用，这个坑已经没了，目前对同地区也生效。
。

优化后的 Dockerfile

Copy
FROM nginx
RUN sed -i 's/worker_processes auto;/worker_processes 8;/' /etc/nginx/nginx.conf
RUN sed -i 's/worker_connections [0-9]*;/worker_connections 9999999;/' /etc/nginx/nginx.conf
COPY nginx.conf /etc/nginx/conf.d/nginx.conf

nginx.conf

Copy
server {
listen 8080 default_server;
listen [::]:8080 default_server;
server_name api.test.com;
keepalive_timeout 75s;
keepalive_requests 100;

location / {
proxy_pass http://ip:80;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_http_version 1.1;
}
}

即可实现低成本的服务自动弹性扩容

成本问题

用于部署 nginx 的 3 台实例免费，后端实例基本上只有一台在开启，每个月 3.8 刀，不开启的不会收费。