mysql事件的替代方案(不是Cronjob)

时间:2016-08-11 16:14:46

标签: php mysql sql

在发生特定用户操作后5分钟,我需要更改数据库中的某些数据。直到现在我已经在我的homeserver上进行了编程,并且我已经使用了mysql Events来实现这一目标,这非常有效。但是我现在托管我网站的当前提供商限制了mysql事件的使用。

现在我必须想出一个mysql Events的替代方案。

我考虑过执行一个php脚本,使用exec("php script.php &> /dev/null &")来改变后台的数据,这实际上有效(至少在我的主服务器上),但也受到我的提供商的限制。

现在我真的没有想法,需要你的帮助 - 我怎么能做到这一点?

谢谢!

克里斯托夫

编辑: 在我的情况下,Cronjobs不会这样做,因为我必须在特定用户操作发生时才执行脚本。

2 个答案:

答案 0 :(得分:1)

我会考虑以下内容,因为您在这里标记了PHP

使用aws ec2创建一个帐户,并以Free-Tier开头一年。这将允许您选择创建AMI(亚马逊机器实例)。通常是Linux,但可以是Microsoft变体。调整它并save它。由于授予的资源(内存)有限,Linux是正常的选择。它将是一个小实例Type,免费使用1年。

注意我与AMZN没有任何关系。它可以很容易地来自Azure / Microsoft或Google。但是,自2008年以来我一直使用ec2,一个合理的人会得出结论,他们比竞争对手提前几年。这可能就是为什么Openshift和其他人只是在他们之间进行了抨击和分层。人们应该阅读IaaS与PaaS,了解设置IaaS解决方案存在复杂性。这不是非技术人员应该向他们推荐的东西。

在PaaS方面,我会选择Openshift。对于那些人来说还有很多话要说。

因为想要在虚拟服务器上安装任何东西以及我的代码来监听任何端口和协议的选择,我为IaaS拍摄。

如果有一个ec2或等效的虚拟服务器,则可以利用他们选择的编程语言(在java,c#,python等中运行的agent)来定时调用您的共享主机环境PHP(包括https上的身份验证)以触发共享主机event-like机制。或者,更好的是,让您的mysql实例在ec2或RDS上运行。

应该考虑以上内容的原因包括

  • 在可能稍后使用的平台上切割牙齿
  • 它可以解决您可以使用的衣柜中的旧笔记本电脑的电源故障
  • 您最终可能会登陆云端并希望这些agents执行其他任务
  • 通过离开共享主机,您不会受到cron或事件限制。

对于其他任务,您会发现事件有局限性。其中最大的一个是无法从存储的程序中调用LOAD DATA INFILE。我使用代理商。您的代理可以在o / s启动时启动。

在试用之后,如果仍然在共享主机上并且与更强大的虚拟服务器集成,则最终可以使用微实例。对于代理商全天候在云端运行,指点并做任何事情,我估计它每月12美元,也许更便宜。功能较少的实例类型,但可能。我不能说nano实例类型的力量或缺乏力量。

请注意,代理可以具有嵌入式mysql客户端库(该程序执行使用或导入,并且是一个mysql客户端程序)。在这种情况下,它会直接连接到端口3306.这可能适用于仅支持AWS的解决方案,但将数据库服务器暴露给Internet存在安全风险。如果有疑问,应该查看General Query日志以查看挂载的攻击。最佳实践是保护您的数据库服务器不被隐藏在防火墙后面。这就是为什么像PHP这样的API是高度优先的原因。因此,没有什么能阻止您编写一个100行代理,通过POST通过https向您的共享主机PHP执行经过身份验证的@Configuration @EnableJpaRepositories(entityManagerFactoryRef = "lmEntityManagerFactory", transactionManagerRef = "lmTransactionManager") class LM_Config { @Bean PlatformTransactionManager lmTransactionManager() { return new JpaTransactionManager(lmEntityManagerFactory().getObject()); } @Bean LocalContainerEntityManagerFactoryBean lmEntityManagerFactory() { HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); vendorAdapter.setGenerateDdl(true); LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean(); factoryBean.setDataSource(lmDataSource()); factoryBean.setJpaVendorAdapter(vendorAdapter); factoryBean.setPackagesToScan(LM_Config.class.getPackage().getName()); return factoryBean; } @Bean @Primary @ConfigurationProperties(prefix="spring.datasource") public DataSource lmDataSource() { return DataSourceBuilder.create().build(); } } ,然后从那里获取它。

其他选项包括创建SSH隧道。但我离题了。

答案 1 :(得分:1)

通常,处理这种悬疑文件数据库项目的最佳方法是使用有效时间策略。关于这个策略的最好的事情是:它不依赖于你的事件或cronjobs等的时间准确性。

您没有说明用户操作五分钟后您的数据需要发生什么,所以我不得不猜测。

假设操作是从table_a中删除一行并在table_b中插入一行。在这种情况下,您需要将DATETIMETIMESTAMPeffective_until添加到table_a,将另一列effective_after添加到table_b

当用户操作发生时,您执行类似

的操作
 UPDATE table_a 
    SET effective_until = NOW() + INTERVAL 5 MINUTE
  WHERE id='whatever';

 INSERT INTO table_b  (id, data, effective_after)
               VALUES (whatever, whatelse, NOW() + INTERVAL 5 MINUTE);

然后,稍后,只要您使用 table_a,就说

 SELECT ... FROM table_a WHERE (effective_until <= NOW() OR effective_until IS NULL) ;

当你使用table_b时,你说

 SELECT ... FROM table_a WHERE effective_after > NOW();

每天一次,或者每周一次,或者其他什么,你可以用这样的东西清除table_a中的死亡东西。

  DELETE FROM table_a WHERE effective_until <= NOW();

诀窍是用时间戳标记行,而不是依赖于精确定时的操作。更加强大和可靠。当cronjobs整个周末失败时有弹性。此外,兼容廉价的托管服务和不合作的dbas,这两者都是世界上丰富的。