比如咱们作为客户端进行购物时,那么多服务提供者【服务提供者有很多实例,可能人家已经搞了拆分模块后的分布式集群,那实例就不少啦】,如果用非技术的眼光看就是,你提供多个,我挑一个买,咱们的访问过程应该是这样的。
话说回来,除了用东方神秘的力量之外,那么多超市服务,我咋知道实际调哪一个呢、这么多怎么管理呢…?【重要概念,微服务中一个服务既可以是服务消费者又可以是服务提供者,服务这个概念是相对的】
针对这么多问题就需要注册中心来帮助我们
- SpringCloud的注册中心Eureka
- Eureka手里有几员大将,为了攒战功,Eureka分别把自己的大将派往不同地方。其中这个eureka-server这个将军属于上将之一。Eureka的大将之一eureka-server,作为大管家,新官上任三把火。【可以到Github或者Gitee看代码,结合图一块看:】
- 第一把火,你们market-service但凡要提供shopping服务,必须在你们market-service服务实例启动后到我这里来注册你们的服务信息【到eureka-server进行服务注册】【每个需要被注册中心管理的服务的配置文件中,有Eureka的配置,包括defalutZone=…,表示你这个服务要注册到哪里呀,这个哪里就指的是eureka-server注册中心所在】
- 第二把火,我这里给购物的消费者(服务)保存服务实例地址列表,并把列表提供给消费者让他们选择,然后拉取market-service的信息选择出心仪的那一个【people-service根据服务名称列表进行服务发现或者拉取】
- 【服务发现其实指的是,咱们服务不是已经注册在Eureka中了嘛,咱们界面上可以看到哪些注册进来了,然后,咱们可以通过DiscoveryClient这个类的getService()方法获得微服务列表List,以及getInstances(服务ID)方法获得一个具体的微服务信息。然后在主程序类加上一个@EnableDiscoveryClient开启服务发现。当然那个actuator导包之后并在application.xml中配置info配置之后,可以配置一些监控信息,在Eureka的页面中点链接也可以显示一下信息,但是这个不好用,一般显示一些author信息这些,主要的还是通过DiscoveryClient】
- Eureka的自我保护机制:
- 某个微服务不可用了,没发来心跳,eureka会90秒后立即清理注销这个实例【有时候由于网络分区存在,微服务可能本身非常健康,不应该被注销】。但是Eurake通过自我保护机制不会注销服务,当网络故障恢复后自动退出保护模式【宁可错误保留,也不盲目注销】
- 第三把火,为了防止market-service哪个由于疫情或者其他原因搞不下去了宕机了【我又不能说是你都不卖东西了,人家购物的人啥啥坐在在看你家的东西,搞了半天下架你也不吭声,这不是坑人嘛】,market-service这边的服务们必须每隔一段时间(默认30)向eureka-server发起请求报告自己的心跳状态【超过一定时间没发心跳则eureka-server就会认为这个微服务发生故障,剔除,你给我除去】
- Eureka说,eureka-server,你烧的好,再奖励你一把火,于是,eureka-server再次下令,但是是一把小火,就是你们people从eureka-server提供的实例列表中选择一个心仪的实例(地址)时,需要通过“负载均衡算法”选择,然后向该实例发起远程调用
- 第一把火,你们market-service但凡要提供shopping服务,必须在你们market-service服务实例启动后到我这里来注册你们的服务信息【到eureka-server进行服务注册】【每个需要被注册中心管理的服务的配置文件中,有Eureka的配置,包括defalutZone=…,表示你这个服务要注册到哪里呀,这个哪里就指的是eureka-server注册中心所在】
- 【Eureka是基于REST(代表性状态转移)的服务,主要在 AWS 云中用于定位服务,以实现负载均衡和中间层服务器的故障转移。我们称此服务为Eureka服务器。】【
可以充当服务发现的组件有很多:Zookeeper ,Consul , Eureka 等
】- 这里面ctrl+F搜餐馆:
- 我们依旧那拿上面的餐馆为例,我们要找合适的餐馆吃饭,但是我又不知道哪个餐馆有啥菜,有这个菜的饭馆在哪里…,所以此时,作为微服务中的 Consumer的咱们以及作为微服务中的Provider。【此时我们作为Consumer需要调用提供者Provider提供的一些服务,就是找到他们的餐馆吃饭】。要是光咱们双方在交涉,不管是餐馆随地贴小广告还是咱们傻乎乎的找,就会出现几个问题(效率是很低的:不是所有人都能看到小广告,所以会出现
资源消耗问题
)。所以搞个中介,中介为我们提供统一房源的餐馆,我们只需要找中介就可以找到餐馆+参观这个服务提供者也只需要把餐馆所在信息发布或者叫注册在中介那里就行
。然后就得考虑餐馆有新的旧的咱们是不是应该增删注册表+服务消费者是不是也得让中介知道自己的信息+一个中介生病了退休了怎么办,你不搞个中介集群 服务发现
:其实就是一个“中介”,整个过程中有三个角色:服务提供者(餐馆)、服务消费者(干饭人)、服务中介。服务中介
:其实就是服务提供者和服务消费者之间的“桥梁”,服务提供者可以把自己注册到服务中介那里,而服务消费者如需要消费一些服务(使用一些功能)就可以在服务中介中寻找注册在服务中介的服务提供者
。- 服务注册 Register:当 Eureka 客户端向 Eureka Server 注册时,它提供自身的元数据,比如 IP 地址、端口,运行状况指示符 URL,主页等。
餐馆 (提供者 Eureka Client Provider)把自己餐馆所在信息以及可以做的菜等信息在中介 (服务器 Eureka Server) 那里登记下来
- 服务续约 Renew:Eureka 客户会每隔 30 秒(默认情况下)发送一次心跳来续约。 通过续约来告知 Eureka Server 该 Eureka 客户仍然存在,没有出现问题。 正常情况下,如果 Eureka Server 在 90 秒没有收到 Eureka 客户的续约,它会将实例从其注册表中删除。【
餐馆 (提供者 Eureka Client Provider)定期告诉中介 (服务器 Eureka Server) 我的餐馆还提供伙食(续约) ,中介 (服务器Eureka Server) 收到之后继续保留该餐馆的信息
。】 - 获取注册列表信息 Fetch Registries:Eureka 客户端从服务器获取注册表信息,并将其缓存在本地。客户端会使用该信息查找其他服务,从而进行远程调用。该注册列表信息定期(每 30 秒钟)更新一次。每次返回注册列表信息可能与 Eureka 客户端的缓存信息不同, Eureka 客户端自动处理。如果由于某种原因导致注册列表信息不能及时匹配,Eureka 客户端则会重新获取整个注册表信息。 Eureka 服务器缓存注册列表信息,整个注册表以及每个应用程序的信息进行了压缩,压缩内容和没有压缩的内容完全相同。Eureka 客户端和 Eureka 服务器可以使用 JSON / XML 格式进行通讯。在默认的情况下 Eureka 客户端使用压缩 JSON 格式来获取注册列表的信息。【
咱们干饭人(消费者 Eureka Client Consumer) 去中介 (服务器 Eureka Server) 那里获取所有的餐馆信息列表 (客户端列表 Eureka Client List) ,而且干饭人为了获取最新的信息会定期向中介 (服务器 Eureka Server) 那里获取并更新本地列表
。】 - 服务下线 Cancel:Eureka 客户端在程序关闭时向 Eureka 服务器发送取消请求。 发送请求后,该客户端实例信息将从服务器的实例注册表中删除。该下线请求不会自动完成,它需要调用以下内容:DiscoveryManager.getInstance().shutdownComponent();【
餐馆 (提供者 Eureka Client Provider)告诉中介 (服务器 Eureka Server) 我的餐馆不卖饭了,中介之后就将注册的房屋信息从列表中剔除。
】 - 服务剔除 Eviction:在默认的情况下,当 Eureka 客户端连续 90 秒(3 个续约周期)没有向 Eureka 服务器发送服务续约,即心跳,Eureka 服务器会将该服务实例从服务注册列表删除,即服务剔除。【
餐馆 (提供者 Eureka Client Provider)会定期联系 中介 (服务器 Eureka Server) 告诉他我的餐馆还卖饭(续约),如果中介 (服务器 Eureka Server) 长时间没收到提供者的信息,那么中介会将他的餐馆信息给下架(服务剔除)。别人就不到这家买饭了
】
- 服务注册 Register:当 Eureka 客户端向 Eureka Server 注册时,它提供自身的元数据,比如 IP 地址、端口,运行状况指示符 URL,主页等。
服务提供者
: 就是提供一些自己能够执行的一些服务给外界。就是餐馆,可以给干饭人提供伙食服务消费者
:就是需要使用一些服务的“用户”
- Eureka的搭建或者实践过程:三步可以上篮
- pom.xml中导入依赖+编写application.xml配置文件【端口号、服务名称,你要被哪个中间件管理,配置中心?注册中心?…】+在主程序类加个@EnableEurekaServer注解,老版本要加,新版本不需要加
- 其实比如你要搞Eureka集群,就是1的application.xml中的defaultZone中原本放一个http://…,现在放集群中除他自己之外的所有http://…,其余的节点一样,自己的application.xml中的defaultZone中原本放一个http://…,现在放集群中除他自己之外的所有http://…
- RestTemplate:微服务之间的调用经常是使用的 RestTemplate,RestTemplate是Spring提供的一个访问 Http 服务的客户端类,比如这个时候我们 消费者 B 需要调用 提供者 A 所提供的服务我们就需要这么写。
@Autowired private RestTemplate restTemplate; // 这里是提供者A的ip地址,但是如果使用了 Eureka 那么就应该是提供者A的名称 private static final String SERVICE_PROVIDER_A = "http://localhost:8081"; @PostMapping("/judge") public boolean judge(@RequestBody Request request) { String url = SERVICE_PROVIDER_A + "/service1"; return restTemplate.postForObject(url, request, Boolean.class); }
@RestController public class UserInfoController { /** * RestTemplate用来提供多种便捷访问远程http服务的方法,简单的restful服务模板 * 消费者这边是不应该有service的,借助RestTemplate,有很多方法供我们直接调用,比如利用GET/POST方式获得实体,好多方法都跟网络有关【参数是url之类的】 */ @Autowired private RestTemplate restTemplate; private static final String REST_URL_PREFIX = "http://localhost:8081"; @RequestMapping("/consumer/userinfo/get/{id}") public UserInfo get(@PathVariable("id") Long id){ return restTemplate.getForObject(REST_URL_PREFIX + "/userinfo/get/" + id, UserInfo.class); } ... }
- Eureka手里有几员大将,为了攒战功,Eureka分别把自己的大将派往不同地方。其中这个eureka-server这个将军属于上将之一。Eureka的大将之一eureka-server,作为大管家,新官上任三把火。【可以到Github或者Gitee看代码,结合图一块看:】
- Zookeeper也可以做注册中心:
- zookeeper主要看这里【https://blog.csdn.net/m0_52436398/article/details/125193033】
- 注册中心中间件们的区别:
Zookeeper保证的是CP(降低可用性)
- 因为选举新主机过程中,整个集群是不可用的
Eureka保证的是AP(降低数据一致性,允许返回旧数据,不能接受服务直接宕机)
- 几个节点宕机其余的依旧可以提供注册和查询服务。只要有一台Eureka还在就可以继续保证注册服务的可用性
巨人的肩膀:
Dubbo中文文档
SpringCloud中文文档
极客时间