SpringCloud微服务中使用zookeeper做为注册中心的相关配置。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
</dependency>
spring:
application:
name: zk-order
cloud:
zookeeper:
connect-string: ***.**.***.***:2181
服务的信息是如何写入到zookeeper中的
- ApplicationListener,没错就是它,应用程序监听。
在web容器初始化完后就会触发onApplicationEvent事件。
没错,我们的服务就是在这个时候被写入到zookeeper中的。
代码分析
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
tomcat就是在这个方法中配启动的
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
最后一步:发布相应的事件。
finishRefresh();
}
重点1
- 发布相应的事件。
- finishRefresh();
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
clearResourceCaches();
// Initialize lifecycle processor for this context.
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();
// Publish the final event.
发布事件
publishEvent(new ContextRefreshedEvent(this));
这个时间就是web容器初始化完成的事件
@Override
public void publishEvent(ApplicationEvent event) {
publishEvent(event, null);
}
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
重点2
事件发布完成后就会对事件进行广播。
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
Executor executor = getTaskExecutor();
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
invokeListener(listener, event);
}
}
}
重点3
对事件进行监听
@EventListener(WebServerInitializedEvent.class)
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();
}
重点4
监听到消息后就开始实现注册逻辑
protected void register() {
this.serviceRegistry.register(getRegistration());
}
-
会将这个对象转为字节数据然后保存到zookeeper中。
到此为止,我们的服务就是已经注册完成了。
用到的就是观察者模式 -
所有你也可以尝试去监听这个事件,去触发一些自己想调用的方法,或者日志什么的。
举例:
@Component
public class TestWebServerInitializedEvent {
@EventListener(ServletWebServerInitializedEvent.class)
public void onApplicationEvent(ServletWebServerInitializedEvent event) {
System.out.println("tomcat启动完成.......");
}
}
DiscoveryClient组件的作用
源码翻译
/**
* DiscoveryClient represents read operations commonly available to Discovery service such as
* Netflix Eureka or consul.io
* @author Spencer Gibb
*/
public interface DiscoveryClient {
/**
* A human readable description of the implementation, used in HealthIndicator
* @return the description
*/
String description();
/**
* Get all ServiceInstances associated with a particular serviceId
* @param serviceId the serviceId to query
* @return a List of ServiceInstance
*/
List<ServiceInstance> getInstances(String serviceId);
/**
* @return all known service ids
*/
List<String> getServices();
}
使用方法
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("getURL")
public void getUrl() {
String url = discoveryClient.getInstances("tgz").get(0).getHost();
}
能通过这个组件获取到的东西是真的多