nacos服务注册和发现原理简单实现案例

Nacos(Naming and Configuration Service)是阿里巴巴开源的服务发现和配置管理平台。下面将介绍Nacos服务注册和发现的原理,并进行简单的源码分析。

服务注册和发现的原理

服务注册
  1. 服务实例启动:当服务实例启动时,它会通过Nacos客户端与Nacos服务端建立连接。
  2. 发送注册请求:服务实例通过HTTP或DNS协议向Nacos服务端发送注册请求,请求中包含服务名、IP、端口、健康检查URL等信息。
  3. 服务端处理:Nacos服务端接收到注册请求后,将服务实例信息存储到内存中,同时持久化到数据库中。
  4. 健康检查:Nacos服务端会定期对已注册的服务实例进行健康检查,确保服务实例可用。
服务发现
  1. 服务消费者:当服务消费者需要调用服务提供者时,它会向Nacos服务端发送服务发现请求。
  2. 服务端响应:Nacos服务端接收到服务发现请求后,会返回所有可用的服务实例列表。
  3. 负载均衡:服务消费者根据某种负载均衡策略(如随机、轮询等)从服务实例列表中选择一个服务实例进行调用。

源码分析

服务注册

服务注册的源码主要在nacos-client模块的NamingProxy类中。

java
// NamingProxy类中的registerService方法
public void registerService(String serviceName, String groupName, Instance instance) throws NacosException {
NAMING_LOGGER.info("[REGISTER-SERVICE] {} registering service {} with instance: {}", namespaceId, serviceName,
instance);
// 构建服务注册的请求
final Map<String, String> params = new HashMap<String, String>(16);
params.put(CommonParams.NAMESPACE_ID, namespaceId);
params.put(CommonParams.SERVICE_NAME, serviceName);
params.put(CommonParams.GROUP_NAME, groupName);
params.put(CommonParams.CLUSTER_NAME, instance.getClusterName());
params.put(“ip”, instance.getIp());
params.put(“port”, String.valueOf(instance.getPort()));
params.put(“weight”, String.valueOf(instance.getWeight()));
params.put(“enable”, String.valueOf(instance.isEnabled()));
params.put(“healthy”, String.valueOf(instance.isHealthy()));
params.put(“ephemeral”, String.valueOf(instance.isEphemeral()));
// 发送注册请求
reqApi(UtilAndComs.nacosUrlInstance, params, HttpMethod.POST);
}

服务发现

服务发现的源码主要在nacos-client模块的NamingProxy类中。

java
// NamingProxy类中的queryList方法
public List queryList(String serviceName, String groupName, List clusters, boolean subscribe) throws NacosException {
// 构建服务发现的请求
Map<String, String> params = new HashMap<String, String>(8);
params.put(CommonParams.NAMESPACE_ID, namespaceId);
params.put(CommonParams.SERVICE_NAME, serviceName);
params.put(CommonParams.GROUP_NAME, groupName);
params.put(CommonParams.CLUSTER_NAME, StringUtils.join(clusters, “,”));
params.put(“subscribe”, String.valueOf(subscribe));
// 发送服务发现请求
String result = reqApi(UtilAndComs.nacosUrlBase + “/instance/list”, params, HttpMethod.GET);
// 解析返回的服务实例列表
return parseInstanceListResult(result);
}

服务端处理

服务端处理注册和发现请求的源码主要在nacos-naming模块的InstanceController类中。

java
// InstanceController类中的register方法
@CanDistro
@PostMapping
@Secured(parser = NamingResourceParser.class, action = ActionTypes.WRITE)
public String register(HttpServletRequest request) throws Exception {
// 从请求中解析服务实例信息
final String namespaceId = WebUtils
.optional(request, CommonParams.NAMESPACE_ID, Constants.DEFAULT_NAMESPACE_ID);
final String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME);
final String group = WebUtils.optional(request, CommonParams.GROUP_NAME, Constants.DEFAULT_GROUP);
// …
// 将服务实例信息注册到服务端
Instance instance = serviceManager.registerInstance(namespaceId, serviceName, group, instance);
// 返回结果
return “ok”;
}

// InstanceController类中的list方法
@CanDistro
@GetMapping("/list")
@Secured(parser = NamingResourceParser.class, action = ActionTypes.READ)
public Object list(HttpServletRequest request) throws Exception {
// …
// 获取服务实例列表
Service service = serviceManager.getService(namespaceId, serviceName, group);
List instances = serviceManager.getAllInstances(namespaceId, serviceName, group, clusters);
// …
// 返回服务实例列表
return ResultUtil.ok(instances);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值