在不考虑成本的情况下部署低流量 rails 应用程序的最佳实践
Best practice for deploying low traffic rails app without cost concerns
我的问题
部署 rails 应用程序时要避免的与成本相关的陷阱?
欢迎攻击,因为它会教会我期待什么并让自己做好准备。
但是,我宁愿避免在月底支付大额账单。
云托管服务好用吗?
我选择 AWS 是因为它看起来可扩展,而且我认为以后可以避免依赖其他服务。
我不后悔,但 AWS 是压倒性的,如果有更简单的服务,我应该使用它。
我目前关注的问题
- AWS S3 上的 Dos 攻击或获取请求泛滥可能会显着增加托管成本,因为我正在那里上传一些内容。
计费警报很有用,但没有自动关机我感觉有点不舒服,休息一下,进入丛林或有人居住的岛屿,在那里我得不到 INTERNET 连接通知或关闭我的服务...
针对我的案例的明显修复
停止使用 S3 并将用户上传保存到我可以控制缩放行为的数据库。但是,大多数人似乎都在使用带有载波的S3,为什么?
我在做什么
使用以下方法制作我的第一个主页:
- 弹性豆茎
- rails5
- Carrierwave gem 配置为在 S3 中保存用户上传
编辑
最后,我找不到任何真正解决 S3 无上限问题的方法。
以下是我的笔记。
我猜 S3 有一些基本的内置防御攻击,因为我没有听说过有人使用 S3 托管静态网站并收到超过 10000 美元的账单的悲惨故事,尽管亚马逊的防御能力如何,这种情况仍然可能发生是。
缓解
定期检查 s3 日志文件并在这些文件的累积大小过大时调用禁用 s3 资源服务的操作的脚本。
S3 日志有时需要一个多小时才能可用,因此这不是解决方案,但聊胜于无。
class LogObserver
def initialize
aws_conf = Aws.config.update({
access_key_id: ENV['AWS_ACCESS_KEY_ID'],
secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
region: 'ap-northeast-1'})
@bucket_name="bucket name that holds s3 log"
@last_checked_log_timestamp = Time.now.utc
log "started at: #{Time.now}"
end
def run
bucket = Aws::S3::Resource.new.bucket(@bucket_name)
while true
prv_log_ts = @last_checked_log_timestamp
log_size = fetch_log_size(bucket)
log "The total size of S3 log accumulated since last time this script was executed: #{log_size}"
time_range = @last_checked_log_timestamp - prv_log_ts # float
log_size_per_second = log_size/time_range
if log_size_per_second > (500.kilobyte/60)
log "Disabling S3 access as S3 log size is greater than expected."
`curl localhost/static_pages/disable_s3`
end
sleep 60*60
end
end
def log text
puts text
File.open('./s3_observer_log.txt','a') do |f|
f << text
end
end
def fetch_log_size(bucket)
log_size=0
bucket.objects(prefix: 'files').each do |o|
time_object = o.last_modified
if time_object < @last_checked_log_timestamp
next
end
@last_checked_log_timestamp = time_object
log_size += o.size.to_i
end
return log_size
end
end
耙任务:
namespace :s3_log do
desc "Access S3 access log files and check their cumulative size. If the size is above the expected value, disables s3 access."
task :start_attack_detection_loop do
require './s3_observer.rb'
id=Process.fork do
o=LogObserver.new
o.run
end
puts "Forked a new process that watches s3 log. Process id: #{id}"
end
end
控制器动作:
before_action :ensure_permited_ip, only: [:enable_s3, :disable_s3]
def enable_s3
# allow disabling s3 only from localhost
CarrierWave.configure do |config|
config.fog_authenticated_url_expiration = 3
end
end
def disable_s3
# allow disabling s3 only from localhost
CarrierWave.configure do |config|
config.fog_authenticated_url_expiration = 0
end
end
private
def ensure_permited_ip
if request.remote_ip!= "127.0.0.1" # allow access only from localhost
redirect_to root_path
end
end
宝石:
gem 'aws-sdk-rails'
gem 'aws-sdk-s3', '~> 1'
我的经验有限,但我的建议是:
Cost related pit falls to avoid when deploying rails app?
- 如果您要使用后台作业,请使用
rufus-scheduler
而不是 sidekiq
或 delayed_job
,因为它在您的 rails server
之上运行并且不需要额外的内存/额外的专用进程。这允许您获得 smallest/cheapest 可能的实例:t2.nano,我之前做过一次。
Easy cloud hosting services to use?
- Heroku 将是一个不错的选择,因为它很容易设置。但是,如果您这样做是为了体验,我建议您在 3 个月前购买像 AWS EC2 or Linode. I recently migrated my server from AWS to Vpsdime 这样的非托管主机,因为它便宜且内存大;到目前为止一切顺利。
My current concern
- 对于
carrierwave
,您可以限制 S3 访问。参见 reference. This then prevents hotlinking and would then require a user to view your Rails pages first in order to download or view or show the S3 files. Now that Rails now have control over the S3 files, you can just simply use something like Rack::Attack to prevent DDOS or excessive requests. If your Rails app is configured with Apache
or Nginx
, you can instead set up DDOS rules there instead of using Rack::Attack
. Or, if you are gonna be using AWS load balancer to manage / route the requests, then you can use AWS Shield ... 虽然还没有真正使用过它。
我的问题
部署 rails 应用程序时要避免的与成本相关的陷阱?
欢迎攻击,因为它会教会我期待什么并让自己做好准备。
但是,我宁愿避免在月底支付大额账单。
云托管服务好用吗?
我选择 AWS 是因为它看起来可扩展,而且我认为以后可以避免依赖其他服务。
我不后悔,但 AWS 是压倒性的,如果有更简单的服务,我应该使用它。
我目前关注的问题
- AWS S3 上的 Dos 攻击或获取请求泛滥可能会显着增加托管成本,因为我正在那里上传一些内容。
计费警报很有用,但没有自动关机我感觉有点不舒服,休息一下,进入丛林或有人居住的岛屿,在那里我得不到 INTERNET 连接通知或关闭我的服务...
针对我的案例的明显修复
停止使用 S3 并将用户上传保存到我可以控制缩放行为的数据库。但是,大多数人似乎都在使用带有载波的S3,为什么?
我在做什么
使用以下方法制作我的第一个主页:
- 弹性豆茎
- rails5
- Carrierwave gem 配置为在 S3 中保存用户上传
编辑
最后,我找不到任何真正解决 S3 无上限问题的方法。
以下是我的笔记。
我猜 S3 有一些基本的内置防御攻击,因为我没有听说过有人使用 S3 托管静态网站并收到超过 10000 美元的账单的悲惨故事,尽管亚马逊的防御能力如何,这种情况仍然可能发生是。
缓解
定期检查 s3 日志文件并在这些文件的累积大小过大时调用禁用 s3 资源服务的操作的脚本。
S3 日志有时需要一个多小时才能可用,因此这不是解决方案,但聊胜于无。
class LogObserver
def initialize
aws_conf = Aws.config.update({
access_key_id: ENV['AWS_ACCESS_KEY_ID'],
secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
region: 'ap-northeast-1'})
@bucket_name="bucket name that holds s3 log"
@last_checked_log_timestamp = Time.now.utc
log "started at: #{Time.now}"
end
def run
bucket = Aws::S3::Resource.new.bucket(@bucket_name)
while true
prv_log_ts = @last_checked_log_timestamp
log_size = fetch_log_size(bucket)
log "The total size of S3 log accumulated since last time this script was executed: #{log_size}"
time_range = @last_checked_log_timestamp - prv_log_ts # float
log_size_per_second = log_size/time_range
if log_size_per_second > (500.kilobyte/60)
log "Disabling S3 access as S3 log size is greater than expected."
`curl localhost/static_pages/disable_s3`
end
sleep 60*60
end
end
def log text
puts text
File.open('./s3_observer_log.txt','a') do |f|
f << text
end
end
def fetch_log_size(bucket)
log_size=0
bucket.objects(prefix: 'files').each do |o|
time_object = o.last_modified
if time_object < @last_checked_log_timestamp
next
end
@last_checked_log_timestamp = time_object
log_size += o.size.to_i
end
return log_size
end
end
耙任务:
namespace :s3_log do
desc "Access S3 access log files and check their cumulative size. If the size is above the expected value, disables s3 access."
task :start_attack_detection_loop do
require './s3_observer.rb'
id=Process.fork do
o=LogObserver.new
o.run
end
puts "Forked a new process that watches s3 log. Process id: #{id}"
end
end
控制器动作:
before_action :ensure_permited_ip, only: [:enable_s3, :disable_s3]
def enable_s3
# allow disabling s3 only from localhost
CarrierWave.configure do |config|
config.fog_authenticated_url_expiration = 3
end
end
def disable_s3
# allow disabling s3 only from localhost
CarrierWave.configure do |config|
config.fog_authenticated_url_expiration = 0
end
end
private
def ensure_permited_ip
if request.remote_ip!= "127.0.0.1" # allow access only from localhost
redirect_to root_path
end
end
宝石:
gem 'aws-sdk-rails'
gem 'aws-sdk-s3', '~> 1'
我的经验有限,但我的建议是:
Cost related pit falls to avoid when deploying rails app?
- 如果您要使用后台作业,请使用
rufus-scheduler
而不是sidekiq
或delayed_job
,因为它在您的rails server
之上运行并且不需要额外的内存/额外的专用进程。这允许您获得 smallest/cheapest 可能的实例:t2.nano,我之前做过一次。
Easy cloud hosting services to use?
- Heroku 将是一个不错的选择,因为它很容易设置。但是,如果您这样做是为了体验,我建议您在 3 个月前购买像 AWS EC2 or Linode. I recently migrated my server from AWS to Vpsdime 这样的非托管主机,因为它便宜且内存大;到目前为止一切顺利。
My current concern
- 对于
carrierwave
,您可以限制 S3 访问。参见 reference. This then prevents hotlinking and would then require a user to view your Rails pages first in order to download or view or show the S3 files. Now that Rails now have control over the S3 files, you can just simply use something like Rack::Attack to prevent DDOS or excessive requests. If your Rails app is configured withApache
orNginx
, you can instead set up DDOS rules there instead of usingRack::Attack
. Or, if you are gonna be using AWS load balancer to manage / route the requests, then you can use AWS Shield ... 虽然还没有真正使用过它。