Polaris Service Governance
Polaris is Lynx's broadest control-plane plugin. In this repository it is driven by two different YAML files:
lynx-polaris/conf/example_config.ymlcontrols the Lynx plugin itself underlynx.polaris.lynx-polaris/conf/polaris.yamlis the Polaris SDK-side transport and config-center file referenced byconfig_path.
The example file also includes lynx.service_info, which is not owned by the plugin but is commonly paired with Polaris registration.
Runtime Facts
| Item | Value |
|---|---|
| Go module | github.com/go-lynx/lynx-polaris |
| Config prefix | lynx.polaris |
| Runtime plugin name | polaris.control.plane |
| Public APIs | GetPolarisPlugin(), GetPolaris(), GetServiceInstances(), GetConfig(fileName, group), WatchService(serviceName), WatchConfig(fileName, group), CheckRateLimit(serviceName, labels), GetMetrics() |
Configuration Sources
| File | Scope | What it changes |
|---|---|---|
lynx-polaris/conf/example_config.yml | Lynx runtime | Namespace, retry, circuit-breaker, watch, rate-limit, graceful shutdown, config loading, and service registration companion data |
lynx-polaris/conf/polaris.yaml | Polaris SDK | gRPC connector addresses, config-center addresses, and optional SDK-side metrics reporting |
Runtime Notes That Matter
namespaceis required by the validator, must stay within64characters, and may only contain letters, digits,_, and-.weightmust stay within1..1000;ttlmust stay within5..300seconds.timeoutmust stay within1s..60sand must be lower thanttl, otherwise validation fails.config_pathis optional, but if it points to a missing file the plugin logs a warning and falls back to default Polaris SDK configuration.service_config.additional_configsis sorted bypriorityin ascending order, so larger priorities override later at merge time.service_config.namespaceandadditional_configs[*].namespaceexist in the schema, but the current config-source call path still reads through the plugin namespace. Keep them aligned with top-levelnamespaceinstead of treating them as independent routing controls.enable_metrics,enable_retry, andenable_circuit_breakerare schema flags, but the current init path still creates helper components with fallback defaults. Treat those booleans as intent flags, not strict hard-off switches.
Field Guide
lynx.polaris
| Field | Role | Set / enable when | Default / interaction | Common misconfig |
|---|---|---|---|---|
namespace | Main Polaris namespace for service lookup, registration, and config reads. | Always; this is the primary tenancy boundary. | Defaults to default if omitted, but validation still requires a non-empty valid name by the time init finishes. | Leaving it empty in custom config, or mixing environments in one namespace. |
token | Access token for Polaris APIs. | When your Polaris control plane requires authentication. | Optional, but if set it must be at least 8 characters and at most 1024. | Setting a short placeholder token and assuming local validation will ignore it. |
weight | Instance weight used by Polaris-side load balancing. | When the service should receive more or less traffic than peers. | Defaults to 100; validator range is 1..1000. | Using 0 to mean "unset"; runtime rewrites it to default 100. |
ttl | Service lease / heartbeat lifetime in seconds. | When using service registration and health expiration. | Defaults to 30; validator range is 5..300. | Setting a very low TTL and forgetting to keep timeout smaller. |
timeout | Timeout for Polaris operations. | Always; especially important across slow control-plane links. | Defaults to 10s; validator range is 1s..60s; must be < ttl. | Making it equal to or greater than ttl, which breaks registration expectations. |
config_path | Path to the SDK-side Polaris YAML file. | When you need explicit server connector, metrics reporter, or config-center endpoints. | Optional; if the file exists the plugin sets POLARIS_CONFIG_PATH and initializes the SDK from it. | Pointing at lynx-polaris/polaris.yaml; in this repo the file is lynx-polaris/conf/polaris.yaml. |
enable_health_check | Declares whether Polaris health-check behavior should be enabled. | When you want Polaris-driven health probing around registration. | Schema flag; keep it aligned with health_check_interval and your deployment policy. | Turning it on without a reachable control plane and assuming local probes are enough. |
health_check_interval | Health-check interval. | When health checks are enabled and the service should be polled at a predictable cadence. | Template uses 30s; defaults helper value to 30s. | Setting an interval shorter than the environment can sustain, causing noisy checks. |
enable_metrics | Declares plugin metrics intent. | When you consume plugin telemetry. | Present in schema; current init still creates metrics helpers. | Assuming false guarantees zero metrics-related setup. |
enable_retry | Declares retry behavior intent for plugin-side operations. | When transient Polaris failures should be retried. | Current retry manager still falls back to 3 retries with 1s interval if values are unset. | Enabling retries without bounding retry count or interval expectations. |
max_retry_times | Maximum retry attempts. | When retries are enabled and you need explicit retry depth. | Valid range 0..10; current helper falls back to 3 when <= 0. | Using negative values or assuming 0 means "disable retries completely". |
retry_interval | Delay between retries. | When retries are enabled. | Defaults to 1s in helper fallback. | Leaving it inconsistent with the application's own higher-level retry policy. |
enable_circuit_breaker | Declares circuit-breaker intent. | When you want plugin-side failure isolation for Polaris calls. | Current init still creates a breaker with threshold fallback 0.5. | Assuming false fully removes breaker behavior in current runtime. |
circuit_breaker_threshold | Error-rate threshold for tripping the breaker. | When circuit breaking is expected. | Defaults to 0.5; schema range is effectively 0.1..0.9 in defaults and validation practice. | Setting 0 or 1, which causes validation or ineffective behavior. |
enable_service_watch | Enables service-instance watch intent. | When business code calls WatchService() or needs live discovery updates. | Only useful with discovery-oriented Polaris usage. | Enabling it without any consumer, then paying watch complexity for nothing. |
enable_config_watch | Enables config watch intent. | When business code calls WatchConfig() or expects config change callbacks. | Works together with remote config usage and service_config. | Turning it on without actually loading config from Polaris. |
load_balancer_type | Chooses Polaris-side discovery load-balancing strategy. | When service discovery is active and governance rules depend on a specific strategy. | Supported values in defaults are weighted_random, ring_hash, maglev, l5cst. | Setting a strategy name unsupported by your Polaris deployment or forgetting that it only matters for discovery traffic. |
enable_route_rule | Enables Polaris route-rule intent. | When the environment actually maintains route rules in Polaris. | Governance-only field; pair it with discovery flows. | Turning it on in a cluster that has no route rules and expecting visible behavior. |
enable_rate_limit | Enables rate-limit checks. | When code calls CheckRateLimit() or gateways rely on Polaris quotas. | Pair with rate_limit_type and server-side rate-limit rules. | Enabling it without provisioning rate-limit rules, leading to confusing "no effect". |
rate_limit_type | Selects rate-limit mode. | When rate limiting is enabled. | Supported values are local and global. | Setting it while enable_rate_limit stays off, or choosing a mode unsupported by the server-side policy. |
enable_graceful_shutdown | Declares graceful deregistration intent. | When services should deregister cleanly during stop. | Cleanup timeout is still driven by shutdown_timeout. | Assuming the flag alone is enough while leaving timeout too low for cleanup. |
shutdown_timeout | Maximum cleanup time during stop. | Always when graceful stop matters. | Defaults to 30s; cleanup clamps it to the supported 5s..300s window. | Setting an unrealistically short timeout and expecting deregistration plus watcher shutdown to finish. |
enable_logging | Declares verbose plugin logging intent. | When diagnosing control-plane behavior. | Schema field; actual log verbosity also depends on global runtime logging. | Assuming this overrides the application's logging backend by itself. |
log_level | Desired plugin log level string. | When detailed plugin logs are required. | Supported values in defaults are debug, info, warn, error. | Setting a custom value that the rest of the runtime does not recognize. |
service_config | Multi-config loading settings for Polaris config center. | When Lynx should bootstrap config from Polaris instead of a single hard-coded file. | Optional nested object. | Enabling config watch but never defining the main config source behavior. |
lynx.polaris.service_config
| Field | Role | Set / enable when | Default / interaction | Common misconfig |
|---|---|---|---|---|
group | Main Polaris config group. | When your config center groups config by business domain or environment. | Falls back to current app name; if app name is unavailable, runtime falls back again to DEFAULT_GROUP. | Leaving group blank while the remote file actually lives in a non-default group. |
filename | Main remote config filename. | When the primary Polaris config is not <app-name>.yaml. | Defaults to <app-name>.yaml. | Forgetting the suffix and creating application instead of application.yaml. |
namespace | Declared namespace for config loading. | When you want the docs and config to stay explicit about config tenancy. | Falls back to top-level namespace; keep it aligned with top-level namespace in current runtime. | Assuming it independently reroutes config reads away from the plugin namespace. |
additional_configs | Additional files merged into runtime config. | When one service consumes shared plus app-specific config files. | Loaded after the main file, ordered by ascending priority. | Using it without deciding which file should win field conflicts. |
lynx.polaris.service_config.additional_configs[*]
| Field | Role | Set / enable when | Default / interaction | Common misconfig |
|---|---|---|---|---|
group | Group for an extra Polaris config file. | When the extra file lives outside the main group. | No automatic rewrite beyond your provided value. | Copying the main group by habit when the shared file belongs elsewhere. |
filename | Extra remote config filename. | Always for each additional file entry. | Required in practice. | Leaving it blank; the plugin cannot fetch an anonymous config file. |
namespace | Declared namespace for that extra file. | When you need the entry to be explicit for operators. | Falls back to service_config.namespace, then top-level namespace. | Treating it as a separate live namespace override without matching top-level namespace. |
priority | Merge ordering hint. | When several config files may write the same keys. | Default 0; lower values load first, higher values override later. | Assuming larger priority loads earlier. |
merge_strategy | Merge conflict strategy metadata. | When operators need to know how conflicts are supposed to be resolved. | Current docs and runtime intent use override, merge, append; missing value behaves as override in logging/merge intent. | Writing custom strategy names that the rest of the config merge stack does not understand. |
Companion lynx.service_info
The example template also includes a root-level lynx.service_info block. It belongs to Lynx application registration, not to the Polaris plugin schema itself, but it must stay coherent with Polaris registration behavior.
| Field | Role | Set / enable when | Default / interaction | Common misconfig |
|---|---|---|---|---|
service_name | Published service name. | When the service should register into Polaris discovery. | Should match the service name expected by callers and route rules. | Using a different name than the one downstream clients query. |
namespace | Service-info namespace. | When service metadata should stay explicit. | Keep it aligned with lynx.polaris.namespace. | Mixing namespaces between service_info and lynx.polaris. |
host | Advertised host or IP. | When the runtime cannot infer the correct reachable address. | No plugin-side default is documented here. | Publishing 127.0.0.1 from a container or remote host. |
port | Advertised service port. | When the service registers itself for discovery. | Must match the actual listening port. | Registering one port while the service listens on another. |
weight | Registration weight companion value. | When the registration payload should mirror plugin weight. | Keep it aligned with lynx.polaris.weight. | Tuning one weight and forgetting the other copy in the example. |
ttl | Registration TTL companion value. | When registration payload should mirror plugin TTL. | Keep it aligned with lynx.polaris.ttl. | Diverging from top-level TTL and creating operator confusion. |
metadata | Free-form metadata attached to the instance. | When discovery, routing, or observability consumers need labels such as version or region. | Optional map. | Treating metadata as secret storage or forgetting to keep label names consistent across services. |
lynx-polaris/conf/polaris.yaml
| YAML path | Role | Set / enable when | Default / interaction | Common misconfig |
|---|---|---|---|---|
global.serverConnector.protocol | SDK transport protocol for talking to Polaris server. | When your Polaris deployment expects a specific connector protocol. | Template uses grpc. | Switching protocol without matching server support. |
global.serverConnector.addresses | Polaris server addresses used by the SDK connector. | Always when config_path is used for explicit server connectivity. | Template uses 127.0.0.1:8091. | Pointing at config-center addresses instead of service-governance addresses. |
global.statReporter.enable | Enables SDK-side stats reporting. | When Polaris SDK metrics should be exported. | Template enables it. | Turning it on without configuring a reachable reporter backend. |
global.statReporter.chain | Reporter pipeline list. | When you want one or more stat reporters active. | Template uses prometheus. | Listing a reporter plugin that is not configured under plugin. |
global.statReporter.plugin.prometheus.type | Reporter mode for the Prometheus reporter. | When Prometheus reporting is enabled. | Template uses push. | Assuming it is pull-based while still providing a push address. |
global.statReporter.plugin.prometheus.address | Prometheus push destination. | When reporter type requires a target address. | Template uses 127.0.0.1:9091. | Leaving a local placeholder in production and silently pushing nowhere useful. |
global.statReporter.plugin.prometheus.interval | Push interval for the reporter. | When SDK stats reporting is enabled. | Template uses 10s. | Setting it too low and creating unnecessary reporting pressure. |
config.configConnector.addresses | Polaris config-center addresses for remote config APIs. | When the plugin should load config from Polaris. | Template uses 127.0.0.1:8093. | Reusing the service connector address when config center is exposed on a different port. |
Complete YAML Example
Main plugin config (lynx-polaris/conf/example_config.yml)
lynx:
polaris:
namespace: default # Polaris namespace; runtime default is default
token: your-polaris-token # Optional auth token; omit if the cluster does not require it
weight: 100 # Instance weight; keep aligned with service_info.weight when registering
ttl: 30 # Heartbeat TTL in seconds; timeout must stay below this value
timeout: 10s # Plugin request timeout; validator expects 1s-60s
config_path: ./conf/polaris.yaml # Optional SDK config file; repository path is lynx-polaris/conf/polaris.yaml
enable_health_check: true # Enable health-check logic
health_check_interval: 30s # Health-check interval; used when health checks are enabled
enable_metrics: true # Enable Polaris metrics collection
enable_retry: true # Enable retry manager for transient failures
max_retry_times: 3 # Retry cap; valid range is 0-10
retry_interval: 1s # Retry wait interval
enable_circuit_breaker: true # Enable circuit-breaker behavior
circuit_breaker_threshold: 0.5 # Failure threshold; valid range is 0.1-0.9
enable_service_watch: true # Watch service instance changes
enable_config_watch: true # Watch remote config changes
load_balancer_type: weighted_random # Example load-balancer strategy
enable_route_rule: true # Enable route-rule awareness
enable_rate_limit: true # Enable rate-limit checks when governance rules exist
rate_limit_type: local # Example rate-limit mode
enable_graceful_shutdown: true # Schema field; cleanup window still follows shutdown_timeout
shutdown_timeout: 30s # Graceful cleanup timeout during unload
enable_logging: true # Schema field describing verbose logging intent
log_level: info # Supported values: debug, info, warn, error
service_info:
service_name: my-service # Registered service name
namespace: default # Registration namespace; usually matches lynx.polaris.namespace
host: 127.0.0.1 # Advertised host or IP; do not keep localhost in containerized deployments
port: 8080 # Advertised service port
weight: 100 # Registration weight; keep aligned with lynx.polaris.weight
ttl: 30 # Registration TTL; keep aligned with lynx.polaris.ttl
metadata:
version: "1.0.0" # Example release label
environment: production # Example environment label
region: us-west-1 # Example region label
SDK companion file (lynx-polaris/conf/polaris.yaml)
global:
serverConnector:
protocol: grpc # SDK transport protocol for Polaris server traffic
addresses:
- 127.0.0.1:8091 # Polaris service-governance endpoint
statReporter:
enable: true # Enable SDK-side stats reporting
chain:
- prometheus # Reporter pipeline; must match a configured plugin entry below
plugin:
prometheus:
type: push # Template uses push mode
address: 127.0.0.1:9091 # Prometheus push destination
interval: 10s # Push interval
config:
configConnector:
addresses:
- 127.0.0.1:8093 # Polaris config-center endpoint
Minimum Viable YAML Example
The Lynx-side plugin can boot with runtime defaults. Add config_path only when you need to override Polaris SDK connectivity explicitly.
lynx:
polaris:
namespace: default # Smallest explicit plugin block; other validation-sensitive fields fall back to defaults
Common Misconfigurations
config_pathuses the wrong path. In this repository the SDK file islynx-polaris/conf/polaris.yaml, notlynx-polaris/polaris.yaml.timeoutis greater than or equal tottl, which fails validation.service_info.namespace,service_info.weight, orservice_info.ttldrift away from top-levellynx.polarisvalues.- Operators set
service_config.namespaceoradditional_configs[*].namespaceto a different namespace and expect the current runtime to read from a separate control-plane namespace automatically. - Governance fields such as
enable_rate_limit,enable_route_rule, andload_balancer_typeare enabled before actual Polaris governance rules exist.
Runtime Usage
plugin, err := polaris.GetPolarisPlugin()
instances, err := polaris.GetServiceInstances("user-service")
content, err := polaris.GetConfig("application.yaml", "DEFAULT_GROUP")
watcher, err := polaris.WatchConfig("application.yaml", "DEFAULT_GROUP")
allowed, err := polaris.CheckRateLimit("user-service", map[string]string{"region": "ap-northeast-1"})
Choose Polaris when registration, discovery, config center, and governance are intentionally owned by the same control plane. If you only need config-center behavior, Apollo or Etcd is usually a narrower fit.