2x Highly performant Microservices using gPRC/http2

I strongly believe its a future of microservices and I have no doubt about it, it’s way faster and lighter than REST-based microservices.

Like Angular and Kubernetes gRPC framework is the third piece of beauty from Google I loved.

Though RPC is not new and is there for decades, as it stands for Remote Procedure Call and you might have come across this service in your operating system which enables applications to communicate with other applications on the same workstation or even with distributed workstations./

GRPC is a modern, high-performance open-source RPC system capable of running in any environment. With pluggable support for load balancing, tracing, health checking and authentication, it can easily link services in and across data centers. It is also applicable in the last mile of distributed computing for connecting devices, mobile applications, and browsers to backend services.

Its actually around since 2015 but seems like people started to take it seriously now when I say people, I meant people from giant companies like Netflix

gPRC is supported by many modern languages, JAVA/C#/GO/NODE/DART, I guess 13 languages in total so far, good thing is, you can generate code in those languages as well

gPRC is built with modern technologies i.e, Protocol Buffers + HTTP/2

Protocol Buffers urf ProtoBuff

ProtoBuff is a mechanism to serialize structured data like XML and JSON — lighter but less human-readable, which gives us an advantage in performance way better than human-readable format based data formats.

It serves multiple purposes like below

  • IDL (Interface definition language) — Describe once and generate code for any supported languages, which makes it language-agnostic ;) just like love needs no language
  • Service Contract like any other service-oriented framework, you need to define and agree upon contracts on both sides to communicate. ProtoBuff is no different principally, In your .proto file you define, Service method and request/response structure. Think gRPC Service as Controller and method as Action if you are .net MVC developer
  • Wire Format is a binary format for network transmission, actual serialization is based upon binary format to gain performance which it does so no complaints

HTTP/2

I presume you all know after http/1.1 companies are upgrading to http/2 for the obvious reason of being more secure and performant.

  • HTTP HOL blocking issue, as you all know HTTP had a serious issue of Head-of-line (HOL) blocking issue which means it doesn’t allow subsequent requests until the previous one is processed on the same connection.
  • HTTP 1.1 alleged to handle this issue but not really, as it allows multiple connections but responses only processed in order, means if 6 requests are made concurrently like request A, B and request B is first one to be completed, its response will not be returned until request A processed and returned.
  • HTTP 2 Multiplexing resolve this issue in an almost real manner, there is a reason I am being sarcastic about it, as with TCP based connection it’s not purely solved as one lost packet could hold the stream until packet resent and processed completely but with UDP and certain framework helps HTTP 2 could be pure solution for HOL problem. Don’t want to bore you with so many details nor this topic is about HTTP

gRPC allows Client-Server model but not from client to server only its vice versa as well and also allows streaming between them which is a fairly powerful feature for real-time applications and quite hard to implement in REST-based services architecture.

as below image depicts how communication model works using gPRC

I think enough of talk lets do some real magic by the implementation, being an advocate of .net technologies, I’ll do asp.net core-based implementation of gRPC

You will need to install .net core 3.0+ and Visual studio 16.3.9+ to ensure you have gPRC service template and SDK

Once you select and create project-based on the aforementioned template, you should see the following files by default in solution explorer. It’s fairly similar to any other .net core based application with the addition of Protos (Messages) and Services (Contracts) files.

I believe its pretty .net standard structured code, leave it on you to explore in detail but happy to describe important files/parts of code.

Aforementioned image is from .proto file defining Service (Controller), SayHello (Action) and Request/Response messages (Object Class) — see nothing new that’s what I love about .net ;)

The aforementioned screenshot shows typical .net core based service class with default ILogger, Action method caller and dependency injection

SayHello method takes request based on the same contract we defined and response, if you noticed in .proto file we assign a number to string name = 1; and message = 1;

The “ = 1”, “ = 2” markers on each element identify the unique “tag” that field uses in the binary encoding. Tag numbers 1–15 require one less byte to encode than higher numbers, so as an optimization you can decide to use those tags for the commonly used or repeated elements, leaving tags 16 and higher for less-commonly used optional elements. Each element in a repeated field requires re-encoding the tag number, so repeated fields are particularly good candidates for this optimization.

As I mentioned earlier, such things make it less human-readable but fairly readable by programmers which are more of a superhuman ;) so that’s all it matter

Once you run this service as it is, it should execute service on port 5001 (by default) and open a console like below

Client

as message describe so it means we have to build a client which can communicate with gPRC service, you can count it a little disadvantage over REST services as they are simply accessible but don’t worry in future I am sure browser will incorporate gPRC clients, or you can simply install gPRC client utilities available on internet.

Let’s create another application as a client and send a request and play with this gPRC

I just added .net core based console app as a client application and by adding connected service dependency reference I end up to the following screen

As you can see there is a section for gPRC service reference, simply use it to add your gPRC service reference in your client application. Just the same as you used to add asmx/wcf type of services reference. I Browse through the .proto file on my machine and voila!!!

In the next step, it will automatically download dependent packages from Nuget and copy .proto reference/proxy on your client application.

<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp3.0</TargetFramework> </PropertyGroup> <ItemGroup> <PackageReference Include="Google.Protobuf" Version="3.9.1" /> <PackageReference Include="Grpc.Net.ClientFactory" Version="2.23.2" /> <PackageReference Include="Grpc.Tools" Version="2.23.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> </ItemGroup> <ItemGroup> <Protobuf Include="..\GrpcService1\Protos\greet.proto" GrpcServices="Client"> <Link>Protos\greet.proto</Link> </Protobuf> </ItemGroup> </Project>

Client application project settings file

Following is another example, I am going to write to use a streaming-based response from the server only. I ‘ll upload an example on Github as well. Happy :)

Notice how I passed a parameter of IServerStreamWriter, which you can see in the server-side code method.

At the client-side its just how you handle response stream object and use it. it’s super fast and super simple, seriously learning curve is very minor if you have a tutor like me ;)

Performance-based comparison

Happy upgrading

Originally published at https://www.linkedin.com.