symfony 水平扩展和cron作业

cbjzeqam  于 2023-02-19  发布在  其他
关注(0)|答案(2)|浏览(107)

我最近被迫将我的应用程序转移到亚马逊并使用自动缩放,我偶然发现了cron作业和自动缩放的问题。
我有一个每15分钟运行一次的cron作业,它检查订阅是否应该收费,查询选择所有过期的订阅,并尝试收费。它在处理后更改订阅的状态,但它们是成批获取的,这个过程需要1-3分钟。
如果我有多个示例使用同一个cron作业,它可能会同时启动并多次收取订阅费,这种情况实际上已经发生过一次。
这里最好的方法是什么?以某种方式锁定表?
我正在使用亚马逊弹性豆茎和symfony 3。

qhhrdooz

qhhrdooz1#

至少你可以使用专用的微示例来进行订阅收费(当然不是自动缩放的),只是使用cron作业。最简单但最安全的方法(显然,如果你将订阅处理逻辑从前端服务器(可能会被黑客攻击)移动到VPC子网后面的服务器(无法从全球网络获得),这将是安全的)。
但是如果你不想,你仍然可以使用另一种方法。你提到你使用BeanstalkBeanstalk允许使用延迟的作业。
因此,可能的方法是:
1)当您创建订阅时,您可以计算它应该何时收费,然后将计算延迟的作业推送到Beanstalk tube。
2)然后,worker将按时获得该作业(订阅)。只有一个worker将获得该特定作业,因此如果使用自动缩放,它将工作。
3)在worker中,你可以检查订阅(可能是被删除或不活动等),如果它准备收费,只需运行收费代码。然后计算下一次收费时间,并将新的延迟作业(与订阅)推送到队列。
Beanstalk具有Symfony bundlepowerful PHP library

rkkpypqq

rkkpypqq2#

您可以使您的作业仅为一个示例运行,即使您的功能-收费订阅仅为一个示例运行。您可以使用AWS API获取所有示例,然后将这些示例与当前正在运行的示例进行匹配。

ec2 = Aws::EC2::Resource.new(region: 'region',
    credentials: Aws::Credentials.new(IAM_KEY', 'IAM_SECRET')
)

metadata_endpoint = 'http://169.254.169.254/latest/meta-data/'
current_server_id = Net::HTTP.get( URI.parse( metadata_endpoint + 'instance-id' ) )

instances = []
ec2.instances.each do |i|
    if (i.state.name == 'running')
       instances << i.id
    end
end

if (instances.first == current_server_id )
{
  your functionality
}

相关问题