rs-zero 0.2.6

Rust-first microservice framework inspired by go-zero engineering practices
Documentation
# Discovery 手册

`rs-zero` 的 `discovery` feature 提供服务发现基础模型和 adapter 边界。

## 核心能力

- `ServiceInstance`:服务实例、endpoint、metadata、weight、health。
- discovery/registry trait:支持 discover、register、deregister 和 watch/refresh 语义。
- static、memory、DNS adapter。
- round-robin selector。
- etcd/Kubernetes adapter 分别通过 `discovery-etcd``discovery-kube` feature 开启;`discovery-etcd` 使用真实 etcd v3 client,`discovery-kube` 使用真实 Kubernetes EndpointSlice watcher。

## etcd registry

启用 `discovery-etcd` 后,`EtcdRegistry::connect` 会连接 etcd,并支持:

- `register`:写入 `/prefix/{service}/{id}`,value 为 `ServiceInstance` JSON。
- lease keep-alive:注册时创建 lease,后台续期,`deregister` 停止续期并 revoke lease。
- `discover`:按 service prefix 查询,只返回 healthy instance;空结果返回 `NoInstances`- `update_health`:更新已注册实例的 healthy 字段并保留 lease。
- `watch_service`:监听 service prefix 的 put/delete 事件;stream 失败后按 `BackoffConfig` 重连。

最小配置示例:

```rust
use rs_zero::discovery_etcd::{BackoffConfig, EtcdDiscoveryConfig, EtcdRegistry};
use std::time::Duration;

# async fn build_registry() -> Result<EtcdRegistry, Box<dyn std::error::Error>> {
let registry = EtcdRegistry::connect(EtcdDiscoveryConfig {
    endpoints: vec!["http://127.0.0.1:2379".to_string()],
    prefix: "/rs-zero".to_string(),
    lease_ttl: 30,
    reconnect_interval: Duration::from_secs(1),
    connect_timeout: Duration::from_secs(3),
    operation_timeout: Duration::from_secs(3),
    keep_alive_interval: Duration::from_secs(5),
    keep_alive_timeout: Duration::from_secs(3),
    watch_backoff: BackoffConfig::default(),
    auth: None,
})
.await?;
# Ok(registry)
# }
```

## Kubernetes discovery

启用 `discovery-kube` 后,`KubeDiscovery::connect` 会从 kubeconfig 或 in-cluster 环境创建 Kubernetes client,并监听指定 namespace 的 `discovery.k8s.io/v1 EndpointSlice`。

主路径支持:

- `connect` / `from_client`:启动真实 EndpointSlice watcher;`from_snapshot` 仅保留给 fixture 和离线测试。
- 初始化同步:处理 `Init` / `InitApply` / `InitDone`,首次同步完成前返回可诊断错误。
- 增删更新:处理 `Apply` / `Delete`,本地缓存按 EndpointSlice 贡献更新,删除后不会保留旧实例。
- 健康过滤:只返回 ready 且非 terminating endpoint。
- 配置:`context``namespace``service_name``label_selector``field_selector``port_name``watch_timeout``page_size``sync_timeout` 和 metadata。

最小配置示例:

```rust
use rs_zero::discovery_kube::{KubeDiscovery, KubeDiscoveryConfig};
use std::time::Duration;

# async fn build_discovery() -> Result<KubeDiscovery, Box<dyn std::error::Error>> {
let discovery = KubeDiscovery::connect(KubeDiscoveryConfig {
    context: Some("docker-desktop".to_string()),
    namespace: "default".to_string(),
    service_name: Some("api".to_string()),
    port_name: Some("http".to_string()),
    sync_timeout: Duration::from_secs(10),
    ..KubeDiscoveryConfig::default()
})
.await?;
# Ok(discovery)
# }
```

## 使用建议

- 本地开发优先使用 static 或 memory adapter。
- 生产注册中心接入前先确认 health、metadata、权重、lease TTL、keep-alive、timeout、Kubernetes RBAC 和 watch 重连策略。
- 外部服务测试默认 ignored,不应纳入默认 CI 主路径。

## 相关示例与测试

- `examples/discovery-hello/README.md`
- `examples/production-adapters/etcd-discovery.rs`
- `cargo test --test discovery_integration`
- `cargo test --no-default-features --features discovery-etcd --test discovery_etcd_codec`
- `RS_ZERO_ETCD_ENDPOINT=http://127.0.0.1:2379 cargo test --no-default-features --features discovery-etcd --test discovery_etcd_external -- --ignored`
- `cargo test --no-default-features --features discovery-kube --test discovery_kube_mapper`
- `RS_ZERO_KUBE_EXTERNAL=1 cargo test --no-default-features --features discovery-kube --test discovery_kube_external -- --ignored`