From 42fdb2b458ce0aa17bf435e5c66968cb086ce030 Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Wed, 21 Feb 2024 14:46:31 -0500 Subject: [PATCH 1/9] initial add, need to create diagram to replace placeholder Signed-off-by: Hannah Hunter --- .../health-checks/sidecar-health.md | 4 ++ .../content/en/reference/api/health_api.md | 59 ++++++++++++++++--- 2 files changed, 54 insertions(+), 9 deletions(-) diff --git a/daprdocs/content/en/operations/resiliency/health-checks/sidecar-health.md b/daprdocs/content/en/operations/resiliency/health-checks/sidecar-health.md index b81efeef9b9..ac679055631 100644 --- a/daprdocs/content/en/operations/resiliency/health-checks/sidecar-health.md +++ b/daprdocs/content/en/operations/resiliency/health-checks/sidecar-health.md @@ -13,6 +13,10 @@ Dapr provides a way to determine its health using an [HTTP `/healthz` endpoint]( In this guide, you learn how the Dapr `/healthz` endpoint integrate with health probes from the application hosting platform (for example, Kubernetes). +The following diagram demonstrates how Dapr checks for outbound health connections from the sidecar using `v1.0/healthz/outbound`, as shown by the green boundary lines. With this behavior, Dapr waits for a successful response from `v1.0/healthz/outbound`, rather than waiting for the Dapr HTTP port to be available. This provides a more explict implementation that is better isolated from accidental change. + +Diagram of Dapr services interacting + When deploying Dapr to a hosting platform like Kubernetes, the Dapr health endpoint is automatically configured for you. {{% alert title="Note" color="primary" %}} diff --git a/daprdocs/content/en/reference/api/health_api.md b/daprdocs/content/en/reference/api/health_api.md index 9f44ad453b7..a943e4a8012 100644 --- a/daprdocs/content/en/reference/api/health_api.md +++ b/daprdocs/content/en/reference/api/health_api.md @@ -6,34 +6,75 @@ description: "Detailed documentation on the health API" weight: 1000 --- -Dapr provides health checking probes that can be used as readiness or liveness of Dapr. +Dapr provides health checking probes that can be used as readiness or liveness of Dapr. ## Get Dapr health state -Gets the health state for Dapr. +Gets the health state for Dapr by either: +- Waiting for a specific health check against `v1.0/healthz/outbound`; or +- Waiting for the Dapr HTTP port to become available -### HTTP Request +### Wait for Dapr HTTP port to become available + +With this behavior, Dapr waits for the Dapr HTTP port to become available to + +#### HTTP Request ``` GET http://localhost:/v1.0/healthz ``` -### HTTP Response Codes +#### HTTP Response Codes Code | Description ---- | ----------- -204 | dapr is healthy -500 | dapr is not healthy +204 | Dapr is healthy +500 | Dapr is not healthy -### URL Parameters +#### URL Parameters Parameter | Description --------- | ----------- -daprPort | The Dapr port. +daprPort | The Dapr port -### Examples +#### Examples ```shell curl -i http://localhost:3500/v1.0/healthz ``` +### Wait for specific health check against `/outbound` path + +With this behavior, Dapr waits for a successful response from `v1.0/healthz/outbound`, rather than waiting for the Dapr HTTP port to be available. This provides a more explict implementation that is better isolated from accidental change. + +For example, [in the .NET SDK,](https://github.com/dapr/dotnet-sdk/blob/17f849b17505b9a61be1e7bd3e69586718b9fdd3/src/Dapr.Client/DaprClientGrpc.cs#L1758-L1785) if the ordering of a Dapr runtime init ever changed (accidentally or deliberately), and the Dapr HTTP port was open _before_ all components were initialized, this would cause a break in behavior. + +#### HTTP Request + +``` +GET http://localhost:/v1.0/healthz/outbound +``` + +#### HTTP Response Codes + +Code | Description +---- | ----------- +204 | Dapr is healthy +500 | Dapr is not healthy + +#### URL Parameters + +Parameter | Description +--------- | ----------- +daprPort | The Dapr port + +#### Examples + +```shell +curl -i http://localhost:3500/v1.0/healthz/outbound +``` + +## Related articles + +- [Sidecar health]({{< ref "sidecar-health.md" >}}) +- [App health]({{< ref "app-health.md" >}}) \ No newline at end of file From 2fb2ed36265e32cfc57193f86ec030801b13deaa Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Thu, 22 Feb 2024 13:05:28 -0500 Subject: [PATCH 2/9] update diagram Signed-off-by: Hannah Hunter --- .../en/operations/resiliency/health-checks/sidecar-health.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/daprdocs/content/en/operations/resiliency/health-checks/sidecar-health.md b/daprdocs/content/en/operations/resiliency/health-checks/sidecar-health.md index ac679055631..d611da60df1 100644 --- a/daprdocs/content/en/operations/resiliency/health-checks/sidecar-health.md +++ b/daprdocs/content/en/operations/resiliency/health-checks/sidecar-health.md @@ -13,9 +13,9 @@ Dapr provides a way to determine its health using an [HTTP `/healthz` endpoint]( In this guide, you learn how the Dapr `/healthz` endpoint integrate with health probes from the application hosting platform (for example, Kubernetes). -The following diagram demonstrates how Dapr checks for outbound health connections from the sidecar using `v1.0/healthz/outbound`, as shown by the green boundary lines. With this behavior, Dapr waits for a successful response from `v1.0/healthz/outbound`, rather than waiting for the Dapr HTTP port to be available. This provides a more explict implementation that is better isolated from accidental change. +The following diagram demonstrates how Dapr checks for outbound health connections from the sidecar using `v1.0/healthz/outbound`, as shown by the green boundary lines. With this behavior, Dapr waits for a successful response from `v1.0/healthz/outbound`, rather than waiting for the Dapr HTTP port to be available (as shown by the red boundary lines). This provides a more explict implementation that is better isolated from accidental change. -Diagram of Dapr services interacting +Diagram of Dapr checking oubound health connections. When deploying Dapr to a hosting platform like Kubernetes, the Dapr health endpoint is automatically configured for you. From 4abce50327ab8c0382cd4928d90c5cf39f390345 Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Mon, 26 Feb 2024 10:15:24 -0500 Subject: [PATCH 3/9] add diagram Signed-off-by: Hannah Hunter --- daprdocs/static/images/healthz-outbound.png | Bin 0 -> 63668 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 daprdocs/static/images/healthz-outbound.png diff --git a/daprdocs/static/images/healthz-outbound.png b/daprdocs/static/images/healthz-outbound.png new file mode 100644 index 0000000000000000000000000000000000000000..457759548d2a71b12ec22fbd5204f2d1d817bdd7 GIT binary patch literal 63668 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
-rvJ5Nd}b4w*twk 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

4Yz%v;_8Yo#Pjz+lyUOtkI>$l*(}Ac+&-!| zgvM*%a^{ZzzyjmpEB2+TH5kC}WC+PKz1D7GiTW;+>r_(Btdb!XGmxw8B^bxkYO&&i zZheit#L!>IwfCnU;L}&)W>Dl1dFEN(5}uIE96;s({4_TKjPb$v6NwUm$A-E0x2q4P z$W}_Luky-$BqVGO!msgZcpJ)r7S|se?vY+wS{nD7Ekca-O7v2T08}=Nv@fI8FaazT zFuWW*l_eE^Z>K(C5D>1&SOGvRXUj;!Fl|$$)qB+4ivS3N5y6#1F1}#i4;_AU%zxo;62IlhVr{rtdh6#|q`gjp1cDg}?M|EHtv%;Xpga!+m z%x)e99ov+!;OuVgX8=AVRHvnW&Mq1nsvvl?k^jT=Vc#BBXM-nxQyPahA5zHvj%n9$ zur258B&F`I6%UvnPXoYwJw-@fumwdW=VQM~NI$GMrvu9-hnvh%x|L?Ufw|tn3F}TR zPHfjtH0)36yC50Y!kPwL8rgtK97n?_P))E!y@S>1>nZENh7WyoHBJomcZZUdo zj$)q3;7K3?`E6pe3>_Cf89oGXJLaJD?8+MstDlP86x@d^eA^~w{HwPxY*unL0YzG| zl>>l^cX^g`x90i6pU!kA?l%f$yY3PyKBa>Ppx^>!8m90EM0@{6+iFT6{;*@Noncki zr%6>_BibS(=y?;9P8n~cd?(#n{6^MRrtoLmwRvKxf*U85J%>>9zbD|3IsgJ2;;7$R z@N&NXA#K#eG>3z_`IJnPPmh$6s2QqZ3+nHMY~SyoFLCyRK-j z==L36rM|NiF3saw)!nNfeqS#<=_9ZFcz$i|wNj0vuI8+GL5R_6Y>O}Q3^%)GGyA&`o~ zBlHCLAUf+ZUxswpS&ZW9T{0y=P*z4ifIphe z;chq&=ly|uu*^9C#KRkeVNFyRgJhj@e(dd6jGzp31QeVb$-#0V`sZV5tW8;EDLlNW zYumD+R=Bf(Osy5`Ts4?bI!Vy4mSX>D69^UY*LwhmW-RN#Y)`$!y*+daH_A!I+*u5G zQfCttQ?hpTr#+=&Rns~a1qN*J-KeG?7_gJ#%jo^)GFrE@01((zxAF{kYGuZ>YpZOU z4QG85F~#+Iv16TCSRlVg)(pfIpj8Oq^#!}o6rq)!9>oHnCs=FcvPKH>umAXBa8hqK z{{@O#2^`Ge){J!qUYnoQ*1Es$%PXjipn|;uJc&-SMwKyHS%M)uxdVdoC-emP;y#Yy zE7!k$Nj1cs{Ku2xtm>*7`%Bj7JZ4cB6lDA@A8;_%VyfKV6+Fy_^Nfw>+uH=j_Wz_* zX9Cq_M;*}t+C}*UfdUMH=AM@}dvd%ZY(P0&hDQO=bl1hqt>g_kaZ?LucunrSFrdPG zPS2!NXG&UHT38sIsHJJmC_-Zk-f&RSrPNh@pF4&x3z(l3+iQ&lQ$&2 zth89?=RG!%BH$k1zcg?xZWVJYzi$b8?4gbSI0xwe n%c%W-lL-FbzRn5TQ#9m-YZ+fI)`@;Ttb1K;gWrqq*oFKX+C*v> literal 0 HcmV?d00001 From 23b530c76d8a1721c86c799ba37525e822f83cf3 Mon Sep 17 00:00:00 2001 From: Mark Fussell Date: Wed, 28 Feb 2024 21:14:22 -0800 Subject: [PATCH 4/9] Update sidecar-health.md Rewrote the start of this section --- .../health-checks/sidecar-health.md | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/daprdocs/content/en/operations/resiliency/health-checks/sidecar-health.md b/daprdocs/content/en/operations/resiliency/health-checks/sidecar-health.md index d611da60df1..22f2a9c325d 100644 --- a/daprdocs/content/en/operations/resiliency/health-checks/sidecar-health.md +++ b/daprdocs/content/en/operations/resiliency/health-checks/sidecar-health.md @@ -8,22 +8,29 @@ description: Dapr sidecar health checks Dapr provides a way to determine its health using an [HTTP `/healthz` endpoint]({{< ref health_api.md >}}). With this endpoint, the *daprd* process, or sidecar, can be: -- Probed for its health -- Determined for readiness and liveness +- Probed for its overall health +- Probed for Dapr sidecar readiness during initialization +- Determined for readiness and liveness with Kubernetes -In this guide, you learn how the Dapr `/healthz` endpoint integrate with health probes from the application hosting platform (for example, Kubernetes). +In this guide, you learn how the Dapr `/healthz` endpoint integrate with health probes from the application hosting platform (for example, Kubernetes) as well as the Dapr SDKs. -The following diagram demonstrates how Dapr checks for outbound health connections from the sidecar using `v1.0/healthz/outbound`, as shown by the green boundary lines. With this behavior, Dapr waits for a successful response from `v1.0/healthz/outbound`, rather than waiting for the Dapr HTTP port to be available (as shown by the red boundary lines). This provides a more explict implementation that is better isolated from accidental change. +{{% alert title="Note" color="primary" %}} +Dapr actors also have a health API endpoint where Dapr probes the application for a response to a signal from Dapr that the actor application is healthy and running. See [actor health API]({{< ref "actors_api.md#health-check" >}}). +{{% /alert %}} + +The following diagram shows the steps when a Dapr sidecar starts, the healthz endpoint and when the App channel is initialized. Diagram of Dapr checking oubound health connections. -When deploying Dapr to a hosting platform like Kubernetes, the Dapr health endpoint is automatically configured for you. +## Outbound health endpoint +The `v1.0/healthz/` endpoint is used to wait when all components are initialized, the Dapr HTTP port to be available _and_ the app channel is initialized, as shown by the red boundary lines. This is used to check the complete initialization of the Dapr sidecar and its health. On the other hand, the `v1.0/healthz/outbound` endpoint returns successfully when all the components are initialized, the Dapr HTTP port to be available, but the app channel is not yet established as shown by the green boundary lines. -{{% alert title="Note" color="primary" %}} -Dapr actors also have a health API endpoint where Dapr probes the application for a response to a signal from Dapr that the actor application is healthy and running. See [actor health API]({{< ref "actors_api.md#health-check" >}}). -{{% /alert %}} +In the Dapr SDKs the `waitForSidecar` method (for example .NET and Java SDKs) uses for this specific check with the `v1.0/healthz/outbound` endpoint. Using this behavior, Dapr waits for a successful response from `v1.0/healthz/outbound`, rather than waiting for the app channel to be available (as shown by the red boundary lines) with the v1.0/healthz/ endpoint. This approach enables your application to perform calls on the Dapr sidecar APIs before the app channel is initalized, for example reading secrets with the secrets API. + +If you are using the `waitForSidecar` method on the SDKs then the correct initialization is performed. Otherwise you can call the `v1.0/healthz/outbound` endpoint during initalization, and if successesful, then you can call the Dapr sidecar APIs. ## Health endpoint: Integration with Kubernetes +When deploying Dapr to a hosting platform like Kubernetes, the Dapr health endpoint is automatically configured for you. Kubernetes uses *readiness* and *liveness* probes to determines the health of the container. From 3f24031fd9ad77589d4283adfda7ae8170219ce0 Mon Sep 17 00:00:00 2001 From: Mark Fussell Date: Wed, 28 Feb 2024 22:31:16 -0800 Subject: [PATCH 5/9] Update health_api.md Edited this PR --- daprdocs/content/en/reference/api/health_api.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/daprdocs/content/en/reference/api/health_api.md b/daprdocs/content/en/reference/api/health_api.md index a943e4a8012..94de706a768 100644 --- a/daprdocs/content/en/reference/api/health_api.md +++ b/daprdocs/content/en/reference/api/health_api.md @@ -6,17 +6,17 @@ description: "Detailed documentation on the health API" weight: 1000 --- -Dapr provides health checking probes that can be used as readiness or liveness of Dapr. +Dapr provides health checking probes that can be used as readiness or liveness of Dapr and for initialization readiness from SDKs. ## Get Dapr health state Gets the health state for Dapr by either: -- Waiting for a specific health check against `v1.0/healthz/outbound`; or -- Waiting for the Dapr HTTP port to become available +- Check for sidecar health +- Check for the sidecar health, including component readiness, used during initialization. ### Wait for Dapr HTTP port to become available -With this behavior, Dapr waits for the Dapr HTTP port to become available to +Wait for all components to be initialized, the Dapr HTTP port to be available _and_ the app channel is initialized. For example, this endpoint is used with Kubernetes liveness probes. #### HTTP Request @@ -45,9 +45,9 @@ curl -i http://localhost:3500/v1.0/healthz ### Wait for specific health check against `/outbound` path -With this behavior, Dapr waits for a successful response from `v1.0/healthz/outbound`, rather than waiting for the Dapr HTTP port to be available. This provides a more explict implementation that is better isolated from accidental change. +Wait for all components to be initialized, the Dapr HTTP port to be available, however the app channel is not yet established. This endpoint enables your application to perform calls on the Dapr sidecar APIs before the app channel is initalized, for example reading secrets with the secrets API. For example used in the Dapr SDKs `waitForSidecar` method (for example .NET and Java SDKs) to check sidecar is initialized correctly ready for any calls. -For example, [in the .NET SDK,](https://github.com/dapr/dotnet-sdk/blob/17f849b17505b9a61be1e7bd3e69586718b9fdd3/src/Dapr.Client/DaprClientGrpc.cs#L1758-L1785) if the ordering of a Dapr runtime init ever changed (accidentally or deliberately), and the Dapr HTTP port was open _before_ all components were initialized, this would cause a break in behavior. +For example, the [Java SDK](https://docs.dapr.io/developing-applications/sdks/java/java-client/#wait-for-sidecar) and [the .NET SDK](https://github.com/dapr/dotnet-sdk/blob/17f849b17505b9a61be1e7bd3e69586718b9fdd3/src/Dapr.Client/DaprClientGrpc.cs#L1758-L1785) uses this endpoint for initialization. #### HTTP Request @@ -77,4 +77,4 @@ curl -i http://localhost:3500/v1.0/healthz/outbound ## Related articles - [Sidecar health]({{< ref "sidecar-health.md" >}}) -- [App health]({{< ref "app-health.md" >}}) \ No newline at end of file +- [App health]({{< ref "app-health.md" >}}) From 103ea58a33049f8b56d487ea95c7e01d2b6f1136 Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Fri, 1 Mar 2024 12:10:59 -0500 Subject: [PATCH 6/9] updates per mark Signed-off-by: Hannah Hunter --- daprdocs/content/en/reference/api/health_api.md | 5 +++++ daprdocs/content/en/reference/environment/_index.md | 1 + 2 files changed, 6 insertions(+) diff --git a/daprdocs/content/en/reference/api/health_api.md b/daprdocs/content/en/reference/api/health_api.md index a943e4a8012..9fb483b804f 100644 --- a/daprdocs/content/en/reference/api/health_api.md +++ b/daprdocs/content/en/reference/api/health_api.md @@ -49,6 +49,11 @@ With this behavior, Dapr waits for a successful response from `v1.0/healthz/outb For example, [in the .NET SDK,](https://github.com/dapr/dotnet-sdk/blob/17f849b17505b9a61be1e7bd3e69586718b9fdd3/src/Dapr.Client/DaprClientGrpc.cs#L1758-L1785) if the ordering of a Dapr runtime init ever changed (accidentally or deliberately), and the Dapr HTTP port was open _before_ all components were initialized, this would cause a break in behavior. +Currently supported in the: +- [.NET SDK](https://github.com/dapr/dotnet-sdk/blob/17f849b17505b9a61be1e7bd3e69586718b9fdd3/src/Dapr.Client/DaprClientGrpc.cs#L1758-L1785) +- [Java SDK](https://github.com/dapr/java-sdk/blob/2f5947392a33bc7911e6669601ddb9e8b59b58fe/sdk/src/main/java/io/dapr/client/DaprClientHttp.java#L143-L165) +- [Python SDK](https://github.com/dapr/python-sdk/blob/0b7aafdab1d4fade424b1b6c9569329ad10bb516/dapr/clients/http/client.py#L52) + #### HTTP Request ``` diff --git a/daprdocs/content/en/reference/environment/_index.md b/daprdocs/content/en/reference/environment/_index.md index e2ce895ea82..d5ed2d529c1 100644 --- a/daprdocs/content/en/reference/environment/_index.md +++ b/daprdocs/content/en/reference/environment/_index.md @@ -29,3 +29,4 @@ The following table lists the environment variables used by the Dapr runtime, CL | DAPR_COMPONENTS_SOCKETS_EXTENSION | .NET and Java pluggable component SDKs | A per-SDK configuration that indicates the default file extension applied to socket files created by the SDKs. Not a Dapr-enforced behavior. | | DAPR_PLACEMENT_METADATA_ENABLED | Dapr placement | Enable an endpoint for the Placement service that exposes placement table information on actor usage. Set to `true` to enable in self-hosted mode. [Learn more about the Placement API]({{< ref placement_api.md >}}) | | DAPR_HOST_IP | Dapr sidecar | The host's chosen IP address. If not specified, will loop over the network interfaces and select the first non-loopback address it finds.| +| DAPR_HEALTH_TIMEOUT | SDKs | Sets the time on the "wait for sidecar" availability. Overrides the default timeout setting of 60 seconds. | \ No newline at end of file From e176899a7daa02422b6312dfa7635cb7409a13be Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Fri, 1 Mar 2024 12:19:59 -0500 Subject: [PATCH 7/9] edit and add cross-linking Signed-off-by: Hannah Hunter --- .../health-checks/sidecar-health.md | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/daprdocs/content/en/operations/resiliency/health-checks/sidecar-health.md b/daprdocs/content/en/operations/resiliency/health-checks/sidecar-health.md index 22f2a9c325d..e89a0d5f0fe 100644 --- a/daprdocs/content/en/operations/resiliency/health-checks/sidecar-health.md +++ b/daprdocs/content/en/operations/resiliency/health-checks/sidecar-health.md @@ -23,11 +23,29 @@ The following diagram shows the steps when a Dapr sidecar starts, the healthz en Diagram of Dapr checking oubound health connections. ## Outbound health endpoint -The `v1.0/healthz/` endpoint is used to wait when all components are initialized, the Dapr HTTP port to be available _and_ the app channel is initialized, as shown by the red boundary lines. This is used to check the complete initialization of the Dapr sidecar and its health. On the other hand, the `v1.0/healthz/outbound` endpoint returns successfully when all the components are initialized, the Dapr HTTP port to be available, but the app channel is not yet established as shown by the green boundary lines. -In the Dapr SDKs the `waitForSidecar` method (for example .NET and Java SDKs) uses for this specific check with the `v1.0/healthz/outbound` endpoint. Using this behavior, Dapr waits for a successful response from `v1.0/healthz/outbound`, rather than waiting for the app channel to be available (as shown by the red boundary lines) with the v1.0/healthz/ endpoint. This approach enables your application to perform calls on the Dapr sidecar APIs before the app channel is initalized, for example reading secrets with the secrets API. +As shown by the red boundary lines in the diagram above, the `v1.0/healthz/` endpoint is used to wait for when: +- All components are initialized; +- The Dapr HTTP port is available; _and,_ +- The app channel is initialized. + +This is used to check the complete initialization of the Dapr sidecar and its health. + +On the other hand, as shown by the green boundary lines in the diagram above, the `v1.0/healthz/outbound` endpoint returns successfully when: +- All the components are initialized; +- The Dapr HTTP port is available; _but,_ +- The app channel is not yet established. + +In the Dapr SDKs, the `waitForSidecar`/`wait_until_ready` method (depending on [which SDK you use]({{< ref "#sdks-supporting-outbound-health-endpoint" >}})) is used for this specific check with the `v1.0/healthz/outbound` endpoint. Using this behavior, instead of waiting for the app channel to be available (see: red boundary lines) with the `v1.0/healthz/` endpoint, Dapr waits for a successful response from `v1.0/healthz/outbound`. This approach enables your application to perform calls on the Dapr sidecar APIs before the app channel is initalized - for example, reading secrets with the secrets API. + +If you are using the `waitForSidecar`/`wait_until_ready` method on the SDKs, then the correct initialization is performed. Otherwise, you can call the `v1.0/healthz/outbound` endpoint during initalization, and if successesful, you can call the Dapr sidecar APIs. + +### SDKs supporting outbound health endpoint +Currently, the `v1.0/healthz/outbound` endpoint is supported in the: +- [.NET SDK](https://github.com/dapr/dotnet-sdk/blob/17f849b17505b9a61be1e7bd3e69586718b9fdd3/src/Dapr.Client/DaprClientGrpc.cs#L1758-L1785) +- [Java SDK](https://github.com/dapr/java-sdk/blob/2f5947392a33bc7911e6669601ddb9e8b59b58fe/sdk/src/main/java/io/dapr/client/DaprClientHttp.java#L143-L165) +- [Python SDK](https://github.com/dapr/python-sdk/blob/0b7aafdab1d4fade424b1b6c9569329ad10bb516/dapr/clients/http/client.py#L52) -If you are using the `waitForSidecar` method on the SDKs then the correct initialization is performed. Otherwise you can call the `v1.0/healthz/outbound` endpoint during initalization, and if successesful, then you can call the Dapr sidecar APIs. ## Health endpoint: Integration with Kubernetes When deploying Dapr to a hosting platform like Kubernetes, the Dapr health endpoint is automatically configured for you. From d9489640f8db7a5a52210e4b24ea508f852617b2 Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Mon, 4 Mar 2024 10:31:26 -0500 Subject: [PATCH 8/9] mark review Signed-off-by: Hannah Hunter --- .../resiliency/health-checks/sidecar-health.md | 13 +++++++------ daprdocs/content/en/reference/api/health_api.md | 10 +++++----- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/daprdocs/content/en/operations/resiliency/health-checks/sidecar-health.md b/daprdocs/content/en/operations/resiliency/health-checks/sidecar-health.md index e89a0d5f0fe..3c356db553b 100644 --- a/daprdocs/content/en/operations/resiliency/health-checks/sidecar-health.md +++ b/daprdocs/content/en/operations/resiliency/health-checks/sidecar-health.md @@ -12,13 +12,13 @@ Dapr provides a way to determine its health using an [HTTP `/healthz` endpoint]( - Probed for Dapr sidecar readiness during initialization - Determined for readiness and liveness with Kubernetes -In this guide, you learn how the Dapr `/healthz` endpoint integrate with health probes from the application hosting platform (for example, Kubernetes) as well as the Dapr SDKs. +In this guide, you learn how the Dapr `/healthz` endpoint integrates with health probes from the application hosting platform (for example, Kubernetes) as well as the Dapr SDKs. {{% alert title="Note" color="primary" %}} Dapr actors also have a health API endpoint where Dapr probes the application for a response to a signal from Dapr that the actor application is healthy and running. See [actor health API]({{< ref "actors_api.md#health-check" >}}). {{% /alert %}} -The following diagram shows the steps when a Dapr sidecar starts, the healthz endpoint and when the App channel is initialized. +The following diagram shows the steps when a Dapr sidecar starts, the healthz endpoint and when the app channel is initialized. Diagram of Dapr checking oubound health connections. @@ -31,6 +31,8 @@ As shown by the red boundary lines in the diagram above, the `v1.0/healthz/` end This is used to check the complete initialization of the Dapr sidecar and its health. +Setting the `DAPR_HEALTH_TIMEOUT` environment variable lets you control the health timeout, which, for example, can be important in different environments with higher latency. + On the other hand, as shown by the green boundary lines in the diagram above, the `v1.0/healthz/outbound` endpoint returns successfully when: - All the components are initialized; - The Dapr HTTP port is available; _but,_ @@ -42,10 +44,9 @@ If you are using the `waitForSidecar`/`wait_until_ready` method on the SDKs, the ### SDKs supporting outbound health endpoint Currently, the `v1.0/healthz/outbound` endpoint is supported in the: -- [.NET SDK](https://github.com/dapr/dotnet-sdk/blob/17f849b17505b9a61be1e7bd3e69586718b9fdd3/src/Dapr.Client/DaprClientGrpc.cs#L1758-L1785) -- [Java SDK](https://github.com/dapr/java-sdk/blob/2f5947392a33bc7911e6669601ddb9e8b59b58fe/sdk/src/main/java/io/dapr/client/DaprClientHttp.java#L143-L165) -- [Python SDK](https://github.com/dapr/python-sdk/blob/0b7aafdab1d4fade424b1b6c9569329ad10bb516/dapr/clients/http/client.py#L52) - +- [.NET SDK]({{< ref "dotnet-client.md#wait-for-sidecar" >}}) +- [Java SDK]({{< ref "java-client.md#wait-for-sidecar" >}}) +- [Python SDK]({{< ref "python-client.md#health-timeout" >}}) ## Health endpoint: Integration with Kubernetes When deploying Dapr to a hosting platform like Kubernetes, the Dapr health endpoint is automatically configured for you. diff --git a/daprdocs/content/en/reference/api/health_api.md b/daprdocs/content/en/reference/api/health_api.md index d420e7cabca..6f69ddbfb48 100644 --- a/daprdocs/content/en/reference/api/health_api.md +++ b/daprdocs/content/en/reference/api/health_api.md @@ -47,12 +47,12 @@ curl -i http://localhost:3500/v1.0/healthz Wait for all components to be initialized, the Dapr HTTP port to be available, however the app channel is not yet established. This endpoint enables your application to perform calls on the Dapr sidecar APIs before the app channel is initalized, for example reading secrets with the secrets API. For example used in the Dapr SDKs `waitForSidecar` method (for example .NET and Java SDKs) to check sidecar is initialized correctly ready for any calls. -For example, the [Java SDK](https://docs.dapr.io/developing-applications/sdks/java/java-client/#wait-for-sidecar) and [the .NET SDK](https://github.com/dapr/dotnet-sdk/blob/17f849b17505b9a61be1e7bd3e69586718b9fdd3/src/Dapr.Client/DaprClientGrpc.cs#L1758-L1785) uses this endpoint for initialization. +For example, the [Java SDK]({{< ref "java-client.md#wait-for-sidecar" >}}) and [the .NET SDK]({{< ref "dotnet-client.md#wait-for-sidecar" >}}) uses this endpoint for initialization. -Currently supported in the: -- [.NET SDK](https://github.com/dapr/dotnet-sdk/blob/17f849b17505b9a61be1e7bd3e69586718b9fdd3/src/Dapr.Client/DaprClientGrpc.cs#L1758-L1785) -- [Java SDK](https://github.com/dapr/java-sdk/blob/2f5947392a33bc7911e6669601ddb9e8b59b58fe/sdk/src/main/java/io/dapr/client/DaprClientHttp.java#L143-L165) -- [Python SDK](https://github.com/dapr/python-sdk/blob/0b7aafdab1d4fade424b1b6c9569329ad10bb516/dapr/clients/http/client.py#L52) +Currently, the `v1.0/healthz/outbound` endpoint is supported in the: +- [.NET SDK]({{< ref "dotnet-client.md#wait-for-sidecar" >}}) +- [Java SDK]({{< ref "java-client.md#wait-for-sidecar" >}}) +- [Python SDK]({{< ref "python-client.md#health-timeout" >}}) #### HTTP Request From e4c904b4757bdee128df88c8c9ec2e00113372d0 Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Mon, 4 Mar 2024 14:48:33 -0500 Subject: [PATCH 9/9] link to js code Signed-off-by: Hannah Hunter --- .../en/operations/resiliency/health-checks/sidecar-health.md | 2 ++ daprdocs/content/en/reference/api/health_api.md | 1 + 2 files changed, 3 insertions(+) diff --git a/daprdocs/content/en/operations/resiliency/health-checks/sidecar-health.md b/daprdocs/content/en/operations/resiliency/health-checks/sidecar-health.md index 3c356db553b..760c0beab41 100644 --- a/daprdocs/content/en/operations/resiliency/health-checks/sidecar-health.md +++ b/daprdocs/content/en/operations/resiliency/health-checks/sidecar-health.md @@ -47,6 +47,8 @@ Currently, the `v1.0/healthz/outbound` endpoint is supported in the: - [.NET SDK]({{< ref "dotnet-client.md#wait-for-sidecar" >}}) - [Java SDK]({{< ref "java-client.md#wait-for-sidecar" >}}) - [Python SDK]({{< ref "python-client.md#health-timeout" >}}) +- [JavaScript SDK](https://github.com/dapr/js-sdk/blob/4189a3d2ad6897406abd766f4ccbf2300c8f8852/src/interfaces/Client/IClientHealth.ts#L14) + ## Health endpoint: Integration with Kubernetes When deploying Dapr to a hosting platform like Kubernetes, the Dapr health endpoint is automatically configured for you. diff --git a/daprdocs/content/en/reference/api/health_api.md b/daprdocs/content/en/reference/api/health_api.md index 6f69ddbfb48..5f9c5dad90a 100644 --- a/daprdocs/content/en/reference/api/health_api.md +++ b/daprdocs/content/en/reference/api/health_api.md @@ -53,6 +53,7 @@ Currently, the `v1.0/healthz/outbound` endpoint is supported in the: - [.NET SDK]({{< ref "dotnet-client.md#wait-for-sidecar" >}}) - [Java SDK]({{< ref "java-client.md#wait-for-sidecar" >}}) - [Python SDK]({{< ref "python-client.md#health-timeout" >}}) +- [JavaScript SDK](https://github.com/dapr/js-sdk/blob/4189a3d2ad6897406abd766f4ccbf2300c8f8852/src/interfaces/Client/IClientHealth.ts#L14) #### HTTP Request