At this point, we’ve covered how the code works. We have a true reactive system that uses a collection of microservices to do its work. Now it’s time to actually deploy and run the application.
Deploying and running the Reactica code
Now we have a true reactive system that uses a collection of microservices to do its work, so it’s time to actually deploy and run the application. Fortunately, the authors of the code (Clement Escoffier, James Falkner, Thomas Qvarnström, and Rodney Russ, none of whom can be praised highly enough) created shell scripts to make deploying and running the code straightforward. The scripts do a lot of work to create a Kubernetes cluster and deploy applications into it. That's the good news. The less good news is that because those scripts do so much work, they take a while. So, grab a cup of coffee, a decent book, perhaps some wholesome snacks, and settle in for a few minutes.
Prereqs
Before you can deploy and run Reactica, you need to have minishift
1.33.0 or later installed and on your path. In our testing, we used version 1.34.0 of minishift
for the Mac, downloaded from https://github.com/minishift/minishift/releases. You can also get minishift
by downloading the Red Hat Container Developer Kit from https://developers.redhat.com/products/cdk/overview. If for some reason you’re not already registered with the Red Hat Developer Program, you’ll need to sign up. (Seriously, why haven't you signed up already? It's free.)
In addition to minishift
, the scripts need curl
and Maven version 3.5.3 or later.
Deploying the infrastructure
If you haven’t already, clone or fork the Reactica code from https://github.com/reactica/rhte-demo. Now run the following commands:
-
minishift profile set rhte-vertx-demo
-
minishift stop
-
minishift delete
-
setup/deploy.sh
Set the profile to rhte-vertx-demo
. Next, run minishift stop
and minishift delete
to make sure we’re all starting at the same place. If you get a message asking if you're sure you want to delete the profile, say yes. The deploy.sh
script creates and configures a new cluster on your machine, so it will obviously take a while. Grab that aforementioned cup of coffee now. On yr author's machine, it took about 18 minutes. Be aware that the script creates a cluster that uses 8 GB of RAM and 3 vCPUs. Before you start the script you'll want to shut down anything that you possibly can.
If deploy.sh
ran successfully, and it should have, we have a running OpenShift cluster with Red Hat AMQ and Red Hat Data Grid running inside it. The script starts the data grid and AMQ, waiting for a status of ready
for each before continuing. Full disclosure: Depending on the processing power of your machine, it's possible that you'll get a timeout error. If that's true, try running setup/deploy.sh
again. The system continues to deploy data grid or AMQ in the background, even if the script timed out and stopped running. When you run the script again, it will skip past all of the things that are running already. The first time is almost always the charm, though. We promise.
Configuring the coaster
Next, create a Kubernetes ConfigMap
to set parameters for the coaster. Configuration settings include how often new User
s get in line, how many people can ride a Ride
at the same time, and how long a Ride
lasts.
Switch to the setup
directory. It contains the file application.yaml
. The three properties you might want to modify are user-simulator/period-in-seconds
to define how often a new User
should be generated, ride-simulator/duration-in-seconds
to set the duration of each round-trip of the coaster, and ride-simulator/users-per-ride
to define how many people can ride a Ride
at the same time.
Here’s the original YAML file:
--- user-simulator: period-in-seconds: 5 jitter-in-seconds: 2 enabled: false ride-simulator: duration-in-seconds: 30 users-per-ride: 5 jitter-in-seconds: 5 enabled: true
Running the script setup/create-application-config.sh
creates a Kubernetes ConfigMap named reactica-config
based on the values in the YAML file. If you want to change the configuration again, you’ll need to edit the ConfigMap (oc edit configmap reactica-config
). This drops you into your system editor, whatever that might be (vi
, nano
, emacs
, etc.). Save your changes and the system uses the new settings.
We encourage you to play around with different values to see how it impacts the billboard.
Deploying the coaster
The last step is to deploy the application inside our cluster. Run setup/deploy-application.sh
to do that. This kicks off a Maven build and other scripts that install the reactive microservices that run on top of Red Hat AMQ and Red Hat Data Grid. This will take a few minutes as well, but the last few lines of output should look like this:
✔️ Pod event-generator is Running ✔️ Pod event-generator is ready ✔️ Pod event-store is Running ✔️ Pod event-store is ready ✔️ Pod current-line-updater is Running ✔️ Pod current-line-updater is ready ✔️ Pod queue-length-calculator is Running ✔️ Pod queue-length-calculator is ready ✔️ Pod billboard is Running ✔️ Pod billboard is ready
“Running
” and “ready
” are what we’re looking for, so all is well. To access the application, you’ll need to know its address so you can open it in the browser. Type oc get routes
to see the routes into the cluster:
oc get routes NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD billboard billboard-reactive-demo.192.168.64.37.nip.io billboard 8080 None console console-reactive-demo.192.168.64.37.nip.io eventstream-amq-jolokia <all> None current-line-updater current-line-updater-reactive-demo.192.168.64.37.nip.io current-line-updater 8080 None event-generator event-generator-reactive-demo.192.168.64.37.nip.io event-generator 8080 None event-store event-store-reactive-demo.192.168.64.37.nip.io event-store 8080 None eventstore-dg eventstore-dg-reactive-demo.192.168.64.37.nip.io eventstore-dg <all> None queue-length-calculator queue-length-calculator-reactive-demo.192.168.64.37.nip.io queue-length-calculator 8080 None
We’re looking for the URL of the billboard
verticle. From this output, we can see that its address is billboard-reactive-demo.192.168.64.37.nip.io
. (The address on your machine will almost certainly be different.) Cut and paste that into your favorite browser and you should see something like this:
This is the Ride Status page; it shows us how many people are in the queue and the wait time. As you can see from the screenshot, there are 10 riders in the display. The bottom three (in green) have completed the ride, the four in the middle (in yellow) are currently on the ride, and the top three (in blue) are waiting in line.
Note: The color green was chosen at random, although many users do indeed turn green while on the ride.
Before you get to this panel, however, you'll need to go to the Ride Admin tab and click Start User Generation:
This tells the event-generator
verticle to start generating new User
s. Now switch back to the Ride Status panel. After a few seconds, you should see some people in line.
Administering the ride
There are more things you can do from the admin panel. Clicking Stop User Generation stops the event-generator
verticle from generating more USER_IN_QUEUE
events. Clicking Flush Queue deletes all of the guests in the queue.
Be aware that the billboard
component still responds to events generated by the current-line
verticle. When you flush the queue, the display is cleared. However, it’s possible that there are guests currently in the ON_RIDE
state. When the ride ends, current-line
changes their status to RIDE_COMPLETED
and the billboard
verticle adds those guests to the empty table. Going back to the Ride Admin panel and clicking Flush Queue again removes those users and empties the table. From that point, nothing is added to the table until you click Start User Generation again.
Using logs
If you want to look under the hood and see exactly what’s going on, each component has a log. To access them, start by getting the name of the pod with the oc get pods
command:
NAME READY STATUS RESTARTS AGE billboard-1-s6wrg 1/1 Running 0 1h billboard-s2i-1-build 0/1 Completed 0 5h current-line-updater-1-dvq2t 1/1 Running 0 1h current-line-updater-s2i-1-build 0/1 Completed 0 5h event-generator-1-h5krz 1/1 Running 0 1h event-generator-s2i-1-build 0/1 Completed 0 5h event-store-1-p455g 1/1 Running 0 1h event-store-s2i-1-build 0/1 Completed 0 5h eventstore-dg-1-tqcw6 1/1 Running 0 1h eventstream-amq-1-24fkq 1/1 Running 0 1h queue-length-calculator-1-6r5z6 1/1 Running 0 1h queue-length-calculator-s2i-1-build 0/1 Completed 0 5h
To see the flow of generated events, type oc logs event-generator-1-h5krz
(or whatever the name of your event-generator
pod happens to be). Here are some typical lines from the log:
17:45:47.215 [vert.x-eventloop-thread-1] INFO com.redhat.coderland.reactica.UserSimulatorVerticle - Creating user Spangle Runner 17:45:51.224 [vert.x-eventloop-thread-1] INFO com.redhat.coderland.reactica.UserSimulatorVerticle - Creating user Root Follower 17:45:51.433 [vert.x-eventloop-thread-0] INFO com.redhat.coderland.reactica.RideSimulator - Ride 7b9e3738-56b8-4911-a83d-7be0537067c6 completed 17:45:51.451 [vert.x-eventloop-thread-0] INFO com.redhat.coderland.reactica.RideSimulator - The users [Typhoon Chopper, Oasis Bat, Maze Arm, Tar Coyote, Fast Ape, Flint Mask, Shard Flasher, Magenta Braid] have completed their ride, bye bye! 17:45:51.452 [vert.x-eventloop-thread-0] INFO com.redhat.coderland.reactica.RideSimulator - Onboarding ride {"uuid":"7877df24-3a76-44e6-88d1-9c88f7468ae5","state":"PLANNED"}
You can see the lifecycle of various objects from the messages in the log and see which class generated the event. In these messages, a couple of User
s (Spangle Runner and Root Follower) were created, a Ride
completed, 10 User
s completed the Ride
(Typhoon Chopper, Oasis Bat, etc.), and another Ride
was created. If these messages were just logged, you should see Root Follower and Spangle Runner in the queue, and you should see the 10 users listed above turn green to indicate they have completed the ride.
You can also see Vert.x’s multi-reactor pattern in action here. Vert.x attaches one event loop per verticle (up to 2x the number of physical CPU cores). The RideSimulatorVerticle
is running on one event loop (thread 0) while the UserSimulatorVerticle
is running on another (thread 1). Vert.x’s architecture allows it to leverage the hardware capabilities of the underlying system effectively.
Summary
That’s a complete tour of how the Reactica roller coaster works. Although the reactive system itself is complex, each of the microservices is fairly straightforward. The data generated by producers and processed by consumers results in a sophisticated web UI that shows the results of everything happening in the system.
To take things to the next level, take a look at these resources:
-
To learn more about reactive programming in general and Vert.x in particular, we cannot recommend highly enough Clement Escoffier’s excellent e-book, Building Reactive Microservices in Java: Asynchronous and Event-Based Application Design, free from the Red Hat Developer Program.
-
The introduction to Reactive Programming you’ve been missing by Andre Staltz
-
The documentation and examples on the Vert.x site
-
Finally, it's worth your time to go through Part 2 of this tutorial if you haven't already.
If you’re not a member of the Red Hat Developer Program, sign up today! You can get access to lots of content and Red Hat products, including Red Hat AMQ and Red Hat Data Grid.
We hope you’ve enjoyed this addition to Coderland. As always, send us your comments, questions, suggestions, and PRs. We’re coderland@redhat.com; let us hear from you!
Last updated: June 28, 2023