java基于数组构建二叉树_如何构建基于Java的云应用程序

java基于数组构建二叉树

java基于数组构建二叉树_如何构建基于Java的云应用程序 最近,我们受命开发用于大数据分析的SAAS应用程序。 要进行数据挖掘,系统需要在数据库中存储数十亿个公共职位,并对其进行分类处理。

在我们的上下文中,分类是一个缓慢的,占用大量资源且痛苦的过程,用于将主题或情感分配给数据库中的任何记录。 根据我们的测试数据,该过程最多可以持续24小时。

为了满足这些要求,我们显而易见的选择是在Amazon Web Services上构建云应用程序。 在进行了一段时间的项目后,我想分享自己的想法,理解和构建基于Java的云应用程序的方法。

什么是云计算

让我们先从*开始:

云计算涉及通过网络进行的分布式计算,其中程序或应用程序可以同时在许多连接的计算机上运行

该定义可能有点含糊,但可以理解,因为In The Cloud本身更多是营销术语,而不是技术术语。 对于新手来说,如果我们以更实用的方式定义它,就更容易理解:

传统Web应用程序与云Web应用程序之间的唯一区别是完美扩展的能力。 给定无限制的硬件,云应用程序应该能够应付无数的工作。

由于对现代应用程序的更高要求,如今云应用程序变得越来越流行。 过去,Google以构建包含互联网上几乎所有可用信息的大规模应用程序而闻名。 但是,目前,许多其他公司都需要构建服务于相似规模的数据和计算的应用程序(Facebook,Youtube,LinkedIn,Twitter等,以及像我们一样抓取和处理其数据的人员)。

使用开发应用程序的传统方法无法实现如此大量的数据和处理。 这导致我们采用一种完全不同的方法来构建可以很好扩展的应用程序。 这是云应用程序。

为什么开发Web应用程序的传统方法无法很好地扩展

开发Web应用程序的传统方法

让我们看一下为什么传统的应用程序不能服务于如此大规模的数据。

java基于数组构建二叉树_如何构建基于Java的云应用程序

如果您开发了一个传统的Web应用程序,则它应该与上图非常相似。 应用程序服务器和Web服务器或多个企业服务器的合并还有一些其他小的变化。 但是,大多数情况下,数据库是关系型的。 Web服务器通常是有状态的,而企业服务器可以同时提供无状态和有状态服务。

存在一些严重的弱点,导致该架构师的伸缩性不够好。 让我们首先定义完美的可伸缩性开始我们的分析。

如果在带宽和硬件数量加倍的情况下,系统始终能够为两倍的工作量提供相同的响应时间,则可以实现完美的可伸缩性。

在现实生活中无法实现完美的可伸缩性。 而是,开发人员仅旨在实现近乎完美的可伸缩性。 例如,DNS服务器不在我们的控制范围内。 因此,从理论上讲,我们不能提供比DNS服务器更多的请求数量。 这是任何系统(甚至Google)的上限。

SQL

回到上图,最大的弱点是数据库的可伸缩性。 当请求量和数据大小足够小时,开发人员在增加负载时不应注意到任何性能影响。 如果CPU已被100%占用或内存被完全占用,则继续增加更高的负载,影响会非常明显。 此时,最现实的选择是将更多的内存和CPU注入数据库系统。 此后,系统可能会再次运行良好。

不幸的是,一旦出现问题,这种方法就不可能永远重复。 无论您拥有多少内存和CPU,性能都会逐渐变差,这是一个极限。 这是可以预期的,因为您将需要通过许多请求来创建,读取,更新,删除(CRUD)某些记录。 不管您选择缓存它们,将它们存储在内存中还是进行任何技巧,它们都是唯一的记录,它们保存在单个计算机中,并且可以发送到单个内存地址的访问请求数量受到限制。

这是不可避免的限制,因为SQL是为完整性而构建的。 为了确保完整性,SQL Server中的任何信息都必须是唯一的。 即使在完成数据分离或复制之后(至少对于主实例而言),该特性仍然适用。

相反,NoSQL不会尝试规范化数据。 而是选择存储可能包含重复信息的聚合对象。 因此,仅当数据完整性不是强制性的时,NoSQL才适用。

java基于数组构建二叉树_如何构建基于Java的云应用程序

上面的示例(来自couchbase.com )显示了如何将数据存储在文档数据库与关系数据库中。 如果一个家族包含许多成员,则关系数据库仅为所有成员存储一个地址,而NoSQL数据库仅复制住房地址。 当一个家庭搬迁时,所有成员的住所地址可能不会在一次交易中更新,这会导致数据完整性受到侵犯。

但是,对于我们的应用程序和许多其他应用程序,此临时违规是可以接受的。 例如,您可能不需要社交页面上的页面浏览量或社交网站上的公共帖子数量就可以100%准确。

数据复制有效地消除了我们上面提到的对单个内存地址的并发访问,并为开发人员提供了将数据存储在所需位置的选项,只要一个节点中的更改可以缓慢地同步到其他节点即可。 该架构师具有更大的可伸缩性。

有状态的

下一个问题是状态服务。 有状态服务需要使用同一组硬件来服务来自同一客户端的请求。 当客户端数量增加时,最好的办法是将更多应用程序服务器和Web服务器部署到系统中。 但是,使用状态服务无法完全优化资源分配。

对于传统应用程序,负载均衡器没有任何系统负载信息,并且通常使用Round Robin技术将请求分发到不同的服务器。 这里的问题不是所有请求都相等,也不是所有客户端都发送相同数量的请求。 这会导致某些服务器严重过载,而另一些服务器仍处于空闲状态。

混合数据检索和处理

对于传统应用程序,从数据库检索数据的服务器最终将对其进行处理。 没有明确区分处理数据和检索数据。 两项任务都可能导致系统瓶颈。 如果瓶颈来自数据检索,则数据处理未得到充分利用,反之亦然。

重新考虑构建可扩展应用程序的最佳方法

看看最近我们的IT领域采用了什么,我几乎没有发现它们是新发明。 相反,它们是在现实生活中成功使用的解决可伸缩性问题的方法。 为了说明这一点,让我们想象一下解决可伸缩性问题的实际情况。

医院

java基于数组构建二叉树_如何构建基于Java的云应用程序

假设我们有一家小型医院。 对于我们的医院,我们主要为忠实的客户提供服务。 每个忠实的客户都有一位私人医生,他/她会追踪他/她的病历。 因此,客户只需要出示要由首选医生提供服务的IC。

为了使事情更具挑战性,我们的医院在互联网时代之前就开始运作了。

无状态与有状态

上面的描述看起来足够类似于有状态服务吗? 现在,您的医院名声大振,客户数量突然激增。 如果您有足够的基础架构,那么显而易见的选择是雇用更多的医生和护士。 但是,客户不愿意尝试新医生。 这导致新员工可以*工作,而旧员工则很忙。

为了确保优化,您选择更改医院政策,以便客户必须保留他们的病历,医院会将其分配给任何可用的医生。 这种新做法有助于解决您的所有头痛问题,并使您可以选择部署更多的季节性人员来应对突然增加的客户。

好的,此策略可能不会使客户满意,但是对于IT领域,无状态和有状态服务会提供相同的结果。

资料复制

假设客户数量不断增加,您开始考虑开设更多分支机构。 同时,出现了一个新的日益严重的问题,即客户在就诊时不断抱怨需要携带病历。

为了解决此问题,您返回了将病历存储在医院的原始策略。 但是,由于您有多个分支机构,因此每个分支机构都需要存储一份用户病历副本。 在一天或一周的结尾,任何记录更改都需要同步到每个分支。

服务分离

在运行了几个月的医院后,您认识到资源分配不是非常优化。 例如,您在分支机构A和B中都有血液检查和X射线工作人员。但是,有很多客户在分支机构A中进行血液检查,并且很多人在分支机构B中进行X射线检查。

这导致客户在一个分支机构中不断等待,而没有人访问另一个分支机构。 为了优化资源,您可以关闭未充分利用的系,并设置唯一的血液测试中心和X射线中心。 客户将从分支机构发送到专门的中心以提供特殊服务。

临时资源

医院很难进行资源规划。 有些季节性疾病仅在一年的特定时间发生。 而且,灾难随时可能发生。 它们会在短期内导致病房患者突然增多。 为解决此问题,您可能需要与市议会签署协议,在需要时临时租用设施并雇用更多的兼职人员。

应用这些想法来构建云应用程序

现在,在看完上面的示例后,您可能会觉得大多数想法都有意义。 开发人员开始将这些想法应用于构建Web应用程序仅需短短时间。

然后,我们进入了云应用时代。

如何构建云应用

要构建云应用程序,我们需要找到将提到的想法应用到我们的应用程序中的方法。 这是我的建议方法

基础设施

如果您开始考虑构建云应用程序,则首先要考虑基础架构。 如果您的平台不支持临时资源(动态爆发现有服务器规范或产生新实例),则很难构建云应用程序。

目前,我们选择AWS是因为它是市场上最成熟的平台。 一年前,由于一些主要优势,我们已经从内部托管迁移到AWS托管:

  • 多个位置 :我们的客户来自五大洲,使用Amazon Region,我们可以将实例部署在离客户位置最近的位置,从而缩短响应时间。
  • 监控和自动扩展 :亚马逊为其平台提供了相当不错的监控服务。 由于服务器负载,可以执行Auto Scaling。
  • 内容交付网络 :Amazon CloudFront为我们提供了从主要部署中卸载静态内容的选项, 这将缩短页面加载时间 与普通实例类似,可以从最近的实例向客户提供静态内容。
  • 同步和分布式缓存 :多年来, MemCache一直是我们首选的缓存解决方案。 但是,一个主要问题是缺乏对节点之间同步的支持。 Amazon Elastic Cache使我们可以选择使用MemCache,而不必担心节点同步。
  • 管理API :这是一大优势。 最近,我们开始使用Management API短暂生成实例以运行集成测试。

数据库

如果您已经选择了开发云应用程序的平台,那么下一步应该是为系统选择正确的数据库。 您需要做出的第一个决定是选择SQL还是NoSQL是您系统的正确选择。 如果系统不是数据密集型系统,则SQL应该很好,如果相反,则应考虑使用NoSQL。

有时,多个数据库可以一起使用。 例如,如果我们要实现Facebook之类的社交网络应用程序,则可以在SQL数据库中存储系统设置甚至用户配置文件。 相反,由于大量数据,用户帖子必须存储在NoSQL数据库中。 此外,由于强大的搜索功能,我们可以选择SOLR来存储公共帖子,而选择Mongo DB来存储用户活动。

如果可能,请选择支持群集,数据隔离和负载平衡的数据库系统。 如果没有,您可能最终自己实现所有这些功能。 例如,与Lucene相比,SOLR应该是更好的选择,除非我们要进行自己的数据隔离。

计算密集型或数据密集型

如果我们知道系统是数据密集型或计算密集型,那就更好了。 例如,Facebook之类的社交网络需要大量数据,而我们的大数据分析既需要数据,也需要计算。

对于数据密集型系统,我们可以让云中的任何节点检索数据并进行处理。 对于计算密集型节点,最好将数据检索和数据处理分开。

java基于数组构建二叉树_如何构建基于Java的云应用程序

数据密集型系统通常提供实时数据,而计算密集型系统则运行后台作业来处理数据。 在同一环境中混合这两项繁重的任务可能最终会降低系统效率。

对于计算云,最好有一个框架来监视负载,分配任务并在计算过程结束时收集结果。 如果您不需要实时处理,则Hadoop是市场上的最佳选择。 如果需要实时计算,请考虑使用Apache Storm

云应用程序的设计模式

要构建成功的云应用程序,我们应牢记以下几点:

  1. 无状态
  2. 必须使所有服务和服务器无状态。 如果服务需要用户数据,请将其作为参数包含在API中。 值得注意的是,要在Web Server上实现无状态会话,我们可以考虑以下几种选择:

  • 基于Cookie的会话
  • 分布式缓存会话
  • 数据库会话

上面的解决方案从上到下排序,具有较低的可伸缩性但更易于管理。

  • 幂等
  • 对于Cloud Application,大多数API调用将通过网络而不是内部方法调用发生。 因此,最好使方法调用安全。 如果您坚持上述无状态原则,则您实现的服务可能已经幂等。

  • 远程门面
  • 远程立面与立面模式不同。 它们在实践上看起来相似,但旨在解决不同的问题。 由于大多数API调用都是通过网络进行的,因此网络延迟在响应时间中占很大的比例。 使用Remote Facade模式,开发人员应该构建一个粗粒度的API,以便减少调用数量。

    用外行的话来说,最好是一次去超市买十件东西,而不是去十次,每次买一件。

  • 数据访问对象
  • 由于您可能会传输数据,因此请注意传输的数据量。 最好仅提供所需的最少数据。

  • 安全玩耍
  • 这不是设计模式,但您要感谢自己以后的安全使用。 由于分布式计算的性质,当出现问题时,很难找出哪一部分是错误的。 如果可能,请对系统中的每个组件实施运行状况检查,ping,彻底记录和调试模式。

    结论

    我希望这种构建云应用程序的方法可以为每个人带来一些好处。 如果您有其他意见或经验,请反馈并与我们分享。

    在下一篇文章中,我将分享我们的社会监控工具的设计。

    翻译自: https://www.javacodegeeks.com/2014/05/how-to-build-java-based-cloud-application.html

    java基于数组构建二叉树