前言
fly.io 是一个现代的应用程序交付平台,提供了负载均衡和自动弹性伸缩功能,保证应用程序的可靠性和性能。
根据 fly.io 负载均衡 的文档,可以知道 fly.io 支持通过请求书或者 tcp 连接数来进行自动扩容,因为前段时间我朋友的 API 被攻击了,然后服务器直接死亡,又因为他的 api 都是在非浏览器下使用,比如一些应用程序,脚本什么的不好做防御策略,所以我推荐他迁移到 fly.io 上
配置
首先把程序打包成 docker,然后部署到 fly.io 上,我使用的是 2H512M 的配置,并且创建了 11 台的实例。
然后通过 fly.toml
进行配置每一台实例的最高连接数,使用 [services.concurrency]
,参考配置:
# 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
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
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 刀,不开启的不会收费。