赞
踩
Springcloud 服务注册接口 ServiceRegistry
- @Configuration(proxyBeanMethods = false)
- @EnableConfigurationProperties
- @ConditionalOnNacosDiscoveryEnabled
- # 默认开启服务自动注册
- @ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled",
- matchIfMissing = true)
- @AutoConfigureAfter({ AutoServiceRegistrationConfiguration.class,
- AutoServiceRegistrationAutoConfiguration.class,
- NacosDiscoveryAutoConfiguration.class })
- public class NacosServiceRegistryAutoConfiguration {
-
- @Bean
- public NacosServiceRegistry nacosServiceRegistry(
- NacosDiscoveryProperties nacosDiscoveryProperties) {
- return new NacosServiceRegistry(nacosDiscoveryProperties);
- }
-
- @Bean
- @ConditionalOnBean(AutoServiceRegistrationProperties.class)
- public NacosRegistration nacosRegistration(
- ObjectProvider<List<NacosRegistrationCustomizer>> registrationCustomizers,
- NacosDiscoveryProperties nacosDiscoveryProperties,
- ApplicationContext context) {
- return new NacosRegistration(registrationCustomizers.getIfAvailable(),
- nacosDiscoveryProperties, context);
- }
-
- @Bean
- @ConditionalOnBean(AutoServiceRegistrationProperties.class)
- public NacosAutoServiceRegistration nacosAutoServiceRegistration(
- NacosServiceRegistry registry,
- AutoServiceRegistrationProperties autoServiceRegistrationProperties,
- NacosRegistration registration) {
- return new NacosAutoServiceRegistration(registry,
- autoServiceRegistrationProperties, registration);
- }
-
- }
配置类中设计到的几个bean:NacosServiceRegistry 、NacosRegistration 、NacosAutoServiceRegistration 、AutoServiceRegistrationConfiguration
NacosServiceRegistry : 实现服务的注册逻辑
NacosRegistration : 通过 NacosRegistrationCustomizer 实现类定制化服务
NacosAutoServiceRegistration : 服务启动后自动注册的入口
AutoServiceRegistrationConfiguration : 用于注册 AutoServiceRegistrationProperties``
1、NacosAutoServiceRegistration
它实现了ApplicationListener,监听 WebServerInitializedEvent 事件,
在spring容器启动过程中,WebServerStartStopLifecycle 发布了 ServletWebServerInitializedEvent
- public void start() {
- this.webServer.start();
- this.running = true;
- this.applicationContext.publishEvent(new ServletWebServerInitializedEvent(this.webServer, this.applicationContext));
- }
2、bind( )
- AbstractAutoServiceRegistration.java
-
- public void bind(WebServerInitializedEvent event) {
- ApplicationContext context = event.getApplicationContext();
- if (context instanceof ConfigurableWebServerApplicationContext) {
- if ("management".equals(((ConfigurableWebServerApplicationContext) context).getServerNamespace())) {
- return;
- }
- }
- //端口绑定
- this.port.compareAndSet(0, event.getWebServer().getPort());
-
- this.start();
- }
3、start( )
- public void start() {
- if (!isEnabled()) {
- if (logger.isDebugEnabled()) {
- logger.debug("Discovery Lifecycle disabled. Not starting");
- }
- return;
- }
-
- // only initialize if nonSecurePort is greater than 0 and it isn't already running
- // because of containerPortInitializer below
- if (!this.running.get()) {
- //发布服务注册前的事件
- this.context.publishEvent(new InstancePreRegisteredEvent(this, getRegistration()));
- //服务注册
- register();
- if (shouldRegisterManagement()) {
- registerManagement();
- }
- //发布服务注册事件
- this.context.publishEvent(new InstanceRegisteredEvent<>(this, getConfiguration()));
- //运行状态设置为true
- this.running.compareAndSet(false, true);
- }
-
- }
4、register( )
- @Override
- protected void register() {
- //校验注册功能是否打开
- if (!this.registration.getNacosDiscoveryProperties().isRegisterEnabled()) {
- log.debug("Registration disabled.");
- return;
- }
- if (this.registration.getPort() < 0) {
- this.registration.setPort(getPort().get());
- }
- //注册
- super.register();
- }
-
- protected void register() {
- //调用 NacosServiceRegistry
- this.serviceRegistry.register(getRegistration());
- }
5、register( )
- NacosServiceRegistry.java
-
- public void register(Registration registration) {
-
- if (StringUtils.isEmpty(registration.getServiceId())) {
- log.warn("No service to register for nacos client...");
- return;
- }
-
- //获取 NamingService
- 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);
- }
- }
6、registerInstance( )
- @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);
- }
7、addBeatInfo( )
- public void addBeatInfo(String serviceName, BeatInfo beatInfo) {
- NAMING_LOGGER.info("[BEAT] adding beat: {} to beat map.", beatInfo);
- String key = buildKey(serviceName, beatInfo.getIp(), beatInfo.getPort());
- BeatInfo existBeat = null;
- //fix #1733
- if ((existBeat = dom2Beat.remove(key)) != null) {
- existBeat.setStopped(true);
- }
- dom2Beat.put(key, beatInfo);
- //创建心跳检测任务 BeatTask,线程池执行该任务
- executorService.schedule(new BeatTask(beatInfo), beatInfo.getPeriod(), TimeUnit.MILLISECONDS);
- MetricsMonitor.getDom2BeatSizeMonitor().set(dom2Beat.size());
- }
8、registerService( )
调用nacos服务端注册服务
- 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()));
-
- //通过 NamingProxy调用nacos api进行服务注册
- reqApi(UtilAndComs.nacosUrlInstance, params, HttpMethod.POST);
-
- }
9、BeatTask
定时任务向nacos服务端发送心跳消息
- class BeatTask implements Runnable {
-
- BeatInfo beatInfo;
-
- public BeatTask(BeatInfo beatInfo) {
- this.beatInfo = beatInfo;
- }
-
- @Override
- public void run() {
- if (beatInfo.isStopped()) {
- return;
- }
- long nextTime = beatInfo.getPeriod();
- try {
- //请求nacos api心跳接口
- JsonNode result = serverProxy.sendBeat(beatInfo, BeatReactor.this.lightBeatEnabled);
- long interval = result.get("clientBeatInterval").asLong();
- boolean lightBeatEnabled = false;
- if (result.has(CommonParams.LIGHT_BEAT_ENABLED)) {
- lightBeatEnabled = result.get(CommonParams.LIGHT_BEAT_ENABLED).asBoolean();
- }
- BeatReactor.this.lightBeatEnabled = lightBeatEnabled;
- if (interval > 0) {
- nextTime = interval;
- }
- //校验返回状态码
- int code = NamingResponseCode.OK;
- if (result.has(CommonParams.CODE)) {
- code = result.get(CommonParams.CODE).asInt();
- }
- if (code == NamingResponseCode.RESOURCE_NOT_FOUND) {
- Instance instance = new Instance();
- instance.setPort(beatInfo.getPort());
- instance.setIp(beatInfo.getIp());
- instance.setWeight(beatInfo.getWeight());
- instance.setMetadata(beatInfo.getMetadata());
- instance.setClusterName(beatInfo.getCluster());
- instance.setServiceName(beatInfo.getServiceName());
- instance.setInstanceId(instance.getInstanceId());
- instance.setEphemeral(true);
- try {
- //服务资源不存在,重新注册
- serverProxy.registerService(beatInfo.getServiceName(),
- NamingUtils.getGroupName(beatInfo.getServiceName()), instance);
- } catch (Exception ignore) {
- }
- }
- } catch (NacosException ex) {
- NAMING_LOGGER.error("[CLIENT-BEAT] failed to send beat: {}, code: {}, msg: {}",
- JacksonUtils.toJson(beatInfo), ex.getErrCode(), ex.getErrMsg());
-
- }
- //延时调度 BeatTask
- executorService.schedule(new BeatTask(beatInfo), nextTime, TimeUnit.MILLISECONDS);
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。