在JVM流程中模拟Amazon Web服务。 避免Roskomnadzor并加快开发和测试

为什么您需要模仿Amazon Web服务基础架构?

首先,它可以节省-节省开发和调试时间,而同样重要的是-从项目预算中节省资金。 显然,该仿真器与我们尝试仿真的原始环境不会100%相同。 但是,为了加快过程的开发和自动化,现有的相似之处就足够了。 AWS在2018年发生的最热门的事情是IP供应商阻止了俄罗斯联邦AWS子网的IP地址。 这些锁影响了我们位于亚马逊云中的基础架构。 如果您计划使用AWS技术并将项目放置在此云中,那么对于开发和测试仿真而言,回报不菲。



在出版物中,我将告诉您多年来将现有数据仓库迁移到AWS时,我们如何通过S3,SQS,RDS PostgreSQL和Redshift服务成功实现这一技巧。

这只是我去年在地图召开会议的一部分,该会议与AWS和Java集线器的主题相对应。 第二部分涉及PostgreSQL,Redshift和专栏数据库,其文本版本可以在相应的中心发布,视频和幻灯片位于会议网站上

在阻止AWS子网期间为AWS开发应用程序时,团队实际上在开发新功能的日常过程中没有注意到它们。 测试也有效,您可以调试应用程序。 而且只有在尝试查看登录项中的应用程序日志时,SignalFX中的指标或Redshift / PostgreSQL RDS中的数据分析才令人失望-该服务无法通过俄罗斯提供商的网络获得。 AWS仿真帮助我们忽略了这一点,并避免了通过VPN网络使用Amazon云时出现更大的延迟。

每个“幕后”的云提供商都有很多龙,您不应该屈服于广告。 您需要了解为什么服务提供商需要所有这些。 当然,亚马逊,微软和谷歌的现有基础设施具有优势。 当他们告诉您一切都为了方便您进行开发而做时,他们很可能会尝试将您放在针头上并免费提供第一剂。 这样,以后他们就不会脱离基础架构和特定技术。 因此,我们将尝试避免供应商锁定。 显然,并非总是可能完全从特定决策中抽象出来,我认为在很多情况下,有可能抽象出90%的项目。 但是,该项目的其余10%与非常重要的技术提供商相关,要么是优化应用程序性能,要么是其独特功能无处不在。 他们应该永远记住技术的优缺点,并尽可能地保护自己,而不是“坐下来”云基础设施提供商的特定API。

亚马逊在其网站上撰写有关消息处理的信息。 尽管存在细微差别-消息通过队列或主题传递,但消息交换技术的本质和抽象在各处都相同。 因此,AWS建议使用由他们提供和管理的Apache ActiveMQ从现有消息传递代理迁移应用程序,并迁移新的Amazon SQS / SNS应用程序。 这是绑定到自己的API的示例,而不是标准JMS API和协议AMQP,MMQT,STOMP的绑定。 很明显,此提供程序及其解决方案可能具有更高的性能,支持可伸缩性等。 从我的角度来看,如果您使用它们的库而不是标准化的API,那么将会有更多的问题。

AWS具有Redshift数据库。 它是具有大规模并行体系结构的分布式数据库。 您可以将大量数据上载到Amazon中多个Redshft站点上的表中,并对大型数据集执行分析查询。 这不是OLTP系统,对于您来说,对具有ACID保证的足够多的少量记录执行少量请求非常重要。 使用Redshift时,假定您每单位时间没有大量查询,但是它们可以读取大量数据上的聚合。 该系统由供应商定位,可以在AWS上升级您的数据仓库(仓库)并保证简单的数据加载。 这根本不是真的。

文档摘录中有关Amazon Redshift 支持哪些类型的信息 。 这是一个相当微不足道的设置,如果您需要某种东西来存储和处理此处未列出的数据,那么工作将很困难。 例如GUID。

大厅里的问题是“还有JSON?”

-JSON只能写为VARCHAR,并且有几个使用JSON的函数。
观众评论:“ Postgres具有常规的JSON支持。”

-是的,它支持这种类型的数据和功能。 但是Redshift基于 PostgreSQL 8.0.2。 有一个ParAccel项目,如果我没记错的话,这项2005年的技术是postgres的一个分支,它具有基于大规模并行体系结构的分布式请求调度程序。 5至6年过去了,该项目获得了Amazon Web Servces平台的许可,并命名为Redshift。 已从原始Postgres中删除了某些内容,并添加了很多内容。 他们补充说,与AWS中的身份验证/授权有关,具有角色,Amazon中的安全性很好。 但是,例如,如果您需要使用外部数据源从Redshift连接到另一个数据库,则不会找到此数据库。 没有使用XML的功能,没有使用JSON两次且计算错误的功能。

在开发应用程序时,请尽量不要依赖于特定的实现,并且应用程序代码仅取决于抽象。 您可以自己创建这些外观和抽象,但是在这种情况下,有许多现成的库-外观。 它从特定的实现,特定的框架中提取代码,很明显,它们可能不支持所有功能作为技术的“通用标准”。 最好依靠抽象来开发软件以简化测试。

为了模拟AWS,我将提到两个选项。 第一个是更诚实和正确的,但是它的运行速度较慢。 第二个又脏又快。 我会告诉您有关hack选项的信息-我们正尝试在一个过程中创建整个基础架构-测试和跨平台选项将在Windows中工作得更快(Docker并不总是能够从您那里赚钱)。

如果您是在linux / macos上开发并且拥有docker ,则第一种方法是完美的,最好使用atlassian localstack 。 使用测试容器将localstack集成到JVM中很方便。

我无法在该项目的docker中使用lockalstack的原因是,开发是在Windows下进行的,并且在该项目启动时没有人担保docker的alpha版本...还有可能不允许他们在任何认真对待Linux和docker的公司中安装虚拟机。信息安全。 我不是在谈论在投资银行的安全环境中工作,也不是在那儿禁止几乎所有的流量防火墙。

让我们考虑如何模拟简单存储S3的选项。 这不是普通的Amazon文件系统,而是分布式对象存储。 在其中将数据作为BLOB放置,而没有修改和添加数据的可能性。 也有其他制造商提供的类似的成熟分布式存储。 例如,使用Ceph分布式对象存储,您可以使用S3 REST协议和现有客户端使用其功能,而只需进行很少的修改即可。 但这是用于Java应用程序开发和测试的相当重量级的解决方案。

更快更适合的项目是s3proxy Java库。 它模拟了S3 REST协议,并将其转换为相应的jcloud API调用,并允许您使用许多实现来真正读取和存储数据。 它可以广播对Google App Engine API,Microsoft Azure API的调用,但是对于测试而言,在RAM中使用jcloud临时存储更为方便。 还需要配置身份验证协议AWS S3的版本并指定密钥和机密值,还需要配置终结点-该S3代理将在其上侦听的端口和接口。 因此,使用AWS开发工具包客户端的代码应在测试中连接到S3 AWS终端节点,而不是AWS区域。 再次提醒您,s3proxy不支持S3 API的所有功能,但是我们所有的使用场景都可以完美模拟! s3proxy甚至支持大文件的分段上传。



Amazon Simple Queue Service是一种排队服务。 有一个用scala编写的elasticmq队列服务 ,可以使用Amazon SQS协议将其提供给您的应用程序。 我没有在项目中使用它,因此我将给出初始化代码,并信任来自其开发人员的信息。



在项目中,我采用了另一种方式,代码依赖于JmsTemplate和JmsListener的spring-jms抽象,并且项目依赖项为SQS com.amazonaws指定了JMS驱动程序:amazon-sqs-java-messaging-lib。 这是与主要应用程序代码有关的内容。



在测试中,我们将Artemis-jms-server连接为嵌入式JMS服务器以进行测试,在测试Spring上下文中,我们使用Artemis连接工厂代替SQS连接工厂。 Artemis是Apache ActiveMQ的下一个版本,Apache ActiveMQ是一种成熟的,现代的面向消息的中间件-不仅仅是一个测试解决方案。 也许我们将来会继续使用它,而不仅仅是在自动测试中。 因此,将JMS抽象与Spring结合使用,我们简化了应用程序代码并简化了对其进行测试的能力。 您只需要添加依赖项org.springframework.boot:spring-boot-starter-artemis和org.apache.activemq:artemis-jms-server。



在某些测试中,可以通过将H2Database替换为PostgreSQL来模拟PostgreSQL。 如果测试不被接受并且不使用特定的PG功能,这将起作用。 同时,H2可以模拟PostgreSQL有线协议的子集,而无需支持数据类型和功能。 在我们的项目中,我们使用Foreing Data Wrapper,因此此方法不适用于我们。

您可以运行真正的PostgreSQL。 嵌入postgresql的程序会下载实际发行版,或者将二进制文件归档到运行我们的平台的实际发行版中。 在RAM中tempfs上的linux中,在%TEMP%中的Windows中,postgresql服务器进程启动,配置服务器设置和数据库参数。 由于发行发行功能,PG 11之前的版本在Linux下不起作用。 我自己做了一个包装器库 ,它使您不仅可以从HTTP服务器而且可以从maven存储库中获取PostgreSQL二进制程序集。 当在隔离的网络中工作并且在没有Internet访问的CI服务器上构建时,这非常有用。 使用包装程序的另一个便利是CDI组件的注释,例如,它使在Spring上下文中轻松使用该组件成为可能。 AutoClosable服务器接口的实现早于原始项目出现。 无需记住停止服务器,它会在Spring上下文自动关闭时停止。

在启动时,您可以基于脚本创建数据库,并用适当的属性补充Spring上下文。 现在,我们正在使用flyway脚本来创建数据库架构,以迁移数据库架构,每次在测试中创建数据库时都会启动数据库架构。

为了在运行测试后验证数据,我们使用spring-test-dbunit库。 在测试方法的注释中,我们指出了与哪些上载进行比较的数据库状态。 这消除了编写与dbunit一起使用的代码的需要,只需要将库侦听器添加到测试代码即可。 如果在测试之间重用数据库上下文,则可以指定在测试方法完成后从表中删除数据的顺序。 在2019年,在数据库骑行中实现了与junit5一起使用的更现代的方法。 您可以在此处查看使用示例。

最难的事情是模仿Amazon Redshift。 有一个redshift-fake-driver项目,该项目专注于模拟从AWS加载到分析数据库中的批处理数据。 在jdbc:postgresqlredshift协议仿真器中,实现了COPY,UNLOAD命令,其他所有命令则委托给常规的JDBC PostgreSQL驱动程序。

因此,测试的工作方式与Redshift的更新操作不同,后者使用另一个表作为数据源进行更新(Redshift和PostgreSQL 9+中的语法不同。我还注意到这些数据库之间SQL命令中对行引号的解释不同。

由于实际的Redshift数据库的体系结构,因此在I / O方面,插入,更新和删除数据的操作相当缓慢且“昂贵”。 仅在大型“数据包”中插入性能可接受的数据是可能的,而COPY命令仅允许您从分布式S3文件系统下载数据。 数据库中的此命令支持多种数据格式AVRO,CSV,JSON,Parquet,ORC和TXT。 模拟器项目的重点是CSV,TXT,JSON。

因此,要在测试中模拟Redshift,您将需要如前所述启动PostgreSQL数据库并模拟S3存储库,并且在创建与postgres的连接时,只需在类路径中添加redshift-fake-driver并指定驱动程序类jp.ne.opt.redshiftfake.postgres。 FakePostgresqlDriver。 之后,您可以使用相同的运行方式来迁移数据库模式,并且dbunit在运行测试后已经很熟悉比较数据。



我想知道有多少读者在他们的工作中使用AWS和Redshift? 在评论中写下您的经历。

仅使用开放源代码项目,团队就可以加速AWS环境中的开发,从项目预算中节省资金,并且在Roskomnadzor阻止AWS子网时不会阻止团队工作。

Source: https://habr.com/ru/post/zh-CN444472/


All Articles