Skip to content

Commit

Permalink
Fix dockerfile and main
Browse files Browse the repository at this point in the history
  • Loading branch information
Ananto30 committed Jan 23, 2021
1 parent b6b34f5 commit 31b5fdc
Show file tree
Hide file tree
Showing 8 changed files with 164 additions and 56 deletions.
9 changes: 6 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
FROM openjdk:11-jre-slim
# copy application WAR (with libraries inside)

COPY target/starter-1.0.0-SNAPSHOT-fat.jar /app.jar
# specify default command
CMD ["java", "-jar", "/app.jar", "-cluster"]

ENV CLUSTER_PUBLIC_PORT 17001
ENV CLUSTER_PUBLIC_HOST 192.168.0.100

CMD java -jar /app.jar -cluster -cluster-public-port $CLUSTER_PUBLIC_PORT -cluster-public-host $CLUSTER_PUBLIC_HOST -instance 4
31 changes: 27 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,33 @@

Example of converting (legacy) async service to sync.

## IMPORTANT!
## Run for dev
Directly run the DevApp. All the tweaks can be done with the code.

Change the `EVENT_BUS_CLUSTER_PUBLIC_HOST` with your machine IP. (for dev)
## Run for production/testing
Can be run using the fat jar.

Create jar:
```
./mvnw clean package
```
Or skip tests:
```
./mvnw clean package -Dmaven.test.skip=true
```
____________________
Run with java:
```
java -jar target/starter-1.0.0-SNAPSHOT-fat.jar -cluster -cluster-public-port 17001 -cluster-public-host <YOUR-MACHINE-IP> -instance 4
```
**Important notes:**
The `-cluster` ensures verticles are running in cluster mode, so the event bus can communicate with all the verticles even if they are running in different machines.

`-cluster-public-port` is the public exposing port where the other clusters can connect to.

`-cluster-public-host` is **really important**. You should expose the IP of your machines so that other clusters can connect to it.

`-instance` is how many instances you want to run. Can be your core numbers, but better play with it. Especially each instance has a single eventloop.

## Test with Docker
Create jar:
Expand All @@ -24,8 +47,8 @@ docker build -t vertx-async-gateway .

Docker run two instances exposed with different ports:
```
docker run -p 8888:8888 -d vertx-async-gateway
docker run -p 8889:8888 -d vertx-async-gateway
docker run -p 8888:8888 -e cluster-public-host=<YOUR-MACHINE-IP> -d vertx-async-gateway
docker run -p 8889:8888 -e cluster-public-host=<YOUR-MACHINE-IP> -d vertx-async-gateway
```

**To test properly use something like nginx to load balance among 8888 and 8889**
5 changes: 5 additions & 0 deletions java_run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env sh

./mvnw clean package -Dmaven.test.skip=true

java -jar target/starter-1.0.0-SNAPSHOT-fat.jar -cluster -cluster-host 192.168.0.100 -instance 4
12 changes: 12 additions & 0 deletions make_two_docker_instances.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env sh

docker rm -f vertx-async-gateway-1
docker rm -f vertx-async-gateway-2

./mvnw clean package -Dmaven.test.skip=true

docker build -t ananto30/vertx-example:vertx-async-gateway .
docker push ananto30/vertx-example:vertx-async-gateway

docker run --name vertx-async-gateway-1 -p 8888:8888 -e CLUSTER_PUBLIC_HOST=192.168.0.119 -d ananto30/vertx-example:vertx-async-gateway
docker run --name vertx-async-gateway-2 -p 8889:8888 -e CLUSTER_PUBLIC_HOST=192.168.0.100 -d vertx-async-gateway
32 changes: 30 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.example</groupId>
Expand Down Expand Up @@ -49,6 +49,34 @@
<artifactId>vertx-hazelcast</artifactId>
</dependency>

<!-- <dependency>-->
<!-- <groupId>org.slf4j</groupId>-->
<!-- <artifactId>slf4j-simple</artifactId>-->
<!-- <version>1.7.25</version>-->
<!-- </dependency>-->
<!-- &lt;!&ndash; https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-slf4j-impl &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>org.apache.logging.log4j</groupId>-->
<!-- <artifactId>log4j-slf4j-impl</artifactId>-->
<!-- <version>2.12.1</version>-->
<!-- <scope>test</scope>-->
<!-- </dependency>-->
<!-- &lt;!&ndash; https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>org.apache.logging.log4j</groupId>-->
<!-- <artifactId>log4j-core</artifactId>-->
<!-- <version>2.12.1</version>-->
<!-- </dependency>-->

<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>




<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-junit5</artifactId>
Expand Down
59 changes: 59 additions & 0 deletions src/main/java/com/ananto/asyncgateway/DevApp.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.ananto.asyncgateway;

import io.vertx.core.Vertx;
import io.vertx.core.VertxOptions;
import io.vertx.core.eventbus.EventBus;
import io.vertx.core.eventbus.EventBusOptions;
import io.vertx.spi.cluster.hazelcast.HazelcastClusterManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* @author Azizul Haque Ananto
* @since 22/1/21
*/
public class DevApp {

private static final String EVENT_BUS_CLUSTER_PUBLIC_HOST = "192.168.0.100"; // IMPORTANT! for dev, IP of your machine
private static final int EVENT_BUS_CLUSTER_PUBLIC_PORT = 17001;

private static final Logger logger = LoggerFactory.getLogger(DevApp.class);

public static void main(String[] args) {
/*
IMPORTANT!!!
The main method is only used in development mode, when run from intellij or calling the main method directly
*/
System.setProperty("vertx.logger-delegate-factory-class-name", "io.vertx.core.logging.SLF4JLogDelegateFactory");
VertxOptions options = new VertxOptions()
.setClusterManager(new HazelcastClusterManager()) // hazlecast is distributed in-memory data grid that can track the distributed clusters
// for kubernetes - https://vertx.io/docs/vertx-hazelcast/java/#_configuring_for_kubernetes

// this is where all the magic happens :D
// the cluster implementation of the event bus allows different instances to talk with each other through tcp network
// basically it's a distributed event bus now
.setEventBusOptions(new EventBusOptions()
// the most important part! public host can be different for each instance
// for kubernetes we can use the service host most probably
.setClusterPublicHost(EVENT_BUS_CLUSTER_PUBLIC_HOST)
.setClusterPublicPort(EVENT_BUS_CLUSTER_PUBLIC_PORT)

);
Vertx.clusteredVertx(options, res -> {
if (res.succeeded()) {
Vertx vertx = res.result();

// we can deploy multiple verticles using same vertx manager to utilize cores
vertx.deployVerticle(new MainVerticle());
vertx.deployVerticle(new MainVerticle());
vertx.deployVerticle(new MainVerticle());
vertx.deployVerticle(new MainVerticle());

EventBus eventBus = vertx.eventBus();
logger.info("We now have a clustered event bus: " + eventBus);
} else {
logger.error("Failed: {}", res.cause(), res.cause());
}
});
}
}
56 changes: 9 additions & 47 deletions src/main/java/com/ananto/asyncgateway/MainVerticle.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,25 @@

import io.vertx.core.AbstractVerticle;
import io.vertx.core.Promise;
import io.vertx.core.Vertx;
import io.vertx.core.VertxOptions;
import io.vertx.core.eventbus.EventBus;
import io.vertx.core.eventbus.EventBusOptions;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.handler.BodyHandler;
import io.vertx.ext.web.handler.LoggerHandler;
import io.vertx.ext.web.handler.TimeoutHandler;
import io.vertx.spi.cluster.hazelcast.HazelcastClusterManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.concurrent.ConcurrentHashMap;

public class MainVerticle extends AbstractVerticle {

private static final int PORT = 8888;
private static final String ASYNC_RESULT_EVENT = "async.result";
private static final long DEFAULT_REQUEST_TIMEOUT = 10000L;
private static final String EVENT_BUS_CLUSTER_PUBLIC_HOST = "192.168.0.100"; // IMPORTANT! for dev, IP of your machine
private static final int EVENT_BUS_CLUSTER_PUBLIC_PORT = 17001;

private static final Logger logger = LoggerFactory.getLogger(MainVerticle.class);


@Override
Expand All @@ -40,8 +36,7 @@ public void start(Promise<Void> startPromise) throws Exception {
router.route().handler(BodyHandler.create());
router.route().handler(TimeoutHandler.create(DEFAULT_REQUEST_TIMEOUT)); // change default timeout to 10sec
router.route().failureHandler(ctx -> {
System.out.println(ctx.failure().getMessage());
System.out.println(Arrays.toString(ctx.failure().getStackTrace()));
logger.error(ctx.failure().getMessage(), ctx.failure());
ctx.next();
});

Expand All @@ -56,7 +51,7 @@ public void start(Promise<Void> startPromise) throws Exception {
server.requestHandler(router).listen(PORT, http -> {
if (http.succeeded()) {
startPromise.complete();
System.out.println("HTTP server started on port " + PORT);
logger.info("HTTP server started on port " + PORT);
requestProcessor(requests);
} else {
startPromise.fail(http.cause());
Expand All @@ -68,11 +63,11 @@ private void requestProcessor(ConcurrentHashMap<String, HttpServerResponse> requ
vertx.eventBus().consumer(ASYNC_RESULT_EVENT).handler(data -> {
var body = (JsonObject) data.body();
var id = body.getString("id");
System.out.printf("Event received | %s : %s%n", id, body);
logger.info(String.format("Event received | %s : %s%n", id, body));
var entry = requests.get(id);
if (entry != null) {
entry.end(body.toString());
requests.remove(id);
if (entry.ended()) requests.remove(id);// timout request
else entry.end(body.toString());
}
});
}
Expand All @@ -92,38 +87,5 @@ private void asyncHandler(io.vertx.ext.web.RoutingContext ctx, ConcurrentHashMap
requests.put(id, response);
}


public static void main(String[] args) {
VertxOptions options = new VertxOptions()
.setClusterManager(new HazelcastClusterManager()) // hazlecast is distributed in-memory data grid that can track the distributed clusters
// for kubernetes - https://vertx.io/docs/vertx-hazelcast/java/#_configuring_for_kubernetes

// this is where all the magic happens :D
// the cluster implementation of the event bus allows different instances to talk with each other through tcp network
// basically it's a distributed event bus now
.setEventBusOptions(new EventBusOptions()
// the most important part! public host can be different for each instance
// for kubernetes we can use the service host most probably
.setClusterPublicHost(EVENT_BUS_CLUSTER_PUBLIC_HOST)
.setClusterPublicPort(EVENT_BUS_CLUSTER_PUBLIC_PORT)

);
Vertx.clusteredVertx(options, res -> {
if (res.succeeded()) {
Vertx vertx = res.result();

// we can deploy multiple verticles using same vertx manager to utilize cores
vertx.deployVerticle(new MainVerticle());
vertx.deployVerticle(new MainVerticle());
vertx.deployVerticle(new MainVerticle());
vertx.deployVerticle(new MainVerticle());

EventBus eventBus = vertx.eventBus();
System.out.println("We now have a clustered event bus: " + eventBus);
} else {
System.out.println("Failed: " + res.cause());
}
});
}
}

16 changes: 16 additions & 0 deletions src/main/resources/logback.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<configuration>

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!-- <pattern>%level [%thread] %logger{0} - %msg%n</pattern>-->
<pattern>%d{yyyy-MM-dd} | %d{HH:mm:ss.SSS} | %-20.20thread | %5p | %-25.25logger{25} | %12(ID: %8mdc{id}) | %m%n</pattern>
</encoder>
</appender>

<logger name="io.netty" level="warn"/>

<root level="debug">
<appender-ref ref="STDOUT"/>
</root>

</configuration>

0 comments on commit 31b5fdc

Please sign in to comment.