Repository: apache/dubbo-go-pixiu

Issue:
[BUG] tools/benchmark: Dubbo and Triple benchmark tests fail because Pixiu cannot discover services
### ✅ 验证清单

- [x] 🔍 我已经搜索过 [现有 Issues](https://github.com/apache/dubbo-go-pixiu/issues)，确信这不是重复问题

### 🚀 Go 版本

1.25.3

### 📦 Dubbo-go-pixiu 版本

develop

### 🖥️ 服务端配置

dubbo-go,v3.1.1

### 💻 客户端配置

dubbo-go,v3.1.1

### 🌐 协议配置

triple dubbo

### 📋 注册中心配置

zookeeper v3.9

### 💾 操作系统

🐧 Linux

### 📝 Bug 描述

pixiu 似乎目前不支持 application mode 服务发现 而 dubbo triple 默认使用 application mode 进行服务发现

这可能导致pixiu无法找到dubbo服务，导致tools/benchmark中的测试无法通过

### 🔄 重现步骤

运行benchmark报错

```
  Expected
      <string>: 404 Not Found
  to equal
      <string>: 200 OK
  In [It] at: /home/ink/Code/dubbo-go-pixiu/tools/benchmark/test/dubbo_suite/dubbo_test.go:158
```

### ✅ 预期行为

benchmark测试通过

### ❌ 实际行为

```
  Expected
      <string>: 404 Not Found
  to equal
      <string>: 200 OK
  In [It] at: /home/ink/Code/dubbo-go-pixiu/tools/benchmark/test/dubbo_suite/dubbo_test.go:158
```

### 💡 可能的解决方案

修改config 让dubbo triple也使用pixiu支持的interface模式

Discussion:
@1kasa: @Similarityoung @Similarityoung: 已复现，目前初步推断是 dubbo-go 从 3.0.4 升级为 3.1.1 之后版本迭代带来的问题，具体问题还在分析中

<img width="1828" height="822" alt="Image" src="https://github.com/user-attachments/assets/3692afb1-6657-4cfe-a08b-434802d10602" />

Solution patch:
diff --git a/pkg/client/dubbo/dubbo.go b/pkg/client/dubbo/dubbo.go
index f56ea652..492806fb 100644
--- a/pkg/client/dubbo/dubbo.go
+++ b/pkg/client/dubbo/dubbo.go
@@ -48,7 +48,6 @@ import (
 import (
 	"github.com/apache/dubbo-go-pixiu/pkg/client"
 	cst "github.com/apache/dubbo-go-pixiu/pkg/common/constant"
-	"github.com/apache/dubbo-go-pixiu/pkg/config"
 	"github.com/apache/dubbo-go-pixiu/pkg/logger"
 )
 
@@ -76,7 +75,6 @@ var (
 		Organization: "dubbo-go-pixiu",
 		Name:         "Dubbogo Pixiu",
 		Module:       "dubbogo Pixiu",
-		Version:      config.Version,
 		Owner:        "Dubbogo Pixiu",
 		Environment:  "dev",
 	}
diff --git a/pkg/config/version.go b/pkg/config/version.go
index c45167df..cf1437a7 100644
--- a/pkg/config/version.go
+++ b/pkg/config/version.go
@@ -18,5 +18,6 @@
 package config
 
 const (
+	// Version TODO: delete this if not used in the future
 	Version = "0.4.0"
 )
diff --git a/tools/benchmark/README.md b/tools/benchmark/README.md
index 987aca56..64e77cb0 100644
--- a/tools/benchmark/README.md
+++ b/tools/benchmark/README.md
@@ -1,5 +1,35 @@
 # Benchmark Results
 
+* dubbo:
+
+```
+dubbo protocol performance test
+      Name                 | N   | Min   | Median | Mean  | StdDev | Max   
+      =====================================================================
+      GetUser [duration]   | 500 | 100µs | 200µs  | 600µs | 2.8ms  | 20.7ms
+      ---------------------------------------------------------------------
+      GetGender [duration] | 500 | 0s    | 100µs  | 200µs | 100µs  | 600µs 
+      ---------------------------------------------------------------------
+      GetUser0 [duration]  | 500 | 100µs | 100µs  | 200µs | 0s     | 400µs 
+      ---------------------------------------------------------------------
+      GetUsers [duration]  | 500 | 100µs | 200µs  | 200µs | 100µs  | 600µs 
+      ---------------------------------------------------------------------
+      GetUser2 [duration]  | 500 | 0s    | 200µs  | 200µs | 100µs  | 500µs 
+      ---------------------------------------------------------------------
+      GetErr [duration]    | 500 | 300µs | 500µs  | 500µs | 200µs  | 1.4ms 
+
+ pixiu to dubbo protocol performance test
+      Name                 | N   | Min   | Median | Mean  | StdDev | Max  
+      ====================================================================
+      GetUser [duration]   | 500 | 200µs | 600µs  | 1.8ms | 8.4ms  | 61ms 
+      --------------------------------------------------------------------
+      GetGender [duration] | 499 | 200µs | 500µs  | 600µs | 300µs  | 4.1ms
+      --------------------------------------------------------------------
+      GetUser0 [duration]  | 497 | 200µs | 500µs  | 600µs | 300µs  | 2.5ms
+      --------------------------------------------------------------------
+      GetUsers [duration]  | 495 | 200µs | 600µs  | 700µs | 300µs  | 2.9ms
+```
+
 * grpc:
 
 ```
@@ -22,6 +52,20 @@ pixiu to grpc protocol performance test
       GetUserByName [duration] | 500 | 800µs | 1.9ms  | 2.7ms | 3.8ms  | 33.4ms
 ```
 
+* triple:
+
+```
+triple protocol performance test
+      Name                | N   | Min   | Median | Mean  | StdDev | Max  
+      ===================================================================
+      SayHello [duration] | 500 | 100µs | 200µs  | 300µs | 300µs  | 2.6ms
+
+pixiu to triple protocol performance test
+      Name                | N   | Min    | Median | Mean | StdDev | Max   
+      ====================================================================
+      SayHello [duration] | 490 | 10.1ms | 12.7ms | 14ms | 4.1ms  | 43.3ms
+```
+
 # How to Run
 
 1. Build the Pixiu executable
diff --git a/tools/benchmark/README_CN.md b/tools/benchmark/README_CN.md
index 94b24c8b..53cfc147 100644
--- a/tools/benchmark/README_CN.md
+++ b/tools/benchmark/README_CN.md
@@ -1,5 +1,35 @@
 # Benchmark 结果
 
+* dubbo:
+
+```
+dubbo protocol performance test
+      Name                 | N   | Min   | Median | Mean  | StdDev | Max   
+      =====================================================================
+      GetUser [duration]   | 500 | 100µs | 200µs  | 600µs | 2.8ms  | 20.7ms
+      ---------------------------------------------------------------------
+      GetGender [duration] | 500 | 0s    | 100µs  | 200µs | 100µs  | 600µs 
+      ---------------------------------------------------------------------
+      GetUser0 [duration]  | 500 | 100µs | 100µs  | 200µs | 0s     | 400µs 
+      ---------------------------------------------------------------------
+      GetUsers [duration]  | 500 | 100µs | 200µs  | 200µs | 100µs  | 600µs 
+      ---------------------------------------------------------------------
+      GetUser2 [duration]  | 500 | 0s    | 200µs  | 200µs | 100µs  | 500µs 
+      ---------------------------------------------------------------------
+      GetErr [duration]    | 500 | 300µs | 500µs  | 500µs | 200µs  | 1.4ms 
+
+ pixiu to dubbo protocol performance test
+      Name                 | N   | Min   | Median | Mean  | StdDev | Max  
+      ====================================================================
+      GetUser [duration]   | 500 | 200µs | 600µs  | 1.8ms | 8.4ms  | 61ms 
+      --------------------------------------------------------------------
+      GetGender [duration] | 499 | 200µs | 500µs  | 600µs | 300µs  | 4.1ms
+      --------------------------------------------------------------------
+      GetUser0 [duration]  | 497 | 200µs | 500µs  | 600µs | 300µs  | 2.5ms
+      --------------------------------------------------------------------
+      GetUsers [duration]  | 495 | 200µs | 600µs  | 700µs | 300µs  | 2.9ms
+```
+
 * grpc:
 
 ```
@@ -22,6 +52,20 @@ pixiu to grpc protocol performance test
       GetUserByName [duration] | 500 | 800µs | 1.9ms  | 2.7ms | 3.8ms  | 33.4ms
 ```
 
+* triple:
+
+```
+triple protocol performance test
+      Name                | N   | Min   | Median | Mean  | StdDev | Max  
+      ===================================================================
+      SayHello [duration] | 500 | 100µs | 200µs  | 300µs | 300µs  | 2.6ms
+
+pixiu to triple protocol performance test
+      Name                | N   | Min    | Median | Mean | StdDev | Max   
+      ====================================================================
+      SayHello [duration] | 490 | 10.1ms | 12.7ms | 14ms | 4.1ms  | 43.3ms
+```
+
 # 运行方法
 
 1. 构建 pixiu 可执行文件
diff --git a/tools/benchmark/protocol/dubbo/go-server/conf/dubbogo.yml b/tools/benchmark/protocol/dubbo/go-server/conf/dubbogo.yml
index 5f770fa0..eed0d783 100644
--- a/tools/benchmark/protocol/dubbo/go-server/conf/dubbogo.yml
+++ b/tools/benchmark/protocol/dubbo/go-server/conf/dubbogo.yml
@@ -25,11 +25,13 @@ dubbo:
       protocol: zookeeper
       timeout: 3s
       address: 127.0.0.1:2181
+      registry-type: all
   protocols:
     dubbo:
       name: dubbo
       port: 20000
   provider:
+    registry-ids: demoZK
     services:
       UserProvider:
         interface: org.apache.dubbo.sample.UserProvider
diff --git a/tools/benchmark/protocol/triple/pb/go-server/conf/dubbogo.yml b/tools/benchmark/protocol/triple/pb/go-server/conf/dubbogo.yml
index e26721f0..988845f1 100644
--- a/tools/benchmark/protocol/triple/pb/go-server/conf/dubbogo.yml
+++ b/tools/benchmark/protocol/triple/pb/go-server/conf/dubbogo.yml
@@ -21,11 +21,13 @@ dubbo:
   registries:
     zk:
       address: zookeeper://127.0.0.1:2181
+      registry-type: all
   protocols:
     triple:
       name: tri
       port: 20001
   provider:
+    registry-ids: zk
     services:
       GreeterProvider:
         protocol-ids: triple # 使用上面定义的协议id



Test patch:
diff --git a/tools/benchmark/test/dubbo_suite/dubbo_test.go b/tools/benchmark/test/dubbo_suite/dubbo_test.go
index 54d1c193..6bf32541 100644
--- a/tools/benchmark/test/dubbo_suite/dubbo_test.go
+++ b/tools/benchmark/test/dubbo_suite/dubbo_test.go
@@ -21,6 +21,7 @@ import (
 	"context"
 	"fmt"
 	"io"
+	"net"
 	"net/http"
 	"os"
 	"os/exec"
@@ -62,76 +63,21 @@ var _ = Describe("test", Ordered, func() {
 		test.CurPath, err = os.Getwd()
 		gomega.Expect(err).NotTo(gomega.HaveOccurred())
 
-		dubboServerSession = prepareDubboServer()
-		pixiuSession = test.PreparePixiu("../../dist/pixiu", test.CurPath+"/../../protocol/dubbo/pixiu/conf/config.yaml")
+		// Wait for ports to be available before starting servers
+		waitForPortAvailable("20000", 10*time.Second)
+		waitForPortAvailable("8881", 10*time.Second)
 
-		time.Sleep(3 * time.Second)
+		dubboServerSession = prepareDubboServer()
+		// Wait for dubbo server to register to Zookeeper
+		time.Sleep(5 * time.Second)
 
-		prepareDubboClient()
+		pixiuSession = test.PreparePixiu("../../dist/pixiu", test.CurPath+"/../../protocol/dubbo/pixiu/conf/config.yaml")
+		// Wait for pixiu to discover services from Zookeeper
+		time.Sleep(5 * time.Second)
 	})
 
 	//TODO(kenwaycai): output to external file
 
-	It("dubbo protocol performance test", func() {
-		defer GinkgoRecover()
-
-		experiment := gmeasure.NewExperiment("dubbo protocol performance test")
-		AddReportEntry(experiment.Name, experiment)
-
-		experiment.Sample(func(idx int) {
-			reqUser := &pkg.User{}
-			reqUser.ID = "003"
-			experiment.MeasureDuration("GetUser", func() {
-				_, err := userProvider.GetUser(context.TODO(), reqUser)
-				gomega.Expect(err).To(gomega.Succeed())
-				//fmt.Printf("consumer:%+v", user)
-			})
-		}, test.SampleConfig)
-
-		experiment.Sample(func(idx int) {
-			experiment.MeasureDuration("GetGender", func() {
-				_, err := userProvider.GetGender(context.TODO(), 1)
-				gomega.Expect(err).To(gomega.Succeed())
-				//fmt.Printf("consumer:%+v", gender)
-			})
-		}, test.SampleConfig)
-
-		experiment.Sample(func(idx int) {
-			experiment.MeasureDuration("GetUser0", func() {
-				_, err := userProvider.GetUser0("003", "Moorse")
-				gomega.Expect(err).To(gomega.Succeed())
-				//fmt.Printf("consumer:%+v", ret)
-			})
-		}, test.SampleConfig)
-
-		experiment.Sample(func(idx int) {
-			experiment.MeasureDuration("GetUsers", func() {
-				_, err := userProvider.GetUsers([]string{"002", "003"})
-				gomega.Expect(err).To(gomega.Succeed())
-				//fmt.Printf("consumer:%+v", ret1)
-			})
-		}, test.SampleConfig)
-
-		experiment.Sample(func(idx int) {
-			experiment.MeasureDuration("GetUser2", func() {
-				var i int32 = 1
-				_, err := userProvider.GetUser2(context.TODO(), i)
-				gomega.Expect(err).To(gomega.Succeed())
-				//fmt.Printf("consumer:%+v", user)
-			})
-		}, test.SampleConfig)
-
-		experiment.Sample(func(idx int) {
-			experiment.MeasureDuration("GetErr", func() {
-				reqUser := &pkg.User{}
-				reqUser.ID = "003"
-				_, err := userProvider.GetErr(context.TODO(), reqUser)
-				gomega.Expect(err).To(gomega.HaveOccurred())
-				//fmt.Printf("consumer:%+v", err.Error())
-			})
-		}, test.SampleConfig)
-	})
-
 	It("pixiu to dubbo protocol performance test", func() {
 
 		urlPrefix := "http://localhost:8881/dubbo.io/org.apache.dubbo.sample.UserProvider/%s"
@@ -155,6 +101,7 @@ var _ = Describe("test", Ordered, func() {
 
 				resp, err := http.Post(url, "application/json", strings.NewReader(data))
 				gomega.Expect(err).NotTo(gomega.HaveOccurred())
+				defer resp.Body.Close()
 				gomega.Expect(resp.Status).To(gomega.Equal("200 OK"))
 				_, err = io.ReadAll(resp.Body)
 				gomega.Expect(err).NotTo(gomega.HaveOccurred())
@@ -172,6 +119,7 @@ var _ = Describe("test", Ordered, func() {
 `
 				resp, err := http.Post(url, "application/json", strings.NewReader(data))
 				gomega.Expect(err).NotTo(gomega.HaveOccurred())
+				defer resp.Body.Close()
 				gomega.Expect(resp.Status).To(gomega.Equal("200 OK"))
 
 				_, err = io.ReadAll(resp.Body)
@@ -193,6 +141,7 @@ var _ = Describe("test", Ordered, func() {
 `
 				resp, err := http.Post(url, "application/json", strings.NewReader(data))
 				gomega.Expect(err).NotTo(gomega.HaveOccurred())
+				defer resp.Body.Close()
 				gomega.Expect(resp.Status).To(gomega.Equal("200 OK"))
 
 				_, err = io.ReadAll(resp.Body)
@@ -216,19 +165,84 @@ var _ = Describe("test", Ordered, func() {
 `
 
 				resp, err := http.Post(url, "application/json", strings.NewReader(data))
-				_, err = io.ReadAll(resp.Body)
 				gomega.Expect(err).NotTo(gomega.HaveOccurred())
+				defer resp.Body.Close()
 				gomega.Expect(resp.Status).To(gomega.Equal("200 OK"))
+				_, err = io.ReadAll(resp.Body)
 				gomega.Expect(err).NotTo(gomega.HaveOccurred())
 			})
 
 		}, test.SampleConfig)
 	})
 
+	It("dubbo protocol performance test", func() {
+		defer GinkgoRecover()
+
+		// Initialize dubbo client only when needed for this test
+		prepareDubboClient()
+
+		experiment := gmeasure.NewExperiment("dubbo protocol performance test")
+		AddReportEntry(experiment.Name, experiment)
+
+		experiment.Sample(func(idx int) {
+			reqUser := &pkg.User{}
+			reqUser.ID = "003"
+			experiment.MeasureDuration("GetUser", func() {
+				_, err := userProvider.GetUser(context.TODO(), reqUser)
+				gomega.Expect(err).To(gomega.Succeed())
+			})
+		}, test.SampleConfig)
+
+		experiment.Sample(func(idx int) {
+			experiment.MeasureDuration("GetGender", func() {
+				_, err := userProvider.GetGender(context.TODO(), 1)
+				gomega.Expect(err).To(gomega.Succeed())
+			})
+		}, test.SampleConfig)
+
+		experiment.Sample(func(idx int) {
+			experiment.MeasureDuration("GetUser0", func() {
+				_, err := userProvider.GetUser0("003", "Moorse")
+				gomega.Expect(err).To(gomega.Succeed())
+			})
+		}, test.SampleConfig)
+
+		experiment.Sample(func(idx int) {
+			experiment.MeasureDuration("GetUsers", func() {
+				_, err := userProvider.GetUsers([]string{"002", "003"})
+				gomega.Expect(err).To(gomega.Succeed())
+			})
+		}, test.SampleConfig)
+
+		experiment.Sample(func(idx int) {
+			experiment.MeasureDuration("GetUser2", func() {
+				var i int32 = 1
+				_, err := userProvider.GetUser2(context.TODO(), i)
+				gomega.Expect(err).To(gomega.Succeed())
+			})
+		}, test.SampleConfig)
+
+		experiment.Sample(func(idx int) {
+			experiment.MeasureDuration("GetErr", func() {
+				reqUser := &pkg.User{}
+				reqUser.ID = "003"
+				_, err := userProvider.GetErr(context.TODO(), reqUser)
+				gomega.Expect(err).To(gomega.HaveOccurred())
+			})
+		}, test.SampleConfig)
+	})
+
 	AfterAll(func() {
-		time.Sleep(5 * time.Second)
-		dubboServerSession.Terminate().Wait()
-		pixiuSession.Terminate().Wait(5 * time.Second)
+		// Use Kill instead of Terminate to ensure processes are fully stopped
+		if pixiuSession != nil {
+			pixiuSession.Kill().Wait(10 * time.Second)
+		}
+		if dubboServerSession != nil {
+			dubboServerSession.Kill().Wait(10 * time.Second)
+		}
+		gexec.CleanupBuildArtifacts()
+		// Wait for ports to be released
+		time.Sleep(2 * time.Second)
 	})
 
 })
@@ -237,7 +251,9 @@ func prepareDubboServer() *gexec.Session {
 	serverProcess, err := gexec.Build("dubbo-go-pixiu-benchmark/protocol/dubbo/go-server/cmd")
 	gomega.Expect(err).NotTo(gomega.HaveOccurred())
 	command := exec.Command(serverProcess)
-	session, err := gexec.Start(command, io.Discard, io.Discard)
+	// Set working directory to test/dubbo_suite so that relative paths in server.go work correctly
+	command.Dir = test.CurPath
+	session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter)
 	//session, err := gexec.Start(command, os.Stdout, os.Stderr)
 	gomega.Expect(err).NotTo(gomega.HaveOccurred())
 
@@ -254,3 +270,21 @@ func prepareDubboClient() {
 	err := config.Load(config.WithPath(test.CurPath + "/../../protocol/dubbo/go-client/conf/dubbogo.yml"))
 	gomega.Expect(err).NotTo(gomega.HaveOccurred())
 }
+
+// waitForPortAvailable waits until the port is available (not in use)
+func waitForPortAvailable(port string, timeout time.Duration) {
+	deadline := time.Now().Add(timeout)
+	for time.Now().Before(deadline) {
+		conn, err := net.DialTimeout("tcp", "127.0.0.1:"+port, 100*time.Millisecond)
+		if err != nil {
+			// Port is available (connection refused means no one is listening)
+			if conn != nil {
+				conn.Close()
+			}
+			return
+		}
+		conn.Close()
+		time.Sleep(500 * time.Millisecond)
+	}
+	gomega.Expect(fmt.Errorf("port %s is still in use after %v", port, timeout)).NotTo(gomega.HaveOccurred())
+}
diff --git a/tools/benchmark/test/triple_suite/proto_suite/proto_test.go b/tools/benchmark/test/triple_suite/proto_suite/proto_test.go
index 5b65c231..24503d6a 100644
--- a/tools/benchmark/test/triple_suite/proto_suite/proto_test.go
+++ b/tools/benchmark/test/triple_suite/proto_suite/proto_test.go
@@ -6,7 +6,7 @@
  * (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
+ * 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,
@@ -21,6 +21,7 @@ import (
 	"context"
 	"fmt"
 	"io"
+	"net"
 	"net/http"
 	"os"
 	"os/exec"
@@ -62,33 +63,17 @@ var _ = Describe("triple protocol performance test", Ordered, func() {
 		test.CurPath, err = os.Getwd()
 		gomega.Expect(err).NotTo(gomega.HaveOccurred())
 
-		tripleServerSession = prepareTripleServer()
-		pixiuSession = test.PreparePixiu("../../../dist/pixiu", test.CurPath+"/../../../protocol/triple/pb/pixiu/conf/config.yaml")
-
-		time.Sleep(3 * time.Second)
-
-		prepareTripleClient()
-
-	})
+		// Wait for ports to be available before starting servers
+		waitForPortAvailable("20000", 10*time.Second)
+		waitForPortAvailable("8881", 10*time.Second)
 
-	It("triple protocol performance test", func() {
-
-		experiment := gmeasure.NewExperiment("triple protocol performance test")
-		AddReportEntry(experiment.Name, experiment)
-
-		experiment.Sample(func(idx int) {
-			defer GinkgoRecover()
+		tripleServerSession = prepareTripleServer()
+		// Wait for dubbo server to register to Zookeeper
+		time.Sleep(5 * time.Second)
 
-			experiment.MeasureDuration("SayHello", func() {
-				req := &triplepb.HelloRequest{
-					Name: "laurence",
-				}
-				ctx := context.WithValue(context.Background(), tripleConstant.TripleCtxKey("tri-req-id"), "test_value_XXXXXXXX")
-				_, err := grpcGreeterImpl.SayHello(ctx, req)
-				gomega.Expect(err).NotTo(gomega.HaveOccurred())
-				//fmt.Printf("consumer:%+v\n", reply)
-			})
-		}, test.SampleConfig)
+		pixiuSession = test.PreparePixiu("../../../dist/pixiu", test.CurPath+"/../../../protocol/triple/pb/pixiu/conf/config.yaml")
+		// Wait for pixiu to discover services from Zookeeper
+		time.Sleep(5 * time.Second)
 	})
 
 	It("pixiu to triple protocol performance test", func() {
@@ -106,11 +91,12 @@ var _ = Describe("triple protocol performance test", Ordered, func() {
 				url := fmt.Sprintf(urlPrefix, "SayHello")
 				data := `
 {
-	"name":"test"
+    "name":"test"
 }
 `
 				resp, err := http.Post(url, "application/json", strings.NewReader(data))
 				gomega.Expect(err).NotTo(gomega.HaveOccurred())
+				defer resp.Body.Close()
 				gomega.Expect(resp.Status).To(gomega.Equal("200 OK"))
 				reply, err := io.ReadAll(resp.Body)
 				gomega.Expect(err).NotTo(gomega.HaveOccurred())
@@ -120,9 +106,39 @@ var _ = Describe("triple protocol performance test", Ordered, func() {
 		}, test.SampleConfig)
 	})
 
+	It("triple protocol performance test", func() {
+		// Initialize dubbo client only when needed for this test
+		prepareTripleClient()
+
+		experiment := gmeasure.NewExperiment("triple protocol performance test")
+		AddReportEntry(experiment.Name, experiment)
+
+		experiment.Sample(func(idx int) {
+			defer GinkgoRecover()
+
+			experiment.MeasureDuration("SayHello", func() {
+				req := &triplepb.HelloRequest{
+					Name: "laurence",
+				}
+				ctx := context.WithValue(context.Background(), tripleConstant.TripleCtxKey("tri-req-id"), "test_value_XXXXXXXX")
+				_, err := grpcGreeterImpl.SayHello(ctx, req)
+				gomega.Expect(err).NotTo(gomega.HaveOccurred())
+				//fmt.Printf("consumer:%+v\n", reply)
+			})
+		}, test.SampleConfig)
+	})
+
 	AfterAll(func() {
-		tripleServerSession.Terminate().Wait(5 * time.Second)
-		pixiuSession.Terminate().Wait(5 * time.Second)
+		// Use Kill instead of Terminate to ensure processes are fully stopped
+		if pixiuSession != nil {
+			pixiuSession.Kill().Wait(10 * time.Second)
+		}
+		if tripleServerSession != nil {
+			tripleServerSession.Kill().Wait(10 * time.Second)
+		}
+		gexec.CleanupBuildArtifacts()
+		// Wait for ports to be released
+		time.Sleep(2 * time.Second)
 	})
 })
 
@@ -131,6 +147,8 @@ func prepareTripleServer() *gexec.Session {
 	gomega.Expect(err).NotTo(gomega.HaveOccurred())
 
 	command := exec.Command(serverProcess)
+	// Set working directory
+	command.Dir = test.CurPath
 	session, err := gexec.Start(command, io.Discard, io.Discard)
 	//session, err := gexec.Start(command, os.Stdout, os.Stderr)
 
@@ -144,3 +162,17 @@ func prepareTripleClient() {
 	err := config.Load(config.WithPath(test.CurPath + "/../../../protocol/triple/pb/go-client/conf/dubbogo.yml"))
 	gomega.Expect(err).NotTo(gomega.HaveOccurred())
 }
+
+// waitForPortAvailable waits until the port is available (not in use)
+func waitForPortAvailable(port string, timeout time.Duration) {
+	deadline := time.Now().Add(timeout)
+	for time.Now().Before(deadline) {
+		conn, err := net.DialTimeout("tcp", "127.0.0.1:"+port, 100*time.Millisecond)
+		if err != nil {
+			// Port is available (connection refused means no one is listening)
+			return
+		}
+		conn.Close()
+		time.Sleep(500 * time.Millisecond)
+	}
+}