使用平面文件与数据库/ API进行前端和后端之间的传输


20

我有一个应用程序,在几个开发人员之间引起了相当激烈的讨论。

基本上,它分为Web层和后端层。Web层通过一个简单的Web表单收集信息,并将此数据作为JSON文档(字面上是.json文件)存储到后端使用的watch文件夹中。后端每隔几秒钟轮询一次该文件夹,拾取文件并执行其功能。

文件本身非常简单(即所有字符串数据,无嵌套),最大时约为1-2k,系统大部分时间都处于空闲状态(但在任何给定时间突发多达100条消息)。每个邮件的后端处理步骤大约需要10分钟。

当一个开发人员建议使用文件系统作为消息传递层是一个糟糕的解决方案时,这种说法就出现了,而应改为使用诸如关系数据库(MySQL),noSQL数据库(Redis)甚至是普通的REST API调用之类的东西。

应当注意,Redis用于组织中其他地方的队列消息处理。

我听到的论点如下


支持平面文件:

  • 平面文件比任何其他解决方案都更可靠,因为仅在拾取后将文件从“监视”文件夹移至“处理”文件夹,完成后才移至“完成”文件夹。除非存在非常低级的错误,否则消息消失的风险为零,这无论如何都会破坏其他功能。

  • 平面文件需要较少的技术知识来理解-就是cat这样。无需编写查询,也不会意外将消息从队列中弹出并永久消失。

  • 从编程的角度来看,文件管理代码比数据库API更简单,因为它是每种语言的标准库的一部分。这降低了代码库的整体复杂性以及必须引入的第三方代码的数量。

  • YAGNI原则规定,平面文件工作得很好,现在,没有表现出需要更换一个更复杂的解决方案,所以离开它。

支持数据库:

  • 扩展数据库比充满文件的目录更容易

  • 平面文件存在有人将“完成”文件复制回“监视”目录的风险。由于此应用程序(虚拟机管理)的性质,这可能会导致灾难性的数据丢失。

  • 要求T / S应用程序具有更高的技术水平,这意味着未受过教育的员工不太可能仅仅通过戳东西来搞砸。

  • 数据库连接代码,尤其是针对Redis之类的数据库连接代码,至少与标准库文件管理功能一样强大。

  • 从开发人员的角度来看,数据库连接代码明显(如果没有功能)更简单,因为它的级别比文件操作更高。


从我的看到,两个开发人员都有很多有效的观点。

因此,在这两个人中,亲文件开发人员或亲数据库开发人员中,哪一个更符合软件工程最佳实践,为什么?


1
这些文件有多大,需要保留多长时间?
JeffO

1
在最坏的情况下,几个K,几个月(出于日志记录/合规目的)
Mikey TK

2
使用数据库作为消息传递服务难道不是像文件系统一样糟糕吗?在两种情况下,您都使用了不适合的东西。
Pieter B

写入文件需要花费多长时间?如果您不需要将“请求”文件排队,则可以立即通过Rest Api处理它们,而仅将它们写入“完成”文件夹(不移动/轮询文件)。前端将成为一个js应用程序,并且在需要它的那一天,您可以在Api和后端之间放置适当的队列。
巨石

Redis的明确卖点之一是用作@PieterB的队列
Mikey TK

Answers:


16

切换到涉及数据库或Ewan提到的排队系统的解决方案将可以

  • 在后端和前端都对新的复杂系统产生依赖性
  • 引入不必要的复杂性和大量新的故障点
  • 增加成本(包括拥有成本)

在所有当前OS上,确保在单个卷内移动/重命名文件都是原子的,无论它们在文件/记录锁定等方面遇到的困难如何。操作系统级别的权限管理应足以锁定未清洗的对象,并防止授权操作员(管理员/开发人员)进行无意/意外的误操作。因此,只要当前解决方案的性能达到标准,数据库就什么也没有提供。

在我们公司,数十年来,我们已经使用类似的基于文件的界面取得了巨大的成功。许多其他事物来去去去,但由于它们完全简单,可靠且耦合/依赖性最小,所以保留了这些接口。


巨型dittos。并确保您记录文件格式,进行维护并分发。下一步:关于“受过教育的人员……到处乱逛”的OP项目符号;如果这是一个真正的问题,那么你们所有人都会遇到系统性问题。在我们的“孤独的开发人员”文化中,我们所经历的最糟糕的情况是某些无能的编码和集体的无知,因为原始编码者会随着时间的流逝而离开。它启动20年后,我到达了那里,我们遇到了一场维修噩梦。
—radbobo

1
由于基于文件的解决方案正在工作,我同意由于您列出的原因而进行的切换是没有意义的。从一张干净的纸开始,将很难证明使用这些文件的理由。
伊恩

10

我认为这两种解决方案都不是一种坏习惯,因此回答哪种最佳做法可能很困难。

如果您要处理规模问题,我认为YAGNI负责人不适用。“工作”是相对的,如果您极有可能发生灾难性的数据丢失,并且扩展能力很弱,那么我真的不会考虑这种工作。我不确定您要处理的规模如何,但是如果您有大量此类条目,则每个条目都很难切换到新系统。因此,如果是这种情况,我会说数据库是最佳实践。

MongoDB或redis(我没有使用redis的经验,只读过好东西)应该做得很好,因为您的数据应该已经很好地适合了(对于MongoDB,json文件经常被简单地更改为BSON文档)。它还具有一个额外的优势,即可以在内存中保留大量数据,而不是一直潜在地对磁盘进行频繁的读/写操作。它还确保并发读取/写入不会导致损坏或阻塞。

如果YAGNI原则确实在这里适用,并且文件不是瓶颈,它们会在范围内扩展,并且没有灾难性的问题,那么我说坚持使用文件是“最佳实践”。如果没有问题,没有理由更改任何东西,也许编写一些测试,对其进行强调,然后查看您的限制和瓶颈在哪里。

我不确定在这种情况下数据库是否是解决方案。如果您正在同一台服务器上进行通信,则可以执行某种IPC,不是吗?


5

好的'ol保存文件并将其复制到完成的dir是许多通信层的主要内容,尤其是。与较旧的主机系统等。“反”家伙确实有道理;因为它有很多问题和边缘情况。如果您需要100%可靠性,则很难处理,随着文件频率和数量的增加,这种情况会更频繁地发生。

如果您控制事务的双方,我建议您看一下可用的许多简单排队系统中的一些。ZeroMQ,RabbitMQ,MSMQ等,而不是数据库。但是正如您所暗示的那样,如果它还没有破裂……


-3

数据库解决方案是正确的。它解决了对特定主机或边界条件的许多依赖性。

两者都是类似的解决方案,只是数据库未托管在特定主机中。这消除了unix系统的防火墙/访问问题。我们曾在文件系统上发生过“意外”删除的情况,没有人应受责备。

使用database,您也可能遇到相同的问题,但是您可以进行审计或仅插入逻辑来删除删除项。

同样在文件系统中,如果您需要将应用程序放在文件名中,例如OASIS,那么您将需要创建文件OASIS.john_doe.system1.20160202。这变得乏味并且可以在数据库中更容易地表示。您甚至可以基于此在数据库和逻辑中包含空字段

如果您要对表进行任何修补或修复,也很容易更新数据库而不是整个文件目录。当然,您可以在文件系统上执行此操作,但是数据库更新更为直观。

例如,您要重新运行,但使用的系统与OASIS不同,请说DESERT和john_doe为doe_smith,日期为20160101至20151231

易于从原始集中为DESERT / doe_smith / 20151231生成行,而不是使用shell脚本创建这些文件。

因此,从可读性的角度出发,扩展数据库解决方案更好。


1
请解释您的意思...从我的角度来看,数据库解决方案只会创建许多其他依赖项,并引入新的边界条件/故障点。
DarthGizka '16

1
将数据库用作消息传递服务与使用文件一样糟糕。
Pieter B
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.