大家好我是小帅,今天我们来讲cloud的服务注册和服务发现。
文章目录
1.注册中心
1.1 什么是注册中心
在最初的架构体系中, 集群的概念还不那么流⾏, 且机器数量也⽐较少, 此时直接使⽤DNS+Nginx就可以满⾜⼏乎所有服务的发现. 相关的注册信息直接配置在Nginx. 但是随着微服务的流⾏与流量的激增,机器规模逐渐变⼤, 并且机器会有频繁的上下线⾏为, 这种时候需要运维⼿动地去维护这个配置信息是⼀个很⿇烦的操作. 所以开发者们开始希望有这么⼀个东西, 它能维护⼀个服务列表, 哪个机器上线了,哪个机器宕机了, 这些信息都会⾃动更新到服务列表上, 客⼾端拿到这个列表, 直接进⾏服务调⽤即可.这个就是注册中⼼.
注册中⼼主要有三种⻆⾊:
- 服务提供者(Server):⼀次业务中, 被其它微服务调⽤的服务. 也就是提供接⼝给其它微服务.
- 服务消费者(Client):⼀次业务中, 调⽤其它微服务的服务. 也就是调⽤其它微服务提供的接⼝.
- 服务注册中⼼(Registry): ⽤于保存Server 的注册信息, 当Server 节点发⽣变更时, Registry 会同步变更. 服务与注册中⼼使⽤⼀定机制通信, 如果注册中⼼与某服务⻓时间⽆法通信, 就会注销该实例.
服务注册:服务提供者在启动时, 向 Registry 注册⾃⾝服务, 并向 Registry 定期发送⼼跳汇报存活状态.
服务发现: 服务消费者从注册中⼼查询服务提供者的地址,并通过该地址调⽤服务提供者的接⼝. 服务发现的⼀个重要作⽤就是提供给服务消费者⼀个可⽤的服务列表.
可能这样一点难理解,看图:
1.2 CAP理论
谈到注册中⼼, 就避不开CAP理论.
CAP 理论是分布式系统设计中最基础, 也是最为关键的理论.
- ⼀致性(Consistency) CAP理论中的⼀致性, 指的是强⼀致性. 所有节点在同⼀时间具有相同的数据
- 可⽤性(Availability) 保证每个请求都有响应(响应结果可能不对) 分区容错性(Partition Tolerance)
- 当出现⽹络分区后,系统仍然能够对外提供服务
在分布式系统中, 系统间的⽹络不能100%保证健康, 服务⼜必须对外保证服务. 因此PartitionTolerance不可避免. 那就只能在C和A中选择⼀个. 也就是CP或者AP架构
正常情况:
⽹络异常:
1.3 常见的注册中心
- Zookeeper
Zookeeper的官⽅并没有说它是⼀个注册中⼼, 但是国内Java体系, ⼤部分的集群环境都是依赖Zookeeper来完成注册中⼼的功能. - Eureka
Eureka是Netflix开发的基于REST的服务发现框架, 主要⽤于服务注册, 管理,负载均衡和服务故障转移.
官⽅声明在Eureka2.0版本停⽌维护, 不建议使⽤. 但是Eureka是SpringCloud服务注册/发现的默认实现, 所以⽬前还是有很多公司在使⽤. - Nacos
Nacos是Spring Cloud Alibaba架构中重要的组件, 除了服务注册, 服务发现功能之外, Nacos还⽀持配置管理, 流量管理, DNS, 动态DNS等多种特性.
CAP理论对⽐
Zookeeper | Eureka | Nacos | |
---|---|---|---|
CAP理论 | CP | AP | CP或AP,默认AP |
我后面会讲解两种eureka和nacos
关于Eureka的学习, 主要包含以下三个部分:
- 搭建Eureka Server
- 将order-service, product-service 都注册到Eureka
- order-service远程调⽤时, 从Eureka中获取product-service的服务列表, 然后进⾏交互。
在上一节课的基础之上。
2. Eureka注册中心
Eureka主要分为两个部分:
- Eureka Server: 作为注册中⼼Server端, 向微服务应⽤程序提供服务注册, 发现, 健康检查等能⼒.
- Eureka Client: 服务提供者, 服务启动时, 会向Eureka Server 注册⾃⼰的信息(IP,端⼝,服务信息等),Eureka Server 会存储这些信息。
2.1 创建Eureka-server ⼦模块
2.2 引⼊eureka-server依赖
<!--eureka 依赖 说明这是一个注册中心-->
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
说明这是一个eureka-server注册中心服务器
2.3 项⽬构建插件(Maven插件)
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
2.4 完善启动类
//开启eureka服务器功能
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
@EnableEurekaServer
将一个 Spring Boot 应用程序标记为 Eureka 服务注册中心(Service Registry)
2.5 编写配置⽂件yml
# Eureka相关配置
# Eureka 服务
server:
port: 10010
spring:
application:
name: eureka-server
eureka:
instance:
hostname: localhost
client:
fetch-registry: false # 表示是否从Eureka Server获取注册信息,默认为true.因为这是一个单点的Eureka Server,不需要同步其他的Eureka Server节点的数据,这里设置为false
register-with-eureka: false # 表示是否将自己注册到Eureka Server,默认为true.由于当前应用就是Eureka Server,故而设置为false.
service-url:
# 设置Eureka Server的地址,查询服务和注册服务都需要依赖这个地址
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
2.6 启动服务
启动服务, 访问注册中⼼: http://127.0.0.1:10010/
可以看到eureka-server已经启动成功了。
3. 服务注册
接下来我们把product-service 注册到eureka-server中
3.1 引⼊eureka-client依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
说明这是一个eureka-client服务提供者服务器
3.2 完善配置⽂件
添加服务名称和eureka地址
#Eureka Client
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10010/eureka/ #服务提供者注册地址 eureka注册中心url地址 (也就是说这个模块的服务注册中心在哪里url)
刷新注册中⼼: http://127.0.0.1:10010/
可以看到product-service已经注册到 eureka上了。
4. 服务发现
接下来我们修改order-service, 在远程调⽤时, 从eureka-server拉取product-service的服务信息, 实现服务发现。
4.1 引⼊依赖
服务注册和服务发现都封装在eureka-client依赖中, 所以服务发现时, 也是引⼊eureka-client依赖.
<!--uerake 依赖 说明这是一个客户端 服务提供者-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
4.2 完善配置⽂件
服务发现也需要知道eureka地址, 因此配置内容依然与服务注册⼀致,都是配置eureka信息。
#Eureka Client
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10010/eureka/ #服务提供者注册地址 eureka注册中心url地址 (也就是说这个模块的服务注册中心在哪里url)
4.3 远程调⽤
package com.cdm.order.service;
import com.cdm.order.mapper.OrderMapper;
import com.cdm.order.model.OrderInfo;
import com.cdm.order.model.ProductInfo;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
@Slf4j
@Service
public class OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private RestTemplate restTemplate;
//yml已经获取到注册中心的url 就可以从这个类里面获取服务列表
@Autowired
private DiscoveryClient discoveryClient;
public OrderInfo selectByOrderId(Integer orderId) {
OrderInfo orderInfo = orderMapper.selectByOrderId(orderId);
//这里可以使用应用名称(product-server)代替ip地址和端口号,跟域名功能相似
String url = "http://product-server/product/" + orderInfo.getProductId();
log.info("url" + url);
ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);
orderInfo.setProductInfo(productInfo);
return orderInfo;
}
}
4.4 启动服务
刷新注册中⼼: http://127.0.0.1:10010/
可以看到order-service已经注册到 eureka上了.
访问接⼝: http://127.0.0.1:8080/order/1
5. Eureka 和Zookeeper区别
Eureka和Zookeeper都是⽤于服务注册和发现的⼯具,区别如下:
- Eureka是Netflix开源的项⽬, ⽽Zookeeper是Apache开源的项⽬.
- Eureka 基于AP原则, 保证⾼可⽤, Zookeeper基于CP原则, 保证数据⼀致性.
- Eureka 每个节点 都是均等的, Zookeeper的节点区分Leader 和Follower 或 Observer, 也正因为这个原因, 如果Zookeeper的Leader发⽣故障时, 需要重新选举, 选举过程集群会有短暂时间的不可⽤.
好了,今天讲到这里,感谢观看。