snapshot of https://github.com/grpc/grpc-go.git (master, 2026-09-15; blobs > 131072B omitted)
Some checks failed
codecov / upload (push) Failing after 13m59s
CodeQL / Analyze (push) Failing after 1s
Testing / vet-proto (push) Failing after 1s
Testing / tests (arm, latest) (push) Waiting to run
Testing / extras (latest) (push) Failing after 1s
Testing / static checks (latest-1) (push) Failing after 1s
Testing / tests (-race, latest) (push) Failing after 1s
Testing / tests (i386, latest) (push) Failing after 1s
Testing / tests (latest) (push) Failing after 1s
Testing / tests (latest-1) (push) Failing after 1s
Lock Threads / lock (push) Failing after 1s
govulncheck / govulncheck (.) (push) Failing after 1s
govulncheck / govulncheck (./cmd/protoc-gen-go-grpc) (push) Failing after 1s
govulncheck / govulncheck (./gcp/observability) (push) Failing after 1s
govulncheck / govulncheck (./security/advancedtls) (push) Failing after 1s
govulncheck / govulncheck (./stats/opencensus) (push) Failing after 1s
Stale bot / stale (push) Failing after 1s

This commit is contained in:
upstream-mirror
2026-09-15 20:40:15 +05:00
commit e241b33f26
1365 changed files with 339570 additions and 0 deletions

View File

@@ -0,0 +1,74 @@
# Health
gRPC provides a health library to communicate a system's health to their
clients. It works by providing a service definition via the
[health/v1](https://github.com/grpc/grpc-proto/blob/master/grpc/health/v1/health.proto)
api.
Clients use the health library to gracefully avoid servers that encounter
issues. Most languages provide an out-of-box implementation, which makes it
interoperable between systems.
## Try it
```
go run server/main.go -port=50051 -sleep=5s
go run server/main.go -port=50052 -sleep=10s
```
```
go run client/main.go
```
## Explanation
### Client
Clients have two ways to monitor a server's health. They use `Check()` to probe
a server's health or `Watch()` to observe changes.
In most cases, clients do not directly check backend servers. Instead, they do
this transparently when you specify a `healthCheckConfig` in the [service
config](https://github.com/grpc/proposal/blob/master/A17-client-side-health-checking.md#service-config-changes)
and import the [health
package](https://pkg.go.dev/google.golang.org/grpc/health). The `serviceName` in
`healthCheckConfig` is used in the health check when connections are
established. An empty string (`""`) typically indicates the overall health of a
server.
```go
// import grpc/health to enable transparent client side checking
import _ "google.golang.org/grpc/health"
serviceConfig := grpc.WithDefaultServiceConfig(`{
"loadBalancingPolicy": "round_robin",
"healthCheckConfig": {
"serviceName": ""
}
}`)
conn, err := grpc.NewClient(..., serviceConfig)
```
See [A17 - Client-Side Health
Checking](https://github.com/grpc/proposal/blob/master/A17-client-side-health-checking.md)
for more details.
### Server
Servers control their serving status. They do this by inspecting dependent
systems, then update their status accordingly. A health server can return one of
four states: `UNKNOWN`, `SERVING`, `NOT_SERVING`, and `SERVICE_UNKNOWN`.
`UNKNOWN` indicates the system does not yet know the current state. Servers
often show this state at startup.
`SERVING` means that the system is healthy and ready to service requests.
Conversely, `NOT_SERVING` indicates the system is unable to service requests at
the time.
`SERVICE_UNKNOWN` communicates the `serviceName` requested by the client is not
known by the server. This status is only reported by the `Watch()` call.
A server may toggle its health using
`healthServer.SetServingStatus("serviceName", servingStatus)`.

View File

@@ -0,0 +1,88 @@
/*
*
* Copyright 2020 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
// Binary client demonstrates how to check and observe gRPC server health using
// the health library.
package main
import (
"context"
"flag"
"fmt"
"log"
"time"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
pb "google.golang.org/grpc/examples/features/proto/echo"
_ "google.golang.org/grpc/health" // REQUIRED to enable health checks
"google.golang.org/grpc/resolver"
"google.golang.org/grpc/resolver/manual"
)
const serviceConfig = `{
"loadBalancingPolicy": "round_robin",
"healthCheckConfig": {
"serviceName": ""
}
}`
func callUnaryEcho(c pb.EchoClient) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
r, err := c.UnaryEcho(ctx, &pb.EchoRequest{})
if err != nil {
fmt.Println("UnaryEcho: _, ", err)
} else {
fmt.Println("UnaryEcho: ", r.GetMessage())
}
}
func main() {
flag.Parse()
r := manual.NewBuilderWithScheme("whatever")
r.InitialState(resolver.State{
Addresses: []resolver.Address{
{Addr: "localhost:50051"},
{Addr: "localhost:50052"},
},
})
address := fmt.Sprintf("%s:///unused", r.Scheme())
options := []grpc.DialOption{
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithResolvers(r),
// google.golang.org/grpc/health must also be imported
grpc.WithDefaultServiceConfig(serviceConfig),
}
conn, err := grpc.NewClient(address, options...)
if err != nil {
log.Fatalf("grpc.NewClient(%q): %v", address, err)
}
defer conn.Close()
echoClient := pb.NewEchoClient(conn)
for {
callUnaryEcho(echoClient)
time.Sleep(time.Second)
}
}

View File

@@ -0,0 +1,90 @@
/*
*
* Copyright 2020 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
// Binary server demonstrates how to manage and report its health status using
// the gRPC health library.
package main
import (
"context"
"flag"
"fmt"
"log"
"net"
"time"
"google.golang.org/grpc"
pb "google.golang.org/grpc/examples/features/proto/echo"
"google.golang.org/grpc/health"
healthgrpc "google.golang.org/grpc/health/grpc_health_v1"
healthpb "google.golang.org/grpc/health/grpc_health_v1"
)
var (
port = flag.Int("port", 50051, "the port to serve on")
sleep = flag.Duration("sleep", time.Second*5, "duration between changes in health")
system = "" // empty string represents the health of the system
)
type echoServer struct {
pb.UnimplementedEchoServer
}
func (e *echoServer) UnaryEcho(context.Context, *pb.EchoRequest) (*pb.EchoResponse, error) {
return &pb.EchoResponse{
Message: fmt.Sprintf("hello from localhost:%d", *port),
}, nil
}
var _ pb.EchoServer = &echoServer{}
func main() {
flag.Parse()
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
healthcheck := health.NewServer()
healthgrpc.RegisterHealthServer(s, healthcheck)
pb.RegisterEchoServer(s, &echoServer{})
go func() {
// asynchronously inspect dependencies and toggle serving status as needed
next := healthpb.HealthCheckResponse_SERVING
for {
healthcheck.SetServingStatus(system, next)
if next == healthpb.HealthCheckResponse_SERVING {
next = healthpb.HealthCheckResponse_NOT_SERVING
} else {
next = healthpb.HealthCheckResponse_SERVING
}
time.Sleep(*sleep)
}
}()
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}