Time is the longest distance between two places.
― Tennessee Williams
If you are a software engineer and you work on websites or any other software which is in high demand by your consumer, but you see that some parts of your application say the products page gets higher demand than any other services you provide at some point of time or let's say you want to loosely couple your application for your application to be developed more easily and flexibly.
These are a few use cases, there are many more. We are seeing a trend in the industry getting more aligned toward following microservices patterns while building the application.
The When, Why, Where, and How parts of microservices can be easily found on the internet.
Here I want to talk more about some new technologies which have become an integral part when we talk about microservices. So this blog would be more fruitful for people who know the When, Why, Where, and How parts.
Today, I will talk about intercommunication between these microservices. How they can be made faster? I would specifically talk about gRPC, a project developed by Google, which leverages Web 2.0 to increase the speed of this intercommunication.
What is gRPC?
- Limited support for browsers, hence majorly used between microservices for connection.
- Request and Response Data is machine readable in bytes.
- Service definition changes pose a problem in development.
What was the need for this?
HTTP/1
- Request and Response are human-readable and then converted to binary.
- No pipelining that is multiple requests = multiple connections
- With HTTP/1.1 pipelining introduced, but still for requests to run in parallel, the response should also be returned in that order.
- If one request gets held due to an HTTP connection or Database Connection, it will be delayed and a delayed response will cause all other responses to be blocked. This is called Head of line blocking.
HTTP/2
- Data is transferred in a binary format and does not require waiting for any request to be completed as the data is reorganized at the target system after being sent by the host.
- Terminologies related to HTTP/2 are Stream, Message, and Frame.
- Stream is a bidirectional flow of data between client and server. It consists of a set of messages; each stream is uniquely identified by a stream id.
- A message is a sequence of frames that correspond to your HTTP request or response.
- Frame is the smallest unit that contains a specific type of information. It has a header and a body. A header frame contains a stream id to determine which stream it belongs to.
How will Java Client call C++ Server method?
For this purpose we use ProtoBuffs or Protocol Buffers.
These protobuffs act as intermediate between client and server to provide uniformity.
The first step when working with protocol buffers is to define the structure for the data you want to serialize in a proto file: this is an ordinary text file with a .proto extension. Protocol buffer data is structured as messages, where each message is a small logical record of information containing a series of name-value pairs called fields. Here’s a simple example:
message Person {
string name = 1;
int32 id = 2;
bool has_ponycopter = 3;
}
Then, once you’ve specified your data structures, you use the protocol buffer compiler protoc to generate data access classes in your preferred language(s) from your proto definition. These provide simple accessors for each field, like name() and set_name(), as well as methods to serialize/parse the whole structure to/from raw bytes. So, for instance, if your chosen language is C++, running the compiler on the example above will generate a class called Person. You can then use this class in your application to populate, serialize, and retrieve Person protocol buffer messages.
You define gRPC services in ordinary proto files, with RPC method parameters and return types specified as protocol buffer messages:
// The greeter service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
gRPC uses protoc with a special gRPC plugin to generate code from your proto file: you get generated gRPC client and server code, as well as the regular protocol buffer code for populating, serializing, and retrieving your message types.
What to do to develop a gRPC Service?
- Write a service definition using proto buffs.
- Generate stubs from the service definition file in the language of choice.
- Implement server methods/business logic and run a gRPC server.
- Implement client with the help of stubs.
Download Bloom RPC
Ok! Let's build Something.
- Bloom RPC will make a call to our User Service running on port 50051 using a request object defined in the service definition.
- User service will get user data from the inbuilt h2 database.
- Then User Service will make a call to the Order Service Client, which will make a call to Order Service using the user id.
- Order Service will make a call to h2 DB and get the order associated with that user and return it to the Order Service Client and then it will be returned to the user service.
- User Service will then create a response object according to the response stub mentioned in the service definition of User Service.
- This Response will then be returned to Bloom RPC and we will be able to see it there.!!!!
Create Service Definition for Stubs
- Stubs are usually created using the files with the .proto extension also known as service definition files.
- These stubs will then be used by our custom applications such as services to transfer data between each other.
User Service Definition:
- UserService.class
- UserRequest.class
- UserResponse.class
Order Service Definition:
Now, We will first need some model classes. Some of you brilliant people may ask Why do we need model classes when we already have stubs!!
Creating Model Classes for exchanging data between databases and services
H2 Connection Class :
This class is responsible for creating an H2 database connection and will leverage the initialize.sql file from the resources folder to create tables and insert data into those tables. Why the resources folder? Because the resources folder is automatically added to the classpath for execution by springboot.
Initialize.sql
Order.java
UserDao.java
Now that we have our DAO classes ready, we can create services to connect to these DAO classes and get the data.
OrderServiceImpl.java
You can compare the methods used in this class with the OrderService.proto Service Definition file and how we are populating the stubs.
UserServiceImpl.java
OrderClient.java
- Gets user data based on what user Id we sent from BloomRPC.
- Then get orders by calling the client which would in turn call the orders microservice running on port 50052.
- Then it returns the data back to bloom RPC
Creating a User And Order Server
Running the Application :
- First start both servers as a java file. You may use any IDE or run command for compiling and running java classes.
- Open bloom RPC and import User.proto file, which we created above.


Comments
Post a Comment