label 包提供两件事:
Labels:从原始的key=value列表解析并校验,支持同一个 key 对应多个 value。Selector/Selectors:解析类 Kubernetes 的 label selector 语法,并对Labels做匹配。
它适合用在“服务发现 / 注册中心 / 端点元数据”场景:把节点的元信息放进 labels,然后用 selector 过滤节点(例如在 grpcbalance 的节点过滤里复用)。
Labels:接口抽象,底层实现是map[string]Set。Set:map[string]struct{}风格集合,用来承载同一 key 的多个 value。
同一个 key 可以拥有多个值,例如:
raw := []string{
"region=cn",
"tag=blue",
"tag=canary",
}
lbs, _ := label.ParseLabels(raw)
// lbs.Get("tag") 里同时包含 blue、canary把 []string{"k=v", ...} 解析为 Labels 并做校验:
func ParseLabels(rawLabels []string) (Labels, error)注意:每个元素必须且只能出现一次 =(a=b=c 会被拒绝)。key/value 会做格式校验。
把一个字符串按 \r\n 分隔成多行 k=v 再解析:
func ParseRawLabels(rawLabels string) (Labels, error)该函数使用固定分隔符 \r\n(CRLF)。如果你的输入是 \n,请先自行替换/转换。
- key:必须是“qualified name”,长度 ≤ 63。
- value:长度 ≤ 63;允许字母数字,以及
- + : _ .(并支持常见 CJK 字符)。
Selector:由多个Requirement组成,语义是 AND(用逗号,连接)。- 例:
"env=prod,region in (cn,us),!deprecated"
- 例:
Selectors:多个Selector的集合,语义是 OR(任意一个Selector命中即为命中)。- 适合表达“多条规则兜底”:primary 命中不了就让 fallback 规则命中。
func ParseSelector(selector string) (Selector, error)
func ParseSelectors(rawSelectors []string) (Selectors, error)匹配:
func (s Selectors) Match(labels Labels) bool
func (s Selectors) MatchRawLabels(rawLabels []string) (bool, error)下表中,key 表示标签名,value 表示标签值:
| 语法 | 操作符 | 说明 | key 不存在时 |
|---|---|---|---|
key |
Exists | key 存在即可 | false |
!key |
DoesNotExist | key 必须不存在 | true |
key=value / key==value |
Equals / DoubleEquals | 任一值等于 value | false |
key!=value |
NotEquals | 所有值都不等于 value | true |
key in (a,b) |
In | 任一值在集合内 | false |
key notin (a,b) |
NotIn | 所有值都不在集合内 | true |
key~=pattern |
Pattern | wildcard 匹配(支持 * / ?) |
false |
key@constraint |
Semver | semver 约束(基于 Masterminds/semver v3) | false |
key>10 / key<0xff |
GreaterThan / LessThan | 数值比较(按 strconv.ParseInt(base=0)) |
false |
补充说明:
NotIn/NotEquals在 key 不存在时返回true,因此它们天然带“缺省放行”的语义。Pattern/Semver/ 数值比较要求 key 存在且值可解析,否则为false。
import "github.com/xkeyideal/grpcbalance/label"
lbs, err := label.ParseLabels([]string{
"env=prod",
"region=cn",
"az=cn-hz-1",
"version=1.7.3",
"system.ip=10.0.12.34",
"weight=0x20",
"tag=blue",
"tag=canary",
})
if err != nil {
// handle invalid labels
}
sel, err := label.ParseSelector("env=prod,region in (cn,us),!deprecated")
if err != nil {
// handle invalid selector
}
_ = sel.Matches(lbs) // true/falsesel1, err := label.ParseSelector("system.ip~=10.0.*")
if err == nil {
_ = sel1.Matches(lbs)
}
sel2, err := label.ParseSelector("az~=cn-?-1")
if err == nil {
_ = sel2.Matches(lbs)
}pattern 支持:
*:任意长度(可为 0)?:单个字符
sel1, err := label.ParseSelector("version@^1.7.0")
if err == nil {
_ = sel1.Matches(lbs)
}
sel2, err := label.ParseSelector("version@>=1.6 <2.0.0")
if err == nil {
_ = sel2.Matches(lbs)
}注意:逗号 , 在 selector 里是 AND 分隔符,因此 @ 后面的 semver 约束不能包含逗号。需要多个条件时,请使用空格把条件写在同一个约束字符串里(Masterminds/semver 支持)。
sel1, err := label.ParseSelector("weight>10")
if err == nil {
_ = sel1.Matches(lbs) // 0x20 > 10 => true
}
sel2, err := label.ParseSelector("weight<0b100")
if err == nil {
_ = sel2.Matches(lbs)
}数值采用 ParseInt(base=0),支持十进制/十六进制(0x)/二进制(0b)/八进制(0o)。
- selector 解析(
ParseSelector)会做词法/语法分析与校验;推荐在初始化阶段解析一次并复用,运行时只调用Matches()。 Selector.String()/Bytes()会输出“按 key 排序”的稳定表示,适合日志与调试。
本包的 selector 语法“看起来像” Kubernetes 的 label selector,但它面向的是“服务发现/注册中心/端点元数据过滤”场景, 因此在保持核心语义一致的同时做了一些扩展。
| 项 | 说明 |
|---|---|
| AND 语义 | 多个条件用逗号 , 连接时,整体是 AND(全部条件满足才算命中)。 |
| 基础操作符 | 支持 key(存在)、!key(不存在)、=/==、!=、in (...)、notin (...)。 |
| 缺失 key 的行为 | key 不存在时,!= 与 notin 返回 true(缺省放行语义);key/in/=/== 返回 false。 |
| 维度 | Kubernetes | 本包(grpcbalance/label) | 影响/备注 |
|---|---|---|---|
| 标签模型 | map[string]string(单值) |
同一 key 支持多个 value(Set) | 影响匹配语义:例如 key in (a,b) 在本包里是“任一值命中即可”;key notin (a,b) 是“所有值都不在集合内”。 |
| 组合能力 | label selector 本身不支持 OR | 提供 Selectors(多个 Selector 的集合)表达 OR(任一命中即命中) |
可用来做 primary/fallback 规则兜底。 |
| 操作符扩展 | 不支持 | 额外支持 key~=pattern(通配符 */?)、key@constraint(semver)、key>n/key<n(数值比较,strconv.ParseInt(base=0)) |
这些是本包扩展语法,不可直接拿去给 K8s 使用。 |
| key/value 校验 | K8s 有自己的 label 规则 | 与 K8s 不完全一致 | 例如:本包 key 采用“qualified name”风格校验,可能不接受某些包含 / 的 Kubernetes 常见 key;value 允许字符集合也有所不同。 |
- 如果你需要与 Kubernetes selector 文本做互转/复用,请优先使用两者共有的“基础操作符 + AND”子集。
- 使用扩展能力(OR、Pattern、Semver、数值比较、多值)时,建议在文档/配置层明确标注“这是 grpcbalance/label 的扩展语法”。