用Vaadin、YugabyteDB和Heroku构建一个多区的Java应用程序的教程

283 阅读8分钟

如何在几天内用Vaadin、YugabyteDB和Heroku建立一个多区的Java应用

欢迎来到我的日志,它记录了我从头开始用Java构建地理分布式应用的经验。在这里,我将分享我的第一个成果和任何挑战。

啊哈,伙计们!终于到了建立和推出我的地理分布式Java应用程序的第一个版本的时候了。

我花了四天时间(总共约24小时)来创建这个版本。该应用目前运行在Vaadin和Spring上,它可以使用PostgreSQL或YugabyteDB作为数据库,它可以在本地工作,也可以在Heroku中部署。

不知道我在说什么?欢迎来到我的开发日志,在这里我一直在记录我用Java从头开始构建地理分布式应用的经验。

在这篇博客中,我将真正把事情做好,分享我的第一个成果和任何挑战。

所以,如果你和我一起走过这段旅程,那么,就像海盗们常说的那样,"All Hand Hoy!"意思是,"所有人都到甲板上!"

我的应用程序:大图片

你们中的一些人可能已经注意到,我一直在谈论建立一个通用的地理分布式Java应用程序,但我的应用程序要做什么?嗯,我正在建立一个类似Slack的企业信使。

是的,这听起来像是我在重新发明轮子,但也许我心中有一个杀手锏:我的特殊秘方,将颠覆Slack的统治地位!"。

严肃地说,我只是好奇如何设计和建立一个地理分布的企业信使(如Slack),在全球范围内以低延迟运作,容忍云中断,并遵守类似GDPR的要求。因此,我想我将尝试制作我自己的!因此,在我的旅程结束时,我希望能拥有这些。

信使应用实例和数据库节点将分布在世界各地,并在离大多数用户最近的云地区运行。全球负载平衡器将拦截用户流量,并将请求路由到离用户最近的应用实例。

这就是大局--他们说的终点线。然而,我们从婴儿的步骤开始。

我的应用程序:第一天

虽然我对我的地理分布式信使有一个雄心勃勃的目标,但第一个版本将是更温和的。

我敢打赌,在第一天,我的Slack杀手,就像大多数创业公司一样,不会大获成功。事实上,它可能几乎不被注意。如果我在头两个月内每天有100个活跃用户,那么它已经是一个很大的胜利。

因此,如果我期望每天有100个左右的活跃用户,我为什么要把钱烧在跨越全球的基础设施上呢?这没有什么意义。从小处着手,然后再做大,这要谨慎得多。这就是为什么我的应用程序的第一个版本看起来像这样。

我的信使将被部署在美国的一个单一云区域内。它将是一个在Heroku中运行的单片机。将有一个三节点的YugabyteDB集群在三个可用区运行。有了这样的架构,我可以承受分区级的中断,并以低延迟为Blue女士和其他美国用户的请求提供服务。

不幸的是,来自柏林的Green先生和来自悉尼的Red先生的延迟会很高。然而,作为一家初创公司,我可以接受这一点,特别是如果我把大部分的营销资金投入到发展美国的用户群中。

一旦时机成熟,我可以很容易地将我目前的多地区地理分布的应用程序扩展为多地区的应用程序。至少,我希望这将是容易的。时间会告诉我们。

让我带你看看我的信使应用程序的第一个版本的主要组成部分。这里是它的GitHub坐标

Vaadin: 后台和前台

作为一名工程师,我在创建网络应用时总是寻找捷径,尤其是在前端方面。我不能被称为网络开发者,因为网络并不是我每天都在痴迷的东西。

它更像是这样:每两年我就会加入或开始一个网络项目,并学习一些新的东西。我还记得用HTML+CSS在原始的JavaScript中创建我的第一个网络应用。后来,jQuery的推出,让人眼前一亮。后来,我在一些项目中使用GWT,在最后一个项目中,有机会使用Angular

为什么我选择Vaadin做这个项目?嗯,尽管我是个多面手,但Java是我的母语。我在Sun Microsystems和Oracle工作了多年,建立了JVM和JDK,与Java建立了特殊的联系。因此,作为一个对Java了如指掌的人,它总是我的第一选择。

抛开我对Java的个人感情,在连续使用了4天后,我喜欢Vaadin的什么呢?Vaadin是一个全栈框架。你可以用它来构建后端和前端的逻辑。

首先,和其他许多前端框架一样,你使用基本的构建模块如Button,Label,HorizontalLayout 等来创建/设计页面和视图。然后,该框架将你用Java编写的代码翻译成具有漂亮用户界面的JavaScript对应代码。这就是我创造的东西。

对于一个设计和前端技能需要一些工作的人来说,这并不坏,对吗?对吧!?

其次,Vaadin不需要我运行一个单独的后台实例并在那里实现API。相反,我只是创建我的视图(在浏览器中显示),并添加服务器端的逻辑,然后视图要求后端执行。例如,这是Button ,在点击按钮的事件中发送一个消息。

Java

sendMessageButton = new Button("Send");

sendMessageButton.addClickListener(e -> {
	… 
    Profile user = userOptional.get();

  	Message newMessage = new Message();

  	newMessage.setChannelId(currentChannel.getId());
  	newMessage.setCountryCode(currentChannel.getCountryCode());
  	newMessage.setSenderId(user.getId());
  	newMessage.setSenderCountryCode(user.getCountryCode());

  	newMessage.setMessage(newMessageArea.getValue().trim());

  	newMessage = messagingService.addMessage(newMessage);
}

倾听者逻辑在我的自定义UI组件中实现。MessageView。监听器在浏览器端被触发,这很明显。然后Vaadin将该事件发送到后台处理,在后台构建一个新的Message ,并通过调用Spring框架的服务实体messagingService.addMessage(newMessage) ,添加到数据库中。

很好!不需要创建一个单独的REST API层。Vaadin可以为我做这个。

PostgreSQL和YugabyteDB:数据库

我对数据库的选择是由过去的经验和个人偏好驱动的。

PostgreSQL不需要介绍。在过去15年多的时间里,这是我在任何项目中都默认使用的数据库。

YugabyteDB可能仍然是许多人的黑马。这是我最近正在研究的数据库。它是一个建立在PostgreSQL上的分布式SQL数据库。粗略的说,这意味着它是一个可以跨地域工作的分布式PostgreSQL:正是我的地理分布式应用所需要的。

只要YugabyteDB与Postgres兼容,该应用程序就支持这两种数据库。我在开发环境中使用Postgres,并可以通过调整连接设置随时切换到多节点YugabyteDB集群。

想试试吗?没问题,伙计!按照这些步骤:

  1. 在本地启动一个Postgres实例,并按照这些说明创建信使的模式。
  2. 然后使用熟悉的语法启动应用程序。mvn spring-boot:run.
  3. 打开http://localhost:8080,享受这个视图。

第一次启动应用程序需要时间,因为DataGenerator生成了数以百计的Workspaces ,而Channels ,有数以千计的Messages 。但之后,启动时间就会很快。

接下来,如果你想在开发环境中也使用YugabyteDB,只要:

  1. 在本地启动YugabyteDB
  2. application-dev.properties文件中调整连接设置。
  3. 启动应用程序!享受吧!

Heroku和YugabyteDB管理:部署到Prod

对我来说,部署到Prod是最简单的部分。我是一个懒人,只要有可能(或合理)就会使用云服务。我的地理信使也不例外。

正如你所记得的,该应用的第一个版本应该在一个单一的云区域内工作,数据库节点至少在三个可用区。区域经常失败,我需要为此做好准备。那么我都做了些什么呢?

首先,我在South Carolina (us-east1) 地区部署了一个多节点的YugabyteDB托管集群,节点位于三个可用区--us-east1-b 、us-east1-c 和us-east1-d 。为了以防万一,每个节点都处理读和写,没有所谓的 "活动和备用 "节点。

接下来,在创建了一个Heroku项目后,我在美国的某个地方部署了我的Java应用。

目前,Heroku对于我的应用程序被分配到哪个云区并不透明。我只能希望应用实例的运行距离我的YugabyteDB集群足够近,而且Heroku会在云中断的情况下照顾到应用的可用性。我可能需要在这里深入了解Heroku的内部情况。如果你比我更了解Heroku,请在评论中分享你的想法。

在地平线上有什么?

我的地理分布式信使的第一个版本的开发是一个迅速而有趣的经历。在短短四天的编码过程中,能让一个多区的应用程序运作起来,这很好。

接下来我们有什么打算?

prod的性能很糟糕。当我改变一个频道时,需要3-6秒来加载信息。这不能怪Heroku或YugabyteDB,因为我的编码速度太快了,而且使用Spring Data的方式也不是很理想。

接下来让我解决性能问题,然后在多个地区扩展该应用程序。在我做到这一点之前,你可以在Heroku中部署当前版本的应用程序,看看它有多 "快"。