DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Related

  • 5 Simple Tips to Keep Dockerized Apps Secure
  • Realistic Test Data Generation for Java Apps
  • Beginners Guide for Web Scraping Using Selenium
  • Visually Designing Views for Java Web Apps

Trending

  • Why Database Migrations Take Months and How to Speed Them Up
  • Beyond Simple Responses: Building Truly Conversational LLM Chatbots
  • MySQL to PostgreSQL Database Migration: A Practical Case Study
  • Securing the Future: Best Practices for Privacy and Data Governance in LLMOps
  1. DZone
  2. Coding
  3. Java
  4. How To Build a Multi-Zone Java App in Days With Vaadin, YugabyteDB, and Heroku

How To Build a Multi-Zone Java App in Days With Vaadin, YugabyteDB, and Heroku

Welcome to my journal documenting my experience building a geo-distributed app in Java from scratch. Here, I’ll share my first results and any challenges.

By 
Denis Magda user avatar
Denis Magda
DZone Core CORE ·
Aug. 15, 22 · Tutorial
Likes (8)
Comment
Save
Tweet
Share
6.8K Views

Join the DZone community and get the full member experience.

Join For Free

Ahoy, matey! At last, the time has come to build and launch the first version of my geo-distributed Java application. 

It took me four days (around 24 hours in total) to create this version. The app currently runs on Vaadin and Spring, it can use PostgreSQL or YugabyteDB as a database, and it either works locally or can be deployed in Heroku. 

Don’t have a clue of what I'm talking about? Welcome to my dev journal where I’ve been documenting my experience of building a geo-distributed app in Java from scratch. In my two previous articles, I talked about geo-distributed apps and what their architecture looks like. If you’re interested in how my dev journey began, then check the first articles from the series:

  • Geo What? A Quick Introduction to Geo-Distributed Apps
  • What Makes the Architecture of Geo-Distributed Apps Different?

In this blog, I’ll actually get things done, sharing my first results and any challenges.

So if you’re with me on this journey, then, as the pirates used to say, “All Hand Hoy!” which means, “Everyone on deck!”

My App: The Big Picture

Some of you might have noticed that I keep talking about building a generic geo-distributed Java app, but what is my app gonna do? Well, I’m building a Slack-like corporate messenger. 

Yep, it may sound like I’m reinventing the wheel, but perhaps I have a killer feature in mind: my special secret sauce that will overturn the dominance of Slack!

On a serious note, I’m just curious about how to design and build a geo-distributed corporate messenger (like Slack) that functions with low latency across the globe, tolerates cloud outages, and honors GDPR-like requirements. So I thought I would try to make my own! Thus, at the end of my journey, I’m expecting to have this:

Goal for finished product of my geo-distributed app

The messenger application instances and database nodes will be spread worldwide and run in the cloud regions closest to most users. The global load balancer will intercept user traffic and route requests to the application instances closest to the user.

That’s the big picture - the finish line, so they say. However, we start with baby steps.

My App: Day 1

While I have an ambitious goal for my geo-distributed messenger, the first version will be much more modest. 

I bet that on day 1, my Slack-killer, like most startup companies out there, will not be a big success. In fact, it might be barely noticed. If I get 100 active users daily within the first two months, then it’s already a big win.

So if I expect to have around 100 active users daily, why should I burn the money on infrastructure that spans the globe? It makes little sense. It’s far more prudent to start small and then grow big. That’s why the first version of my app looks like this:

First version of my geo-distributed app

My messenger will be deployed within a single cloud region in the US. It’s going to be a monolith running in Heroku. There will be a three-node YugabyteDB cluster running across three availability zones. With such architecture, I can withstand zone-level outages and serve the user requests of Ms. Blue and other US-based users at low latency.

Unfortunately, the latency for Mr. Green from Berlin and Mr. Red from Sydney will be high. However, as a startup, I can live with that, especially if I put most of my marketing dollars into growing the US-based user base. 

Once the time comes, I can easily scale my current multi-zone geo-distributed app to a multi-region one. At least, I hope that it’s going to be easy. Time will tell.

Let me walk you through the main components of the first version of my messenger application. Here are its GitHub coordinates.

Vaadin: Backend and Frontend

As an engineer, I always look for shortcuts when creating web applications, especially on the frontend side. I can’t be called a web developer, because the Web is not what I’m nerding on daily. 

It’s more like this: every two years I join or start a web project and learn something new. I still remember creating my first web app in raw JavaScript with HTML+CSS. Then, jQuery was launched and was a big thing. Later, I used GWT for a few projects and during the last project got a chance to work on Angular.  

Why did I pick Vaadin for this project? Well, even though I’m a polyglot, Java is my mother tongue. I built a special bond with Java after spending many years at Sun Microsystems and Oracle building JVM and JDK. Thus, as a guy who knows Java inside out, it’s always my first choice.

Putting my personal attachment to Java aside, what do I like about Vaadin after using it for 4 days in a row? Vaadin is a full-stack framework. You can use it to build both the backend and frontend logic.

Firstly, as with many other frontend frameworks, you create/design pages and views using essential building blocks like Button, Label, HorizontalLayout, etc. Then the framework translates your code, written in Java, to the JavaScript counterpart with a nice-looking UI. This is what I created: 

Geo-distributed messenger UI

Not bad for a guy whose design and front-end skills require some work, right? Right?!

Secondly, Vaadin doesn’t require me to run a separate backend instance and implement APIs there. Instead, I just create my views (displayed in the browser) and add the server-side logic that the views then ask the backend to execute. For instance, this is the Button that sends a message on a button-click event:

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);
}


The listener logic is implemented in my custom UI component: MessageView. The listener gets triggered in the browser end, it’s obvious. Then Vaadin sends this event for processing to the backend side where a new Message is constructed and added to the database via the call to a Spring Framework’s Service entity messagingService.addMessage(newMessage). 

Nice! No need to create a separate REST API layer. Vaadin can do this for me.

PostgreSQL and YugabyteDB: Database

My database choice was driven by past experience and personal preferences.

PostgreSQL needs no introduction. This is my default go-to database for any project for the last 15+ years.

YugabyteDB might still be a dark horse for many. That’s the database I’m nerding on these days. It’s a distributed SQL database built on PostgreSQL. Roughly speaking, that means it’s a distributed PostgreSQL that can work across geographies: exactly what I need for my geo-distributed app.

As long as YugabyteDB is Postgres-compliant, the app supports both databases out of the box. I use Postgres for my development environment and can always switch to a multi-node YugabyteDB cluster by tweaking the connectivity settings. 

Wanna try? No problem, matey! Follow these steps:

  1. Launch a Postgres instance locally and create the messenger’s schema following these instructions.
  2. Then start the app using a familiar syntax: mvn spring-boot:run.
  3. Open http://localhost:8080 and enjoy this view.

Log-in screen for geo-distributed-messenger

It takes time to start the app for the first time as the DataGenerator generates hundreds of Workspaces and Channels with thousands of Messages. But after that, the startup time will be fast.

Next, if you want to use YugabyteDB for the dev environment as well, just:

  1. Start YugabyteDB locally.
  2. Tweak connectivity settings in the application-dev.properties file.
  3. Start the app! Enjoy!

Heroku and YugabyteDB Managed: Deploying To Prod

The deployment to the prod was the most straightforward part for me. I’m a lazy guy who uses cloud services whenever possible (or reasonable). My geo-messenger was no exception.

As you remember, the first version of the app is supposed to work within a single cloud region with database nodes at least in three availability zones. Zones fail frequently and I need to be ready for that. So what have I done?

First, I deployed a multi-node YugabyteDB Managed cluster in the South Carolina (us-east1) region with nodes in three availability zones - us-east1-b, us-east1-c and us-east1-d. Just in case, each node handles both reads and writes, there is no such a thing as “active and standby” nodes:

Multi-node YugabyteDB Managed cluster in the South Carolina (us-east1) region with nodes in three availability zones


Next, after creating a Heroku project, I deployed my Java app somewhere in the USA:

Java app deployment

Currently, Heroku is not transparent about the cloud region my app is assigned to. I can only hope that the app instance will be running close enough to my YugabyteDB cluster and that Heroku will take care of the app’s availability in case of cloud outages. I probably need to dig into Heroku internals here. Please share your thoughts in the comments if you know Heroku better than I do!

What’s on the Horizon?

The development of the first version of my geo-distributed messenger was a swift and fun experience. It’s nice to get a multi-zone app functioning within just four days of coding.

What do we have coming up next? 

Performance in prod sucks. It takes 3-6 seconds to load messages when I change a channel. I can’t blame Heroku or YugabyteDB for that as I was coding too fast and used Spring Data in a less than optimal way. 

Let me work on the performance issues next and then scale the app across multiple regions. Until I do that, you can deploy the current version of the app in Heroku and see how “fast” it is. 

IT Vaadin YugabyteDB app Build (game engine) Java (programming language)

Opinions expressed by DZone contributors are their own.

Related

  • 5 Simple Tips to Keep Dockerized Apps Secure
  • Realistic Test Data Generation for Java Apps
  • Beginners Guide for Web Scraping Using Selenium
  • Visually Designing Views for Java Web Apps

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!