Spring Cloud 服务注册&发现-Eureka
文章目录
导引
在上一篇文章中我们在进行远程调用时碰到了一个问题:我们的URL是写死的[文章链接]:
String url = "http://127.0.0.1:9090/product/" + orderInfo.getProductId();
如果在这个时候我们更换了机器或者新增了机器,这个URL就需要跟着进行变更,原本部署好的服务以及配置文件就需要再进行更新,这会给我们带来很多麻烦。
而在SpringCloud
中,我们可以使用注册中心来解决这个问题!
1. 注册中心
1.1 介绍
在生活中,我们往往避免不了和各个机构(医院,学校,政府部门等)打交道,这个时候就需要保存好各个机构的电话号码,可如果这些机构更换了电话号码,就需要通知各个使用方他们更换了号码,可是对于这些机构来说他们的使用方群体是巨大的,一一通知到位很难处理,这个时候就需要使用到114来查台:机构电话如果发生了变化,会通知114;用户需要联系机构时,先拨打114查询机构电话,然后再联系各个机构
可见114查号台的作用主要有两个:
- 号码注册:服务方把电话上报给114
- 号码查询:使用方通过114查询对应号码
而对于计算机来讲,注册中心就充当着上述"114"的作用!
注册中心主要有三种角色:
- 服务提供者(Server):一次业务中,被其它微服务调用的服务,也就是提供接口给其它微服务
- 服务消费者(Client):一次业务中,调用其它微服务的服务,也就是调用其它微服务提供的接口
- 服务注册中心(Registry):用于保存Server的注册信息,当Server节点发生变更时,Registry会同步变更,服务与注册中心使用一定机制通信,如果注册中心长时间与某服务无法通信,就会注销该实例
注:服务提供者和服务消费者是相对的,二者位置可以相互转换!
它们之间的关系以及工作内容,可以通过两个概念来描述:
服务注册:服务提供者在启动时,向Registry注册自身服务,并向Registry定期发送心跳汇报存活状态
服务发现:服务消费者从注册中心查询服务提供者的地址,并通过该地址调用服务提供者的接口,同时服务发现会提供给服务消费者一个可用的服务列表
1.2 CAP理论
谈到注册中心,就避不开CAP理论!
CAP理论是分布式系统设计中最基础,也是最为关键的理论.
- 一致性(Consistency):CAP理论中的一致性,指的是强一致性,所有节点在同一时间具有相同的数据(如主从复制,主机和从机需要做到数据的同步更新)
- 可用性(Availability):保证每个请求都要有响应(响应结果可能是错的,但就是要有响应)
- 分区容错性(Paitition Tolerance):当出现网络分区后,系统仍然能够对外提供服务(如集群中如果一台机器宕机了还有其它的机器能够顶上提供相应的服务)
CAP理论告诉我们:一个分布式系统不可能同时满足这三个基本需求,最多只能同时满足其中的两个
在分布式系统中,系统间的网络不能100%保证健康,而服务又必须对外保证服务,因此分区容错性(P)不可避免,那就只能在C和A中选择一个,也就是CP架构或AP架构:
CP架构:两个节点在进行数据同步时,如果出现了网络问题,为了保证分布式系统对外的数据一致性,出现网络问题的节点会选择不返回任何数据
AP架构:两个节点在进行数据同步时,如果出现了网络问题,为了保证分布式系统的可用性,出现网络问题的节点依旧会返回数据回去,即使这个数据是错误的
1.3 常见的注册中心
比较常见的注册中心有:ZooKeeper
,Eureka
,Nacos
ZooKeeper
使用CP架构,EureKa
使用AP架构,Nacos
使用CP或AP架构,默认使用AP架构
这篇文章主要介绍EureKa!
2. EureKa
2.1 介绍
EureKa 主要分为两个部分:
- Eureka Server:作为注册中心Server端,向微服务应用程序提供服务注册、发现、健康检查等能力
- Eureka Client:服务提供者,服务启动时,会像Eureka Server注册自己的信息(IP,端口,服务信息等),Eureka Server会存储这些信息
对于EureKa的使用主要分为以下三个部分:
- 搭建Eureka Server
- 将order-servicec和product-service都注册到Eureka
- order-service远程调用时,从Eureka中获取到product-service的服务列表,然后进行交互
2.2 搭建Eureka Server
Eureka Servers 是一个独立的微服务,需要为它创立子模块:
引入eureka-server依赖与项目构建插件:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/**</include>
</includes>
</resource>
</resources>
</build>
完善启动类,并添加上@EnableEurekaServer
注解用于开启eureka注册中心服务:
package com.eureka;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
编写配置文件:
# 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/
完成上述配置后可以启动服务进行测试:
访问注册中心:127.0.0.1:10010
出现上述界面则表示eureka-server启动成功了!!
2.3 服务注册
接下来我们把product-service
注册到eureka-serve
r中
先给product-service引入eureka-client依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
之后完善配置文件,添加上服务名称和eureka地址:
spring:
application:
name: product-service
#Eureka Client
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10010/eureka/
启动product-service服务,再次刷新127.0.0.1:10010
注册中心:
可以看到product-service
这个服务已注册到了eureka中!
2.3 服务发现
接下来修改我们order-service
,在远程调用时,从eureka-service
拉取product-service
的服务信息,实现服务发现。
先给order-service引入eureka-client依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
之后完善配置文件,配置eureka地址与服务名称:
spring:
application:
name: order-service
#Eureka Client
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10010/eureka/
修改远程调用(OrderServiceImpl
),我们需要从eureka-server中获取product-service的列表(可能存在多个服务),并选择其中一个进行调用:
package com.order.service.Impl;
import com.order.mapper.OrderMapper;
import com.order.model.OrderInfo;
import com.order.model.ProductInfo;
import com.order.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private DiscoveryClient discoveryClient;
@Autowired
private RestTemplate restTemplate;
@Override
public OrderInfo selectOrderById(Integer orderId) {
OrderInfo orderInfo = orderMapper.selectOrderById(orderId);
// String url = "http://127.0.0.1:9090/product/" + orderInfo.getProductId();
// 从 eureka-server 中获取product-service 服务列表
List<ServiceInstance> instances = discoveryClient.getInstances("product-service");
String uri = instances.get(0).getUri().toString(); // 从服务列表中获取ip地址,此时服务列表中只有一个服务所有索引0下标即可
String url = uri + "/product/" + orderInfo.getProductId();
ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);
orderInfo.setProductInfo(productInfo);
return orderInfo;
}
}
启动服务并刷新注册中心:
可以看到order-service
也注册到了eureka中!
这个时候我们再次通过127.0.0.1:8080
发送请求获取订单数据:
可以看到远程调用成功,数据也能够正确的获取到!!
以上便是对服务注册和发现与EureKa使用的介绍了,对于注册中心后续还可能会添加对Nacos
的讲解,敬请期待!!