服务注册:
先说原理逻辑
:就是一个http请求,然后交给nacos服务端,服务端采用了异步任务+阻塞队列的形式,提升了高并发的处理。
Nacos客户端:首先我们在服务中引用nacos-discovery依赖,当我们启动项目时,nacos会根据事件发布的机制,
public abstract class AbstractAutoServiceRegistration<R extends Registration>
implements AutoServiceRegistration, ApplicationContextAware,
ApplicationListener<WebServerInitializedEvent> {
//省略部分
@Override
@SuppressWarnings("deprecation")
//事件监听,由spring自动触发。
public void onApplicationEvent(WebServerInitializedEvent event) {
bind(event);
}
//事件处理
@Deprecated
public void bind(WebServerInitializedEvent event) {
//省略部分
this.start();
}
public void start() {
if (!isEnabled()) {
if (logger.isDebugEnabled()) {
logger.debug("Discovery Lifecycle disabled. Not starting");
}
return;
}
if (!this.running.get()) {
this.context.publishEvent(
new InstancePreRegisteredEvent(this, getRegistration()));
//服务注册核心
register();
if (shouldRegisterManagement()) {
registerManagement();
}
this.context.publishEvent(
new InstanceRegisteredEvent<>(this, getConfiguration()));
this.running.compareAndSet(false, true);
}
}
protected void register() {
//服务注册
this.serviceRegistry.register(getRegistration());
}
NacosServiceRegistry
类
@Override
public void register(Registration registration) {
if (StringUtils.isEmpty(registration.getServiceId())) {
log.warn("No service to register for nacos client...");
return;
}
//获取配置信息
NamingService namingService = namingService();
String serviceId = registration.getServiceId();
String group = nacosDiscoveryProperties.getGroup();
Instance instance = getNacosInstanceFromRegistration(registration);
try {
//注册核心
namingService.registerInstance(serviceId, group, instance);
log.info("nacos registry, {} {} {}:{} register finished", group, serviceId,
instance.getIp(), instance.getPort());
}
catch (Exception e) {
log.error("nacos registry, {} register failed...{},", serviceId,
registration.toString(), e);
// rethrow a RuntimeException if the registration is failed.
// issue : https://github.com/alibaba/spring-cloud-alibaba/issues/1132
rethrowRuntimeException(e);
}
}
NacosNamingService
类
@Override
public void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException {
NamingUtils.checkInstanceIsLegal(instance);
String groupedServiceName = NamingUtils.getGroupedName(serviceName, groupName);
if (instance.isEphemeral()) {
//发送心跳检查(先不看),我们先看注册逻辑
BeatInfo beatInfo = beatReactor.buildBeatInfo(groupedServiceName, instance);
beatReactor.addBeatInfo(groupedServiceName, beatInfo);
}
//注册核心这里
serverProxy.registerService(groupedServiceName, groupName, instance);
}
NamingProxy
类 实际上就是一个http的请求:请求路径为:"/nacos/v1/ns/instance"
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()));
params.put("metadata", JacksonUtils.toJson(instance.getMetadata()));
//注册核心。就是一个http请求。就是你nacos服务端的地址+端口+"/nacos/v1/ns/instance"
reqApi(UtilAndComs.nacosUrlInstance, params, HttpMethod.POST);
}
上面参数路径为:UtilAndComs.nacosUrlInstance = "/nacos/v1/ns/instance"
官方文档:
你的yml配置文件中的spring.cloud.nacos.discovery
@ConfigurationProperties("spring.cloud.nacos.discovery")
public class NacosDiscoveryProperties {
private static final Logger log = LoggerFactory
.getLogger(NacosDiscoveryProperties.class);
/**
* Prefix of {@link NacosDiscoveryProperties}.
*/
public static final String PREFIX = "spring.cloud.nacos.discovery";
private static final Pattern PATTERN = Pattern.compile("-(\\w)");
你nacos的地址
/**
* nacos discovery server address.
*/
private String serverAddr;
/**
* the nacos authentication username.
*/
private String username;
/**
* the nacos authentication password.
*/
private String password;
/**
* the domain name of a service, through which the server address can be dynamically
* obtained.
*/
private String endpoint;
/**
* namespace, separation registry of different environments.
*/
private String namespace;
/**
* watch delay,duration to pull new service from nacos server.
*/
private long watchDelay = 30000;
/**
* nacos naming log file name.
*/
private String logName;
/**
* service name to registry.
*/
@Value("${spring.cloud.nacos.discovery.service:${spring.application.name:}}")
private String service;
/**
* weight for service instance, the larger the value, the larger the weight.
*/
private float weight = 1;
/**
* cluster name for nacos .
*/
private String clusterName = "DEFAULT";
/**
* group name for nacos.
*/
private String group = "DEFAULT_GROUP";
/**
* naming load from local cache at application start. true is load.
*/
private String namingLoadCacheAtStart = "false";
/**
* extra metadata to register.
*/
private Map<String, String> metadata = new HashMap<>();
/**
* if you just want to subscribe, but don't want to register your service, set it to
* false.
*/
private boolean registerEnabled = true;
/**
* The ip address your want to register for your service instance, needn't to set it
* if the auto detect ip works well.
*/
private String ip;
/**
* which network interface's ip you want to register.
*/
private String networkInterface = "";
/**
* The port your want to register for your service instance, needn't to set it if the
* auto detect port works well.
*/
private int port = -1;
/**
* whether your service is a https service.
*/
private boolean secure = false;
/**
* access key for namespace.
*/
private String accessKey;
/**
* secret key for namespace.
*/
private String secretKey;
/**
* Heart beat interval. Time unit: millisecond.
*/
private Integer heartBeatInterval;
/**
* Heart beat timeout. Time unit: millisecond.
*/
private Integer heartBeatTimeout;
/**
* Ip delete timeout. Time unit: millisecond.
*/
private Integer ipDeleteTimeout;
/**
* If instance is enabled to accept request. The default value is true.
*/
private boolean instanceEnabled = true;
/**
* If instance is ephemeral.The default value is true.
*/
private boolean ephemeral = true;
然后你的nacos服务端就有一个接口去接收上面的这个请求
@RestController
@RequestMapping(UtilsAndCommons.NACOS_NAMING_CONTEXT + "/instance")
public class InstanceController {
//省略部分
//服务注册在这个方法里面。实现方式:异步任务+阻塞队列
@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);
NamingUtils.checkServiceNameFormat(serviceName);
final Instance instance = parseInstance(request);
//真正的处理客户端的注册。
serviceManager.registerInstance(namespaceId, serviceName, instance);
return "ok";
}