This is an automated email from the ASF dual-hosted git repository.

xuetaoli pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-go-samples.git


The following commit(s) were added to refs/heads/main by this push:
     new 5c11a1f5 feat: add hystrix sample (#1060)
5c11a1f5 is described below

commit 5c11a1f527f6e3838c3569995d3381937877e3af
Author: Zecheng Zhu <[email protected]>
AuthorDate: Sun Apr 5 22:02:45 2026 +0800

    feat: add hystrix sample (#1060)
    
    * feat: add hystrix sample
    
    * update readme
    
    * fix docs
    
    * update readme
    
    * fix: improve hystrix sample concurrency and error handling
    
    * add hystrix to integration test list
    
    * fix readme err
---
 README.md                                  |   5 +
 README_CN.md                               |   5 +
 filter/hystrix/README.md                   | 118 +++++++++++++++
 filter/hystrix/README_zh.md                | 118 +++++++++++++++
 filter/hystrix/go-client/cmd/main.go       | 119 +++++++++++++++
 filter/hystrix/go-server/cmd/main.go       |  74 ++++++++++
 filter/hystrix/proto/greet.pb.go           | 230 +++++++++++++++++++++++++++++
 filter/hystrix/proto/greet.proto           |  33 +++++
 filter/{ => hystrix}/proto/greet.triple.go |   2 +-
 filter/proto/greet.triple.go               |   2 +-
 go.mod                                     |   3 +-
 go.sum                                     |   2 +
 start_integrate_test.sh                    |   1 +
 13 files changed, 709 insertions(+), 3 deletions(-)

diff --git a/README.md b/README.md
index 9de60f94..7dfc6b2d 100644
--- a/README.md
+++ b/README.md
@@ -20,7 +20,12 @@ Please refer to [HOWTO.md](HOWTO.md) for detailed 
instructions on running the sa
 * `context`: Demonstrates passing user data (attachments) via Go `context` 
between client and server.
 * `error`: Error-handling examples in Dubbo-go.
 * `filter`: Demonstrates the use of built-in and custom filters in Dubbo-go.
+  * `custom`: Implements custom client and server filters.
+  * `hystrix`: Uses `hystrix-go` to demonstrate circuit breaker protection on 
Dubbo-go calls.
+  * `sentinel`: Demonstrates flow control, isolation, and circuit breaking 
with Sentinel filters.
   * `polaris/limit`: Uses Polaris as a TPS limiter.
+  * `token`: Demonstrates token-based request validation between consumer and 
provider.
+  * `tpslimit`: Demonstrates Dubbo-go's built-in TPS limiting filter with 
custom limit and rejection strategies.
 * `healthcheck`: Service health check example.
 * `helloworld`: Basic “Hello World” example for Dubbo-go, also includes 
Go–Java interoperability.
 * `http3`: HTTP/3 (QUIC) protocol support example demonstrating how to use 
Triple protocol with HTTP/3 for high-performance communication between Go and 
Java services with TLS encryption.
diff --git a/README_CN.md b/README_CN.md
index b42aab1b..fd74ad3d 100644
--- a/README_CN.md
+++ b/README_CN.md
@@ -20,7 +20,12 @@
 * `context`:演示如何通过 Go 的 `context` 在客户端与服务端之间传递用户数据(attachments)。
 * `error`:Dubbo-go 的错误处理示例。
 * `filter`:演示 Dubbo-go 中内置和自定义 Filter 的使用。
+  * `custom`:实现自定义的客户端和服务端 Filter。
+  * `hystrix`:使用 `hystrix-go` 演示 Dubbo-go 调用中的熔断保护。
+  * `sentinel`:演示基于 Sentinel Filter 的流控、隔离和熔断能力。
   * `polaris/limit`:使用 Polaris 实现 TPS 限流。
+  * `token`:演示消费端与提供端之间基于 token 的请求校验。
+  * `tpslimit`:演示 Dubbo-go 内置 TPSLimit Filter,以及自定义限流和拒绝处理策略。
 * `healthcheck`:服务健康检查示例。
 * `helloworld`:Dubbo-go 最基础的 “Hello World” 示例,同时包含 Go 与 Java 的互操作示例。
 * `http3`:HTTP/3(QUIC)协议支持示例,演示如何通过 Triple 协议使用 HTTP/3 实现 Go 与 Java 
服务之间的高性能通信,并支持 TLS 加密。
diff --git a/filter/hystrix/README.md b/filter/hystrix/README.md
new file mode 100644
index 00000000..e9e4d62c
--- /dev/null
+++ b/filter/hystrix/README.md
@@ -0,0 +1,118 @@
+# Hystrix Filter Example
+
+[English](README.md) | [中文](README_zh.md)
+
+## Background
+
+This example demonstrates how to use the Hystrix filter in dubbo-go to 
implement circuit breaker functionality. Hystrix is a latency and fault 
tolerance library designed to isolate points of access to remote systems, 
services, and 3rd party libraries, stop cascading failures, and enable 
resilience in complex distributed systems.
+
+## Implementation
+
+### 1. Configure Hystrix Commands
+
+Use the `hystrix-go` API to configure circuit breaker commands. The resource 
name format is:
+```
+dubbo:consumer:InterfaceName:group:version:Method
+```
+
+**Client Configuration** (`go-client/cmd/main.go`):
+```go
+import (
+    "github.com/afex/hystrix-go/hystrix"
+    _ "github.com/apache/dubbo-go-extensions/filter/hystrix"
+)
+
+func init() {
+    // Resource name format: dubbo:consumer:InterfaceName:group:version:Method
+    cmdName := "dubbo:consumer:greet.GreetService:::Greet"
+
+    hystrix.ConfigureCommand(cmdName, hystrix.CommandConfig{
+        Timeout:                1000, // timeout in milliseconds
+        MaxConcurrentRequests:  10,   // max concurrent requests
+        RequestVolumeThreshold: 5,    // minimum requests to trip the circuit
+        SleepWindow:            5000,  // time to wait before attempting 
recovery (ms)
+        ErrorPercentThreshold:  50,   // error rate threshold (percentage)
+    })
+}
+```
+
+### 2. Use Hystrix Filter
+
+**Client** (`go-client/cmd/main.go`):
+```go
+import (
+    "dubbo.apache.org/dubbo-go/v3/client"
+)
+
+svc, err := greet.NewGreetService(cli, client.WithFilter("hystrix_consumer"))
+```
+
+## Configuration Parameters
+
+| Parameter | Description |
+|-----------|-------------|
+| `Timeout` | Command execution timeout in milliseconds |
+| `MaxConcurrentRequests` | Maximum number of concurrent requests allowed |
+| `RequestVolumeThreshold` | Minimum number of requests required to trip the 
circuit (within sliding window) |
+| `SleepWindow` | Time to wait after circuit opens before attempting recovery 
(milliseconds) |
+| `ErrorPercentThreshold` | Error rate threshold that triggers circuit opening 
(percentage) |
+
+## How to Run
+
+### Prerequisites
+
+1. Start the Go server and make sure `127.0.0.1:20000` is ready to accept 
requests.
+
+### Start Server
+
+```shell
+cd filter/hystrix/go-server
+go run ./cmd/main.go
+```
+
+### Start Client
+
+```shell
+cd filter/hystrix/go-client
+go run ./cmd/main.go
+```
+
+## Expected Output
+
+**Client Output:**
+```bash
+=== Test 1: Sending normal requests ===
+Request 1 success: Hello, request-1! (request #1)
+Request 2 success: Hello, request-2! (request #2)
+Request 3 success: Hello, request-3! (request #3)
+
+=== Test 2: Sending concurrent requests ===
+Concurrent request 1 success: Hello, concurrent-1! (request #4)
+Concurrent request 2 success: Hello, concurrent-2! (request #5)
+...
+
+=== Test 3: Sending requests after concurrent test ===
+After-test request 1 failed (circuit might be open): ...
+```
+
+When the circuit breaker is open, you will see errors like:
+```bash
+After-test request 1 failed: hystrix: circuit open
+```
+
+## Testing Circuit Breaker
+
+The example program includes three test phases:
+
+1. **Normal Requests**: Sends 3 normal requests to verify basic functionality
+2. **Concurrent Requests**: Sends 15 concurrent requests, potentially 
triggering the circuit breaker
+3. **Recovery Test**: Continues sending requests after concurrent test to 
observe circuit breaker state
+
+If the circuit breaker is triggered, wait about 5 seconds (SleepWindow 
configuration) before running the client again to see the circuit recover.
+
+## Notes
+
+- Hystrix filter is primarily used on the **client side** to protect callers 
from downstream service failures
+- The resource name must match the actual interface, group, version, and 
method name
+- Circuit breaker states: Closed → Open → Half-Open → Closed
+- Configure timeout and concurrency limits appropriately to avoid resource 
exhaustion
diff --git a/filter/hystrix/README_zh.md b/filter/hystrix/README_zh.md
new file mode 100644
index 00000000..5ead47fa
--- /dev/null
+++ b/filter/hystrix/README_zh.md
@@ -0,0 +1,118 @@
+# Hystrix Filter 示例
+
+[English](README.md) | [中文](README_zh.md)
+
+## 背景
+
+本示例演示了如何在 dubbo-go 中使用 Hystrix filter 实现熔断器功能。Hystrix 
是一个延迟和容错库,用于隔离访问远程系统、服务或第三方库的访问点,防止级联故障,实现熔断器模式。
+
+## 实现方法
+
+### 1. 配置 Hystrix 命令
+
+使用 `hystrix-go` API 配置熔断器命令。资源名称格式为:
+```
+dubbo:consumer:InterfaceName:group:version:Method
+```
+
+**客户端配置** (`go-client/cmd/main.go`):
+```go
+import (
+    "github.com/afex/hystrix-go/hystrix"
+    _ "github.com/apache/dubbo-go-extensions/filter/hystrix"
+)
+
+func init() {
+    // 资源名称格式: dubbo:consumer:接口名:分组:版本:方法
+    cmdName := "dubbo:consumer:greet.GreetService:::Greet"
+
+    hystrix.ConfigureCommand(cmdName, hystrix.CommandConfig{
+        Timeout:                1000, // 超时时间(毫秒)
+        MaxConcurrentRequests:  10,   // 最大并发请求数
+        RequestVolumeThreshold: 5,    // 熔断器触发的最小请求数
+        SleepWindow:            5000, // 熔断后尝试恢复的时间(毫秒)
+        ErrorPercentThreshold:  50,   // 错误率阈值(百分比)
+    })
+}
+```
+
+### 2. 使用 Hystrix Filter
+
+**客户端** (`go-client/cmd/main.go`):
+```go
+import (
+    "dubbo.apache.org/dubbo-go/v3/client"
+)
+
+svc, err := greet.NewGreetService(cli, client.WithFilter("hystrix_consumer"))
+```
+
+## 配置参数说明
+
+| 参数 | 说明 |
+|------|------|
+| `Timeout` | 命令执行超时时间(毫秒) |
+| `MaxConcurrentRequests` | 同一时间最大的并发请求数 |
+| `RequestVolumeThreshold` | 熔断器触发的最小请求数(滑动窗口内) |
+| `SleepWindow` | 熔断器打开后,等待多久尝试恢复(毫秒) |
+| `ErrorPercentThreshold` | 错误率阈值,超过此百分比熔断器打开 |
+
+## 运行方法
+
+### 前置条件
+
+1. 先启动 Go 服务端,并确认 `127.0.0.1:20000` 已经可以接受请求。
+
+### 启动服务端
+
+```shell
+cd filter/hystrix/go-server
+go run ./cmd/main.go
+```
+
+### 启动客户端
+
+```shell
+cd filter/hystrix/go-client
+go run ./cmd/main.go
+```
+
+## 预期输出
+
+**客户端输出:**
+```bash
+=== Test 1: Sending normal requests ===
+Request 1 success: Hello, request-1! (request #1)
+Request 2 success: Hello, request-2! (request #2)
+Request 3 success: Hello, request-3! (request #3)
+
+=== Test 2: Sending concurrent requests ===
+Concurrent request 1 success: Hello, concurrent-1! (request #4)
+Concurrent request 2 success: Hello, concurrent-2! (request #5)
+...
+
+=== Test 3: Sending requests after concurrent test ===
+After-test request 1 failed (circuit might be open): ...
+```
+
+当熔断器打开时,你会看到类似以下的错误:
+```bash
+After-test request 1 failed: hystrix: circuit open
+```
+
+## 测试熔断器功能
+
+示例程序包含三个测试阶段:
+
+1. **正常请求**: 发送3个正常请求,验证基本功能
+2. **并发请求**: 发送15个并发请求,可能触发熔断器
+3. **恢复测试**: 在并发请求后继续发送请求,观察熔断器状态
+
+如果触发了熔断器,等待约5秒(SleepWindow配置)后再运行客户端,可以看到熔断器恢复。
+
+## 注意事项
+
+- Hystrix filter 主要用于**客户端**,保护调用方免受下游服务故障的影响
+- 资源名称需要与实际接口、分组、版本和方法名保持一致
+- 熔断器状态:关闭 → 打开 → 半开 → 关闭
+- 合理配置超时时间和并发数,避免资源耗尽
diff --git a/filter/hystrix/go-client/cmd/main.go 
b/filter/hystrix/go-client/cmd/main.go
new file mode 100644
index 00000000..827f07a7
--- /dev/null
+++ b/filter/hystrix/go-client/cmd/main.go
@@ -0,0 +1,119 @@
+/*
+ * 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 main
+
+import (
+       "context"
+       "fmt"
+       "sync"
+       "time"
+)
+
+import (
+       "dubbo.apache.org/dubbo-go/v3/client"
+       _ "dubbo.apache.org/dubbo-go/v3/imports"
+
+       "github.com/afex/hystrix-go/hystrix"
+
+       _ "github.com/apache/dubbo-go-extensions/filter/hystrix"
+
+       "github.com/dubbogo/gost/log/logger"
+)
+
+import (
+       greet "github.com/apache/dubbo-go-samples/filter/hystrix/proto"
+)
+
+func init() {
+       // Configure hystrix command for the GreetService.Greet method
+       // Resource name format: 
dubbo:consumer:InterfaceName:group:version:Method
+       // For this example: dubbo:consumer:greet.GreetService:::Greet
+       cmdName := "dubbo:consumer:greet.GreetService:::Greet"
+
+       hystrix.ConfigureCommand(cmdName, hystrix.CommandConfig{
+               Timeout:                1000, // 1 second timeout
+               MaxConcurrentRequests:  10,   // Max 10 concurrent requests
+               RequestVolumeThreshold: 5,    // Minimum 5 requests before 
circuit can trip
+               SleepWindow:            5000, // 5 seconds to wait after 
circuit opens before testing
+               ErrorPercentThreshold:  50,   // 50% error rate triggers 
circuit opening
+       })
+
+       logger.Infof("Configured hystrix command: %s", cmdName)
+}
+
+func logGreetResult(stage string, idx int, resp *greet.GreetResponse, err 
error) {
+       if err != nil {
+               logger.Infof("%s %d failed: %v", stage, idx, err)
+               return
+       }
+
+       logger.Infof("%s %d success: %s", stage, idx, resp.Greeting)
+}
+
+func main() {
+       cli, err := client.NewClient(
+               client.WithClientURL("127.0.0.1:20000"),
+       )
+       if err != nil {
+               panic(err)
+       }
+
+       svc, err := greet.NewGreetService(cli, 
client.WithFilter("hystrix_consumer"))
+       if err != nil {
+               panic(err)
+       }
+
+       // Test 1: Normal requests
+       logger.Info("=== Test 1: Sending normal requests ===")
+       for i := 1; i <= 3; i++ {
+               resp, err := svc.Greet(context.Background(), 
&greet.GreetRequest{Name: fmt.Sprintf("request-%d", i)})
+               logGreetResult("Request", i, resp, err)
+       }
+
+       // Test 2: Multiple concurrent requests to potentially trigger circuit 
breaker
+       logger.Info("\n=== Test 2: Sending concurrent requests ===")
+       var wg sync.WaitGroup
+       for i := 1; i <= 15; i++ {
+               wg.Add(1)
+               go func(idx int) {
+                       defer wg.Done()
+
+                       resp, err := svc.Greet(context.Background(), 
&greet.GreetRequest{Name: fmt.Sprintf("concurrent-%d", idx)})
+                       logGreetResult("Concurrent request", idx, resp, err)
+               }(i)
+       }
+
+       // Wait for concurrent requests to complete before observing circuit 
state.
+       wg.Wait()
+
+       // Test 3: Try requests after circuit might be open
+       logger.Info("\n=== Test 3: Sending requests after concurrent test ===")
+       for i := 1; i <= 5; i++ {
+               resp, err := svc.Greet(context.Background(), 
&greet.GreetRequest{Name: fmt.Sprintf("after-%d", i)})
+               if err != nil {
+                       logger.Infof("After-test request %d failed (circuit 
might be open): %v", i, err)
+               } else {
+                       logger.Infof("After-test request %d success: %s", i, 
resp.Greeting)
+               }
+               time.Sleep(500 * time.Millisecond)
+       }
+
+       logger.Info("\nAll tests completed!")
+       logger.Info("If you see 'circuit open' errors, it means Hystrix 
successfully triggered the circuit breaker.")
+       logger.Info("Wait a few seconds and try again to see the circuit 
recover.")
+}
diff --git a/filter/hystrix/go-server/cmd/main.go 
b/filter/hystrix/go-server/cmd/main.go
new file mode 100644
index 00000000..bd081e02
--- /dev/null
+++ b/filter/hystrix/go-server/cmd/main.go
@@ -0,0 +1,74 @@
+/*
+ * 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 main
+
+import (
+       "context"
+       "fmt"
+       "sync/atomic"
+       "time"
+)
+
+import (
+       _ "dubbo.apache.org/dubbo-go/v3/imports"
+       "dubbo.apache.org/dubbo-go/v3/protocol"
+       "dubbo.apache.org/dubbo-go/v3/server"
+
+       "github.com/dubbogo/gost/log/logger"
+)
+
+import (
+       greet "github.com/apache/dubbo-go-samples/filter/hystrix/proto"
+)
+
+type GreetTripleServer struct {
+       requestCount atomic.Int64
+}
+
+func (srv *GreetTripleServer) Greet(ctx context.Context, req 
*greet.GreetRequest) (*greet.GreetResponse, error) {
+       requestNum := srv.requestCount.Add(1)
+       logger.Infof("[%d] Received request: %s", requestNum, req.Name)
+
+       // Simulate some processing time
+       time.Sleep(100 * time.Millisecond)
+
+       resp := &greet.GreetResponse{
+               Greeting: fmt.Sprintf("Hello, %s! (request #%d)", req.Name, 
requestNum),
+       }
+       return resp, nil
+}
+
+func main() {
+       srv, err := server.NewServer(
+               server.WithServerProtocol(
+                       protocol.WithPort(20000),
+                       protocol.WithTriple(),
+               ),
+       )
+       if err != nil {
+               panic(err)
+       }
+
+       if err := greet.RegisterGreetServiceHandler(srv, &GreetTripleServer{}); 
err != nil {
+               panic(err)
+       }
+
+       if err := srv.Serve(); err != nil {
+               logger.Error(err)
+       }
+}
diff --git a/filter/hystrix/proto/greet.pb.go b/filter/hystrix/proto/greet.pb.go
new file mode 100644
index 00000000..d45ce90c
--- /dev/null
+++ b/filter/hystrix/proto/greet.pb.go
@@ -0,0 +1,230 @@
+//
+// 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.31.0
+//     protoc        v3.21.12
+// source: proto/greet.proto
+
+package greet
+
+import (
+       protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+       protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+       reflect "reflect"
+       sync "sync"
+)
+
+const (
+       // Verify that this generated code is sufficiently up-to-date.
+       _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+       // Verify that runtime/protoimpl is sufficiently up-to-date.
+       _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type GreetRequest struct {
+       state         protoimpl.MessageState
+       sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       Name string `protobuf:"bytes,1,opt,name=name,proto3" 
json:"name,omitempty"`
+}
+
+func (x *GreetRequest) Reset() {
+       *x = GreetRequest{}
+       if protoimpl.UnsafeEnabled {
+               mi := &file_proto_greet_proto_msgTypes[0]
+               ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+               ms.StoreMessageInfo(mi)
+       }
+}
+
+func (x *GreetRequest) String() string {
+       return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GreetRequest) ProtoMessage() {}
+
+func (x *GreetRequest) ProtoReflect() protoreflect.Message {
+       mi := &file_proto_greet_proto_msgTypes[0]
+       if protoimpl.UnsafeEnabled && x != nil {
+               ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+               if ms.LoadMessageInfo() == nil {
+                       ms.StoreMessageInfo(mi)
+               }
+               return ms
+       }
+       return mi.MessageOf(x)
+}
+
+// Deprecated: Use GreetRequest.ProtoReflect.Descriptor instead.
+func (*GreetRequest) Descriptor() ([]byte, []int) {
+       return file_proto_greet_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *GreetRequest) GetName() string {
+       if x != nil {
+               return x.Name
+       }
+       return ""
+}
+
+type GreetResponse struct {
+       state         protoimpl.MessageState
+       sizeCache     protoimpl.SizeCache
+       unknownFields protoimpl.UnknownFields
+
+       Greeting string `protobuf:"bytes,1,opt,name=greeting,proto3" 
json:"greeting,omitempty"`
+}
+
+func (x *GreetResponse) Reset() {
+       *x = GreetResponse{}
+       if protoimpl.UnsafeEnabled {
+               mi := &file_proto_greet_proto_msgTypes[1]
+               ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+               ms.StoreMessageInfo(mi)
+       }
+}
+
+func (x *GreetResponse) String() string {
+       return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GreetResponse) ProtoMessage() {}
+
+func (x *GreetResponse) ProtoReflect() protoreflect.Message {
+       mi := &file_proto_greet_proto_msgTypes[1]
+       if protoimpl.UnsafeEnabled && x != nil {
+               ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+               if ms.LoadMessageInfo() == nil {
+                       ms.StoreMessageInfo(mi)
+               }
+               return ms
+       }
+       return mi.MessageOf(x)
+}
+
+// Deprecated: Use GreetResponse.ProtoReflect.Descriptor instead.
+func (*GreetResponse) Descriptor() ([]byte, []int) {
+       return file_proto_greet_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *GreetResponse) GetGreeting() string {
+       if x != nil {
+               return x.Greeting
+       }
+       return ""
+}
+
+var File_proto_greet_proto protoreflect.FileDescriptor
+
+var file_proto_greet_proto_rawDesc = []byte{
+       0x0a, 0x11, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x72, 0x65, 0x65, 
0x74, 0x2e, 0x70, 0x72,
+       0x6f, 0x74, 0x6f, 0x12, 0x05, 0x67, 0x72, 0x65, 0x65, 0x74, 0x22, 0x22, 
0x0a, 0x0c, 0x47, 0x72,
+       0x65, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 
0x0a, 0x04, 0x6e, 0x61,
+       0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 
0x6d, 0x65, 0x22, 0x2b,
+       0x0a, 0x0d, 0x47, 0x72, 0x65, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 
0x6e, 0x73, 0x65, 0x12,
+       0x1a, 0x0a, 0x08, 0x67, 0x72, 0x65, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x18, 
0x01, 0x20, 0x01, 0x28,
+       0x09, 0x52, 0x08, 0x67, 0x72, 0x65, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x32, 
0x44, 0x0a, 0x0c, 0x47,
+       0x72, 0x65, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 
0x34, 0x0a, 0x05, 0x47,
+       0x72, 0x65, 0x65, 0x74, 0x12, 0x13, 0x2e, 0x67, 0x72, 0x65, 0x65, 0x74, 
0x2e, 0x47, 0x72, 0x65,
+       0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 
0x67, 0x72, 0x65, 0x65,
+       0x74, 0x2e, 0x47, 0x72, 0x65, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 
0x6e, 0x73, 0x65, 0x22,
+       0x00, 0x42, 0x3f, 0x5a, 0x3d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 
0x63, 0x6f, 0x6d, 0x2f,
+       0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x64, 0x75, 0x62, 0x62, 0x6f, 
0x2d, 0x67, 0x6f, 0x2d,
+       0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x66, 0x69, 0x6c, 0x74, 
0x65, 0x72, 0x2f, 0x68,
+       0x79, 0x73, 0x74, 0x72, 0x69, 0x78, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 
0x3b, 0x67, 0x72, 0x65,
+       0x65, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+       file_proto_greet_proto_rawDescOnce sync.Once
+       file_proto_greet_proto_rawDescData = file_proto_greet_proto_rawDesc
+)
+
+func file_proto_greet_proto_rawDescGZIP() []byte {
+       file_proto_greet_proto_rawDescOnce.Do(func() {
+               file_proto_greet_proto_rawDescData = 
protoimpl.X.CompressGZIP(file_proto_greet_proto_rawDescData)
+       })
+       return file_proto_greet_proto_rawDescData
+}
+
+var file_proto_greet_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
+var file_proto_greet_proto_goTypes = []interface{}{
+       (*GreetRequest)(nil),  // 0: greet.GreetRequest
+       (*GreetResponse)(nil), // 1: greet.GreetResponse
+}
+var file_proto_greet_proto_depIdxs = []int32{
+       0, // 0: greet.GreetService.Greet:input_type -> greet.GreetRequest
+       1, // 1: greet.GreetService.Greet:output_type -> greet.GreetResponse
+       1, // [1:2] is the sub-list for method output_type
+       0, // [0:1] is the sub-list for method input_type
+       0, // [0:0] is the sub-list for extension type_name
+       0, // [0:0] is the sub-list for extension extendee
+       0, // [0:0] is the sub-list for field type_name
+}
+
+func init() { file_proto_greet_proto_init() }
+func file_proto_greet_proto_init() {
+       if File_proto_greet_proto != nil {
+               return
+       }
+       if !protoimpl.UnsafeEnabled {
+               file_proto_greet_proto_msgTypes[0].Exporter = func(v 
interface{}, i int) interface{} {
+                       switch v := v.(*GreetRequest); i {
+                       case 0:
+                               return &v.state
+                       case 1:
+                               return &v.sizeCache
+                       case 2:
+                               return &v.unknownFields
+                       default:
+                               return nil
+                       }
+               }
+               file_proto_greet_proto_msgTypes[1].Exporter = func(v 
interface{}, i int) interface{} {
+                       switch v := v.(*GreetResponse); i {
+                       case 0:
+                               return &v.state
+                       case 1:
+                               return &v.sizeCache
+                       case 2:
+                               return &v.unknownFields
+                       default:
+                               return nil
+                       }
+               }
+       }
+       type x struct{}
+       out := protoimpl.TypeBuilder{
+               File: protoimpl.DescBuilder{
+                       GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+                       RawDescriptor: file_proto_greet_proto_rawDesc,
+                       NumEnums:      0,
+                       NumMessages:   2,
+                       NumExtensions: 0,
+                       NumServices:   1,
+               },
+               GoTypes:           file_proto_greet_proto_goTypes,
+               DependencyIndexes: file_proto_greet_proto_depIdxs,
+               MessageInfos:      file_proto_greet_proto_msgTypes,
+       }.Build()
+       File_proto_greet_proto = out.File
+       file_proto_greet_proto_rawDesc = nil
+       file_proto_greet_proto_goTypes = nil
+       file_proto_greet_proto_depIdxs = nil
+}
diff --git a/filter/hystrix/proto/greet.proto b/filter/hystrix/proto/greet.proto
new file mode 100644
index 00000000..e7701946
--- /dev/null
+++ b/filter/hystrix/proto/greet.proto
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+syntax = "proto3";
+package greet;
+
+option go_package = 
"github.com/apache/dubbo-go-samples/filter/hystrix/proto;greet";
+
+message GreetRequest {
+  string name = 1;
+}
+
+message GreetResponse {
+  string greeting = 1;
+}
+
+service GreetService {
+  rpc Greet(GreetRequest) returns (GreetResponse) {}
+}
\ No newline at end of file
diff --git a/filter/proto/greet.triple.go b/filter/hystrix/proto/greet.triple.go
similarity index 99%
copy from filter/proto/greet.triple.go
copy to filter/hystrix/proto/greet.triple.go
index 6f906938..1df73466 100644
--- a/filter/proto/greet.triple.go
+++ b/filter/hystrix/proto/greet.triple.go
@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-triple. DO NOT EDIT.
 //
-// Source: greet.proto
+// Source: proto/greet.proto
 package greet
 
 import (
diff --git a/filter/proto/greet.triple.go b/filter/proto/greet.triple.go
index 6f906938..1df73466 100644
--- a/filter/proto/greet.triple.go
+++ b/filter/proto/greet.triple.go
@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-triple. DO NOT EDIT.
 //
-// Source: greet.proto
+// Source: proto/greet.proto
 package greet
 
 import (
diff --git a/go.mod b/go.mod
index 68887276..e8ed4165 100644
--- a/go.mod
+++ b/go.mod
@@ -4,7 +4,9 @@ go 1.25.0
 
 require (
        dubbo.apache.org/dubbo-go/v3 v3.3.1
+       github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5
        github.com/alibaba/sentinel-golang v1.0.4
+       github.com/apache/dubbo-go-extensions v0.0.0-20260312085545-de428af0b99e
        github.com/apache/dubbo-go-hessian2 v1.12.5
        github.com/dubbogo/go-zookeeper v1.0.4-0.20211212162352-f9d2183d89d5
        github.com/dubbogo/gost v1.14.3
@@ -30,7 +32,6 @@ require (
 require (
        github.com/RoaringBitmap/roaring v1.2.3 // indirect
        github.com/Workiva/go-datastructures v1.0.52 // indirect
-       github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 // 
indirect
        github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68 // 
indirect
        github.com/alibabacloud-go/tea v1.1.17 // indirect
        github.com/alibabacloud-go/tea-utils v1.4.4 // indirect
diff --git a/go.sum b/go.sum
index 6d0136ab..2676b7cd 100644
--- a/go.sum
+++ b/go.sum
@@ -96,6 +96,8 @@ github.com/antihax/optional v1.0.0/go.mod 
h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kd
 github.com/apache/dubbo-getty v1.4.8/go.mod 
h1:cPJlbcHUTNTpiboMQjMHhE9XBni11LiBiG8FdrDuVzk=
 github.com/apache/dubbo-getty v1.4.10 
h1:ZmkpHJa/qgS0evX2tTNqNCz6rClI/9Wwp7ctyMml82w=
 github.com/apache/dubbo-getty v1.4.10/go.mod 
h1:V64WqLIxksEgNu5aBJBOxNIvpOZyfUJ7J/DXBlKSUoA=
+github.com/apache/dubbo-go-extensions v0.0.0-20260312085545-de428af0b99e 
h1:qwdBjqJhwHbRXBtpehiEzilkgFAyZs90e6OC7kNWxwQ=
+github.com/apache/dubbo-go-extensions 
v0.0.0-20260312085545-de428af0b99e/go.mod 
h1:vpp1J/MZLQYPNrpzx5PsDFCceUEBkdV8KBHVbEfqr4A=
 github.com/apache/dubbo-go-hessian2 v1.9.1/go.mod 
h1:xQUjE7F8PX49nm80kChFvepA/AvqAZ0oh/UaB6+6pBE=
 github.com/apache/dubbo-go-hessian2 v1.9.3/go.mod 
h1:xQUjE7F8PX49nm80kChFvepA/AvqAZ0oh/UaB6+6pBE=
 github.com/apache/dubbo-go-hessian2 v1.11.0/go.mod 
h1:7rEw9guWABQa6Aqb8HeZcsYPHsOS7XT1qtJvkmI6c5w=
diff --git a/start_integrate_test.sh b/start_integrate_test.sh
index 6666f31e..df11ea29 100755
--- a/start_integrate_test.sh
+++ b/start_integrate_test.sh
@@ -31,6 +31,7 @@ array+=("direct")
 # filter
 array+=("filter/token")
 array+=("filter/custom")
+array+=("filter/hystrix")
 
 # registry
 array+=("registry/zookeeper")

Reply via email to