第一节 注册中心的相关知识
1、为什么要使用注册中心?
随着互联网的发展,微服务应用和机器越来越多,达到成百上千台,调用方需要知道被调用方接口的网络地址,如果靠配置文件的方式去获取网络地址,对于动态新增机器和维护带来很大问题。
使用注册中心后结构图
(1)Server 服务端:一般相对于注册中心而言,它是服务的提供者
(2)Client 客户端:除了注册中心之外的其他微服务
- Service Provider:服务提供方,需要上报自身网络信息到注册中心,并通过心跳机制维护。
- Service Consumer:服务消费方,也需要上报自身的网络信息到注册中心,因为一个微服务相对于其他微服务来说既有可能是消费方,也有可能是提供方。并从注册中心获取调用方的网络信息,发起调用。
2、主流的注册中心有哪些?
主流的注册中心有
-
Eureka
-
Zookeeper
-
Consul
-
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集成 | 已支持 | 已支持 | 已支持 | 已支持 |
3、注册中心的CAP理论
指的是在一个分布式系统中,Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可同时获得。
- 一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值。(所有节点在同一时间的数据完全一致,越多节点,数据同步越耗时)
- 可用性(A):负载过大后,集群整体是否还能响应客户端的读写请求。(服务一直可用,而且是正常响应时间)
- 分区容错性(P):分区容错性,就是高可用性,一个节点崩了,并不影响其它的节点(100个节点,挂了几个,不影响服务,越多机器越好)
CAP理论就是说在分布式存储系统中,最多只能实现上面的两点。而由于当前的网络硬件肯定会出现延迟丢包等问题,所以分区容错性是我们必须需要实现的。所以我们只能在一致性和可用性之间进行权衡
为什么无法同时满足: 一致性/可用性/分区容错性
CA 满足的情况下,P不能满足的原因:
数据同步 ( C ) 需要时间,也要正常的时间内响应 ( A ),那么机器数量就要少,所以P就不满足
CP 满足的情况下,A不能满足的原因:
数据同步 ( C ) 需要时间, 机器数量也多 ( P ),但是同步数据需要时间,所以不能在正常时间内响应,所以A就不满足
AP 满足的情况下,C不能满足的原因:
机器数量也多 ( P ),正常的时间内响应 ( A ),那么数据就不能及时同步到其他节点,所以C不满足
第二节 Eureka注册中心实战
1、Eureka简介
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
- 服务提供方
- 将自身服务注册到Eureka,从而使服务消费方能够找到
3、Service Consumer
-
服务消费方
-
从Eureka获取注册服务列表,从而能够消费服务
2、基于eureka注册中心的服务端
第一步: 在idea中创建一个spring项目,作为eureka的服务端
(1)创建spring项目
(2)选择eureka server 依赖,点击next完成创建
第二步:查看pom.xml 是否引入相关依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</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 界面如下
3、基于eureka注册中心的客户端
第一步:在idea中创建一个spring项目,作为eureka的客户端(创建过程类似eureka服务端)
注意:选择正确的依赖
第二步:查看pom.xml 是否引入相关依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</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注册中心
注册中心这么关键的服务,如果是单点话,遇到故障就是毁灭性的。在一个分布式系统中,服务注册中心是最重要的基础部分,理应随时处于可以提供服务的状态。为了维持其可用性,使用集群是很好的解决方案。Eureka通过互相注册的方式来实现高可用的部署,所以我们只需要将Eureke Server配置其他可用的serviceUrl就能实现高可用部署。
1、改造eureka-server项目:
在上面的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,
- linux系统通过vim /etc/hosts
- windows系统修改C:\Windows\System32\drivers\etc\hosts文件
127.0.0.1 peer1
127.0.0.1 peer2
127.0.0.1 peer3
2、正确启动项目
依次执行下面命令
#打包
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项目中检查注册中心地址是否正确
3、架构分析
此时的架构图:
Eureka-server-cluster peer1 8761
Eureka-server-cluster peer2 8762
Eureka-server-cluster peer3 8763
三个服务相互感应,当有服务注册时,三个Eureka-server是对等的,它们都存有相同的信息,这就是通过服务器的冗余来增加可靠性,当有一台服务器宕机了,服务并不会终止,因为其他服务存有相同的数据