在上一篇文章中我们在进行远程调用时碰到了一个问题:我们的URL是写死的[文章链接]:
String url = "http://127.0.0.1:9090/product/" + orderInfo.getProductId(); 如果在这个时候我们更换了机器或者新增了机器,这个URL就需要跟着进行变更,原本部署好的服务以及配置文件就需要再进行更新,这会给我们带来很多麻烦。
而在SpringCloud中,我们可以使用注册中心来解决这个问题!
在生活中,我们往往避免不了和各个机构(医院,学校,政府部门等)打交道,这个时候就需要保存好各个机构的电话号码,可如果这些机构更换了电话号码,就需要通知各个使用方他们更换了号码,可是对于这些机构来说他们的使用方群体是巨大的,一一通知到位很难处理,这个时候就需要使用到114来查台:机构电话如果发生了变化,会通知114;用户需要联系机构时,先拨打114查询机构电话,然后再联系各个机构
可见114查号台的作用主要有两个:

而对于计算机来讲,注册中心就充当着上述"114"的作用!
注册中心主要有三种角色:
注:服务提供者和服务消费者是相对的,二者位置可以相互转换!
它们之间的关系以及工作内容,可以通过两个概念来描述:
服务注册:服务提供者在启动时,向Registry注册自身服务,并向Registry定期发送心跳汇报存活状态
服务发现:服务消费者从注册中心查询服务提供者的地址,并通过该地址调用服务提供者的接口,同时服务发现会提供给服务消费者一个可用的服务列表

谈到注册中心,就避不开CAP理论!
CAP理论是分布式系统设计中最基础,也是最为关键的理论.

CAP理论告诉我们:一个分布式系统不可能同时满足这三个基本需求,最多只能同时满足其中的两个
在分布式系统中,系统间的网络不能100%保证健康,而服务又必须对外保证服务,因此分区容错性(P)不可避免,那就只能在C和A中选择一个,也就是CP架构或AP架构:
CP架构:两个节点在进行数据同步时,如果出现了网络问题,为了保证分布式系统对外的数据一致性,出现网络问题的节点会选择不返回任何数据
AP架构:两个节点在进行数据同步时,如果出现了网络问题,为了保证分布式系统的可用性,出现网络问题的节点依旧会返回数据回去,即使这个数据是错误的
比较常见的注册中心有:ZooKeeper,Eureka,Nacos
ZooKeeper使用CP架构,EureKa使用AP架构,Nacos使用CP或AP架构,默认使用AP架构
这篇文章主要介绍EureKa!
EureKa 主要分为两个部分:
对于EureKa的使用主要分为以下三个部分:
Eureka Servers 是一个独立的微服务,需要为它创立子模块:

引入eureka-server依赖与项目构建插件:
org.springframework.cloud spring-cloud-starter-netflix-eureka-server org.springframework.boot spring-boot-maven-plugin src/main/resources true **/** 完善启动类,并添加上@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启动成功了!!
接下来我们把product-service 注册到eureka-server中
先给product-service引入eureka-client依赖:
org.springframework.cloud spring-cloud-starter-netflix-eureka-client 之后完善配置文件,添加上服务名称和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中!
接下来修改我们order-service,在远程调用时,从eureka-service拉取product-service的服务信息,实现服务发现。
先给order-service引入eureka-client依赖:
org.springframework.cloud spring-cloud-starter-netflix-eureka-client 之后完善配置文件,配置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 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的讲解,敬请期待!!