High-performance Services with gRPC: What's new in .NET 5

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
up next i'm excited to bring james newton king on he's going to spend some time talking about hives performance services with grpc with what's new in dot net 5. james go ahead and jump in my man hi my name is james union king i'm an engineer on the don air team and today i'm going to talk about grpcn.net grpc is a modern high performance way to communicate between applications so our agenda for today first i'm going to introduce grpc to any developers who are new to it i'll compare it to restful apis and also building a basic grpc server and client to call it call it we're going to take a look at what's new on net5 there are a lot of new features that have been added in the past year and i'll also focus on grpc performance and net performance is a big draw for grpc and there have been a lot of great improvements here and finally i'll discuss resources for anyone who's interested in learning more about grpc so what is grbc it's a popular open source remote procedure called framework rpc frameworks make it easy for apps to talk to each other there are alternative frameworks rpc frameworks out there thrift json rbc wcf to name a few but the developer community is really coalescing behind grpc as its framework rpc framework of choice grpc is run by the cncf and the cloud native computing foundation and what microsoft has done is we have uh created a new implementation of grbc built on high performance.net apis and we've contributed it to the cncf grpc is not new it was originally open sourced in 2015 but it's built with modern technologies it's a union of hb2 which is its transport protocol layer and protobuf which acts as grpc's serialization technology for its messages and also its language neutral contract language grpc is designed for modern apps particularly microservices it's high performance both hb2 and protobuf are designed with performance in mind and it's platform independent there are grpc implementations for every major programming language today so you can be in net or ruby or go or c plus plus java node python you name it you can talk between your apps using grpc they're all completely interoperable so how does grbc compare with restful hup apis that i think most developers are pretty familiar with so the first big difference is grpc is an opinionated contract first rpc framework so that contract is defined in a proto file that proto file is really the heart of grpc it defines your apis and the messages that you're going to send it's a language neutral way of defining your apis and that's important because you uh pass that profile to other languages and use it from them and depending upon which language you're using you it drives code generation that will then generate you a strongly typed client and messages for your current platform we compare that with http apis they tend to focus on the shape and content of http so you're thinking a lot more about your urls your http methods your json your headers how to do serialization and you tend to write code first and perhaps as an optional step afterwards you might use something like swashbuckle to generate a swagger contract compare that with grpc and that proto file really does come first grpc the content is binary hbb2 and protobuf are binary protocols and the content is designed for computers and high performance compare that with rest apis um actually rest api say text space so http 1.1 and json they're human readable which means they're great for debugging but not so good for performance because the computer is having to produce text and then pause text so it's really designed for humans to read and write not computers grpc is designed to hide the complexity of remoting grpc libraries plus code generation mean you don't need to worry about routing and headers and serialization a lot of those low level concerns when it comes to calling a grpc service using a client you really just you've already got a strongly typed client you're just invoking a method on it you're passing your message then you're awaiting a result compare that with http apis and rest they tend to emphasize http a lot more you're thinking about those lower level concerns a lot more which is good because you're given a lot of control over http requests but there is additional complexity because of that so if i was going to sum up these two approaches at grpc it focuses on performance and developer productivity while restful apis they're about the widest audience because every computer is able to talk http 1.1 and json and also the ease of getting started you don't need to set up any code generation and like if you want to call a restful api like it's you can just call it in a couple of lines of javascript you don't need to get any other tooling involved with that um let's demo um building a basic grpc service an app for calling it so first thing we'll do is we'll create our grpc service and the way that's done is we'll use our a grpc template which ships with the net sdk so search for grpc and we can see we've got a grpc service uh we'll create this and what will happen is we'll get a asp.net core website set up with grpc already and also a basic grpc service all ready to go so give officials here a second okay so if we take a look at our solution folder uh we've got a couple of interesting things here first thing we'll look at look at is that proto file so this is this is the language neutral way of defining your apis and here we can see we're defining a greeter service and a say hello method so think of a service like a controller an nbc and think of a method like an action so our method is taking a hello request which is a message that's defined down here and it has a name property on it and we're returning a reply and it has a message so this is basically hello world where we've got a service it's got a method on it we're giving it a name and it's going to return a message to us if we look at the implementation we can see we've got a we've got a service greeter service and we've got a say hello method and i'm gonna say hello method we're taking a request and we're returning a reply and inside the actual method body we're taking the name and working concatenating it with hello and we're returning it back to the client very simple and easy to implement um but one thing which jumps out to you is where are these types coming from where is hello reply where is greeterbase these are all the types we have in our project and the answer to that is they're coming from code generation so code generation is generating these files based on a protofile definition and if we f12 into our greeterbase file we can see we've got a whole bunch of generated code going on so grpc is doing all the heavy lifting of generating all this serialization code and routing code and it's doing all of this so you don't have to all you need to do is implement the screederbase class and override this method and then write your implementation and then likewise it's doing exactly the same for all the messages like you don't want to write this you just want to focus on building your app so now we have this let's uh let's run our grpc service so we'll come along to the console and do net run and kestrel will start up and we've got a web server now listening on this address so let's browse to that in our in a browser and we get this message communication with grbc endpoints must be made through a grpc client so grbc isn't like rest where you can like have a get endpoint and browse to it and you can see some json results grpc it really requires that proto file because it's a contract first rpc framework our client needs to know about that proto file and right now our browser doesn't know anything about it so what we need to do to call our grpc service is we need to create a client and the way we'll do that is we'll create a new console app project and let's just change this to donate five and now we need to add the um protofile to it because the protofile needs to be known both about the client needs to be known both on the server and the client now we could um copy it from this location like we could copy the file to this location also copy um this code that is in our cs proj that's required for code generation to the server location um but we've got a shortcut that visual studio provides so what we can do in visual studio is we can add a connected service and in here we can choose to add a service reference and we've got a grbc option so we'll add a grbc service reference and this will look quite familiar to anyone who's ever done something similar to us and um and wcf we're going to navigate to our greek dot product file so our file path is to our original project grpc service 49 and we'll select the type of code we want generated we've got a bunch of options our server was generating server code we want to generate client code so we'll click finish and a bunch of stuff starts happening so visual studio is just adding some nougat packages that are required for a client to that project and it also is adding a reference to that profile so if we take a look in our cs proj file we can see we've got our nougat packages and this protobuf element so this protobuf element is how um code generation knows about the protofile here we're saying we want client code because we're in the client and if we take a look in our server file we can see we've got that exact same reference but here it says server rather than client okay so now that we have that let's write some code to call our client i call our server so first thing we're going to do is we're going to create a grpc channel so a grpc channel represents the connection from the client to the server and this address here port 5 5001 that's the same port we saw up here from kestrel then we're going to create our reader client so this is the strongly typed client that was created for us from code generation again if we f12 into us we can see we've got a whole bunch of code that has automatically been generated for us including our method to invoke our sayhello method you don't need to worry about this this is all automatically generated for you and then to call that uh we just invoke it so we're going to call say hello async and let's make our method asynchronous to keep visual studio happy all we're doing is we're passing in a hello request we're passing in our name and we're getting back our response after awaiting it and then finally let's write it out to the console so if i get the path to this guy and i'll just compile it um let's run our grpc client and if everything has gone to plan it's worked so what's happened is we've sent donetconf off to the server and then the server has handled it concatenated our new message and returned it back to the client and we can see over here on the server our http 2 request has come in of application grpc grpc endpoint has handled our request and it has then returned it back to the client and we can see that it has finished processing it that's a very basic grpc call that's called a unary call so grpc as well as supporting a standard request and response grpc also supports uh streaming so a streaming call is uh when you send instead of just one request you can send multiple requests or responses so in this case we're going to create a say hello stream method or update our profile and now instead of returning a single reply we're returning a stream of replies to implement that on the server we're going to override the new method which has been code generated for us and notice that the method signature is slightly different instead of returning a single reply here now we have a response stream so what we're going to do is we're going to write to our response stream we'll write 10 messages and to each uh each time we'll call write async on our response stream and we'll create 10 replies and a message will be very similar to what we had earlier hello request name and we'll be slightly different here we'll include a number so we can tell them apart and because streaming happens very very quickly by default um let's add another delay actually we need to make this method async let's add in a delay so we'll add in a task.delay of one second let's compile this so if everything has gone to plan start off our server again and we'll run our client and we should start getting back a stream of messages so we've updated our server we need to update our client so to update our client what we'll do is instead of calling say hello async we'll call say hello stream and again we'll pass in our request message say doneconf streaming and instead of awaiting our call now on the client we also have a response stream so what we can do with this response stream is we can do an await for each so this is just like a regular forage but it doesn't block the thread and we'll write out our our result from the server okay now i think we should be could be better so our streaming call has started you'll notice there's this delay between all the messages and as we reach number 10 you can see our call has started and our call should now finish and it's now finished and we can see call is taken about 10 000 milliseconds or 10 seconds so that's grpc basic unrecall and service streaming a powerful feature but also very easy to use so what have we done in dot net 5 for grpc there are a bunch of new features grpc is now supported in the browser with grbc web along with net so what grpc web is is it modifies grp grpc slightly so it makes it compatible um with uh browsers um because browser apis like javascript apis like fetch and xhr they don't support standard grpc by default so grbc web is a slight modification and in.net we now have server middleware that is able to handle grpc web calls and we've also created a blazer client so if you're within a blazer webassembly app you're able to invoke grbc web from within your blazer application donet 5 and grpc now is hosted supports being hosted by http sys and iis on windows note that windows changes were required to support this feature and because of that you will need a modern supported version of windows that has these changes in them current insider builds of windows have support for grbc and hbss and iis grpc is a great choice for communicating between processes grpc client and server can now use efficient ipc transports like units domain sockets and named pipes so you could do ipc communication between processes before but before it always had to be tcp now you can use uds and named pipes and finally donet 5 introduces trimming to reduce app size kind of as like a preview feature you can use that today pretty well with grpc at its higher level highest level because grpc uses a lot of code generation for its serialization grpc already has excellent support for even the most aggressive trimming levels and dot net 5. so i've got a bunch of slides here talking about why grbc is really fast what hb2 features it uses to get such good performance and also how it's able to use protobuf to create really small messages but i think rather than talking about it i'll show you so i've got a grpc webassembly app and it is set up to fetch weather data from the server and there are two options we can either fetch json or we can fetch or we can fetch um grpc web data so if we fetch json uh we'll make a call off to the server uh we can see we've got a whole bunch of results that have been returned to us and we can see our data size it's about about 100 kilobytes in size for the data and it took like half a second to deserialize it if we then go back and we change this to use grpc web instead we can see now we're just a fraction of the size we've gone from um we've gone from 100 kilobytes to a quarter of that size like about 25 kilobytes this is the exact same data or equivalent data weather data just represented and protobuf and grpc instead of json and rest and we can see the deserialization time it's now just like less than 20 percent the previous time of half a second if we uh take a look at our requests inside the network tab we can see we've got our first call which is our json call and we can see the great big json web requests being returned with all this information if we then compare that to grpc call this is the like the binary representation this is the protobuf messages that jason has returned that grpc has returned and as you can see there are much smaller and we can compare that directly over here in the network browser so we've got 100 kilobytes for our json call and just a fraction of that size for grpc so what work has gone into grbc performance and dot net 5 to make it even faster so the biggest improvements have come come from optimizing http 2 and hp client and kestrel we've reduced latency we've improved concurrency and we've removed a lot of allocations in fact server allocations have reduced by 92 percent compared to uh dotnet core 31 and compared to don m5 and these improvements are great because it isn't just grpc that benefits from the http 2 performance improvements every app that's using http 2 whether it's using rest or as just a normal website they also are able to share in these improvements kestrel now supports hpac dynamic compression of response headers so hvac compression is able to take commonly occurring headers like content type and instead of just sending the same data down with every response it's able to compress it down to just a couple of bits so huge huge potential savings although headers tend to be quite small we've worked with the protobuf team to add support of span of t and other advanced net core memory features to the protobuf serializer and with those features when we do protobuf serialization of messages we no longer need to allocate a temporary buffer when serializing and deserializing we can do that directly to a web server's memory so what's the end result of these performance improvements our server requests per second have increased by 65 and client requests per second have increased by two hundred and twenty percent so these are the improvements that you see in dot net five compared to um done core three one and how does grpc on.net compare against other grpc implementations so this is a community benchmark of different grbc implementations and comparing their server performance you can see net and grpc we were second in the results so we're at the very top with other fast implementations like c plus plus go and rust and you can add net to those other fast implementations so if you're interested in learning more about grpc let's talk about some of the resources that are available we've spent a lot of time investing in documentation this is just a brief summary of what's available but if you have any questions about using grpc or you want to learn more i recommend going to docs.microsoft.com there's also a quick link here and we've also written a lot of basic examples each example shows one or two core concepts in action whether it's streaming or showing you how to do authentication or unit testing with grpc services or clients they're all available on a grpc repo github repo and that's all i have time for you today i hope everyone has learned something about grpc and using it on.net and hopefully now we have some time for questions we do thanks james there's lots of uh that's lots of great stuff that was a good deep dive there's been a bunch of really good questions uh in the in our uh that people have tweeted out with the hashtag.netconf so we'll get into a couple of those the first one from kier asks james is there a way to have your c-sharp code as a single source of truth and generate those dot protofiles from code maybe using source generators uh so source generators i don't believe you can take a protofile and then generate c sharp from it i don't know if source generators source generators support that uh if you want to have a code first approach to grpc so not have that profile um there is a community implementation that builds on top of our grpc library that supports code first i believe it's called protobuff.net grpc and it enables code first so you define your contract using a c-sharp file rather than a protofile it's great if you're just talking between c-sharp applications but the great thing about a proto-file is it's language neutral so you can give it to any platform any language and they're able to use it awesome okay we've got a couple we've got a couple more minutes so we'll do a couple more questions this one from bitbonk james is it possible to serialize and deserialize classes that are not known at compile time with grp somehow for example if we have polymorphism um so there is a documentation a doc and docsmicrosoft.com that talks about working with more dynamic protobuf messages and net so there are a couple of options there is a type known as any and protobuf so like you can have a message type of hello request there is a special grpc protobuf type called any and with that you can specify like a message and then you specify its name and then the client is able to read that name of that message type and then deserialize it but i recommend looking at docs.microsoft.com and there is a doc on there about protobuf messages and it has lots of information about doing that sort of thing all right cool we got one more uh this one's from dennis uh is there an analog of swagger for grpc yes that's it's that proto file okay so that proto that protofile is the contract yeah perfect perfect okay james thanks very much that uh we covered a lot of the good questions and we're right on time
Info
Channel: dotNET
Views: 59,962
Rating: undefined out of 5
Keywords: .NET
Id: EJ8M2Em5Zzc
Channel Id: undefined
Length: 27min 26sec (1646 seconds)
Published: Thu Nov 12 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.