温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

如何理解ZookeeperDiscoveryAutoConfiguration

发布时间:2021-10-20 18:02:00 来源:亿速云 阅读:163 作者:柒染 栏目:大数据

本篇文章为大家展示了如何理解ZookeeperDiscoveryAutoConfiguration,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

主要研究一下ZookeeperDiscoveryAutoConfiguration

ZookeeperDiscoveryAutoConfiguration

spring-cloud-zookeeper-discovery-2.1.2.RELEASE-sources.jar!/org/springframework/cloud/zookeeper/discovery/ZookeeperDiscoveryAutoConfiguration.java

@Configuration
@ConditionalOnBean(ZookeeperDiscoveryClientConfiguration.Marker.class)
@ConditionalOnZookeeperDiscoveryEnabled
@AutoConfigureBefore({ CommonsClientAutoConfiguration.class,
		NoopDiscoveryClientAutoConfiguration.class })
@AutoConfigureAfter({ ZookeeperDiscoveryClientConfiguration.class })
public class ZookeeperDiscoveryAutoConfiguration {

	@Autowired(required = false)
	private ZookeeperDependencies zookeeperDependencies;

	@Autowired
	private CuratorFramework curator;

	@Bean
	@ConditionalOnMissingBean
	public ZookeeperDiscoveryProperties zookeeperDiscoveryProperties(
			InetUtils inetUtils) {
		return new ZookeeperDiscoveryProperties(inetUtils);
	}

	@Bean
	@ConditionalOnMissingBean
	// currently means auto-registration is false. That will change when
	// ZookeeperServiceDiscovery is gone
	public ZookeeperDiscoveryClient zookeeperDiscoveryClient(
			ServiceDiscovery<ZookeeperInstance> serviceDiscovery,
			ZookeeperDiscoveryProperties zookeeperDiscoveryProperties) {
		return new ZookeeperDiscoveryClient(serviceDiscovery, this.zookeeperDependencies,
				zookeeperDiscoveryProperties);
	}

	@Bean
	public ZookeeperServiceWatch zookeeperServiceWatch(
			ZookeeperDiscoveryProperties zookeeperDiscoveryProperties) {
		return new ZookeeperServiceWatch(this.curator, zookeeperDiscoveryProperties);
	}

	@Configuration
	@ConditionalOnEnabledHealthIndicator("zookeeper")
	@ConditionalOnClass(Endpoint.class)
	protected static class ZookeeperDiscoveryHealthConfig {

		@Autowired(required = false)
		private ZookeeperDependencies zookeeperDependencies;

		@Bean
		@ConditionalOnMissingBean
		public ZookeeperDiscoveryHealthIndicator zookeeperDiscoveryHealthIndicator(
				CuratorFramework curatorFramework,
				ServiceDiscovery<ZookeeperInstance> serviceDiscovery,
				ZookeeperDiscoveryProperties properties) {
			return new ZookeeperDiscoveryHealthIndicator(curatorFramework,
					serviceDiscovery, this.zookeeperDependencies, properties);
		}

	}

}
  • ZookeeperDiscoveryAutoConfiguration注册了ZookeeperDiscoveryProperties、ZookeeperDiscoveryClient、ZookeeperServiceWatch、ZookeeperDiscoveryHealthIndicator

ZookeeperDiscoveryProperties

spring-cloud-zookeeper-discovery-2.1.2.RELEASE-sources.jar!/org/springframework/cloud/zookeeper/discovery/ZookeeperDiscoveryProperties.java

@ConfigurationProperties("spring.cloud.zookeeper.discovery")
public class ZookeeperDiscoveryProperties {

	/**
	 * Default URI spec.
	 */
	public static final String DEFAULT_URI_SPEC = "{scheme}://{address}:{port}";

	private InetUtils.HostInfo hostInfo;

	private boolean enabled = true;

	/**
	 * Root Zookeeper folder in which all instances are registered.
	 */
	private String root = "/services";

	/**
	 * The URI specification to resolve during service registration in Zookeeper.
	 */
	private String uriSpec = DEFAULT_URI_SPEC;

	/** Id used to register with zookeeper. Defaults to a random UUID. */
	private String instanceId;

	/**
	 * Predefined host with which a service can register itself in Zookeeper. Corresponds
	 * to the {code address} from the URI spec.
	 */
	private String instanceHost;

	/**
	 * IP address to use when accessing service (must also set preferIpAddress to use).
	 */
	private String instanceIpAddress;

	/**
	 * Use ip address rather than hostname during registration.
	 */
	private boolean preferIpAddress = false;

	/** Port to register the service under (defaults to listening port). */
	private Integer instancePort;

	/** Ssl port of the registered service. */
	private Integer instanceSslPort;

	/**
	 * Register as a service in zookeeper.
	 */
	private boolean register = true;

	/**
	 * Gets the metadata name/value pairs associated with this instance. This information
	 * is sent to zookeeper and can be used by other instances.
	 */
	private Map<String, String> metadata = new HashMap<>();

	/**
	 * The initial status of this instance (defaults to
	 * {@link StatusConstants#STATUS_UP}).
	 */
	private String initialStatus = StatusConstants.STATUS_UP;

	/**
	 * Order of the discovery client used by `CompositeDiscoveryClient` for sorting
	 * available clients.
	 */
	private int order = 0;

	//......
}
  • ZookeeperDiscoveryProperties定义了enabled、root、uriSpec、instanceId、instanceHost、instanceIpAddress、preferIpAddress、instancePort、instanceSslPort、register、metadata、initialStatus、order属性

ZookeeperDiscoveryClient

spring-cloud-zookeeper-discovery-2.1.2.RELEASE-sources.jar!/org/springframework/cloud/zookeeper/discovery/ZookeeperDiscoveryClient.java

public class ZookeeperDiscoveryClient implements DiscoveryClient {

	private static final Log log = LogFactory.getLog(ZookeeperDiscoveryClient.class);

	private final ZookeeperDependencies zookeeperDependencies;

	private final ServiceDiscovery<ZookeeperInstance> serviceDiscovery;

	private final ZookeeperDiscoveryProperties zookeeperDiscoveryProperties;

	public ZookeeperDiscoveryClient(ServiceDiscovery<ZookeeperInstance> serviceDiscovery,
			ZookeeperDependencies zookeeperDependencies,
			ZookeeperDiscoveryProperties zookeeperDiscoveryProperties) {
		this.serviceDiscovery = serviceDiscovery;
		this.zookeeperDependencies = zookeeperDependencies;
		this.zookeeperDiscoveryProperties = zookeeperDiscoveryProperties;
	}

	@Override
	public String description() {
		return "Spring Cloud Zookeeper Discovery Client";
	}

	private static org.springframework.cloud.client.ServiceInstance createServiceInstance(
			String serviceId, ServiceInstance<ZookeeperInstance> serviceInstance) {
		return new ZookeeperServiceInstance(serviceId, serviceInstance);
	}

	@Override
	public List<org.springframework.cloud.client.ServiceInstance> getInstances(
			final String serviceId) {
		try {
			if (getServiceDiscovery() == null) {
				return Collections.EMPTY_LIST;
			}
			String serviceIdToQuery = getServiceIdToQuery(serviceId);
			Collection<ServiceInstance<ZookeeperInstance>> zkInstances = getServiceDiscovery()
					.queryForInstances(serviceIdToQuery);
			List<org.springframework.cloud.client.ServiceInstance> instances = new ArrayList<>();
			for (ServiceInstance<ZookeeperInstance> instance : zkInstances) {
				instances.add(createServiceInstance(serviceIdToQuery, instance));
			}
			return instances;
		}
		catch (KeeperException.NoNodeException e) {
			if (log.isDebugEnabled()) {
				log.debug(
						"Error getting instances from zookeeper. Possibly, no service has registered.",
						e);
			}
			// this means that nothing has registered as a service yes
			return Collections.emptyList();
		}
		catch (Exception exception) {
			rethrowRuntimeException(exception);
		}
		return new ArrayList<>();
	}

	private ServiceDiscovery<ZookeeperInstance> getServiceDiscovery() {
		return this.serviceDiscovery;
	}

	private String getServiceIdToQuery(String serviceId) {
		if (this.zookeeperDependencies != null
				&& this.zookeeperDependencies.hasDependencies()) {
			String pathForAlias = this.zookeeperDependencies.getPathForAlias(serviceId);
			return pathForAlias.isEmpty() ? serviceId : pathForAlias;
		}
		return serviceId;
	}

	@Override
	public List<String> getServices() {
		List<String> services = null;
		if (getServiceDiscovery() == null) {
			log.warn(
					"Service Discovery is not yet ready - returning empty list of services");
			return Collections.emptyList();
		}
		try {
			Collection<String> names = getServiceDiscovery().queryForNames();
			if (names == null) {
				return Collections.emptyList();
			}
			services = new ArrayList<>(names);
		}
		catch (KeeperException.NoNodeException e) {
			if (log.isDebugEnabled()) {
				log.debug(
						"Error getting services from zookeeper. Possibly, no service has registered.",
						e);
			}
			// this means that nothing has registered as a service yes
			return Collections.emptyList();
		}
		catch (Exception e) {
			rethrowRuntimeException(e);
		}
		return services;
	}

	@Override
	public int getOrder() {
		return this.zookeeperDiscoveryProperties.getOrder();
	}

}
  • ZookeeperDiscoveryClient实现了org.springframework.cloud.client.discovery.DiscoveryClient接口,其getInstances使用curator的ServiceDiscovery.queryForInstances获取服务实例信息,然后转换为org.springframework.cloud.client.ServiceInstance类型;getServices则是使用curator的ServiceDiscovery.queryForNames获取服务名信息

ZookeeperServiceWatch

spring-cloud-zookeeper-discovery-2.1.2.RELEASE-sources.jar!/org/springframework/cloud/zookeeper/discovery/ZookeeperServiceWatch.java

public class ZookeeperServiceWatch
		implements ApplicationListener<InstanceRegisteredEvent<?>>, TreeCacheListener,
		ApplicationEventPublisherAware {

	private final CuratorFramework curator;

	private final ZookeeperDiscoveryProperties properties;

	private final AtomicLong cacheChange = new AtomicLong(0);

	private ApplicationEventPublisher publisher;

	private TreeCache cache;

	public ZookeeperServiceWatch(CuratorFramework curator,
			ZookeeperDiscoveryProperties properties) {
		this.curator = curator;
		this.properties = properties;
	}

	@Override
	public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
		this.publisher = publisher;
	}

	public TreeCache getCache() {
		return this.cache;
	}

	@Override
	public void onApplicationEvent(InstanceRegisteredEvent<?> event) {
		this.cache = TreeCache.newBuilder(this.curator, this.properties.getRoot())
				.build();
		this.cache.getListenable().addListener(this);
		try {
			this.cache.start();
		}
		catch (Exception e) {
			ReflectionUtils.rethrowRuntimeException(e);
		}
	}

	@PreDestroy
	public void stop() throws Exception {
		if (this.cache != null) {
			this.cache.close();
		}
	}

	@Override
	public void childEvent(CuratorFramework client, TreeCacheEvent event)
			throws Exception {
		if (event.getType().equals(TreeCacheEvent.Type.NODE_ADDED)
				|| event.getType().equals(TreeCacheEvent.Type.NODE_REMOVED)
				|| event.getType().equals(TreeCacheEvent.Type.NODE_UPDATED)) {
			long newCacheChange = this.cacheChange.incrementAndGet();
			this.publisher.publishEvent(new HeartbeatEvent(this, newCacheChange));
		}
	}

}
  • ZookeeperServiceWatch实现了ApplicationListener、TreeCacheListener、ApplicationEventPublisherAware接口;其childEvent方法在event类型是NODE_ADDED、NODE_REMOVED、NODE_UPDATED类型时会发布HeartbeatEvent事件

ZookeeperDiscoveryHealthIndicator

spring-cloud-zookeeper-discovery-2.1.2.RELEASE-sources.jar!/org/springframework/cloud/zookeeper/discovery/ZookeeperDiscoveryHealthIndicator.java

public class ZookeeperDiscoveryHealthIndicator implements DiscoveryHealthIndicator {

	private static final Log log = LogFactory
			.getLog(ZookeeperDiscoveryHealthIndicator.class);

	private CuratorFramework curatorFramework;

	private ServiceDiscovery<ZookeeperInstance> serviceDiscovery;

	private final ZookeeperDependencies zookeeperDependencies;

	private final ZookeeperDiscoveryProperties zookeeperDiscoveryProperties;

	public ZookeeperDiscoveryHealthIndicator(CuratorFramework curatorFramework,
			ServiceDiscovery<ZookeeperInstance> serviceDiscovery,
			ZookeeperDependencies zookeeperDependencies,
			ZookeeperDiscoveryProperties zookeeperDiscoveryProperties) {
		this.curatorFramework = curatorFramework;
		this.serviceDiscovery = serviceDiscovery;
		this.zookeeperDependencies = zookeeperDependencies;
		this.zookeeperDiscoveryProperties = zookeeperDiscoveryProperties;
	}

	@Override
	public String getName() {
		return "zookeeper";
	}

	@Override
	public Health health() {
		Health.Builder builder = Health.unknown();
		try {
			Iterable<ServiceInstance<ZookeeperInstance>> allInstances = new ZookeeperServiceInstances(
					this.curatorFramework, this.serviceDiscovery,
					this.zookeeperDependencies, this.zookeeperDiscoveryProperties);
			builder.up().withDetail("services", allInstances);
		}
		catch (Exception e) {
			log.error("Error", e);
			builder.down(e);
		}

		return builder.build();
	}

}
  • ZookeeperDiscoveryHealthIndicator实现了DiscoveryHealthIndicator接口,其health方法创建ZookeeperServiceInstances

ZookeeperServiceInstances

spring-cloud-zookeeper-discovery-2.1.2.RELEASE-sources.jar!/org/springframework/cloud/zookeeper/discovery/ZookeeperServiceInstances.java

public class ZookeeperServiceInstances
		implements Iterable<ServiceInstance<ZookeeperInstance>> {

	private static final Log log = LogFactory.getLog(ZookeeperServiceInstances.class);

	private ServiceDiscovery<ZookeeperInstance> serviceDiscovery;

	private final ZookeeperDependencies zookeeperDependencies;

	private final ZookeeperDiscoveryProperties zookeeperDiscoveryProperties;

	private final List<ServiceInstance<ZookeeperInstance>> allInstances;

	private final CuratorFramework curator;

	public ZookeeperServiceInstances(CuratorFramework curator,
			ServiceDiscovery<ZookeeperInstance> serviceDiscovery,
			ZookeeperDependencies zookeeperDependencies,
			ZookeeperDiscoveryProperties zookeeperDiscoveryProperties) {
		this.curator = curator;
		this.serviceDiscovery = serviceDiscovery;
		this.zookeeperDependencies = zookeeperDependencies;
		this.zookeeperDiscoveryProperties = zookeeperDiscoveryProperties;
		this.allInstances = getZookeeperInstances();
	}

	private List<ServiceInstance<ZookeeperInstance>> getZookeeperInstances() {
		ArrayList<ServiceInstance<ZookeeperInstance>> allInstances = new ArrayList<>();
		try {
			Collection<String> namesToQuery = getNamesToQuery();
			if (log.isDebugEnabled()) {
				log.debug("Querying the following names [" + namesToQuery + "]");
			}
			for (String name : namesToQuery) {
				allInstances.addAll(nestedInstances(allInstances, name));
			}
			return allInstances;
		}
		catch (Exception e) {
			log.debug("Exception occurred while trying to build the list of instances",
					e);
			return allInstances;
		}
	}

	//......
}
  • ZookeeperServiceInstances的构造器会调用getZookeeperInstances拉取ServiceInstance

小结

ZookeeperDiscoveryAutoConfiguration注册了ZookeeperDiscoveryProperties、ZookeeperDiscoveryClient、ZookeeperServiceWatch、ZookeeperDiscoveryHealthIndicator

上述内容就是如何理解ZookeeperDiscoveryAutoConfiguration,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI