1、apollo的架构图
apollo部署后,从前端看,有三个端口监听,有eureka服务,有两个数据库,那么它实际的架构师什么样的呢?
我可以通过这个博客中图片了解一下
至于为什么要用eureka,值得学习
apollo在eureka上面,封装了一层简单的Meta Service,用于多服务的负载均衡。
这比直接使用ureka client变简单了。
@Service
@ConditionalOnMissingProfile({"kubernetes", "nacos-discovery"})
public class DefaultDiscoveryService implements DiscoveryService {
private final EurekaClient eurekaClient;
public DefaultDiscoveryService(final EurekaClient eurekaClient) {
this.eurekaClient = eurekaClient;
}
@Override
public List<ServiceDTO> getServiceInstances(String serviceId) {
Application application = eurekaClient.getApplication(serviceId);
if (application == null || CollectionUtils.isEmpty(application.getInstances())) {
Tracer.logEvent("Apollo.Discovery.NotFound", serviceId);
return Collections.emptyList();
}
return application.getInstances().stream().map(instanceInfoToServiceDTOFunc)
.collect(Collectors.toList());
}
private static final Function<InstanceInfo, ServiceDTO> instanceInfoToServiceDTOFunc = instance -> {
ServiceDTO service = new ServiceDTO();
service.setAppName(instance.getAppName());
service.setInstanceId(instance.getInstanceId());
service.setHomepageUrl(instance.getHomePageUrl());
return service;
};
}
2、apollo-portal服务
portal服务需要访问admin服务,在配置时,其先去配置中性,从配置中心(Eureka)拉取了admin服务的信息,让后使用客户端做了负载均衡。这个是自定义实现的。
private <T> ResponseEntity<T> exchangeGet(Env env, String path, ParameterizedTypeReference<T> reference,
Object... uriVariables) {
xxx
List<ServiceDTO> services = getAdminServices(env, ct);
HttpEntity<Void> entity = new HttpEntity<>(assembleExtraHeaders(env));
for (ServiceDTO serviceDTO : services) {
try {
ResponseEntity<T> result =
restTemplate.exchange(parseHost(serviceDTO) + path, HttpMethod.GET, entity, reference, uriVariables);
ct.setStatus(Transaction.SUCCESS);
ct.complete();
return result;
} catch (Throwable t) {
xxx
}
//all admin server down
}
在portal中,还有比较常用的是权限控制。灵活的模式一般都是RBAC(Role-Based Access Control),Spring Security主要也是这个吧。
3、apollo-client服务
Apollo-client服务是集成在client中的,使用EnableApolloConfig就可以使用了。
@Configuration
@EnableApolloConfig
public class AppConfig {
}
//
@Component
public class SomeBean {
//timeout的值会自动更新
@Value("${request.timeout:200}")
private int timeout;
}