diff --git a/server/cluster/cluster.go b/server/cluster/cluster.go index 35d3d4ad4f8..444220c0556 100644 --- a/server/cluster/cluster.go +++ b/server/cluster/cluster.go @@ -65,6 +65,7 @@ import ( "github.com/tikv/pd/pkg/syncer" "github.com/tikv/pd/pkg/tso" "github.com/tikv/pd/pkg/unsaferecovery" + "github.com/tikv/pd/pkg/utils/apiutil" "github.com/tikv/pd/pkg/utils/etcdutil" "github.com/tikv/pd/pkg/utils/keypath" "github.com/tikv/pd/pkg/utils/logutil" @@ -2504,6 +2505,7 @@ func CheckHealth(client *http.Client, members []*pdpb.Member) map[uint64]*pdpb.M for _, cURL := range member.ClientUrls { ctx, cancel := context.WithTimeout(context.Background(), clientTimeout) req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s%s", cURL, healthURL), http.NoBody) + req.Header.Set(apiutil.PDAllowFollowerHandleHeader, "true") if err != nil { log.Error("failed to new request", errs.ZapError(errs.ErrNewHTTPRequest, err)) cancel() diff --git a/tests/server/api/api_test.go b/tests/server/api/api_test.go index 859bf8cb56e..2c805d656e5 100644 --- a/tests/server/api/api_test.go +++ b/tests/server/api/api_test.go @@ -672,6 +672,42 @@ func (suite *redirectorTestSuite) TestAllowFollowerHandle() { re.NoError(err) } +func (suite *redirectorTestSuite) TestPing() { + re := suite.Require() + // Find a follower. + var follower *server.Server + leader := suite.cluster.GetLeaderServer() + for _, svr := range suite.cluster.GetServers() { + if svr != leader { + follower = svr.GetServer() + break + } + } + + for _, svr := range suite.cluster.GetServers() { + if svr.GetServer() != follower { + svr.Stop() + } + } + addr := follower.GetAddr() + "/pd/api/v1/ping" + request, err := http.NewRequest(http.MethodGet, addr, http.NoBody) + // ping request should not be redirected. + request.Header.Add(apiutil.PDAllowFollowerHandleHeader, "true") + re.NoError(err) + resp, err := tests.TestDialClient.Do(request) + re.NoError(err) + defer resp.Body.Close() + re.Equal(http.StatusOK, resp.StatusCode) + _, err = io.ReadAll(resp.Body) + re.NoError(err) + for _, svr := range suite.cluster.GetServers() { + if svr.GetServer() != follower { + re.NoError(svr.Run()) + } + } + re.NotEmpty(suite.cluster.WaitLeader()) +} + func (suite *redirectorTestSuite) TestNotLeader() { re := suite.Require() // Find a follower. diff --git a/tools/pd-ctl/pdctl/command/ping_command.go b/tools/pd-ctl/pdctl/command/ping_command.go index 7efa46180d1..be6d9a93a34 100644 --- a/tools/pd-ctl/pdctl/command/ping_command.go +++ b/tools/pd-ctl/pdctl/command/ping_command.go @@ -19,6 +19,8 @@ import ( "time" "github.com/spf13/cobra" + + "github.com/tikv/pd/pkg/utils/apiutil" ) const pingPrefix = "pd/api/v1/ping" @@ -35,7 +37,7 @@ func NewPingCommand() *cobra.Command { func showPingCommandFunc(cmd *cobra.Command, _ []string) { start := time.Now() - _, err := doRequest(cmd, pingPrefix, http.MethodGet, http.Header{}) + _, err := doRequest(cmd, pingPrefix, http.MethodGet, http.Header{apiutil.PDAllowFollowerHandleHeader: {"true"}}) if err != nil { cmd.Println(err) return