grpc.io/public/docs/guides/concepts/index.html

410 lines
20 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="/css/style.css">
<title>
gRPC Concepts &ndash; gRPC
</title>
<link rel="apple-touch-icon" href="/favicons/apple-touch-icon.png" sizes="180x180">
<link rel="icon" type="image/png" href="/favicons/android-chrome-192x192.png" sizes="192x192" >
<link rel="icon" type="image/png" href="/favicons/favicon-32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="/favicons/favicon-16x16.png" sizes="16x16">
<link rel="manifest" href="/favicons/manifest.json">
<link rel="mask-icon" href="/favicons/safari-pinned-tab.svg" color="#2DA6B0">
<meta name="msapplication-TileColor" content="#ffffff">
<meta name="msapplication-TileImage" content="/favicons/mstile-150x150.png">
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-60127042-1"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-60127042-1');
</script>
</head>
<body>
<div id="landing-content">
<div class="row">
<div class="topbannersub">
<nav class="navbar navbar-expand-md navbar-dark topnav">
<a class="navbar-brand" href="https://cjyabraham.github.io/">
<img src="https://cjyabraham.github.io/img/grpc-logo.png" width="114" height="50">
</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="topnav, collapse navbar-collapse" id="navbarSupportedContent" style="float:right !important">
<ul class="navbar-nav ml-auto">
<li class="nav-item ">
<a class="nav-link" href="https://cjyabraham.github.io/about/">About</a>
</li>
<li class="nav-item dropdown active">
<a class="nav-link dropdown-toggle" href="https://cjyabraham.github.io/docs/" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Docs
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="/docs">
Overview
</a>
<a class="dropdown-item" href="/docs/quickstart/">
Quick Start
</a>
<a class="dropdown-item" href="/docs/guides/">
Guides
</a>
<a class="dropdown-item" href="/docs/tutorials/">
Tutorials
</a>
<a class="dropdown-item" href="/docs/reference/">
Reference
</a>
<a class="dropdown-item" href="/docs/samples/">
Samples
</a>
<a class="dropdown-item" href="/docs/talks">
Presentations
</a>
</div>
</li>
<li class="nav-item ">
<a class="nav-link" href="/blog">
Blog
</a>
</li>
<li class="nav-item ">
<a class="nav-link" href="/community">Community</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://packages.grpc.io/">
Packages
</a>
</li>
<li class="nav-item ">
<a class="nav-link" href="https://cjyabraham.github.io/faq/">FAQ</a>
</li>
</ul>
</div>
</nav>
<div class="headertext">Documentation</div>
</div>
</div>
</div>
<div class="subnav d-none d-md-block">
<a href="https://cjyabraham.github.io/docs/" >Overview</a>
| <a href="https://cjyabraham.github.io/docs/quickstart/" >Quick Start</a>
| <a href="https://cjyabraham.github.io/docs/guides/" class="active">Guides</a>
| <a href="https://cjyabraham.github.io/docs/tutorials/" >Tutorials</a>
| <a href="https://cjyabraham.github.io/docs/reference/" >Reference</a>
| <a href="https://cjyabraham.github.io/docs/samples/" >Samples</a>
| <a href="https://cjyabraham.github.io/docs/talks/" >Presentations</a>
</div>
<div class="quickstartcols">
<div class="quickstartcol1">
<h8>Guides</h8>
<a href="/docs/guides/">
What is gRPC?
</a>
<a href="/docs/guides/concepts/" class="active">
gRPC Concepts
</a>
<a href="/docs/guides/auth/">
Authentication
</a>
<a href="/docs/guides/error/">
Error handling and debugging
</a>
<a href="/docs/guides/benchmarking/">
Benchmarking
</a>
<a href="https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md">
gRPC Wire Format
</a>
<h8 style="margin-top:25%">Related Guides</h8>
<a href="https://developers.google.com/protocol-buffers/docs/overview">Protocol Buffers</a>
</div>
<div class="quickstartcol2" style="margin-top:4%">
<h3 style="margin-top:0px;">
gRPC Concepts
</h3>
<p class="lead">This document introduces some key gRPC concepts with an overview
of gRPC's architecture and RPC life cycle.</p>
<p>It assumes that you&rsquo;ve read <a href="/docs/guides">What is gRPC?</a>. For
language-specific details, see the Quick Start, tutorial, and reference
documentation for your chosen language(s), where available (complete reference
docs are coming soon).</p>
<div id="toc" class="toc mobile-toc"></div>
<h3 id="overview">Overview</h3>
<h4 id="service-definition">Service definition</h4>
<p>Like many RPC systems, gRPC is based around the idea of defining a service,
specifying the methods that can be called remotely with their parameters and
return types. By default, gRPC uses <a href="https://developers.google.com/protocol-buffers/">protocol
buffers</a> as the Interface
Definition Language (IDL) for describing both the service interface and the
structure of the payload messages. It is possible to use other alternatives if
desired.</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-proto" data-lang="proto"><span style="color:#66d9ef">service</span> HelloService {<span style="color:#960050;background-color:#1e0010">
</span><span style="color:#960050;background-color:#1e0010"></span> <span style="color:#66d9ef">rpc</span> SayHello (HelloRequest) <span style="color:#66d9ef">returns</span> (HelloResponse);<span style="color:#960050;background-color:#1e0010">
</span><span style="color:#960050;background-color:#1e0010"></span>}<span style="color:#960050;background-color:#1e0010">
</span><span style="color:#960050;background-color:#1e0010">
</span><span style="color:#960050;background-color:#1e0010"></span><span style="color:#66d9ef">message</span> <span style="color:#a6e22e">HelloRequest</span> {<span style="color:#960050;background-color:#1e0010">
</span><span style="color:#960050;background-color:#1e0010"></span> <span style="color:#66d9ef">string</span> greeting <span style="color:#f92672">=</span> <span style="color:#ae81ff">1</span>;<span style="color:#960050;background-color:#1e0010">
</span><span style="color:#960050;background-color:#1e0010"></span>}<span style="color:#960050;background-color:#1e0010">
</span><span style="color:#960050;background-color:#1e0010">
</span><span style="color:#960050;background-color:#1e0010"></span><span style="color:#66d9ef">message</span> <span style="color:#a6e22e">HelloResponse</span> {<span style="color:#960050;background-color:#1e0010">
</span><span style="color:#960050;background-color:#1e0010"></span> <span style="color:#66d9ef">string</span> reply <span style="color:#f92672">=</span> <span style="color:#ae81ff">1</span>;<span style="color:#960050;background-color:#1e0010">
</span><span style="color:#960050;background-color:#1e0010"></span>}</code></pre></div>
<p>gRPC lets you define four kinds of service method:</p>
<ul>
<li>Unary RPCs where the client sends a single request to the server and gets a
single response back, just like a normal function call.</li>
</ul>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-proto" data-lang="proto"><span style="color:#66d9ef">rpc</span> SayHello(HelloRequest) <span style="color:#66d9ef">returns</span> (HelloResponse){<span style="color:#960050;background-color:#1e0010">
</span><span style="color:#960050;background-color:#1e0010"></span>}</code></pre></div>
<ul>
<li>Server streaming RPCs where the client sends a request to the server and gets
a stream to read a sequence of messages back. The client reads from the
returned stream until there are no more messages. gRPC guarantees message
ordering within an individual RPC call.</li>
</ul>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-proto" data-lang="proto"><span style="color:#66d9ef">rpc</span> LotsOfReplies(HelloRequest) <span style="color:#66d9ef">returns</span> (stream HelloResponse){<span style="color:#960050;background-color:#1e0010">
</span><span style="color:#960050;background-color:#1e0010"></span>}</code></pre></div>
<ul>
<li>Client streaming RPCs where the client writes a sequence of messages and sends
them to the server, again using a provided stream. Once the client has
finished writing the messages, it waits for the server to read them and return
its response. Again gRPC guarantees message ordering within an individual RPC
call.</li>
</ul>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-proto" data-lang="proto"><span style="color:#66d9ef">rpc</span> LotsOfGreetings(stream HelloRequest) <span style="color:#66d9ef">returns</span> (HelloResponse) {<span style="color:#960050;background-color:#1e0010">
</span><span style="color:#960050;background-color:#1e0010"></span>}</code></pre></div>
<ul>
<li>Bidirectional streaming RPCs where both sides send a sequence of messages
using a read-write stream. The two streams operate independently, so clients
and servers can read and write in whatever order they like: for example, the
server could wait to receive all the client messages before writing its
responses, or it could alternately read a message then write a message, or
some other combination of reads and writes. The order of messages in each
stream is preserved.</li>
</ul>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-proto" data-lang="proto"><span style="color:#66d9ef">rpc</span> BidiHello(stream HelloRequest) <span style="color:#66d9ef">returns</span> (stream HelloResponse){<span style="color:#960050;background-color:#1e0010">
</span><span style="color:#960050;background-color:#1e0010"></span>}</code></pre></div>
<p>We&rsquo;ll look at the different types of RPC in more detail in the RPC life cycle section below.</p>
<h4 id="using-the-api-surface">Using the API surface</h4>
<p>Starting from a service definition in a .proto file, gRPC provides protocol
buffer compiler plugins that generate client- and server-side code. gRPC users
typically call these APIs on the client side and implement the corresponding API
on the server side.</p>
<ul>
<li>On the server side, the server implements the methods declared by the service
and runs a gRPC server to handle client calls. The gRPC infrastructure decodes
incoming requests, executes service methods, and encodes service responses.</li>
<li>On the client side, the client has a local object known as <em>stub</em> (for some
languages, the preferred term is <em>client</em>) that implements the same methods as
the service. The client can then just call those methods on the local object,
wrapping the parameters for the call in the appropriate protocol buffer
message type - gRPC looks after sending the request(s) to the server and
returning the server&rsquo;s protocol buffer response(s).</li>
</ul>
<h4 id="synchronous-vs-asynchronous">Synchronous vs. asynchronous</h4>
<p>Synchronous RPC calls that block until a response arrives from the server are
the closest approximation to the abstraction of a procedure call that RPC
aspires to. On the other hand, networks are inherently asynchronous and in many
scenarios it&rsquo;s useful to be able to start RPCs without blocking the current
thread.</p>
<p>The gRPC programming surface in most languages comes in both synchronous and
asynchronous flavors. You can find out more in each language&rsquo;s tutorial and
reference documentation (complete reference docs are coming soon).</p>
<h3 id="rpc-life-cycle">RPC life cycle</h3>
<p>Now let&rsquo;s take a closer look at what happens when a gRPC client calls a gRPC
server method. We won&rsquo;t look at implementation details, you can find out more
about these in our language-specific pages.</p>
<h4 id="unary-rpc">Unary RPC</h4>
<p>First let&rsquo;s look at the simplest type of RPC, where the client sends a single request and gets back a single response.</p>
<ul>
<li>Once the client calls the method on the stub/client object, the server is
notified that the RPC has been invoked with the client&rsquo;s <a href="#metadata">metadata</a>
for this call, the method name, and the specified <a href="#deadlines">deadline</a> if
applicable.</li>
<li>The server can then either send back its own initial metadata (which must be
sent before any response) straight away, or wait for the client&rsquo;s request
message - which happens first is application-specific.</li>
<li>Once the server has the client&rsquo;s request message, it does whatever work is
necessary to create and populate its response. The response is then returned
(if successful) to the client together with status details (status code and
optional status message) and optional trailing metadata.</li>
<li>If the status is OK, the client then gets the response, which completes the
call on the client side.</li>
</ul>
<h4 id="server-streaming-rpc">Server streaming RPC</h4>
<p>A server-streaming RPC is similar to our simple example, except the server sends
back a stream of responses after getting the client&rsquo;s request message. After
sending back all its responses, the server&rsquo;s status details (status code and
optional status message) and optional trailing metadata are sent back to
complete on the server side. The client completes once it has all the server&rsquo;s
responses.</p>
<h4 id="client-streaming-rpc">Client streaming RPC</h4>
<p>A client-streaming RPC is also similar to our simple example, except the client
sends a stream of requests to the server instead of a single request. The server
sends back a single response, typically but not necessarily after it has
received all the client&rsquo;s requests, along with its status details and optional
trailing metadata.</p>
<h4 id="bidirectional-streaming-rpc">Bidirectional streaming RPC</h4>
<p>In a bidirectional streaming RPC, again the call is initiated by the client
calling the method and the server receiving the client metadata, method name,
and deadline. Again the server can choose to send back its initial metadata or
wait for the client to start sending requests.</p>
<p>What happens next depends on the application, as the client and server can read
and write in any order - the streams operate completely independently. So, for
example, the server could wait until it has received all the client&rsquo;s messages
before writing its responses, or the server and client could &ldquo;ping-pong&rdquo;: the
server gets a request, then sends back a response, then the client sends another
request based on the response, and so on.</p>
<p><a name="deadlines"></a></p>
<h4 id="deadlines-timeouts">Deadlines/Timeouts</h4>
<p>gRPC allows clients to specify how long they are willing to wait for an RPC to
complete before the RPC is terminated with the error <code>DEADLINE_EXCEEDED</code>. On
the server side, the server can query to see if a particular RPC has timed out,
or how much time is left to complete the RPC.</p>
<p>How the deadline or timeout is specified varies from language to language - for
example, not all languages have a default deadline, some language APIs work in
terms of a deadline (a fixed point in time), and some language APIs work in
terms of timeouts (durations of time).</p>
<h4 id="rpc-termination">RPC termination</h4>
<p>In gRPC, both the client and server make independent and local determinations of
the success of the call, and their conclusions may not match. This means that,
for example, you could have an RPC that finishes successfully on the server side
(&ldquo;I have sent all my responses!&rdquo;) but fails on the client side (&ldquo;The responses
arrived after my deadline!&ldquo;). It&rsquo;s also possible for a server to decide to
complete before a client has sent all its requests.</p>
<h4 id="cancelling-rpcs">Cancelling RPCs</h4>
<p>Either the client or the server can cancel an RPC at any time. A cancellation
terminates the RPC immediately so that no further work is done. It is <em>not</em> an
&ldquo;undo&rdquo;: changes made before the cancellation will not be rolled back.</p>
<p><a name="metadata"></a></p>
<h4 id="metadata">Metadata</h4>
<p>Metadata is information about a particular RPC call (such as <a href="/docs/guides/auth/">authentication details</a>) in the
form of a list of key-value pairs, where the keys are strings and the values are
typically strings (but can be binary data). Metadata is opaque to gRPC itself -
it lets the client provide information associated with the call to the server
and vice versa.</p>
<p>Access to metadata is language-dependent.</p>
<h4 id="channels">Channels</h4>
<p>A gRPC channel provides a connection to a gRPC server on a specified host and
port and is used when creating a client stub (or just &ldquo;client&rdquo; in some
languages). Clients can specify channel arguments to modify gRPC&rsquo;s default
behaviour, such as switching on and off message compression. A channel has
state, including <code>connected</code> and <code>idle</code>.</p>
<p>How gRPC deals with closing down channels is language-dependent. Some languages
also permit querying channel state.</p>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
</body>
</html>