Updates to Service Invocation and State Management (#822)

* Updates to Service Invocation and State Management

* update

* Another update

* Update concepts/service-invocation/README.md

Co-authored-by: Mukundan Sundararajan <musundar@microsoft.com>

* Update concepts/service-invocation/README.md

Co-authored-by: Mukundan Sundararajan <musundar@microsoft.com>

* Update concepts/service-invocation/README.md

Co-authored-by: Mukundan Sundararajan <musundar@microsoft.com>

* Update howto/invoke-and-discover-services/README.md

Co-authored-by: Mukundan Sundararajan <musundar@microsoft.com>

* Updated retries

Co-authored-by: Mukundan Sundararajan <musundar@microsoft.com>
Co-authored-by: Yaron Schneider <yaronsc@microsoft.com>
This commit is contained in:
Mark Fussell 2020-09-25 12:20:30 -07:00 committed by GitHub
parent ddc8f61ffc
commit 45f7adb635
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 147 additions and 70 deletions

View File

@ -1,32 +1,108 @@
# Service Invocation
Using the service invocation API, your microservice can find and reliably communicate with other microservices in your system using standard protocols ([gRPC](https://grpc.io) or HTTP are currently supported).
Using service invocation, your application can discover and reliably and securely communicate with other applications using the standard protocols of [gRPC](https://grpc.io) or [HTTP](https://www.w3.org/Protocols/).
Below is a high level overview of how Dapr's service invocation system works.
- [Overview](#overview)
- [Features](#features)
- [Next steps](#next-steps)
## Overview
In many environments with multiple services that need to communicate with each other, developers often ask themselves the following questions:
* How do I discover and invoke methods on different services?
* How do I call other services securely?
* How do I handle retries and transient errors?
* How do I use distributed tracing to see a call graph to diagnose issues in production?
Dapr allows you to overcome these challenges by providing an endpoint that acts as a combination of a reverse proxy with built-in service discovery, while leveraging built-in distributed tracing, metrics, error handling and more.
Dapr uses a sidecar, decentralized architecture. To invoke an application using Dapr, you use the `invoke` API on any Dapr instance. The sidecar programming model encourages each applications to talk to its own instance of Dapr. The Dapr instances discover and communicate with one another.
The diagram below is an overview of how Dapr's service invocation works.
![Service Invocation Diagram](../../images/service-invocation.png)
1. Service A makes a http/gRPC call meant for Service B. The call goes to the local Dapr sidecar.
2. Dapr discovers Service B's location and forwards the message to Service B's Dapr sidecar
3. Service B's Dapr sidecar forwards the request to Service B. Service B performs its corresponding business logic.
4. Service B sends a response for Service A. The response goes to Service B's sidecar.
5. Dapr forwards the response to Service A's Dapr sidecar.
6. Service A receives the response.
1. Service A makes an http/gRPC call meant for Service B. The call goes to the local Dapr sidecar.
2. Dapr discovers Service B's location using the [name resolution component](https://github.com/dapr/components-contrib/tree/master/nameresolution) installed for the given hosting platform.
3. Dapr forwards the message to Service B's Dapr sidecar
* Note: All calls between Dapr sidecars go over gRPC for performance. Only calls between services and Dapr sidecars are either HTTP or gRPC
4. Service B's Dapr sidecar forwards the request to the specified endpoint (or method) on Service B. Service B then runs its business logic code.
5. Service B sends a response to Service A. The response goes to Service B's sidecar.
6. Dapr forwards the response to Service A's Dapr sidecar.
7. Service A receives the response.
As an example for all the above, suppose we have the collection of apps described in the following sample, where a python app invokes a Node.js app: https://github.com/dapr/quickstarts/blob/master/hello-kubernetes/README.md
### Example
As an example for the above call sequence, suppose you have the applications as described in the [hello world sample](https://github.com/dapr/quickstarts/blob/master/hello-world/README.md), where a python app invokes a node.js app.
In such a scenario, the python app would be "Service A" above, and the Node.js app would be "Service B".
The following describes items 1-6 again in the context of this sample:
The diagram below shows sequence 1-7 again on a local machine showing the API call:
1. Suppose the Node.js app has a Dapr app id of "nodeapp", as in the sample. The python app invokes the Node.js app's `neworder` method by posting `http://localhost:3500/v1.0/invoke/nodeapp/method/neworder`, which first goes to the python app's local Dapr sidecar.
2. Dapr discovers the Node.js app's location and forwards it to the Node.js app's sidecar.
3. The Node.js app's sidecar forwards the request to the Node.js app. The Node.js app performs its business logic, which, as described in the sample, is to log the incoming message and then persist the order ID into Redis (not shown in the diagram above).
![Service Invocation Diagram](../../images/service-invocation-example.png)
Steps 4-5 are the same as the list above.
1. Suppose the Node.js app has a Dapr app ID of `nodeapp`, as in the sample. The python app invokes the Node.js app's `neworder` method by posting `http://localhost:3500/v1.0/invoke/nodeapp/method/neworder`, which first goes to the python app's local Dapr sidecar.
2. Dapr discovers the Node.js app's location using multicast DNS component which runs on your local machine.
3. Dapr forwards the request to the Node.js app's sidecar.
4. The Node.js app's sidecar forwards the request to the Node.js app. The Node.js app performs its business logic, which, as described in the sample, is to log the incoming message and then persist the order ID into Redis (not shown in the diagram above).
# Next Steps
Steps 5-7 are the same as above.
**If you're ready to get started**, follow this how-to guide on [how to get started with service invocation](https://github.com/dapr/docs/tree/master/howto/invoke-and-discover-services)
## Features
Service invocation provides several features to make it easy for you to call methods on remote applications.
If you'd like more technical detail on how service invocation works, move on to the [API Spec](../../reference/api/service_invocation_api.md)
- [Namespaces scoping](#namespaces-scoping)
- [Retries](#Retries)
- [Service-to-service security](#service-to-service-security)
- [Service access security](#service-access-security)
- [Observability: Tracing, logging and metrics](#observability)
- [Pluggable service discovery](#pluggable-service-discovery)
### Namespaces scoping
Service invocation supports calls across namespaces. On all supported hosting platforms, Dapr app IDs conform to a valid FQDN format that includes the target namespace.
For example, the following string contains the app ID `nodeapp` in addition to the namespace the app runs in `production`.
```
localhost:3500/v1.0/invoke/nodeapp.production/method/neworder
```
This is especially useful in cross namespace calls in a Kubernetes cluster. Watch this [video](https://youtu.be/LYYV_jouEuA?t=495) for a demo on how to use namespaces with service invocation.
### Retries
Service invocation performs automatic retries with backoff time periods in the event of call failures and transient errors.
Errors that cause retries are:
* Network errors including endpoint unavailability and refused connections
* Authentication errors due to a renewing certificate on the calling/callee dapr sidecars
Per call retries are performed with a backoff interval of 1 second up to a threshold of 3 times.
Connection establishment via gRPC to the target sidecar has a timeout of 5 seconds.
### Service-to-service security
All calls between Dapr applications can be made secure with mutual (mTLS) authentication on hosted platforms, including automatic certificate rollover, via the Dapr Sentry service. The diagram below shows this for self hosted applications.
For more information read the [service-to-service security](../security#mtls-self-hosted) article.
![Self Hosted service to service security](../../images/security-mTLS-sentry-selfhosted.png)
### Service access security
Applications can control which other applications are allowed to call them and what they are authorized to do via access policies. This enables you to restrict sensitive applications, that say have personnel information, from being accessed by unauthorized applications, and combined with service-to-service secure communication, provides for soft multi-tenancy deployments.
For more information read the [access control allow lists for service invocation](../configuration#access-control-allow-lists-for-service-invocation) article.
### Observability
By default, all calls between applications are traced and metrics are gathered to provide insights and diagnostics for applications, which is especially important in production scenarios.
For more information read the [observability](../concepts/observability) article.
### Pluggable service discovery
Dapr can run on any [hosting platform](../concepts/hosting). For the supported hosting platforms this means they have a [name resolution component](https://github.com/dapr/components-contrib/tree/master/nameresolution) developed for them that enables service discovery. For example, the Kubernetes name resolution component uses the Kubernetes DNS service to resolve the location of other applications running in the cluster.
## Next steps
* Follow these guide on
* [How-to: Get started with HTTP service invocation](../../howto/invoke-and-discover-services)
* [How-to: Get started with Dapr and gRPC](../../howto/create-grpc-app)
* Try out the [hello world sample](https://github.com/dapr/quickstarts/blob/master/hello-world/README.md) which shows how to use HTTP service invocation or visit the samples in each of the [Dapr SDKs](https://github.com/dapr/docs#further-documentation)
* Read the [service invocation API specification](../../reference/api/service_invocation_api.md)

View File

@ -2,7 +2,12 @@
Dapr offers key/value storage APIs for state management. If a microservice uses state management, it can use these APIs to leverage any of the [supported state stores](https://github.com/dapr/docs/blob/master/howto/setup-state-store/supported-state-stores.md), without adding or learning a third party SDK.
When using state management your application will also be able to leverage several other features that would otherwise be complicated and error-prone to build yourself such as:
- [Overview](#overview)
- [Features](#features)
- [Next Steps](#next-steps)
## Overview
When using state management your application can leverage several features that would otherwise be complicated and error-prone to build yourself such as:
- Distributed concurrency and data consistency
- Retry policies
@ -12,7 +17,7 @@ See below for a diagram of state management's high level architecture.
![State management](../../images/state_management.png)
## Contents:
## Features
- [State Management API](#state-management-api)
- [State Store Behaviors](#state-store-behaviors)
@ -21,7 +26,6 @@ See below for a diagram of state management's high level architecture.
- [Retry Policies](#retry-policies)
- [Bulk Operations](#bulk-operations)
- [Querying State Store Directly](#querying-state-store-directly)
- [References](#references)
## State management API
@ -105,14 +109,15 @@ SELECT AVG(value) FROM StateTable WHERE Id LIKE '<app-id>||<thermometer>||*||tem
> **NOTE:** Direct queries of the state store are not governed by Dapr concurrency control, since you are not calling through the Dapr runtime. What you see are snapshots of committed data which are acceptable for read-only queries across multiple actors, however writes should be done via the actor instances.
## References
## Next steps
* [Spec: Dapr state management specification](../../reference/api/state_api.md)
* [Spec: Dapr actors specification](../../reference/api/actors_api.md)
* [How-to: Set up Azure Cosmos DB store](../../howto/setup-state-store/setup-azure-cosmosdb.md)
* [How-to: Query Azure Cosmos DB store](../../howto/query-state-store/query-cosmosdb-store.md)
* [How-to: Set up PostgreSQL store](../../howto/setup-state-store/setup-postgresql.md)
* [How-to: Set up Redis store](../../howto/setup-state-store/setup-redis.md)
* [How-to: Query Redis store](../../howto/query-state-store/query-redis-store.md)
* [How-to: Set up SQL Server store](../../howto/setup-state-store/setup-sqlserver.md)
* [How-to: Query SQL Server store](../../howto/query-state-store/query-sqlserver-store.md)
* Follow these guides on
* [How-to: Set up Azure Cosmos DB store](../../howto/setup-state-store/setup-azure-cosmosdb.md)
* [How-to: query Azure Cosmos DB store](../../howto/query-state-store/query-cosmosdb-store.md)
* [How-to: Set up PostgreSQL store](../../howto/setup-state-store/setup-postgresql.md)
* [How-to: Set up Redis store](../../howto/setup-state-store/setup-redis.md)
* [How-to: Query Redis store](../../howto/query-state-store/query-redis-store.md)
* [How-to: Set up SQL Server store](../../howto/setup-state-store/setup-sqlserver.md)
* [How-to: Query SQL Server store](../../howto/query-state-store/query-sqlserver-store.md)
* Read the [state management API specification](../../reference/api/state_api.md)
* Read the [actors API specification](../../reference/api/actors_api.md)

View File

@ -1,16 +1,24 @@
# Dapr and gRPC
# Get started with Dapr and gRPC
Dapr implements both an http API and a gRPC interface.
gRPC is useful for low-latency, high performance scenarios and has deep language integration using the proto clients.
Dapr implements both an HTTP and a gRPC API for local calls.gRPC is useful for low-latency, high performance scenarios and has language integration using the proto clients.
You can find a list of autogenerated client [here](https://github.com/dapr/docs#sdks).
You can find a list of auto-generated clients [here](https://github.com/dapr/docs#sdks).
The Dapr runtime implements a [proto service](https://github.com/dapr/dapr/blob/master/dapr/proto/runtime/v1/dapr.proto) that apps can communicate with via gRPC.
In addition to talking to Dapr via gRPC, Dapr can communicate with an application via gRPC.
To do that, the app simply needs to host a gRPC server and implement the [Dapr appcallback service](https://github.com/dapr/dapr/blob/master/dapr/proto/runtime/v1/appcallback.proto).
In addition to calling Dapr via gRPC, Dapr can communicate with an application via gRPC. To do that, the app needs to host a gRPC server and implements the [Dapr appcallback service](https://github.com/dapr/dapr/blob/master/dapr/proto/runtime/v1/appcallback.proto)
## Configuring Dapr to communicate with an app via gRPC
### Self hosted
When running in self hosted mode, use the `--app-protocol` flag to tell Dapr to use gRPC to talk to the app:
```bash
dapr run --app-protocol grpc --app-port 5005 node app.js
```
This tells Dapr to communicate with your app via gRPC over port `5005`.
## Configuring Dapr to communicate with app via gRPC
### Kubernetes
@ -41,19 +49,9 @@ spec:
...
```
This tells Dapr to communicate with your app via gRPC over port `5005`.
## Invoking Dapr with gRPC - Go example
### Standalone
When running in standalone mode, use the `--app-protocol` flag to tell Dapr to use gRPC to talk to the app:
```bash
dapr run --app-protocol grpc --app-port 5005 node app.js
```
## Invoking Dapr - Go example
The following steps will show you how to create a Dapr client and call the Save State operation on it:
The following steps show you how to create a Dapr client and call the `SaveStateData` operation on it:
1. Import the package

View File

@ -1,14 +1,6 @@
# Invoke remote services
# Get started with HTTP service invocation
In many environments with multiple services that need to communicate with each other, developers often ask themselves the following questions:
* How do I discover and invoke different services?
* How do I handle retries and transient errors?
* How do I use distributed tracing correctly to see a call graph?
Dapr allows developers to overcome these challenges by providing an endpoint that acts as a combination of a reverse proxy with built-in service discovery, while leveraging built-in distributed tracing and error handling.
For more info on service invocation, read the [conceptional documentation](../../concepts/service-invocation/README.md).
This article describe how to deploy services each with an unique application ID, so that other services can discover and call endpoints on them using service invocation API.
## 1. Choose an ID for your service
@ -18,7 +10,7 @@ This ID encapsulates the state for your application, regardless of the number of
### Setup an ID using the Dapr CLI
In Standalone mode, set the `--app-id` flag:
In self hosted mode, set the `--app-id` flag:
```bash
dapr run --app-id cart --app-port 5000 python app.py
@ -52,9 +44,9 @@ spec:
...
```
## Invoke a service in code
## 2. Invoke a service
Dapr uses a sidecar, decentralized architecture. To invoke an applications using Dapr, you can use the `invoke` endpoint on any Dapr instance in your cluster/environment.
Dapr uses a sidecar, decentralized architecture. To invoke an application using Dapr, you can use the `invoke` API on any Dapr instance.
The sidecar programming model encourages each applications to talk to its own instance of Dapr. The Dapr instances discover and communicate with one another.
@ -74,7 +66,7 @@ if __name__ == '__main__':
This Python app exposes an `add()` method via the `/add` endpoint.
### Invoke with curl
### Invoke with curl over HTTP
```bash
curl http://localhost:3500/v1.0/invoke/cart/method/add -X POST
@ -94,7 +86,7 @@ To invoke a 'DELETE' endpoint:
curl http://localhost:3500/v1.0/invoke/cart/method/add -X DELETE
```
Dapr puts any payload return by their called service in the HTTP response's body.
Dapr puts any payload returned by the called service in the HTTP response's body.
### Namespaces
@ -104,15 +96,21 @@ When running on [namespace supported platforms](../../reference/api/service_invo
myApp.production
```
See the [Cross namesapce API spec](../../reference/api/service_invocation_api.md#cross-namespace-invocation) for more information on namespaces.
For example, invoking the example python service with a namespace would be;
## Overview
```bash
curl http://localhost:3500/v1.0/invoke/cart.production/method/add -X POST
```
The example above showed you how to directly invoke a different service running in our environment, locally or in Kubernetes.
Dapr outputs metrics and tracing information allowing you to visualize a call graph between services, log errors and optionally log the payload body.
See the [Cross namespace API spec](../../reference/api/service_invocation_api.md#cross-namespace-invocation) for more information on namespaces.
For more information on tracing, visit [this link](../../best-practices/troubleshooting/tracing.md).
## 3. View traces and logs
## Related Topics
The example above showed you how to directly invoke a different service running locally or in Kubernetes. Dapr outputs metrics, tracing and logging information allowing you to visualize a call graph between services, log errors and optionally log the payload body.
For more information on tracing and logs see the [observability](../../concepts/observability) article.
## Related Links
* [Service invocation concepts](../../concepts/service-invocation/README.md)
* [Service invocation API specification](../../reference/api/service_invocation_api.md)

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 14 KiB