跳转至

服务发现指南

仓库中包含一套基于 Redis 的服务发现与 HTTP 调用工具。

核心组件

组件 描述
ServiceRegistry 服务注册与心跳
DiscoveryClient 带缓存的服务发现与负载均衡
DiscoveryHttpClient 结合服务发现的 HTTP 重试与节点切换

ServiceRegistry

服务注册中心,负责管理服务的注册与心跳。

from by_framework.core.discovery import ServiceRegistry

registry = ServiceRegistry(redis_client=redis)
await registry.register("my-service", "192.168.1.100", 8080)
# register() 内部会自动启动后台心跳循环,不需要(也没有)单独的 heartbeat() 方法
import com.iwhaleai.byai.framework.core.discovery.ServiceRegistry;

ServiceRegistry registry = new ServiceRegistry(redisClient);
registry.register("my-service", "http", "192.168.1.100", 8080, "/api", 1, null, 30);
// 心跳自动通过后台线程维护
import { ServiceRegistry } from '@byclaw/by-framework';

const registry = new ServiceRegistry(redis);
await registry.register({
    serviceName: "my-service",
    host: "192.168.1.100",
    port: 8080,
    heartbeatInterval: 10,  // 秒
});
// 心跳自动通过 setInterval 维护

DiscoveryClient

带缓存的服务发现客户端:

from by_framework.core.discovery import DiscoveryClient

discovery = DiscoveryClient(redis_client=redis, cache_interval=30)
endpoints = await discovery.discover("my-service")
# 返回可用的服务节点列表
import com.iwhaleai.byai.framework.core.discovery.DiscoveryClient;

DiscoveryClient discovery = new DiscoveryClient(redisClient);
List<ServiceInstance> endpoints = discovery.getInstances("my-service");
import { DiscoveryClient } from '@byclaw/by-framework';

const discovery = new DiscoveryClient(redis, 5);  // 5秒缓存
const endpoints = await discovery.getInstances("my-service");

DiscoveryHttpClient

结合服务发现的 HTTP 客户端,支持自动重试与节点切换:

from by_framework.util.discovery_http_client import DiscoveryHttpClient

# 构造函数接收一个已有的 DiscoveryClient 实例,不是 redis_client / service_name;
# service_name 是每次请求单独传入的(一个 DiscoveryHttpClient 可以调用多个服务)
http_client = DiscoveryHttpClient(discovery_client)

response = await http_client.get("api-service", "/api/v1/users")
response = await http_client.post("api-service", "/api/v1/users", json={"name": "test"})
import com.iwhaleai.byai.framework.util.http.DiscoveryHttpClient;

// 构造函数接收 DiscoveryClient + 底层 ByHttpClient(可传 null 使用默认实现)+ RetryConfig;
// serviceName 同样是每次请求单独传入的
DiscoveryHttpClient httpClient = new DiscoveryHttpClient(
    discoveryClient, null, RetryConfig.builder().build()
);

HttpResponse response = httpClient.get("api-service", "/api/v1/users", null, null).get();
HttpResponse response = httpClient.post(
    "api-service", "/api/v1/users", null, Map.of("name", "test"), null
).get();
import { DiscoveryHttpClient, DiscoveryClient } from '@byclaw/by-framework';

const discoveryClient = new DiscoveryClient(redis);
const httpClient = new DiscoveryHttpClient({ discoveryClient });

const response = await httpClient.get("api-service", "/api/v1/users");
const response = await httpClient.post("api-service", "/api/v1/users", {
    json: { name: "test" },
});