Skip to content

Commit e8b4b2f

Browse files
authored
fix:修复ServiceDiscovery中对于map的错误使用 (#56)
1 parent d16ec7a commit e8b4b2f

File tree

2 files changed

+39
-10
lines changed

2 files changed

+39
-10
lines changed

dubbo/dubbo-plugins/dubbo-metadatareport-polaris/src/main/java/com/tencent/polaris/dubbo/metadata/report/PolarisMetadataReport.java

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,14 +145,16 @@ public void publishAppMetadata(SubscriberMetadataIdentifier identifier, Metadata
145145

146146
@Override
147147
public MetadataInfo getAppMetadata(SubscriberMetadataIdentifier identifier, Map<String, String> instanceMetadata) {
148+
// 这里由于查询的应用的接口定义数据,这里不能设置 version,必须显示设置 version 为空
148149
GetServiceContractRequest request = new GetServiceContractRequest();
149150
request.setName(formatAppMetaName(identifier));
150151
request.setService(identifier.getApplication());
151152
request.setVersion("");
152153

153154
Optional<ServiceContractProto.ServiceContract> result = getServiceContract(request);
154155
if (!result.isPresent()) {
155-
return new MetadataInfo();
156+
// 这里返回一个空的 MetadataInfo
157+
return MetadataInfo.EMPTY;
156158
}
157159

158160
Map<String, MetadataInfo.ServiceInfo> serviceInfos = new HashMap<>();
@@ -163,6 +165,7 @@ public MetadataInfo getAppMetadata(SubscriberMetadataIdentifier identifier, Map<
163165
return new MetadataInfo(identifier.getApplication(), identifier.getRevision(), serviceInfos);
164166
}
165167

168+
// toDescriptor 该方法是将 dubbo 接口运维元数据转为北极星的服务契约定义进行存储
166169
private ReportServiceContractRequest toDescriptor(MetadataIdentifier identifier, String serviceDefinitions) {
167170
ReportServiceContractRequest request = new ReportServiceContractRequest();
168171
request.setName(formatMetadataIdentifier(identifier));
@@ -183,6 +186,12 @@ private ReportServiceContractRequest toDescriptor(MetadataIdentifier identifier,
183186
return request;
184187
}
185188

189+
/**
190+
* 获取服务契约的通用调用接口
191+
*
192+
* @param req {@link GetServiceContractRequest}
193+
* @return {@link Optional<ServiceContractProto.ServiceContract>}
194+
*/
186195
private Optional<ServiceContractProto.ServiceContract> getServiceContract(GetServiceContractRequest req) {
187196
req.setNamespace(config.getNamespace());
188197
req.setProtocol(Consts.DUBBO_PROTOCOL);
@@ -206,7 +215,11 @@ private Optional<ServiceContractProto.ServiceContract> getServiceContract(GetSer
206215
return Optional.empty();
207216
}
208217

209-
218+
/**
219+
* 上报服务契约定义通用接口
220+
*
221+
* @param req {@link ReportServiceContractRequest}
222+
*/
210223
private void reportServiceContract(ReportServiceContractRequest req) {
211224
req.setNamespace(config.getNamespace());
212225
req.setProtocol(Consts.DUBBO_PROTOCOL);
@@ -226,6 +239,15 @@ private void reportServiceContract(ReportServiceContractRequest req) {
226239
// ------- 和 Dubbo3 应用级注册发现有关的操作 --------
227240
// ------- 这里必须实现,否则就需要用户指定 providerBy ------
228241

242+
/**
243+
* 存储 dubbo 的接口-应用的 mapping 数据时,这里对接的北极星的服务契约时,服务、版本信息为空,必须显示设置
244+
* InterfaceDescriptor -> 作为记录 dubbo 应用数据
245+
*
246+
* @param serviceKey dubbo 接口名称
247+
* @param application dubbo 应用名称
248+
* @param url {@link URL}
249+
* @return 返回接口-应用 mapping 数据是否发布成功
250+
*/
229251
@Override
230252
public boolean registerServiceAppMapping(String serviceKey, String application, URL url) {
231253
ReportServiceContractRequest request = new ReportServiceContractRequest();
@@ -322,24 +344,30 @@ public void run() {
322344
try {
323345
GetServiceContractRequest request = new GetServiceContractRequest();
324346
request.setName(formatMappingName(serviceKey));
347+
request.setService("");
348+
request.setVersion("");
325349

326350
Optional<ServiceContractProto.ServiceContract> result = report.getServiceContract(request);
327351
result.ifPresent(serviceContract -> {
328352
ServiceContractProto.ServiceContract saveData = report.mappingSubscribes.get(serviceKey);
329353
boolean needNotify = false;
354+
// 如果之前就不存在这个 mapping 数据,需要触发通知
330355
if (Objects.isNull(saveData)) {
331356
report.mappingSubscribes.put(serviceKey, serviceContract);
332357
needNotify = true;
333358
}
334359
if (Objects.nonNull(saveData)) {
360+
// 如果 revision 信息比较不一致,则表明出现更细,需要触发通知
335361
if (!Objects.equals(saveData.getRevision(), serviceContract.getRevision())) {
336362
report.mappingSubscribes.put(serviceKey, serviceContract);
337363
needNotify = true;
338364
}
339365
}
340366
if (needNotify) {
367+
Set<String> newApplications = getAppNames(serviceContract);
368+
report.logger.info(String.format("receive mapping change event, interface=%s applications=%s", serviceKey, newApplications));
341369
Set<MappingListener> listeners = report.mappingListeners.getOrDefault(serviceKey, Collections.emptySet());
342-
MappingChangedEvent event = new MappingChangedEvent(serviceKey, getAppNames(serviceContract));
370+
MappingChangedEvent event = new MappingChangedEvent(serviceKey, newApplications);
343371
listeners.forEach(mappingListener -> mappingListener.onEvent(event));
344372
}
345373
});

dubbo/dubbo-plugins/dubbo-registry-polaris/src/main/java/com/tencent/polaris/dubbo/registry/PolarisServiceDiscovery.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -133,19 +133,20 @@ public void addServiceInstancesChangedListener(ServiceInstancesChangedListener
133133
}
134134
Set<String> services = listener.getServiceNames();
135135
for (String service : services) {
136-
serviceListeners.computeIfAbsent(service, name -> {
137-
ServiceListener serviceListener = new InnerServiceListener(service);
138-
listenerMap.put(service, serviceListener);
136+
serviceListeners.computeIfAbsent(service, name -> new ConcurrentHashSet<>());
137+
serviceListeners.get(service).add(listener);
139138

139+
// 按照一个 service 一个 ServiceListener 的纬度
140+
listenerMap.computeIfAbsent(service, s -> {
141+
ServiceListener serviceListener = new InnerServiceListener(service);
140142
WatchServiceRequest request = new WatchServiceRequest();
141143
request.setNamespace(operator.getPolarisConfig().getNamespace());
142144
request.setService(service);
143145
request.setListeners(Collections.singletonList(serviceListener));
144146
consumerAPI.watchService(request);
145-
return new ConcurrentHashSet<>();
147+
return serviceListener;
146148
});
147149

148-
serviceListeners.get(service).add(listener);
149150
}
150151
}
151152

@@ -158,6 +159,7 @@ public void removeServiceInstancesChangedListener(ServiceInstancesChangedListene
158159
Set<String> services = listener.getServiceNames();
159160
for (String service : services) {
160161
Set<ServiceInstancesChangedListener> listeners = serviceListeners.get(service);
162+
listeners.remove(listener);
161163
if (CollectionUtils.isEmpty(listeners)) {
162164
serviceListeners.remove(service);
163165

@@ -171,9 +173,7 @@ public void removeServiceInstancesChangedListener(ServiceInstancesChangedListene
171173
.build();
172174
consumerAPI.unWatchService(request);
173175
}
174-
continue;
175176
}
176-
listeners.remove(listener);
177177
}
178178
}
179179

@@ -188,6 +188,7 @@ private InnerServiceListener(String service) {
188188
@Override
189189
public void onEvent(ServiceChangeEvent event) {
190190
String serviceName = event.getServiceKey().getService();
191+
// 注意,这里不能走 Event 里面的服务数据列表,必须要走 ConsumerAPI 重新走正常的 Router 能力过滤掉隔离、权重为0的实例
191192
Instance[] instances = operator.getAvailableInstances(serviceName, true);
192193
if (Objects.isNull(instances) || instances.length == 0) {
193194
return;

0 commit comments

Comments
 (0)