gRPC Microservices and Eclipse Che

Microservices vs monolithic applications are fast becoming the new development trend. Microservices have many great benefits such as scalability, redundancy, and faster agile development. But one of the problems that microservices have that monolithic typically doesn’t is the increased network traffic for communication done between these microservices. Currently most communication tends to be done through REST api. REST api has many great usages but it can put a lot of strain onto the network and suffer from latency issues.

RPC seems to me like it would be a great alternative to REST for micro-services when you compare RPC vs REST network performance and RPC built-in security. However, a big draw back to RPC versus REST is RPC is done at the process level. This means RPC communication interfaces need to be coded into client and server code. This can cause direct dependencies between the client and server programs which should be avoided when using microservices. Typically, microservice servers should make promises to microservice clients/consumers in what it will provide when certain requests are made. As long as those promises are kept by the server there should be no coding dependencies from RPC between the client/server except the an interface description language IDL. There are various IDL currently available but most require both microservices to use the same programming language.

This is where gRPC can help as it supports various programming languages. There of course are other benefits that gRPC provides but this is one that really sticks out to me.

In addition to discussing gRPC in this article I will also discuss how to run a simple client/server gRPC applications with Eclipse Che using factories. Factories is by far one of my favorite things to use when working with Eclipse Che. It provides developers and organizations a way to easily share a development workspace/environment with all required runtimes and development tools with other developer by using only a url link and having Eclipse Che installed. Also commands that launch client and server applications in workspace machines can be done right after the repositories are cloned. I personally cannot think of an easier or faster way for a developer to get started in learning and developing in something she/he are not familiar with than using Eclipse Che and factories.

Please note that this article is being written while I learn and create the gRPC for the first time. I hope that I can capture some thoughts along the way as well as additional details by writing as I am learning something new. I hope you enjoy the article and please leave feedback if you found this article help.

This article is rather long so if you want to just jump right into the code without reading the rest of blog or you want to have code running before hand it’s just three easy steps:

  1. Install and run Eclipse Che on your local machine using docker https://eclipse.org/che/docs/setup/getting-started/index.html.
  2. Click the following link to launch gRPC-sample git repo factory http://localhost:8080/f?url=https://github.com/JamesDrummond/gRPC-sample .
  3. After workspace has started, run command “Gradle Run Client” from command UI(at top of workspace) on the “client” machine.

Factories

So, first thing that we need to do is review how to create factory so we no what our end goal will be. I have created a few factories in the past using Codenvy server to store the factory definition in the server persistent data. The problem is that when you have various Eclipse Che servers developers using their own local/remote Eclipse Che servers they will not have access to the factory definition of Che server it’s created on like you can with Codenvy. Therefore, it is required that this factory configuration be shared externally. Even with Codenvy it is a good idea to store factory configurations externally so that a developer that may need to work offline when not having direct access to the their company Codenvy server perhaps while travelling can still use the factory.

We are going store our factory configuration file in our example gRPC client/server application in a git repository. We need to add a special file .factory.jsonwhich Eclipse Che will load when creating a new workspace from a factory url with an associated git repository parameter. The easiest way to create a factory configuration is from an existing workspace and the factory UI in the Eclipse server. We will circle back to to factories later in this article but I felt it important to explain what are final goal of having a factory url requires.


Create a New Workspace

I made copy of the runtime ready-to-go stack Java MySQL in stacks section of the dashboard to customize to create two machines to act as client/server for our gRPC example. I did the following on the copy:

  1. Remove existing command
  2. Remove existing db machine.
  3. Change stack name to something like gRPC.
  4. Change dev-machine name to client.
  5. Add a new machine
  6. Change name to server, keep imagecodenvy/ubuntu_jdk8, change memory to 1GB, and add volumes_from:\n — client.
  7. Save.

Final recipe :

services:
client:
image: eclipse/ubuntu_jdk8
mem_limit: 2147483648
server:
image: eclipse/ubuntu_jdk8
mem_limit: 1073741824
volumes_from:
- client

I created a new workspace based on this new stack. I will not go into much detail on how to create a new workspace from this stack which is documented in the multi-machine workspace tutorial but instead focus on specific needs of our gRPC sample.

First thing to do is install Gradle because that’s what I like to use :)~. I ran the following on the “server” dev-machine terminal. This step is included in final factory so don’t worry about doing it just need to be aware of it.

wget https://services.gradle.org/distributions/gradle-3.4.1-bin.zip
sudo mkdir /opt/gradle
sudo unzip -d /opt/gradle gradle-3.4.1-bin.zip

ln -s /opt/gradle/gradle-3.4.1/bin/gradle /usr/bin/gradle

gRPC Java Hello World

We are going to take a look at a simple hello world gRPC program that I extracted from an example in https://github.com/grpc/grpc-java . It simply creates a hello message between a client and server. However, this simple example is a great starting point for learning gRPC basics and with Eclipse Che factories it’s almost laughable how easy it is to get the sample running.


Let’s take a look at the “build.gradle” file first.

build.gradle

Line 112 copies dependencies into the “libs/lib” folder for dependencies indicated at line 37.

Lines 84, 98 and 118 creates scripts required to run applications.

Lines 93 and 107 modifies the scripts so we can set java classpath in these scripts via an environment variable APP_CLASS_PATH which we specify in our workspace commands.

Line 63 defines the language specific gRPC artifact to use which in this case is for java. If we were using Node.js, Python etc we would add these artifacts here.

Line 140 is to publish a pom.xml for maven based on this build configuration file. Within the workspace commands that we will look at shortly I expletively run publish before building with Gradle to ensure that Maven pom file is always kept up-to-date. Eclipse Che supports Maven projects but not directly support Gradle which is not a huge deal as long as you publish maven pom file each time you update Gradle build file.


HelloWorldClient

There are three source java files in this sample gRPC project “HelloWorldClient.java”, “HelloWorldServer.java”, and “helloworld.proto”. This section we will look at “HelloWorldClient.java” and “helloworld.proto”.

HelloWorldClient.java

Most important line to me is line 87 where our “HelloWorldClient” class is initialized. Following the code from line 87 to line 52 where is defines the host and port of our grpc channel and the to lines 60–61 where it creates our grpc channel “ManagedChannelBuilder” function channel = channelBuilder.build() and creation of block stub from blockingStub = GreeterGrpc.newBlockingStub(channel) .

Class “GreeterGrpc” is generated with gradle build script from our “helloworld.proto” file at line 40 where it has a service named “Greeter”. The class naming convention is “<service name>Grpc”. The gRPC service is sort of like the glue that defines what message will be sent and what message will be returned.

Line 71 and 72 shows the use of gRPC messages defined in the “helloworld.proto” file line 46 and 51 by sending a message with

HelloRequest request = HelloRequest.newBuilder().setName(name).build();

and receiving a message with:

HelloReply response;    
try {
response = blockingStub.sayHello(request);
}
catch (StatusRuntimeException e) {logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus()); return; }

logger.info("Greeting: " + response.getMessage());
helloworld.proto

HelloWorldServer

There are three source java files in this sample gRPC project “HelloWorldClient.java”, “HelloWorldServer.java”, and “helloworld.proto”. This section we will look at “HelloWorldServer.java” and again at “helloworld.proto”.

HelloWorldServer.java

With the knowledge of how gRPC works with the client it will be easier to under how the server works with gRPC too. There are a few important parts of code to me in “HelloWorldServer.java”.

Line 52 creates a new gRPC service with “ ServerBuilder” via class “GreeterImpl” that extends “GreeterGrpc.GreeterImplBase”. Again class “GreeterGrpc” is generated with gradle build script from our “helloworld.proto” file line that has a service named “Greeter”. The class naming convention is “<service name>Grpc”.

Line 94 overrides the generated gRPC class “GreeterGrpc” RPC function “sayHello”. This allows us define what we do with the message received and what we respond back with.


Eclipse Che Factory MAGIC

At the start of this article I explained what factories were and how to define a configuration file in a git repository with file .factory.json . Now we will take a closer look at this file https://github.com/JamesDrummond/gRPC-sample/blob/master/.factory.json.

Line 8 defined two machines “client” and “server”. Server is a special machine called dev-machine which gets a agent called “ws-agent”. Additional information about agents can be found at https://eclipse.org/che/docs/devops/ws-agents/index.html.

Line 61 is where we import our git project “gRPC-sample” from my github repo https://github.com/JamesDrummond/gRPC-sample.

Line 65 has all of the existing predefined workspace commands associated with “gRPC-sample” project which can be used once the workspace is launched.

Line 95 actually runs the command “ Setup Build-Run gRPC Server” defined in git project “gRPC-sample” on line 71 after the project(s) are imported/cloned. This is a really useful feature as it one less thing a user/developer needs to know to run and test your project/application. However, currently(5/28/17 release 5.11.1) factory commands cannot be run on non dev-machines. A new enhancement request has been posted at https://github.com/eclipse/che/issues/5219 to allow this. For now though the after the factory is load and additional command “Gradle Run Client” needs to run on the “client” machine. See https://eclipse.org/che/docs/ide/commands/index.html for additional information on commands.


Wrapping it up

So all of the information should give you basic knowledge of how gRPC works and how to possibly create Eclipse Che factories for yourself to allow others to quickly test your applications. As mentioned at the top of the article do the following to start testing/developing this “gRPC-sample” project.

  1. Install and run Eclipse Che on your local machine using docker https://eclipse.org/che/docs/setup/getting-started/index.html.
  2. Click the following link to launch gRPC-sample git repo factory http://localhost:8080/f?url=https://github.com/JamesDrummond/gRPC-sample .
  3. After workspace has started, run command “Gradle Run Client” from command UI(at top of workspace) on the “client” machine.