随着互联网的发展,微服务应用和机器越来越多,达到成百上千台,调用方需要知道被调用方接口的网络地址,如果靠配置文件的方式去获取网络地址,对于动态新增机器和维护带来很大问题。
(1)Server 服务端:一般相对于注册中心而言,它是服务的提供者
(2)Client 客户端:除了注册中心之外的其他微服务
主流的注册中心有
Eureka
学习地址:https://cloud.spring.io/spring-cloud-static/spring-cloud-netflix/2.1.0.RELEASE/single/spring-cloud-netflix.html
Zookeeper
学习地址:http://zookeeper.apache.org/
Consul
学习地址:https://www.consul.io/intro/vs/index.html
Etcd
学习地址:
Feature | Consul | Zookeeper | Etcd | Eureka |
---|---|---|---|---|
服务健康检查 | 服务状态,内存,硬盘等 | (弱)长连接,keepalive | 连接心跳 | 可配支持 |
多数据中心 | 支持 | — | — | — |
kv存储服务 | 支持 | 支持 | 支持 | — |
一致性 | raft | paxos | raft | — |
cap | cp | cp | cp | ap |
使用接口(多语言能力) | 支持http和dns | 客户端 | http/grpc | http(sidecar) |
watch支持 | 全量/支持long polling | 支持 | 支持 long polling | 支持 long polling/大部分增量 |
自身监控 | metrics | — | metrics | metrics |
安全 | acl /https | acl | https支持(弱) | — |
spring cloud集成 | 已支持 | 已支持 | 已支持 | 已支持 |
指的是在一个分布式系统中,Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可同时获得。
CAP理论就是说在分布式存储系统中,最多只能实现上面的两点。而由于当前的网络硬件肯定会出现延迟丢包等问题,所以分区容错性是我们必须需要实现的。所以我们只能在一致性和可用性之间进行权衡
为什么无法同时满足: 一致性/可用性/分区容错性
CA 满足的情况下,P不能满足的原因:
数据同步 ( C ) 需要时间,也要正常的时间内响应 ( A ),那么机器数量就要少,所以P就不满足
CP 满足的情况下,A不能满足的原因:
数据同步 ( C ) 需要时间, 机器数量也多 ( P ),但是同步数据需要时间,所以不能在正常时间内响应,所以A就不满足
AP 满足的情况下,C不能满足的原因:
机器数量也多 ( P ),正常的时间内响应 ( A ),那么数据就不能及时同步到其他节点,所以C不满足
Spring Cloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务注册和发现。Eureka 采用了 C-S 的设计架构。Eureka Server 作为服务注册功能的服务器,它是服务注册中心。而系统中的其他微服务,使用 Eureka 的客户端连接到 Eureka Server,并维持心跳连接。这样系统的维护人员就可以通过 Eureka Server 来监控系统中各个微服务是否正常运行。Spring Cloud 的一些其他模块(比如Zuul)就可以通过 Eureka Server 来发现系统中的其他微服务,并执行相关的逻辑。
Eureka由两个组件组成:Eureka服务器和Eureka客户端。Eureka服务器用作服务注册服务器。Eureka客户端是一个java客户端,用来简化与服务器的交互、作为轮询负载均衡器,并提供服务的故障切换支持。Netflix在其生产环境中使用的是另外的客户端,它提供基于流量、资源利用率以及出错状态的加权负载均衡。
用一张图来认识以下:
上图简要描述了Eureka的基本架构,由3个角色组成:
1、Eureka Server
2、Service Provider
3、Service Consumer
服务消费方
从Eureka获取注册服务列表,从而能够消费服务
第一步: 在idea中创建一个spring项目,作为eureka的服务端
(2)选择eureka server 依赖,点击next完成创建
第二步:查看pom.xml 是否引入相关依赖
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
dependency>
第三步:在启动项中加入注解(@EnableEurekaServer),支持EurekaServer
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
第四步:配置application.yml配置文件
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
通过eureka.client.registerWithEureka:false和fetchRegistry:false来表明自己是一个eureka server。
第五步:启动项目,浏览器中访问 http://localhost:8761 界面如下
第一步:在idea中创建一个spring项目,作为eureka的客户端(创建过程类似eureka服务端)
第二步:查看pom.xml 是否引入相关依赖
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
第三步:在启动项中加入注解(@EnableDiscoveryClient),并创建一个接口
@SpringBootApplication
@EnableDiscoveryClient
@RestController
public class EurekaClientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaClientApplication.class, args);
}
@RequestMapping("/hello")
public Object hello(){
return "hello";
}
}
第四步:配置application.yml配置文件
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
server:
port: 8762
spring:
application:
name: service-hi
第五步:启动项目,再次访问 http://localhost:8761,界面如下
你会发现一个服务已经注册在服务中了,服务名为SERVICE-HI ,端口为7862
注册中心这么关键的服务,如果是单点话,遇到故障就是毁灭性的。在一个分布式系统中,服务注册中心是最重要的基础部分,理应随时处于可以提供服务的状态。为了维持其可用性,使用集群是很好的解决方案。Eureka通过互相注册的方式来实现高可用的部署,所以我们只需要将Eureke Server配置其他可用的serviceUrl就能实现高可用部署。
在上面的eureka-server项目的基础上进行改造,创建一个eureka-server-cluster的集群项目
在eureka-server-cluster 工程中resources文件夹下,
(1)创建配置文件application-peer1.yml:
spring:
profiles: peer1
server:
port: 8761
eureka:
instance:
hostname: peer1
client:
serviceUrl:
defaultZone: http://peer2:8762/eureka/,http://peer3:8763/eureka/
(2)创建配置文件application-peer2.yml:
spring:
profiles: peer2
server:
port: 8762
eureka:
instance:
hostname: peer2
client:
serviceUrl:
defaultZone: http://peer1:8761/eureka/,http://peer3:8763/eureka/
(3)创建配置文件application-peer3.yml:
spring:
profiles: peer3
server:
port: 8763
eureka:
instance:
hostname: peer3
client:
serviceUrl:
defaultZone: http://peer1:8761/eureka/,http://peer2:8762/eureka/
这时eureka-server就已经改造完毕。
ou could use this configuration to test the peer awareness on a single host (there’s not much value in doing that in production) by manipulating /etc/hosts to resolve the host names.
按照官方文档的指示,需要改变etc/hosts,
127.0.0.1 peer1
127.0.0.1 peer2
127.0.0.1 peer3
依次执行下面命令
#打包
mvn clean package
# 分别以peer1、peeer2和peer3 配置信息启动eureka-server-cluster
java -jar eureka-server-cluster-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer1
java -jar eureka-server-cluster-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer2
java -jar eureka-server-cluster-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer3
依次启动完成后,启动eureka-client项目,浏览器输入:http://localhost:8761/
效果图如下:
注意:eureka-client项目中检查注册中心地址是否正确
Eureka-server-cluster peer1 8761
Eureka-server-cluster peer2 8762
Eureka-server-cluster peer3 8763
三个服务相互感应,当有服务注册时,三个Eureka-server是对等的,它们都存有相同的信息,这就是通过服务器的冗余来增加可靠性,当有一台服务器宕机了,服务并不会终止,因为其他服务存有相同的数据
完整的项目地址:https://github.com/dongtiandexue/AggregationCenter