Skip to content

Commit

Permalink
add dynamic request worker number && Adjust configuration parameter
Browse files Browse the repository at this point in the history
Signed-off-by: ii2day <ji.li@daocloud.io>
  • Loading branch information
ii2day committed Nov 29, 2023
1 parent 5069599 commit 98b0ba9
Show file tree
Hide file tree
Showing 18 changed files with 114 additions and 66 deletions.
17 changes: 9 additions & 8 deletions charts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,15 @@
| ----------------------------------------------------------------------- | ----------------------------------------------------------------------- | ------------------------------------ |
| `feature.enableIPv4` | enable ipv4 | `true` |
| `feature.enableIPv6` | enable ipv6 | `true` |
| `feature.nethttp_defaultRequest_Qps` | qps for kind nethttp | `10` |
| `feature.nethttp_defaultRequest_MaxQps` | qps for kind nethttp | `100` |
| `feature.nethttp_defaultConcurrency` | concurrency for kind nethttp | `50` |
| `feature.nethttp_defaultMaxIdleConnsPerHost` | max idle connect for kind nethttp | `50` |
| `feature.nethttp_defaultRequest_DurationInSecond` | Duration In Second for kind nethttp | `2` |
| `feature.nethttp_defaultRequest_PerRequestTimeoutInMS` | PerRequest Timeout In MS for kind nethttp | `500` |
| `feature.nethttp_defaultFail_MeanDelayInMs` | mean delay in ms for kind nethttp | `2000` |
| `feature.netdns_defaultConcurrency` | concurrency for kind netdns | `50` |
| `feature.netReachRequestMaxQPS` | qps for kind NetReach | `10` |
| `feature.netReachMaxConcurrency` | concurrency for kind NetReach | `20` |
| `feature.appHttpHealthyMaxConcurrency` | concurrency for kind AppHttpHealthy | `10` |
| `feature.appHttpHealthyRequestMaxQps` | qps for kind AppHttpHealthy | `100` |
| `feature.netHttpDefaultMaxIdleConnsPerHost` | max idle connect for kind NetHttp | `50` |
| `feature.netHttpDefaultRequestDurationInSecond` | Duration In Second for kind NetHttp | `2` |
| `feature.netHttpDefaultRequestPerRequestTimeoutInMS` | PerRequest Timeout In MS for kind NetHttp | `500` |
| `feature.netDnsMaxConcurrency` | concurrency for kind NetDns | `20` |
| `feature.netDnsRequestMaxQPS` | qps for kind NetDns | `100` |
| `feature.agentDefaultTerminationGracePeriodMinutes` | agent termination after minutes | `60` |
| `feature.taskPollIntervalInSecond` | the interval to poll the task in controller and agent pod | `5` |
| `feature.multusPodAnnotationKey` | the multus annotation key for ip status | `k8s.v1.cni.cncf.io/networks-status` |
Expand Down
35 changes: 19 additions & 16 deletions charts/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,29 +38,32 @@ feature:
## @param feature.enableIPv6 enable ipv6
enableIPv6: true

## @param feature.nethttp_defaultRequest_Qps qps for kind nethttp
nethttp_defaultRequest_Qps: 10
## @param feature.netReachRequestMaxQPS qps for kind NetReach
netReachRequestMaxQPS: 10

## @param feature.nethttp_defaultRequest_MaxQps qps for kind nethttp
nethttp_defaultRequest_MaxQps: 100
## @param feature.netReachMaxConcurrency concurrency for kind NetReach
netReachMaxConcurrency: 20

## @param feature.nethttp_defaultConcurrency concurrency for kind nethttp
nethttp_defaultConcurrency: 50
## @param feature.appHttpHealthyMaxConcurrency concurrency for kind AppHttpHealthy
appHttpHealthyMaxConcurrency: 10

## @param feature.nethttp_defaultMaxIdleConnsPerHost max idle connect for kind nethttp
nethttp_defaultMaxIdleConnsPerHost: 50
## @param feature.appHttpHealthyRequestMaxQPS qps for kind AppHttpHealthy
appHttpHealthyRequestMaxQPS: 100

## @param feature.nethttp_defaultRequest_DurationInSecond Duration In Second for kind nethttp
nethttp_defaultRequest_DurationInSecond: 2
## @param feature.netHttpDefaultMaxIdleConnsPerHost max idle connect for kind NetHttp
netHttpDefaultMaxIdleConnsPerHost: 50

## @param feature.nethttp_defaultRequest_PerRequestTimeoutInMS PerRequest Timeout In MS for kind nethttp
nethttp_defaultRequest_PerRequestTimeoutInMS: 500
## @param feature.netHttpDefaultRequestDurationInSecond Duration In Second for kind NetHttp
netHttpDefaultRequestDurationInSecond: 2

## @param feature.nethttp_defaultFail_MeanDelayInMs mean delay in ms for kind nethttp
nethttp_defaultFail_MeanDelayInMs: 2000
## @param feature.netHttpDefaultRequestPerRequestTimeoutInMS PerRequest Timeout In MS for kind NetHttp
netHttpDefaultRequestPerRequestTimeoutInMS: 500

## @param feature.netdns_defaultConcurrency concurrency for kind netdns
netdns_defaultConcurrency: 50
## @param feature.netDnsMaxConcurrency concurrency for kind NetDns
netDnsMaxConcurrency: 20

## @param feature.netDnsRequestMaxQPS qps for kind NetDns
netDnsRequestMaxQPS: 100

## @param feature.agentDefaultTerminationGracePeriodMinutes agent termination after minutes
agentDefaultTerminationGracePeriodMinutes: 60
Expand Down
4 changes: 2 additions & 2 deletions docs/usage/debug-zh_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@

**Q: 想要使用更高的 QPS 应该如何设置?**
* A: 当 QPS 设置过大,会导致服务器资源占用过高,影响业务。为了防止在生产坏境出现误操作。kdoctor 在 webhook 中添加了 QPS 的检查。如果您想使用更高的 QPS
可通过参数设置 QPS 限制 `--set feature.nethttp_defaultRequest_MaxQps=1000`,也可以通过 kdoctor 的 configmap 中去更改 `nethttp_defaultRequest_MaxQps`
可通过参数设置 QPS 限制 `--set feature.appHttpHealthyRequestMaxQPS=1000`,`--set feature.netReachRequestMaxQPS=1000`,`--set feature.netDnsRequestMaxQPS=1000`,也可以通过 kdoctor 的 configmap 中去更改 ,
并重启 kdoctor 的相关 pod 重新加载 configmap。

**Q: 为什么我的任务无法达到期望的 QPS ?**
* A:无法达到 QPS 的期望原因有很多主要分为以下几种原因:
* 并发 worker 设置过低,kdoctor 可通过设置参数调整并发数 `--set feature.nethttp_defaultConcurrency=50``--set feature.netdns_defaultConcurrency=50`
* 并发 worker 设置过低,kdoctor 可通过设置参数调整并发数 `--set feature.netReachMaxConcurrency=50``--set feature.appHttpHealthyMaxConcurrency=50``--set feature.netDnsMaxConcurrency=50`
* kdoctor agent 分配资源不充足,可通过 kdoctor 的聚合报告`kubectl get kdoctorreport `查看任务消耗的 cpu 与 内存使用量,确定 kdoctor agent 资源分配是否充足。
```shell
~kubectl get kdoctorreport test-task -oyaml
Expand Down
4 changes: 2 additions & 2 deletions docs/usage/debug.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
**Q: How to achieve higher QPS?**
* A: When the QPS setting is too high, it can result in excessive server resource utilization, impacting business operations.
To prevent accidental misconfiguration in production environments, kdoctor has added QPS checks in the webhook.
* If you wish to use a higher QPS, you can set the QPS limit using the parameter `--set feature.nethttp_defaultRequest_MaxQps=1000`,You can also modify it through the configmap in kdoctor `nethttp_defaultRequest_MaxQps`,
* If you wish to use a higher QPS, you can set the QPS limit using the parameter `--set feature.appHttpHealthyRequestMaxQPS=1000`,`--set feature.netReachRequestMaxQPS=1000`,`--set feature.netDnsRequestMaxQPS=1000`,You can also modify it through the configmap in kdoctor,
And restart the relevant pods of kdoctor to reload the configmap.

**Q: Why is my task unable to achieve the desired QPS ?**
* A:There are several reasons why the expected QPS cannot be achieved, primarily categorized into the following reasons:
* The concurrency worker setting is too low. kdoctor can adjust the concurrency by setting the parameters `--set feature.nethttp_defaultConcurrency=50` and `--set feature.netdns_defaultConcurrency=50`.
* The concurrency worker setting is too low. kdoctor can adjust the concurrency by setting the parameters `--set feature.netReachMaxConcurrency=50``--set feature.appHttpHealthyMaxConcurrency=50``--set feature.netDnsMaxConcurrency=50`.
* The kdoctor agent may have insufficient resource allocation. You can use the kdoctor aggregate report `kubectl get kdoctorreport` to check the CPU and memory usage of the task. This will help you determine if the resource allocation for the kdoctor agent is sufficient.
```shell
~kubectl get kdoctorreport test-task -oyaml
Expand Down
8 changes: 4 additions & 4 deletions pkg/loadRequest/loadDns/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ import (
"github.com/miekg/dns"
"go.uber.org/zap"
"time"

config "github.com/kdoctor-io/kdoctor/pkg/types"
)

type RequestProtocol string
Expand All @@ -52,6 +50,7 @@ type DnsRequestData struct {
DnsServerAddr string
PerRequestTimeoutInMs int
Qps int
Workers int
DurationInSecond int
EnableLatencyMetric bool
}
Expand All @@ -68,11 +67,12 @@ func DnsRequest(logger *zap.Logger, reqData *DnsRequestData) (result *v1beta1.DN
reqData.TargetDomain = dns.Fqdn(reqData.TargetDomain)
logger.Sugar().Debugf("convert target domain to fqdn %v", reqData.TargetDomain)
}

duration := time.Duration(reqData.DurationInSecond) * time.Second

logger.Sugar().Infof("http request Concurrency=%d", reqData.Workers)

w := &Work{
Concurrency: config.AgentConfig.Configmap.NetdnsDefaultConcurrency,
Concurrency: reqData.Workers,
RequestTimeSecond: reqData.DurationInSecond,
QPS: reqData.Qps,
Timeout: reqData.PerRequestTimeoutInMs,
Expand Down
3 changes: 0 additions & 3 deletions pkg/loadRequest/loadDns/dns_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import (

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"

config "github.com/kdoctor-io/kdoctor/pkg/types"
)

func TestLoadDns(t *testing.T) {
Expand All @@ -18,5 +16,4 @@ func TestLoadDns(t *testing.T) {

var _ = BeforeSuite(func() {
// nothing to do
config.AgentConfig.Configmap.NetdnsDefaultConcurrency = 10
})
5 changes: 5 additions & 0 deletions pkg/loadRequest/loadDns/dns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ var _ = Describe("test dns ", Label("dns"), func() {
PerRequestTimeoutInMs: 5000,
DurationInSecond: 10,
Qps: 10,
Workers: 10,
}

log := logger.NewStdoutLogger("debug", "test")
Expand Down Expand Up @@ -57,6 +58,7 @@ var _ = Describe("test dns ", Label("dns"), func() {
PerRequestTimeoutInMs: 5000,
DurationInSecond: 10,
Qps: 10,
Workers: 10,
EnableLatencyMetric: true,
}

Expand Down Expand Up @@ -88,6 +90,7 @@ var _ = Describe("test dns ", Label("dns"), func() {
PerRequestTimeoutInMs: 5000,
DurationInSecond: 10,
Qps: 10,
Workers: 10,
}

log := logger.NewStdoutLogger("debug", "test")
Expand Down Expand Up @@ -117,6 +120,7 @@ var _ = Describe("test dns ", Label("dns"), func() {
PerRequestTimeoutInMs: 5000,
DurationInSecond: 10,
Qps: 10,
Workers: 10,
}

log := logger.NewStdoutLogger("debug", "test")
Expand Down Expand Up @@ -146,6 +150,7 @@ var _ = Describe("test dns ", Label("dns"), func() {
PerRequestTimeoutInMs: 5000,
DurationInSecond: 10,
Qps: 10,
Workers: 10,
}

log := logger.NewStdoutLogger("debug", "test")
Expand Down
6 changes: 3 additions & 3 deletions pkg/loadRequest/loadHttp/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import (
"go.uber.org/zap"

"github.com/kdoctor-io/kdoctor/pkg/k8s/apis/system/v1beta1"
config "github.com/kdoctor-io/kdoctor/pkg/types"
)

type HttpMethod string
Expand All @@ -51,6 +50,7 @@ type HttpRequestData struct {
Method HttpMethod
Url string
Qps int
Workers int
PerRequestTimeoutMS int
RequestTimeSecond int
Header map[string]string
Expand All @@ -73,12 +73,12 @@ func HttpRequest(logger *zap.Logger, reqData *HttpRequestData) *v1beta1.HttpMetr
req.Header.Set(k, v)
}

logger.Sugar().Infof("http request Concurrency=%d", config.AgentConfig.Configmap.NethttpDefaultConcurrency)
logger.Sugar().Infof("http request Concurrency=%d", reqData.Workers)

w := &Work{
Request: req,
RequestTimeSecond: reqData.RequestTimeSecond,
Concurrency: config.AgentConfig.Configmap.NethttpDefaultConcurrency,
Concurrency: reqData.Workers,
QPS: reqData.Qps,
Timeout: reqData.PerRequestTimeoutMS,
DisableCompression: reqData.DisableCompression,
Expand Down
2 changes: 1 addition & 1 deletion pkg/loadRequest/loadHttp/http_requester.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ func (b *Work) runWorker() {
InsecureSkipVerify: true,
ServerName: b.Request.Host,
},
MaxIdleConnsPerHost: config.AgentConfig.Configmap.NethttpDefaultMaxIdleConnsPerHost,
MaxIdleConnsPerHost: config.AgentConfig.Configmap.NetHttpDefaultMaxIdleConnsPerHost,
DisableCompression: b.DisableCompression,
DisableKeepAlives: b.DisableKeepAlives,
Proxy: http.ProxyURL(b.ProxyAddr),
Expand Down
3 changes: 0 additions & 3 deletions pkg/loadRequest/loadHttp/http_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import (

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"

config "github.com/kdoctor-io/kdoctor/pkg/types"
)

func TestLoadHttp(t *testing.T) {
Expand All @@ -18,5 +16,4 @@ func TestLoadHttp(t *testing.T) {

var _ = BeforeSuite(func() {
// nothing to do
config.AgentConfig.Configmap.NethttpDefaultConcurrency = 10
})
2 changes: 2 additions & 0 deletions pkg/loadRequest/loadHttp/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ var _ = Describe("test http ", Label("http"), func() {
PerRequestTimeoutMS: 10000,
RequestTimeSecond: 10,
Qps: 10,
Workers: 10,
Header: header,
}
log := logger.NewStdoutLogger("debug", "test")
Expand All @@ -51,6 +52,7 @@ var _ = Describe("test http ", Label("http"), func() {
RequestTimeSecond: 10,
EnableLatencyMetric: true,
Qps: 10,
Workers: 10,
Header: header,
}
log := logger.NewStdoutLogger("debug", "test")
Expand Down
10 changes: 10 additions & 0 deletions pkg/pluginManager/apphttphealthy/agentExecuteTask.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/kdoctor-io/kdoctor/pkg/pluginManager/types"
"github.com/kdoctor-io/kdoctor/pkg/resource"
"github.com/kdoctor-io/kdoctor/pkg/runningTask"
config "github.com/kdoctor-io/kdoctor/pkg/types"
"go.uber.org/zap"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/utils/pointer"
Expand Down Expand Up @@ -91,13 +92,22 @@ func (s *PluginAppHttpHealthy) AgentExecuteTask(logger *zap.Logger, ctx context.
target := instance.Spec.Target
request := instance.Spec.Request
successCondition := instance.Spec.SuccessCondition

var workers int
if request.QPS > config.AgentConfig.Configmap.AppHttpHealthyMaxConcurrency {
workers = config.AgentConfig.Configmap.AppHttpHealthyMaxConcurrency
} else {
workers = request.QPS
}

logger.Sugar().Infof("load test custom target: Method=%v, Url=%v , qps=%v, PerRequestTimeout=%vs, Duration=%vs", target.Method, target.Host, request.QPS, request.PerRequestTimeoutInMS, request.DurationInSecond)
task.TargetType = "HttpAppHealthy"
task.TargetNumber = 1
d := &loadHttp.HttpRequestData{
Method: loadHttp.HttpMethod(target.Method),
Url: target.Host,
Qps: request.QPS,
Workers: workers,
PerRequestTimeoutMS: request.PerRequestTimeoutInMS,
RequestTimeSecond: request.DurationInSecond,
Http2: target.Http2,
Expand Down
10 changes: 5 additions & 5 deletions pkg/pluginManager/apphttphealthy/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ func (s *PluginAppHttpHealthy) WebhookMutating(logger *zap.Logger, ctx context.C

if req.Spec.Request == nil {
m := &crd.NetHttpRequest{
DurationInSecond: types.ControllerConfig.Configmap.NethttpDefaultRequestDurationInSecond,
QPS: types.ControllerConfig.Configmap.NethttpDefaultRequestQps,
PerRequestTimeoutInMS: types.ControllerConfig.Configmap.NethttpDefaultRequestPerRequestTimeoutInMS,
DurationInSecond: types.ControllerConfig.Configmap.NetHttpDefaultRequestDurationInSecond,
QPS: types.ControllerConfig.Configmap.NetHttpDefaultRequestQPS,
PerRequestTimeoutInMS: types.ControllerConfig.Configmap.NetHttpDefaultRequestPerRequestTimeoutInMS,
}
req.Spec.Request = m
logger.Sugar().Debugf("set default Request for HttpAppHealthy %v", req.Name)
Expand Down Expand Up @@ -94,8 +94,8 @@ func (s *PluginAppHttpHealthy) WebhookValidateCreate(logger *zap.Logger, ctx con

// validate request
if true {
if r.Spec.Request.QPS >= types.ControllerConfig.Configmap.NethttpDefaultRequestMaxQps {
s := fmt.Sprintf("HttpAppHealthy %v requires qps %v bigger than maximum %v", r.Name, r.Spec.Request.QPS, types.ControllerConfig.Configmap.NethttpDefaultRequestMaxQps)
if r.Spec.Request.QPS >= types.ControllerConfig.Configmap.AppHttpHealthyRequestMaxQps {
s := fmt.Sprintf("HttpAppHealthy %v requires qps %v bigger than maximum %v", r.Name, r.Spec.Request.QPS, types.ControllerConfig.Configmap.AppHttpHealthyRequestMaxQps)
logger.Error(s)
return apierrors.NewBadRequest(s)
}
Expand Down
Loading

0 comments on commit 98b0ba9

Please sign in to comment.