服务治理其核心就是注册中心。他负责所有服务的自动注册和服务发现。注册中心相当于一个登记的功能,所有的服务都向中心登记,登记会带上被登记服务的信息以供调用者调用。服务中心会定时去检测各个服务,如果挂掉会标记来保障所有服务的可用性,这就是所谓的心跳检测。调用者在首先会去注册中心查询所有可用服务,然后通过负载均衡机制去选择调用哪一个服务。
Eureka的缓存和延迟: SpringCloud官网上介绍Eureka说,如果一个服务启动后向 Eureka注册,有可能最长需要两分钟才能被其他的服务检测到。其原因是 Eureka的缓存和延迟造成的。
http请求缓存:在 Eureka的源码中有一个 getApplication() 方法,是客户端查询服务的http请求,这里会影响服务发现的速度。
Eureka client缓存:Eureka client对查询到的服务信息也做了30s缓存,即第一次服务发现的结果会缓存下来,以后不会每一次都去查询。
Ribbon负载均衡缓存:Ribbon做负载均衡的时候,对查询到的服务信息有30s缓存。
心跳检测延迟:Eureka通过心跳检测来判断服务是否正常,而心跳检测的间隔是30s。
分布式系统提出过CAP理论:C就是一致性,意思是集群内多个节点的信息全部一样。A是可用性,是指集群能够正常的向调用者提供服务。p是指容错性, 容错性是指单个节点的错误不会影响服务的正常使用。往往一个分布式系统的设计在三者中都会取舍。
zookeeper的CP,zookeeper有master节点的概念,节点之前同步信息。但是一旦master节点down 掉,需要通过leader选举机制去选举。选举是需要时间的,期间会导致服务不可用,虽然像dubbo会在本地通过缓存来解决这个问题,但从设计角度上是有缺陷的。
eureka 的AP, eureka没有中心节点一说,如果某个节点down掉,客户端会自动向其他节点注册。这样的设计能保证只要有节点提供服务就能保证可用性。虽然故障会导致节点间的数据不一致,但这种设计更倾向的是可用性。
第一步: 新建注册中心的服务,首先pom文件需要引入spring-cloud-starter-netflix-eureka-server
org.springframework.cloud
spring-cloud-starter-netflix-eureka-server
修改配置文件application.yml
server:
port: 8081
eureka:
instance:
hostname: localhost
client:
serviceUrl:
defaultZone: http://localhost2:8082/eureka/
spring:
application:
name: eurka-server
server.port:注册中心的启动端口号。
instance.hostname:设置当前实例的主机名称。
client.registerWithEureka:false不向注册中心注册自己。
client.fetchRegistry:false禁止检索服务。
serviceUrl.defaultZone:服务注册发现的地址。
启动代码:
@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
注解@EnableEurekaServer:标明是注册服务中心
第二步: 创建一个服务提供者来注册服务,参见项目 cloud-service
pom 文件需要引入spring-cloud-starter-netflix-eureka-client
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
配置文件application.yml
server:
port: 8085
spring:
application:
name: cloud-service
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8081/eureka/
defaultZone:这里是注册中心的地址。
启动代码:
@SpringBootApplication
@EnableEurekaClient
@RestController
public class ServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceApplication.class, args);
}
@Value("${server.port}")
String port;
@RequestMapping("hello")
public String hello(@RequestParam(value = "name", defaultValue = "forwei") String name){
return "hello" + name + ", i am from port:" + port;
}
}
注解@EnableEurekaClient:标注是注册的client。
hello方法做为rest接口对外提供服务。
第三步:启动服务
1、先启动cloud-eureka再启动cloud-service;
2、访问注册中心的管理页面http://localhost:8081会发现已经有一个服务注册成功;
3、可以看到服务名称叫做cloud-servce,有一个注册实例,端口号为8085