服务治理能够说是微服务架构中最为核心和基础的模块,主要用来实现各个微服务实例的自动化注册与发现。 使用服务治理的缘由:在服务引用并不算多的时候,能够经过静态配置来完成服务的调用,但随着业务的发展,系统功能愈来愈复杂,相应的微服务也不断增长,此时静态配置会变得愈来愈难以维护。而且面对不断发展的业务,集群规模,服务的位置、服务的命名等都有可能发生变化,若是仍是经过手工维护的方式,极易发生错误或是命名冲突等问题。同时,也将消耗大量的人力来维护静态配置的内容。为了解决微服务架构中的服务实例维护问题,就产生了大量的服务治理框架和产品。这些框架和产品的实现都围绕着服务注册与服务发现机制来完成对微服务应用实例的自动化管理。缓存
注册到服务中心的主要都有哪些信息: ip、port(端口)、instance_id(实例id)、name(服务名)等。 当eureka客户端启动的时候,EurekaClientConfiguration读书客户端配置信息,建立一个InstanceInfo实例,而后交给ApplicationInfoManager管理,下面看段代码:bash
@Configuration
@ConditionalOnMissingRefreshScope
protected static class EurekaClientConfiguration {
@Autowired
private ApplicationContext context;
@Autowired(required = false)
private DiscoveryClientOptionalArgs optionalArgs;
@Bean(destroyMethod = "shutdown")
@ConditionalOnMissingBean(value = EurekaClient.class, search = SearchStrategy.CURRENT)
public EurekaClient eurekaClient(ApplicationInfoManager manager,
EurekaClientConfig config) {
return new CloudEurekaClient(manager, config, this.optionalArgs,
this.context);
}
@Bean
@ConditionalOnMissingBean(value = ApplicationInfoManager.class, search = SearchStrategy.CURRENT)
public ApplicationInfoManager eurekaApplicationInfoManager(
EurekaInstanceConfig config) {
//获取配置 建立实例
InstanceInfo instanceInfo = new InstanceInfoFactory().create(config);
return new ApplicationInfoManager(config, instanceInfo);
}
}
复制代码
在实例化过程当中,DiscoveryClient的HeartbeatThread定时任务会不断扫描,找到未注册的实例,并注册到服务中心,下面DiscoveryClient类的某段代码:restful
/**
* The heartbeat task that renews the lease in the given intervals.
* 心跳,注册定时任务
*/
private class HeartbeatThread implements Runnable {
public void run() {
if (renew()) {
lastSuccessfulHeartbeatTimestamp = System.currentTimeMillis();
}
}
}
/**
* Renew with the eureka service by making the appropriate REST call
*/
boolean renew() {
EurekaHttpResponse<InstanceInfo> httpResponse;
try {
//向注册中心发送一个注册请求
httpResponse = eurekaTransport.registrationClient.sendHeartBeat(instanceInfo.getAppName(), instanceInfo.getId(), instanceInfo, null);
logger.debug("{} - Heartbeat status: {}", PREFIX + appPathIdentifier, httpResponse.getStatusCode());
//当注册中心返回404,证实这个实例没注册,则进行注册,不然返回注册成功
if (httpResponse.getStatusCode() == 404) {
REREGISTER_COUNTER.increment();
logger.info("{} - Re-registering apps/{}", PREFIX + appPathIdentifier, instanceInfo.getAppName());
return register();
}
return httpResponse.getStatusCode() == 200;
} catch (Throwable e) {
logger.error("{} - was unable to send heartbeat!", PREFIX + appPathIdentifier, e);
return false;
}
}
/**
* Register with the eureka service by making the appropriate REST call.
* 向服务端注册方法
*/
boolean register() throws Throwable {
logger.info(PREFIX + appPathIdentifier + ": registering service...");
EurekaHttpResponse<Void> httpResponse;
try {
httpResponse = eurekaTransport.registrationClient.register(instanceInfo);
} catch (Exception e) {
logger.warn("{} - registration failed {}", PREFIX + appPathIdentifier, e.getMessage(), e);
throw e;
}
if (logger.isInfoEnabled()) {
logger.info("{} - registration status: {}", PREFIX + appPathIdentifier, httpResponse.getStatusCode());
}
return httpResponse.getStatusCode() == 204;
}
复制代码
在微服务架构中,业务都会被拆分红一个独立的服务,服务与服务的通信是基于http restful的。Spring cloud有两种服务调用方式,一种是ribbon+restTemplate,另外一种是feign。架构
Ribbon是Netflix公司开源的一个负载均衡的项目,是一个客户端负载均衡器,运行在客户端上。它是一个通过了云端测试的IPC库,能够很好地控制HTTP和TCP客户端的一些行为。 Feign已经默认使用了Ribbon。app
深刻理解及源码:blog.csdn.net/forezp/arti…负载均衡
Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单。使用Feign,只须要建立一个接口并注解。它具备可插拔的注解特性,可以使用Feign 注解和JAX-RS注解。Feign支持可插拔的编码器和解码器。Feign默认集成了Ribbon,并和Eureka结合,默认实现了负载均衡的效果。框架
简而言之:异步
深刻理解及源码: blog.csdn.net/forezp/arti…微服务
使用Ribbon+RestTemplate时,利用RestTemplate对http请求的封装处理,造成了一套模板化的调用方式。但实际开发中,因为对服务的依赖调用可能不止一处,每每一个接口会被多出调用,因此一般会针对每一个微服务自行封装一些客户端类来包装这些依赖服务的调用。因此Fegin字此基础上作了进一步封装,由它来帮助咱们定义和实现依赖服务接口的定义。在Feign的实现下,咱们只须要建立一个接口并使用注解的方式来配置它(之前是Dao接口上面添加Mapper注解,如今是一个微服务接口上面标注一个Feign注解),便可完成服务提供方的接口绑定,简化使用Spring Cloud Ribbon时,自动封装服务调用客户的开发量。测试