在Flutter中如何基于grpc包实现客户端侧负载均衡
Flutter 使用官方 grpc 包实现客户端侧负载均衡方案
注意:grpc 包版本需不低于 3.1.0,早期版本未提供原生负载均衡相关API
基础实现(基于DNS服务发现)
grpc-dart 原生内置了服务解析与负载均衡能力,不需要引入第三方依赖,仅需在创建ClientChannel时配置对应参数即可:
- 配置通道的负载均衡策略,目前内置支持两种策略:
pick_first:默认策略,始终使用第一个解析成功的可用节点,仅节点故障时才会切换到下一个节点round_robin:轮询策略,将请求依次均匀分发到所有可用后端节点
- 代码示例:
import 'package:grpc/grpc.dart'; // 创建grpc客户端通道 final channel = ClientChannel( '你的服务域名', // 会自动通过DNS解析该域名对应的所有后端IP port: 50051, options: ChannelOptions( // 指定负载均衡策略为轮询 loadBalancingPolicy: LoadBalancingPolicy.roundRobin, // 根据你的服务配置选择TLS或明文凭证 credentials: ChannelCredentials.insecure(), ), ); // 后续直接使用该channel创建stub调用接口即可,请求会自动按策略分发 final stub = YourServiceClient(channel);
对接自定义服务注册中心
如果你的服务节点存储在Consul、Etcd等自定义服务注册中心,需要自己实现NameResolver完成服务节点获取:
- 继承
NameResolver类实现自定义节点解析逻辑 - 将自定义解析器注册到全局解析器注册表
- 创建通道时使用对应scheme的服务地址
代码示例:
import 'package:grpc/grpc.dart'; // 自定义服务解析器 class CustomServiceNameResolver extends NameResolver { final String serviceName; CustomServiceNameResolver(this.serviceName); @override Future<void> resolve(NameResolverListener listener) async { // 调用你的服务注册中心接口,拉取当前可用的服务节点列表 final List<Map<String, dynamic>> serviceNodes = await YourServiceDiscovery.getAvailableNodes(serviceName); // 转换为grpc要求的Address格式 final addresses = serviceNodes.map((node) => Address(node['host'], node['port'])).toList(); // 通知负载均衡器更新可用节点列表 listener.onAddresses(addresses, const <String, dynamic>{}); } @override void shutdown() {} } // 应用启动时注册自定义解析器 void initGrpcConfig() { NameResolverRegistry.instance.registerFactory( 'my_discovery', // 自定义的scheme标识 (Uri uri, Map<String, dynamic> args) => CustomServiceNameResolver(uri.pathSegments.first), ); } // 创建通道时使用自定义scheme的地址 final channel = ClientChannel( 'my_discovery:///你的服务名称', port: 50051, options: ChannelOptions( loadBalancingPolicy: LoadBalancingPolicy.roundRobin, credentials: ChannelCredentials.insecure(), ), );
其他说明
- 内置负载均衡器会自动完成节点健康检测,故障节点会被自动剔除,恢复后自动重新加入可用列表
- 业务层无需处理节点选择逻辑,所有请求都会自动按照配置的策略分发到不同节点
- 有自定义分发需求的场景可以继承
LoadBalancer实现自定义策略,注册到LoadBalancerRegistry后即可使用
内容的提问来源于stack exchange,提问作者Daniel Armas
相关产品推荐
相关产品推荐

