- 🎥 个人主页:Dikz12
- 🔥个人专栏:Spring Cloud实战
- 📕格言:吾愚多不敏,而愿加学
- 欢迎大家👍点赞✍评论⭐收藏
目录
1.项目问题
2.解决URL问题
2.1解决思路
2.2注册中心
2.3 CAP理论
3.Eureka
3.1搭建Eureka Server
4.服务注册
1.项目问题
- url是写死的,如果IP地址发生变化,需要修改代码;
- 如果多机部署,怎么处理?
- 返回结果如何共用,url非常容易写错;
2.解决URL问题
当更换机器,或者新增机器时,这个URL就需要跟着变更,就需要去通知所有的相关服务去修改.
2.1解决思路
试想⽣活中的场景:
我们⽣活中,避免不了和各个机构(医院,学校,政府部⻔等)打交道,就需要保存各个机构的电话号码.如果机构换了电话号码,就需要通知各个使⽤⽅,但是这些机构的使⽤⽅群体是巨⼤的,没办法做到⼀⼀通知,怎么处理呢?
机构电话如果发⽣变化,通知114.⽤⼾需要联系机构时,先打114查询电话,然后再联系各个机构.
114查号台的作⽤主要有两个:
号码注册:服务⽅把电话上报给114.
号码查询:使⽤⽅通过114可以查到对应的号码.
同样的,微服务开发时,也可以采⽤类似的⽅案.
服务启动/变更时,向注册中⼼报道.注册中⼼记录应⽤和IP的关系.
调⽤⽅调⽤时,先去注册中⼼获取服务⽅的IP,再去服务⽅进⾏调⽤.
2.2注册中心
注册中⼼主要有三种⻆⾊:
- 服务提供者(Server):⼀次业务中,被其它微服务调⽤的服务.也就是提供接⼝给其它微服务.
- 服务消费者(Client):⼀次业务中,调⽤其它微服务的服务.也就是调⽤其它微服务提供的接⼝.
- 服务注册中⼼(Registry):⽤于保存Server的注册信息,当Server节点发⽣变更时,Registry会同步变更.服务与注册中⼼使⽤⼀定机制通信,如果注册中⼼与某服务⻓时间⽆法通信,就会注销该实例.
服务提供者和服务消费者是相对的.
服务注册:服务提供者在启动时,向Registry注册⾃⾝服务,并向Registry定期发送⼼跳汇报存活状态.
服务发现:服务消费者从注册中⼼查询服务提供者的地址,并通过该地址调⽤服务提供者的接⼝.服务发现的⼀个重要作⽤就是提供给服务消费者⼀个可⽤的服务列表.
2.3 CAP理论
谈到注册中⼼,就避不开CAP理论.
CAP理论是分布式系统设计中最基础,也是最为关键的理论.
- ⼀致性(Consistency):CAP理论中的⼀致性,指的是强⼀致性.所有节点在同⼀时间具有相同的数据.
- 可⽤性(Availability):保证每个请求都有响应(响应结果可能不对)
- 分区容错性(Partition Tolerance):当出现⽹络分区后,系统仍然能够对外提供服务.
以生活中的场景举例:银行利率下调,这个通知需要下发到各个银行的工作人员.
一致性:所有的银行工作人员,对客户讲的利率都是一样的.
可用性:不论何时,银行人员对客户咨询利率的请求,都是有答案的.(答案可能是旧的)
分区容错性:如果一个工作人员请假了,银行依然可以对外提供服务.
P是必须要保证的,所以C和A只能选一个.我们的架构就是CP架构或者AP架构。
CP架构:为了保证分布式系统对外的数据⼀致性,于是选择不返回任何数据
AP架构:为了保证分布式系统的可⽤性,节点返回旧版本的数据(即使这个数据不正确)
3.Eureka
Eureka是Netflix OSS套件中关于服务注册和发现的解决⽅案.Spring Cloud对ureka进⾏了集成,并作为优先推荐⽅案进⾏宣传,虽然⽬前Eureka 2.0已经停⽌维护,新的微服务架构设计中,也不再建议使⽤,但是⽬前依然有⼤量公司的微服务系统使⽤Eureka作为注册中⼼.
官⽅⽂档:https://github.com/Netflix/eureka/wiki
Eureka的学习,主要包含以下三个部分:
- 搭建Eureka Server
- 将order-service,product-service都注册到Eureka
- order-service远程调⽤时,从Eureka中获取product-service的服务列表,然后进⾏交互
3.1搭建Eureka Server
创建Eureka-server⼦模块
引⼊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>
</build>
编写配置文件
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/
完善启动类
给该项⽬编写⼀个启动类,并在启动类上添加 @EnableEurekaServer 注解,开启eureka注册中⼼服务.
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class,args);
}
}
启动服务
可以看到eureka-server已经启动成功了.
4.服务注册
把product-service,order-service注册到eureka-server中
引入eureka-client依赖到product-service,order-service中的pom文件
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
完善product-service,order-service中配置⽂件
spring:
application:
name: product-service
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10010/eureka
启动product-service服务
可以看到product-service已经注册到eureka上了.
远程调用
@Service
public class OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
public OrderInfo selectOrderById(Integer orderId) {
OrderInfo orderInfo = orderMapper.selectOrderById(orderId);
// String url = "http://127.0.0.1:9090/product/" + orderInfo.getProductId();
//根据应用名获取服务列表
List<ServiceInstance> instances = discoveryClient.getInstances("product-service");
//获取第一个服务
// EurekaServiceInstance serviceInstance = (EurekaServiceInstance)instances.get(0);
//拼接url
String url = instances.get(0).getUri() + "/product/" + orderInfo.getProductId();
ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);
orderInfo.setProductInfo(productInfo);
return orderInfo;
}
}
启动测试
刷新注册中⼼,可以看到order-service已经注册到eureka上了
访问接⼝:http://127.0.0.1:8080/order/1
可以看到,远程调⽤也成功了.