Apollo客户端配置获取深度解析_apollo could not find config for namespace - appid

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Golang全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注go)
img

正文

HttpRequest request = new HttpRequest(url);

if (!StringUtils.isBlank(secret)) {

Map<String, String> headers = Signature.buildHttpHeaders(url, appId, secret);

request.setHeaders(headers);

}

Transaction transaction = Tracer.newTransaction(“Apollo.ConfigService”, “queryConfig”);

transaction.addData(“Url”, url);

try {

HttpResponse response = m_httpUtil.doGet(request, ApolloConfig.class);

m_configNeedForceRefresh.set(false);

m_loadConfigFailSchedulePolicy.success();

transaction.addData(“StatusCode”, response.getStatusCode());

transaction.setStatus(Transaction.SUCCESS);

if (response.getStatusCode() == 304) {

logger.debug(“Config server responds with 304 HTTP status code.”);

return m_configCache.get();

}

ApolloConfig result = response.getBody();

logger.debug(“Loaded config for {}: {}”, m_namespace, result);

return result;

} catch (ApolloConfigStatusCodeException ex) {

ApolloConfigStatusCodeException statusCodeException = ex;

//config not found

if (ex.getStatusCode() == 404) {

String message = String.format(

"Could not find config for namespace - appId: %s, cluster: %s, namespace: %s, " +

“please check whether the configs are released in Apollo!”,

appId, cluster, m_namespace);

statusCodeException = new ApolloConfigStatusCodeException(ex.getStatusCode(),

message);

}

Tracer.logEvent(“ApolloConfigException”, ExceptionUtil.getDetailMessage(statusCodeException));

transaction.setStatus(statusCodeException);

exception = statusCodeException;

if(ex.getStatusCode() == 404) {

break retryLoopLabel;

}

} catch (Throwable ex) {

Tracer.logEvent(“ApolloConfigException”, ExceptionUtil.getDetailMessage(ex));

transaction.setStatus(ex);

exception = ex;

} finally {

transaction.complete();

}

// if force refresh, do normal sleep, if normal config load, do exponential sleep

onErrorSleepTime = m_configNeedForceRefresh.get() ? m_configUtil.getOnErrorRetryInterval() :

m_loadConfigFailSchedulePolicy.fail();

}

}

String message = String.format(

“Load Apollo Config failed - appId: %s, cluster: %s, namespace: %s, url: %s”,

appId, cluster, m_namespace, url);

throw new ApolloConfigException(message, exception);

}

配置实时生效的单靠短连接肯定是不能完成的,需要和长连接配合完成。下面将介绍长连接实现原理及长连接和短连接如何配合完成配置实时生效。

    1. 长连接实现原理

长连接,顾名思义就是客户端与服务端建立连接后不断开,一个客户端就是一个长连接,,而不是一个Namespace一个长连接,如果想要实现动态关闭某个appId长连接,是可以通过修改下面代码实现,同时通过修改短连接请求,添加开与关标志位实现。Apollo配置中心长连接实现逻辑是具体是什么呢?

      • 1.3.1. 客户端主要逻辑

private void doLongPollingRefresh(String appId, String cluster, String ataCenter, String secret) {

final Random random = new Random();

ServiceDTO lastServiceDto = null;

//循环发生请求,实现客户端长连接

while (!m_longPollingStopped.get() && !Thread.currentThread().isInterrupted()) {

if (!m_longPollRateLimiter.tryAcquire(5, TimeUnit.SECONDS)) {

//wait at most 5 seconds

try {

TimeUnit.SECONDS.sleep(5);

} catch (InterruptedException e) {

}

}

Transaction transaction = Tracer.newTransaction(“Apollo.ConfigService”, “pollNotification”);

String url = null;

try {

if (lastServiceDto == null) {

List configServices = getConfigServices();

//随机获取一个可用的节点

lastServiceDto =configServices.get(random.nextInt(configServices.size()));

}

//拼接请求URL

url = assembleLongPollRefreshUrl(lastServiceDto.getHomepageUrl(), appId, cluster, dataCenter, m_notifications);

logger.debug(“Long polling from {}”, url);

HttpRequest request = new HttpRequest(url);

request.setReadTimeout(LONG_POLLING_READ_TIMEOUT);

if (!StringUtils.isBlank(secret)) {

Map<String, String> headers = Signature.buildHttpHeaders(url, appId, secret);

request.setHeaders(headers);

}

transaction.addData(“Url”, url);

//请求发送

final HttpResponse<List> response =

m_httpUtil.doGet(request, m_responseType);

logger.debug(“Long polling response: {}, url: {}”, response.getStatusCode(), url);

if (response.getStatusCode() == 200 && response.getBody() != null) {

updateNotifications(response.getBody());

updateRemoteNotifications(response.getBody());

transaction.addData(“Result”, response.getBody().toString());

notify(lastServiceDto, response.getBody());

}

//try to load balance

//304: NOT_MODIFIED(304, “Not Modified”),

//random.nextBoolean:伪均匀分布的布尔值,保证长连接均匀分布在各节点上

if (response.getStatusCode() == 304 && random.nextBoolean()) {

lastServiceDto = null;

}

m_longPollFailSchedulePolicyInSecond.success();

transaction.addData(“StatusCode”, response.getStatusCode());

transaction.setStatus(Transaction.SUCCESS);

} catch (Throwable ex) {

lastServiceDto = null;

Tracer.logEvent(“ApolloConfigException”, ExceptionUtil.getDetailMessage(ex));

transaction.setStatus(ex);

long sleepTimeInSecond = m_longPollFailSchedulePolicyInSecond.fail();

logger.warn(

“Long polling failed, will retry in {} seconds. appId: {}, cluster: {}, namespaces: {}, long polling url: {}, reason: {}”,

sleepTimeInSecond, appId, cluster, assembleNamespaces(), url, ExceptionUtil.getDetailMessage(ex));

try {

TimeUnit.SECONDS.sleep(sleepTimeInSecond);

} catch (InterruptedException ie) {

//ignore

}

} finally {

transaction.complete();

}

}

}

从上面代码可以看出,长连接实现逻辑是一个无限循环发请求的过程。返回200更新本地配置,返回304说明配置没有改变。

      • 1.3.2. 服务端主要逻辑

Namespace在点击发布按钮时会项ReleaseMessage表里插入一条信息,AppId+集群+Namespace(apollo+default+application),代码如下

DeferredResultWrapper deferredResultWrapper = new DeferredResultWrapper();

Set namespaces = Sets.newHashSet();

Map<String, Long> clientSideNotifications = Maps.newHashMap();

Map<String, ApolloConfigNotification> filteredNotifications = filterNotifications(appId, notifications);

for (Map.Entry<String, ApolloConfigNotification> notificationEntry : filteredNotifications.entrySet()) {

String normalizedNamespace = notificationEntry.getKey();

ApolloConfigNotification notification = notificationEntry.getValue();

namespaces.add(normalizedNamespace);

clientSideNotifications.put(normalizedNamespace, notification.getNotificationId());

if (!Objects.equals(notification.getNamespaceName(), normalizedNamespace)) {

deferredResultWrapper.recordNamespaceNameNormalizedResult(notification.getNamespaceName(), normalizedNamespace);

}

}

if (CollectionUtils.isEmpty(namespaces)) {

throw new BadRequestException("Invalid format of notifications: " + notificationsAsString);

}

Multimap<String, String> watchedKeysMap =

watchKeysUtil.assembleAllWatchKeys(appId, cluster, namespaces, dataCenter);

Set watchedKeys = Sets.newHashSet(watchedKeysMap.values());

//获取ReleaseMessage的最新数据,然后通知客户端配置信息有修改

List latestReleaseMessages =

releaseMessageService.findLatestReleaseMessagesGroupByMessages(watchedKeys);

/**

* Manually close the entity manager.

* Since for async request, Spring won’t do so until the request is finished,

* which is unacceptable since we are doing long polling - means the db connection would be hold

* for a very long time

*/

entityManagerUtil.closeEntityManager();

List newNotifications = getApolloConfigNotifications(namespaces, clientSideNotifications, watchedKeysMap,latestReleaseMessages);

服务端保持长连接的核心就不得不提DeferredResultWrapper这个类,这是对DeferredResult-异步请求处理的一个包装类,使用DeferredResult的流程:

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Go)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
ManagerUtil.closeEntityManager();

List newNotifications = getApolloConfigNotifications(namespaces, clientSideNotifications, watchedKeysMap,latestReleaseMessages);

服务端保持长连接的核心就不得不提DeferredResultWrapper这个类,这是对DeferredResult-异步请求处理的一个包装类,使用DeferredResult的流程:

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Go)
[外链图片转存中…(img-lXBctu8Z-1713284610018)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 23
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
root@in_dev_docker:/apollo# bash scripts/msf_create_lossless_map.sh /apollo/hdmap/pcd_apollo/ 50 /apollo/hdmap/ /apollo/bazel-bin WARNING: Logging before InitGoogleLogging() is written to STDERR E0715 22:08:35.399576 6436 lossless_map_creator.cc:162] num_trials = 1 Pcd folders are as follows: /apollo/hdmap/pcd_apollo/ Resolution: 0.125 Dataset: /apollo/hdmap/pcd_apollo Dataset: /apollo/hdmap/pcd_apollo/ Loaded the map configuration from: /apollo/hdmap//lossless_map/config.xml. Saved the map configuration to: /apollo/hdmap//lossless_map/config.xml. Saved the map configuration to: /apollo/hdmap//lossless_map/config.xml. E0715 22:08:35.767315 6436 lossless_map_creator.cc:264] ieout_poses = 1706 Failed to find match for field 'intensity'. Failed to find match for field 'timestamp'. E0715 22:08:35.769896 6436 velodyne_utility.cc:46] Un-organized-point-cloud E0715 22:08:35.781770 6436 lossless_map_creator.cc:275] Loaded 245443D Points at Trial: 0 Frame: 0. F0715 22:08:35.781791 6436 base_map_node_index.cc:101] Check failed: false *** Check failure stack trace: *** scripts/msf_create_lossless_map.sh: line 11: 6436 Aborted (core dumped) $APOLLO_BIN_PREFIX/modules/localization/msf/local_tool/map_creation/lossless_map_creator --use_plane_inliers_only true --pcd_folders $1 --pose_files $2 --map_folder $IN_FOLDER --zone_id $ZONE_ID --coordinate_type UTM --map_resolution_type single root@in_dev_docker:/apollo# bash scripts/msf_create_lossless_map.sh /apollo/hdmap/pcd_apollo/ 50 /apollo/hdmap/
最新发布
07-16
根据提供的信息,执行脚本 `scripts/msf_create_lossless_map.sh` 时出现了错误。具体的错误信息如: ``` E0715 22:08:35.399576 6436 lossless_map_creator.cc:162] num_trials = 1 Pcd folders are as follows: /apollo/hdmap/pcd_apollo/ Resolution: 0.125 Dataset: /apollo/hdmap/pcd_apollo Dataset: /apollo/hdmap/pcd_apollo/ Loaded the map configuration from: /apollo/hdmap//lossless_map/config.xml. Saved the map configuration to: /apollo/hdmap//lossless_map/config.xml. Saved the map configuration to: /apollo/hdmap//lossless_map/config.xml. E0715 22:08:35.767315 6436 lossless_map_creator.cc:264] ieout_poses = 1706 Failed to find match for field 'intensity'. Failed to find match for field 'timestamp'. E0715 22:08:35.769896 6436 velodyne_utility.cc:46] Un-organized-point-cloud E0715 22:08:35.781770 6436 lossless_map_creator.cc:275] Loaded 245443D Points at Trial: 0 Frame: 0. F0715 22:08:35.781791 6436 base_map_node_index.cc:101] Check failed: false *** Check failure stack trace: *** scripts/msf_create_lossless_map.sh: line 11: 6436 Aborted (core dumped) $APOLLO_BIN_PREFIX/modules/localization/msf/local_tool/map_creation/lossless_map_creator --use_plane_inliers_only true --pcd_folders $1 --pose_files $2 --map_folder $IN_FOLDER --zone_id $ZONE_ID --coordinate_type UTM --map_resolution_type single ``` 这段错误信息表明在执行脚本时发生了一个检查失败的情况。错误的具体位置在 `base_map_node_index.cc:101`。可能的原因包括: 1. 数据不匹配:脚本中使用的数据可能存在不匹配的情况,例如字段名或者数据格式不正确。 2. 数据文件缺失:脚本所需的某些数据文件可能不存在或者路径不正确。 3. 依赖问题:脚本所依赖的某些组件或库可能缺失或者版本不兼容。 请检查脚本 `scripts/msf_create_lossless_map.sh` 中的相关代码,确保数据文件和依赖项的正确性。如果问题仍然存在,您可以提供更多的上下文信息,以便我们能够更好地帮助您解决问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值