Cloud Native 14 min read

How to Integrate Sentinel‑Go with Nacos for Dynamic Flow‑Control Rules

This guide explains how to use Sentinel‑Go with Nacos as an external dynamic data source, covering background, installation, configuration, code examples, deployment steps, and how to update flow‑control rules in real time for cloud‑native microservices.

Alibaba Cloud Native
Alibaba Cloud Native
Alibaba Cloud Native
How to Integrate Sentinel‑Go with Nacos for Dynamic Flow‑Control Rules

Overview

Sentinel‑Go is an open‑source flow‑control library for Go, providing traffic limiting, circuit breaking and system load protection. Nacos is a dynamic service discovery and configuration platform. By using Nacos as an external data source, Sentinel‑Go can load flow‑control rules at runtime and update them without restarting services.

Prerequisites

Go 1.13+ installed.

Java 1.8+ and Maven 3.2+ for building Nacos (or download a binary release).

Install Sentinel‑Go

go get github.com/alibaba/sentinel-golang

Run a static Sentinel‑Go flow‑control demo

The program initializes Sentinel, loads a static flow rule (QPS 10, reject), and spawns 10 goroutines that continuously try to enter the resource “some-test”.

package main

import (
    "fmt"
    "log"
    "math/rand"
    "time"

    sentinel "github.com/alibaba/sentinel-golang/api"
    "github.com/alibaba/sentinel-golang/core/base"
    "github.com/alibaba/sentinel-golang/core/flow"
    "github.com/alibaba/sentinel-golang/util"
)

func main() {
    if err := sentinel.InitDefault(); err != nil {
        log.Fatalf("Init error: %+v", err)
    }
    _, err := flow.LoadRules([]*flow.FlowRule{{
        Resource:        "some-test",
        MetricType:     flow.QPS,
        Count:          10,
        ControlBehavior: flow.Reject,
    }})
    if err != nil {
        log.Fatalf("Load rule error: %+v", err)
    }

    ch := make(chan struct{})
    for i := 0; i < 10; i++ {
        go func() {
            for {
                e, b := sentinel.Entry("some-test", sentinel.WithTrafficType(base.Inbound))
                if b != nil {
                    // blocked
                    time.Sleep(time.Duration(rand.Uint64()%10) * time.Millisecond)
                } else {
                    fmt.Println(util.CurrentTimeMillis(), "passed")
                    time.Sleep(time.Duration(rand.Uint64()%10) * time.Millisecond)
                    e.Exit()
                }
            }
        }()
    }
    <-ch
}

Deploy Nacos

Clone the source, build with Maven and start in standalone mode:

git clone https://github.com/alibaba/nacos.git
cd nacos
mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U
cd distribution/target/nacos-server-<em>$version</em>/nacos/bin
sh startup.sh -m standalone   # Linux/macOS
# or: cmd startup.cmd      # Windows

After startup, the console is reachable at http://127.0.0.1:8848/nacos (default credentials nacos/nacos).

Store Sentinel flow rules in Nacos

Log in to the Nacos console.

Navigate to Configuration Management → Create Configuration .

Set dataId=flow and group=sentinel-go.

Paste the following JSON (example: reject traffic when QPS > 100):

[
  {
    "resource": "some-test",
    "metricType": 1,
    "count": 100.0,
    "controlBehavior": 0
  }
]

Integrate Nacos as a dynamic data source

Use the Nacos Go SDK together with Sentinel‑Go’s datasource extension. The code creates a Nacos config client, registers a FlowRulesHandler, and builds a NacosDataSource that watches the configuration defined above.

package main

import (
    "fmt"
    "math/rand"
    "sync/atomic"
    "time"

    sentinel "github.com/alibaba/sentinel-golang/api"
    "github.com/alibaba/sentinel-golang/core/base"
    "github.com/alibaba/sentinel-golang/ext/datasource"
    "github.com/alibaba/sentinel-golang/ext/datasource/nacos"
    "github.com/alibaba/sentinel-golang/util"
    "github.com/nacos-group/nacos-sdk-go/clients"
    "github.com/nacos-group/nacos-sdk-go/common/constant"
)

type Counter struct {
    pass, block, total *int64
}

func main() {
    counter := Counter{pass: new(int64), block: new(int64), total: new(int64)}

    // Nacos server address
    sc := []constant.ServerConfig{{ContextPath: "/nacos", Port: 8848, IpAddr: "127.0.0.1"}}
    cc := constant.ClientConfig{TimeoutMs: 5000}
    client, err := clients.CreateConfigClient(map[string]interface{}{
        "serverConfigs": sc,
        "clientConfig":  cc,
    })
    if err != nil {
        fmt.Printf("Create client error: %+v
", err)
        return
    }

    // Handler that parses JSON array into FlowRule objects
    h := datasource.NewFlowRulesHandler(datasource.FlowRuleJsonArrayParser)

    // Nacos data source: group=sentinel-go, dataId=flow
    nds, err := nacos.NewNacosDataSource(client, "sentinel-go", "flow", h)
    if err != nil {
        fmt.Printf("Create Nacos data source error: %+v
", err)
        return
    }
    if err = nds.Initialize(); err != nil {
        fmt.Printf("Initialize Nacos data source error: %+v
", err)
        return
    }

    go timerTask(&counter)

    ch := make(chan struct{})
    for i := 0; i < 10; i++ {
        go func() {
            for {
                atomic.AddInt64(counter.total, 1)
                e, b := sentinel.Entry("some-test", sentinel.WithTrafficType(base.Inbound))
                if b != nil {
                    atomic.AddInt64(counter.block, 1)
                    time.Sleep(time.Duration(rand.Uint64()%10) * time.Millisecond)
                } else {
                    atomic.AddInt64(counter.pass, 1)
                    time.Sleep(time.Duration(rand.Uint64()%10) * time.Millisecond)
                    e.Exit()
                }
            }
        }()
    }
    <-ch
}

// Periodically prints pass/block statistics
func timerTask(c *Counter) {
    fmt.Println("begin to statistic!!!")
    var oldTotal, oldPass, oldBlock int64
    for {
        time.Sleep(1 * time.Second)
        total := atomic.LoadInt64(c.total)
        pass := atomic.LoadInt64(c.pass)
        block := atomic.LoadInt64(c.block)
        fmt.Println(util.CurrentTimeMillis()/1000,
            "total:", total-oldTotal,
            "pass:", pass-oldPass,
            "block:", block-oldBlock)
        oldTotal, oldPass, oldBlock = total, pass, block
    }
}

When the JSON in Nacos is modified (e.g., change count from 100 to 400), the NacosDataSource automatically reloads the rules, and the running application immediately enforces the new limits.

Project setup

Use Sentinel‑Go version 0.6.0 and Nacos‑SDK‑Go version 1.0.0.

module sentinel-go-nacos-example

go 1.13

require (
    github.com/alibaba/sentinel-golang v0.6.0
    github.com/nacos-group/nacos-sdk-go v1.0.0
)

Result verification

The console prints per‑second statistics of total requests, passed and blocked counts. After updating the rule in Nacos, the block rate changes accordingly without restarting the Go process.

Key points

Replace static flow.LoadRules with a Nacos‑backed datasource.

The same pattern works for circuit‑breaking, warm‑up and hotspot‑parameter rules by using the corresponding handlers.

References

Sentinel‑Go repository: https://github.com/alibaba/sentinel-golang Nacos repository: https://github.com/alibaba/nacos Sentinel‑Go Nacos example:

https://github.com/alibaba/sentinel-golang/tree/master/example/nacos
Sentinel‑Go Nacos dynamic data source architecture
Sentinel‑Go Nacos dynamic data source architecture
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Cloud NativeGoNacossentinelFlow Controldynamic-config
Alibaba Cloud Native
Written by

Alibaba Cloud Native

We publish cloud-native tech news, curate in-depth content, host regular events and live streams, and share Alibaba product and user case studies. Join us to explore and share the cloud-native insights you need.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.