Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ Please refer to [HOWTO.md](HOWTO.md) for detailed instructions on running the sa
* `otlp_http_exporter`: Uses `otlpHttpExporter` to export tracing data, covering `dubbo`/`triple`/`jsonrpc` protocols.
* `registry`: Examples of using different service registries (e.g., Nacos, Zookeeper).
* `retry`: Demonstrates retry mechanisms in Dubbo-go RPC calls.
* `router`: Various Dubbo-go router examples.
* `router/tag`: Dubbo-go tag router examples.
* `router/condition`: Dubbo-go condition router examples.
* `router/script`: Dubbo-go script router examples.
* `rpc`: Various RPC protocol examples with Dubbo-go.
* `rpc/dubbo`: Dubbo protocol example, including Java–Go interop.
* `rpc/grpc`: gRPC protocol example.
Expand Down
4 changes: 4 additions & 0 deletions README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@
* `otlp_http_exporter`:使用 `otlpHttpExporter` 导出追踪数据,覆盖 `dubbo` / `triple` / `jsonrpc` 协议。
* `registry`:使用不同服务注册中心(如 Nacos、Zookeeper)的示例。
* `retry`:Dubbo-go RPC 调用重试机制示例。
* `router`: Dubbo-go 各种 Router 调用示例。
* `router/tag`: Dubbo-go 的 tag router 使用示例。
* `router/condition`: Dubbo-go 的 condition router 使用示例。
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Chinese sample index under router lists tag/condition, but this PR also adds a router/script example directory. Consider adding a router/script entry here to keep the index complete.

Suggested change
* `router/condition`: Dubbo-go 的 condition router 使用示例。
* `router/condition`: Dubbo-go 的 condition router 使用示例。
* `router/script`: Dubbo-go 的 script router 使用示例。

Copilot uses AI. Check for mistakes.
* `router/script`: Dubbo-go 的 script router 使用示例。
* `rpc`:Dubbo-go 支持的多种 RPC 协议示例。
* `rpc/dubbo`:Dubbo 协议示例,包含 Java–Go 互操作。
* `rpc/grpc`:基于 gRPC 协议的示例。
Expand Down
7 changes: 7 additions & 0 deletions router/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Dubbo-go Router Sample

English | [中文](README_CN.md)

## Description

This directory includes multiple types of dubbo-go router function.
7 changes: 7 additions & 0 deletions router/README_CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Dubbo-go Router 示例

[English](README.md) | 中文

## 描述

这个文件夹包含了 dubbo-go router 功能的多个示例。
68 changes: 68 additions & 0 deletions router/condition/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Condition router

This example shows how to use dubbo-go's condition router.

English | [中文](README_CN.md)

## Prerequisites

- Docker and docker compose to run Nacos registry.
- Go Version 1.23+.
- Nacos Version 2.x+.

## How to run

### Run Nacos registry

Follow this instruction
to [install and run Nacos](https://dubbo-next.staged.apache.org/zh-cn/overview/reference/integrations/nacos/).

### Run server (Provider)

In this example, you will run two servers on ports 20000 and 20001 respectively.

```shell
$ go run ./go-server/cmd/server.go # port 20000
$ go run ./go-node2-server/cmd/server_node2.go # port 20001
```

### Run client (Consumer)

In this example, the client will keep calling Greet method in an infinity loop. You need to:

- Start the client and observe the load balancing behavior during calls.

- Set up the condition router configuration in the Nacos registry, then observe the client's calls again.

```shell
$ go run ./go-client/cmd/client.go
```

### Configuration of Nacos

Create a new configuration with the `Data ID` **condition-server.condition-router** and set the format to `yaml`.

Set the Group to `DEFAULT_GROUP`.

> Note: The naming convention in Nacos is {application.name}.{router_type}.

```yaml
configVersion: V3.3.2
scope: "application"
key: "condition-server"
priority: 1
force: true
enabled: true
conditions:
- from:
match: "application = condition-client"
to:
- match: "port = 20001"
```

## Expected result

- When the client starts without the condition router configuration in Nacos,
it will alternate calls between the two server endpoints.
- When the client starts with the condition router configured in Nacos,
it will route traffic to only one server endpoint.
67 changes: 67 additions & 0 deletions router/condition/README_CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Condition router

这个例子展示了如何使用dubbo-go的condition router功能。

[English](README.md) | 中文

## 前置准备

- Docker以及Docker Compose环境来运行Nacos注册中心。
- Go 1.23+版本。
- Nacos 2.x+版本。

## 如何运行

### 启动Nacos注册中心

参考这个教程来[启动Nacos](https://dubbo-next.staged.apache.org/zh-cn/overview/reference/integrations/nacos/)。

### 运行服务端(Provider)

在这个示例中,你将运行两个服务端,分别在20000以及20001端口上提供服务。

```shell
$ go run ./go-server/cmd/server.go # 20000端口
$ go run ./go-node2-server/cmd/server_node2.go # 20001端口
```

### 运行客户端(Consumer)

在这个示例中,客户端将在一个死循环中一直调用Greet方法,你需要:

- 启动客户端,观察其调用时的负载均衡(Load Balance)。
- 在Nacos注册中心上设置`condition router`的配置,再次观察客户端的调用情况。

```shell
$ go run ./go-client/cmd/client.go
```

### Nacos配置

新建一个`Data ID`为`condition-server.condition-router`,格式为`yaml`的配置。

Group设置为`DEFAULT_GROUP`。

> 注意:Nacos中命名规则为{application.name}.{router_type}

```yaml
configVersion: V3.3.2
scope: "application"
key: "condition-server"
priority: 1
force: true
enabled: true
conditions:
- from:
match: "application = condition-client"
to:
- match: "port = 20001"
```

## 预期结果

- 启动客户端但是未在nacos配置中心设置condition router的配置的时候,客户端将在两个服务端之间来回调用。
- 启动客户端并在nacos配置中心设置了condition router后,客户端将只调用其中一个服务端。



96 changes: 96 additions & 0 deletions router/condition/go-client/cmd/client.go
Original file line number Diff line number Diff line change
@@ -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 main

import (
"context"
"os/signal"
"syscall"
"time"
)

import (
"dubbo.apache.org/dubbo-go/v3"
"dubbo.apache.org/dubbo-go/v3/config_center"
_ "dubbo.apache.org/dubbo-go/v3/imports"
"dubbo.apache.org/dubbo-go/v3/registry"

"github.com/dubbogo/gost/log/logger"
)

import (
greet "github.com/apache/dubbo-go-samples/direct/proto"
)

const (
RegistryAddress = "127.0.0.1:8848"
)

func main() {
ins, err := dubbo.NewInstance(
dubbo.WithName("condition-client"),
dubbo.WithRegistry(
registry.WithNacos(),
registry.WithAddress(RegistryAddress),
),
dubbo.WithConfigCenter( // configure config center to enable condition router
config_center.WithNacos(),
config_center.WithAddress(RegistryAddress),
),
)

if err != nil {
logger.Errorf("new instance failed: %v", err)
panic(err)
}

cli, err := ins.NewClient()

if err != nil {
logger.Errorf("new client failed: %v", err)
panic(err)
}

srv, err := greet.NewGreetService(cli)

if err != nil {
logger.Errorf("new service failed: %v", err)
panic(err)
}

ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer stop()

ticker := time.NewTicker(5 * time.Second)
defer ticker.Stop()

for {
select {
case <-ctx.Done():
logger.Info("gracefully exiting...")
return
case <-ticker.C:
rep, err := srv.Greet(context.Background(), &greet.GreetRequest{Name: "hello world"})
if err != nil {
logger.Errorf("call greet method failed: %v", err)
} else {
logger.Infof("receive: %s", rep.GetGreeting())
}
}
}
}
90 changes: 90 additions & 0 deletions router/condition/go-node2-server/cmd/server_node2.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* 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"
"strconv"
"strings"
)

import (
"dubbo.apache.org/dubbo-go/v3"
_ "dubbo.apache.org/dubbo-go/v3/imports"
"dubbo.apache.org/dubbo-go/v3/protocol"
"dubbo.apache.org/dubbo-go/v3/registry"

"github.com/dubbogo/gost/log/logger"
)

import (
greet "github.com/apache/dubbo-go-samples/direct/proto"
)

const (
RegistryAddress = "127.0.0.1:8848"
TriPort = 20000
)

type GreetServer struct {
srvPort int
}

func (srv *GreetServer) Greet(_ context.Context, req *greet.GreetRequest) (rep *greet.GreetResponse, err error) {
rep = &greet.GreetResponse{Greeting: req.Name + " from: " + strconv.Itoa(srv.srvPort)}
return rep, nil
}

func main() {
ins, err := dubbo.NewInstance(
dubbo.WithName("condition-server"),
dubbo.WithRegistry(
registry.WithNacos(),
registry.WithAddress(RegistryAddress),
),
dubbo.WithProtocol(
protocol.WithTriple(),
protocol.WithPort(TriPort),
),
)

if err != nil {
logger.Errorf("new instance failed: %v", err)
panic(err)
}

srv, err := ins.NewServer()

if err != nil {
logger.Errorf("new server failed: %v", err)
panic(err)
}

if err := greet.RegisterGreetServiceHandler(srv, &GreetServer{srvPort: TriPort}); err != nil {
logger.Errorf("register service failed: %v", err)
panic(err)
}

if err := srv.Serve(); err != nil {
logger.Errorf("server serve failed: %v", err)
if strings.Contains(err.Error(), "client not connected") {
logger.Errorf("hint: Nacos client not connected (gRPC). Check %s is reachable and gRPC port %d is open (Nacos 2.x default).", RegistryAddress, 9848)
}
panic(err)
}
}
Loading
Loading