AlexStocks commented on code in PR #3502:
URL: https://github.com/apache/dubbo-go/pull/3502#discussion_r3662225568


##########
tools/benchmark/scripts/run_all.sh:
##########
@@ -0,0 +1,168 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+
+set -e
+
+BASE_DIR=$(cd "$(dirname "$0")/.." && pwd)
+LOG_DIR="$BASE_DIR/logs"
+REPORT_DIR="$BASE_DIR/report"
+DATA_DIR="$BASE_DIR/data"
+PID_FILE="/tmp/benchmark_server.pid"
+SEPARATOR="========================================"
+
+mkdir -p "$LOG_DIR"
+mkdir -p "$REPORT_DIR"
+mkdir -p "$DATA_DIR"
+
+echo "$SEPARATOR"
+echo "   Dubbo-Go Benchmark - Full Test Suite"
+echo "$SEPARATOR"
+
+echo "[INFO] Checking environment dependencies..."
+
+if ! command -v go > /dev/null 2>&1; then
+    echo "[ERROR] Go not installed, please install Go 1.25+"
+    exit 1
+fi
+
+echo "[INFO] Environment check passed"
+
+cleanup() {
+    echo "[INFO] Cleaning up resources..."
+    if [ -f "$PID_FILE" ]; then
+        pid=$(cat "$PID_FILE")
+        if kill -0 "$pid" 2>/dev/null; then
+            kill "$pid" 2>/dev/null || true
+            sleep 2
+            if kill -0 "$pid" 2>/dev/null; then
+                kill -9 "$pid" 2>/dev/null || true
+            fi
+        fi
+        rm -f "$PID_FILE"
+    fi
+}
+
+trap cleanup EXIT
+
+echo ""
+echo "[INFO] Compiling Dubbo-Go server..."
+cd "$BASE_DIR/server/dubbo-go"
+go build -o benchmark-dubbo-go main.go
+
+echo "[INFO] Compiling gRPC server..."
+cd "$BASE_DIR/server/grpc"
+go build -o benchmark-grpc main.go
+
+echo ""
+echo "[INFO] Compiling benchmark client..."
+cd "$BASE_DIR/client"
+go build -o benchmark-client main.go
+
+echo ""
+echo "[INFO] Starting full benchmark suite..."
+
+FRAMEWORKS=("dubbo-go" "grpc")
+PAYLOADS=("128" "1024" "16384" "1048576")
+SERIALIZATIONS=("protobuf")
+COMPRESSIONS=("none")
+CONCURRENCY=("50" "100")
+CALL_MODES=("unary")
+
+for framework in "${FRAMEWORKS[@]}"; do
+    echo ""
+    echo "[INFO] ==== Testing framework: $framework ===="
+    
+    case "$framework" in
+        dubbo-go)
+            SERVER_BIN="$BASE_DIR/server/dubbo-go/benchmark-dubbo-go"
+            SERVER_PORT=20000
+            ;;
+        grpc)
+            SERVER_BIN="$BASE_DIR/server/grpc/benchmark-grpc"
+            SERVER_PORT=50051
+            ;;
+        *)
+            echo "[WARNING] Skipping unknown framework: $framework"
+            continue
+            ;;
+    esac
+
+    for payload in "${PAYLOADS[@]}"; do
+        for serialization in "${SERIALIZATIONS[@]}"; do
+            for compression in "${COMPRESSIONS[@]}"; do
+                for concurrency in "${CONCURRENCY[@]}"; do
+                    for mode in "${CALL_MODES[@]}"; do
+                        echo ""
+                        echo 
"--------------------------------------------------------"
+                        echo "Test case: $framework | $payload bytes | 
$serialization | $compression | $concurrency concurrency | $mode"
+                        echo 
"--------------------------------------------------------"
+
+                        
LOG_FILE="$LOG_DIR/${framework}_${payload}_${serialization}_${compression}_${concurrency}_${mode}.log"
+                        
DATA_FILE="$DATA_DIR/${framework}_${payload}_${serialization}_${compression}_${concurrency}_${mode}.json"
+
+                        echo "[INFO] Starting server..."
+                        case "$framework" in
+                            dubbo-go)
+                                "$SERVER_BIN" --serialization "$serialization" 
--compression "$compression" --port "$SERVER_PORT" > "$LOG_FILE.server.log" 
2>&1 &
+                                ;;
+                            grpc)
+                                "$SERVER_BIN" --port "$SERVER_PORT" > 
"$LOG_FILE.server.log" 2>&1 &
+                                ;;
+                            *)
+                                echo "[ERROR] Unsupported framework: 
$framework"
+                                exit 1
+                                ;;
+                        esac
+                        pid=$!
+                        echo "$pid" > "$PID_FILE"
+
+                        sleep 3

Review Comment:
   [P2] sleep 3 无就绪探测
   服务器慢启动时客户端连未就绪端口会全失败但仍写结果文件,产生误导性数据。建议在跑客户端前 poll 端口/健康检查直到就绪或超时。



##########
tools/benchmark/client/clients/grpc_client.go:
##########
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package clients
+
+import (
+       "context"
+       "fmt"
+)
+
+import (
+       "google.golang.org/grpc"
+       "google.golang.org/grpc/credentials/insecure"
+)
+
+import (
+       benchmark "dubbo.apache.org/dubbo-go/v3/tools/benchmark/proto"
+)
+
+type GrpcClient struct {
+       conn     *grpc.ClientConn
+       client   benchmark.BenchmarkServiceClient
+       payload  []byte
+       callMode string
+}
+
+func NewGrpcClient(addr string, callMode string, payload []byte) (*GrpcClient, 
error) {
+       conn, err := grpc.Dial(addr, 
grpc.WithTransportCredentials(insecure.NewCredentials()))

Review Comment:
   [P2] grpc.Dial 已废弃
   grpc.Dial 在新版 grpc-go 已废弃,建议改用 grpc.NewClient(addr, 
grpc.WithTransportCredentials(insecure.NewCredentials()))(非阻塞、显式)。



##########
tools/benchmark/client/engine/engine.go:
##########
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package engine
+
+import (
+       "context"
+       "sync"
+       "sync/atomic"
+       "time"
+)
+
+import (
+       "github.com/dubbogo/gost/log/logger"
+)
+
+type BenchmarkFunc func(ctx context.Context) (duration time.Duration, err 
error)
+
+type Engine struct {
+       concurrency      int
+       warmupDuration   time.Duration
+       testDuration     time.Duration
+       requestTimeout   time.Duration
+       metricsCollector *MetricsCollector
+       stats            *Statistics
+       isWarmup         atomic.Bool
+       wg               sync.WaitGroup
+       stopChan         chan struct{}
+       ctx              context.Context
+       cancel           context.CancelFunc
+}
+
+func NewEngine(concurrency int, warmupDuration, testDuration, requestTimeout 
time.Duration) *Engine {
+       ctx, cancel := context.WithCancel(context.Background())
+       e := &Engine{
+               concurrency:      concurrency,
+               warmupDuration:   warmupDuration,
+               testDuration:     testDuration,
+               requestTimeout:   requestTimeout,
+               metricsCollector: NewMetricsCollector(),
+               stats:            NewStatistics(),
+               stopChan:         make(chan struct{}),
+               ctx:              ctx,
+               cancel:           cancel,
+       }
+       e.isWarmup.Store(true)
+       return e
+}
+
+func (e *Engine) Run(benchmarkFunc BenchmarkFunc) *Statistics {
+       logger.Info("[INFO] Starting warmup...")
+
+       e.startWorkers(benchmarkFunc)
+
+       time.Sleep(e.warmupDuration)
+
+       logger.Info("[INFO] Warmup completed, starting benchmark...")
+       e.metricsCollector.Reset()
+       e.isWarmup.Store(false)
+
+       timer := time.NewTimer(e.testDuration)
+       defer timer.Stop()
+
+       <-timer.C
+
+       e.Stop()
+
+       return e.stats.Compute(e.metricsCollector)
+}
+
+func (e *Engine) startWorkers(benchmarkFunc BenchmarkFunc) {
+       for i := 0; i < e.concurrency; i++ {
+               e.wg.Add(1)
+               go e.worker(benchmarkFunc)
+       }
+}
+
+func (e *Engine) worker(benchmarkFunc BenchmarkFunc) {
+       defer e.wg.Done()
+
+       for {
+               select {
+               case <-e.stopChan:
+                       return
+               default:
+                       ctx, cancel := context.WithTimeout(e.ctx, 
e.requestTimeout)
+                       start := time.Now()
+                       _, err := benchmarkFunc(ctx)
+                       duration := time.Since(start)
+                       cancel()
+
+                       if !e.isWarmup.Load() {
+                               e.metricsCollector.Record(duration, err)
+                       }
+               }
+       }
+}
+
+func (e *Engine) Stop() {
+       close(e.stopChan)

Review Comment:
   [P2] Engine.Stop() 非幂等
   close(e.stopChan) 在二次调用时 panic(close of closed channel);Stop 为公开方法且 Run 
内部也调用,外部信号处理误触会崩溃(当前用法未触发,属潜在风险)。建议用 sync.Once 或 done channel 保护。



##########
tools/benchmark/proto/benchmark.pb.go:
##########
@@ -0,0 +1,194 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+//     protoc-gen-go v1.36.11
+//     protoc        v7.35.1

Review Comment:
   [P2] 生成头 protoc 版本异常
   protoc v7.35.1 非有效 protoc 版本(protoc 为 3.x/2x+ 系列,无 7.x);不影响编译,但 DO NOT EDIT 
文件的生成工具链来源存疑。建议确认实际 protoc/protoc-gen-go 版本并重新生成以保持元数据准确。



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to