您的位置:首页 > 游戏 > 游戏 > 庆阳西峰疫情最新消息_个人网站备案名称_每天三分钟新闻天下事_百度问答怎么赚钱

庆阳西峰疫情最新消息_个人网站备案名称_每天三分钟新闻天下事_百度问答怎么赚钱

2025/1/13 17:37:28 来源:https://blog.csdn.net/weixin_45593273/article/details/144224398  浏览:    关键词:庆阳西峰疫情最新消息_个人网站备案名称_每天三分钟新闻天下事_百度问答怎么赚钱
庆阳西峰疫情最新消息_个人网站备案名称_每天三分钟新闻天下事_百度问答怎么赚钱

在之前的文章《揭秘!微服务架构下,Apollo 配置中心凭啥扮演关键角色?》中,我们提到Apollo的可以支持多环境、多集群灵活配置。今天我们来探究下Apollo是如何实现环境隔离的。

Apollo 实现环境隔离的核心源码剖析

1. 客户端加载指定环境的apollo服务端配置

在 Apollo 客户端源码中,ConfigServiceLocator 类扮演着关键角色。当微服务启动时,它会负责定位和加载配置服务。在这个过程中,会读取系统环境变量。核心方法是tryUpdateConfigServices,该方法有一个核心逻辑会获取meta.service的url,在获取的过程中,会先获取环境变量m_env。

以下是代码片段。

	// 获取环境变量的值,test,ontest,prod等m_env = System.getProperty("env");if (!Utils.isBlank(m_env)) {m_env = m_env.trim();logger.info("Environment is set to [{}] by JVM system property 'env'.", m_env);return;}
		// 获取meta.service的urlString url = this.assembleMetaServiceUrl();HttpRequest request = new HttpRequest(url);int maxRetries = 2;Throwable exception = null;// 采用重试机制拉取apollo服务端的配置,并缓存到本地for(int i = 0; i < maxRetries; ++i) {HttpResponse<List<ServiceDTO>> response = this.m_httpClient.doGet(request, this.m_responseType);transaction.setStatus("0");List<ServiceDTO> services = (List)response.getBody();if (services == null || services.isEmpty()) {this.logConfigService("Empty response!");continue;}this.setConfigServices(services);}
	// 用可调度的线程池每隔5秒,启动一个线程,执行一下上述更新操作。tryUpdateConfigServices()方法的逻辑就是上述提到的2次重试,从apollo服务端拉取配置,更新本地缓存。this.m_executorService.scheduleAtFixedRate(new Runnable() {public void run() {ConfigServiceLocator.logger.debug("refresh config services");Tracer.logEvent("Apollo.MetaService", "periodicRefresh");ConfigServiceLocator.this.tryUpdateConfigServices();}}, (long)this.m_configUtil.getRefreshInterval(), (long)this.m_configUtil.getRefreshInterval(), this.m_configUtil.getRefreshIntervalTimeUnit());

2. 服务端配置信息存储与隔离机制

在 Apollo 服务端源码中,配置信息在数据库中的存储结构设计体现了环境隔离的思想。在配置数据的持久化操作中,例如在InstanceConfigRepository 类的相关方法里,在插入或查询配置数据时,都会带上环境标识作为条件。

每个环境对应一个或多个集群(clusterName),每个集群中有多个命名空间(amespaceNam),每个命名空间属于一个应用(appId)

3. 客户端缓存

Apollo 客户端为了提高配置读取效率,采用了缓存机制。

	ApolloConfig previous = (ApolloConfig)this.m_configCache.get();ApolloConfig current = this.loadApolloConfig();if (previous != current) {logger.debug("Remote Config refreshed!");this.m_configCache.set(current);this.fireRepositoryChange(this.m_namespace, this.getConfig());}

以下是ApolloConfig实体。

public class ApolloConfig {private String appId;private String cluster;private String namespaceName;private Map<String, String> configurations;private String releaseKey;
}

最后在来串一个流程,微服务在启动时,Apollo会通过ConfigServiceLocator类的schedulePeriodicRefresh方法每隔5秒启动一个线程,拉取Apollo服务节点的相关信息,包括AppName, 服务实例ID等,并更新ServiceDTO。

拉取的时候会通过环境变量获取服务节点url,做到了环境隔离。

public class ServiceDTO {private String appName;private String instanceId;private String homepageUrl;
}

同时,会通过RemoteConfigRepository类的schedulePeriodicRefresh方法每隔5秒去拉取Apollo的配置,包括appId, 集群,命名空间等,并更新ApolloConfig(缓存机制)。在拉取的时候,会先获取Apollo服务节点的相关信息。然后组装URL,通过HTTP客户端去发起请求,拉取数据。

	private List<ServiceDTO> getConfigServices() {// 调用ConfigServiceLocator类getConfigServices()方法List<ServiceDTO> services = this.m_serviceLocator.getConfigServices();if (services.size() == 0) {throw new ApolloConfigException("No available config service");} else {return services;}}
	// 组装urlurl = this.assembleQueryConfigUrl(configService.getHomepageUrl(), appId, cluster, this.m_namespace, dataCenter, (ApolloNotificationMessages)this.m_remoteMessages.get(), (ApolloConfig)this.m_configCache.get());HttpRequest request = new HttpRequest(url);// 发起http请求HttpResponse<ApolloConfig> response = this.m_httpClient.doGet(request, ApolloConfig.class);this.m_configNeedForceRefresh.set(false);this.m_loadConfigFailSchedulePolicy.success();transaction.addData("StatusCode", response.getStatusCode());transaction.setStatus("0");ApolloConfig result;// 根据响应码处理相关逻辑if (response.getStatusCode() != 304) {result = (ApolloConfig)response.getBody();logger.debug("Loaded config for {}: {}", this.m_namespace, result);ApolloConfig var34 = result;return var34;}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com