【微服务】服务注册与发现 - Eureka(day3)

CAP理论

P是分区容错性。简单来说,分区容错性表示分布式服务中一个节点挂掉了,并不影响其他节点对外提供服务。也就是一台服务器出错了,仍然可以对外进行响应,不会因为某一台服务器出错而导致所有的请求都无法响应。综上所述,在分布式系统中,分区容错性是必须要保证的一个特性。

C表示一致性。通俗的讲,一致性就是所有节点在某个响应时的数据都是相同的。

A表示可用性。可用性指代对所有的请求都有相应结果。

在分布式系统中,P是必须要保证的一个特性,因此可用性和一致性就不能同时保证。原因就是当一个节点收到数据之后,要传给别的节点进行复制,在这个过程中,如果有请求的话,那么就可能导致一致性出现问题。假设要保证一致性,那就得上锁,不对外响应,那么此时可用性就出现了问题。因此,分布式系统中,只存在AP理论和CP理论。

举个例子来说明一下CAP的概念。在一家生意火爆的饭店中,一道菜的原料没有了,就要告诉所有的服务员不能再下单该菜了,但是通知的过程是要浪费时间的。

一致性表示所有的服务都接到通知了,因此对客户的响应都是相同的。可用性就是不管有没有接收到通知,服务员都会给出一个响应。分区容错性是指一个服务员请假了,那也不会影响今天的饭店开门。分区容错性饭店肯定是能保证的。但是如果要保证一致性,那么在所有服务员接收到通知之前,都是不能讲话的,这就影响到了可用性。如果要保证可用性,那么所有的服务员都能讲话,但是不确定谁没有接收到信息。如果想要同时保证可用性和一致性,只有一种可能,就是饭店只有一个人,但是这种情况下,他请假,饭店就关门了,分区容错性就没有了。

服务注册和发现引入

概述

在基础工程搭建中,我们发现调用服务时是以硬编码的方式来创建URL的,但是对于微服务来说,一个服务可能有成百上千个实例,并且还会随时扩缩容。因此,我们采用这种方式是不合理的。并且,在日常管理中,对这么多的实例,我们并不能立马确定哪个实例出现了宕机等问题。因此就出现了微服务家族的第一套组件——服务注册和发现。

服务注册和发现,最重要干的事就是把所有注册到注册中心的实例给展示出来。这样,我们可以轻松的看到所有的实例运行情况。如果此时某台实例出错下线了,注册中心也能监控到,并将该实例进行剔除,不再对外进行服务。而且,有的注册中心也能支持实例的动态上下线,这样能很快的实现扩缩容,大大减少了运维开发的工作。

综上所述,服务注册和发现组件的功能大概有:服务管理、容错处理、动态扩展等。当然,不同产品也会存在一定的差异化,例如咋们中国阿里巴巴的Nacos就不止实现了服务注册和发现这个功能,还有分布式配置管理等,当然,这都是下文了。

功能图

 角色

Server,服务提供者:一次业务中,被其他服务调用的服务,也就是提供接口给其他服务。

Client,服务消费者:一次业务中,调用其他服务的服务,也就是使用接口的服务。

Registry,服务注册中心:用来保存Server的注册信息,当Server节点发生变更时,注册中心就会感知到并进行同步更新。注册中心和注册的服务存在一定机制进行通信,如果注册中心与某服务长期没有通信,也就是超过限定的阈值,那么注册中心就会下线该实例。

服务注册和服务发现

服务注册:服务提供者在启动服务时,将自身注册到注册中心中,并定期向注册中心发送心跳包表示自己还存活。

服务发现:服务消费者需要调用某服务时,就先去注册中心找到服务提供者的地址,通过该地址对服务提供者进行调用。服务发现的重要作用就是提供一个可用的服务列表给消费者。

搭建注册中心

内容

1. Eureka Server:作为注册中心,向服务提供服务注册、服务发现、健康检查等功能。

2. Eureka Client:服务提供者,服务启动时,会向注册中心提供自己的信息,例如端口号,IP地址等内容,而注册中心会保存这些信息。

步骤

1. 搭建Eureka Server。

2. 将服务都注册到注册中心中。

3. 服务与服务之间进行调用时,先去注册中心查找被调用服务的服务列表,然后进行调用。

搭建案例

搭建注册中心

建模块

写pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.wbz</groupId>
        <artifactId>spring-cloud-test</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>cloud-server-eureka10010</artifactId>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>

        <!--web通用模块-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--注册中心-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

    </dependencies>

</project>

写yml文件

server:
  port: 10010

spring:
  application:
    name: cloud-server-eureka10010

eureka:
  instance:
    hostname: localhost
  client:
    # 表示是否从注册中心中获取注册的服务信息,默认是true
    # 咋们搭建的只是一个单体的,没有其他注册中心,因此不需要同步
    fetch-registry: false
    # 表示是否将自己注册到注册中心
    register-with-eureka: false
    service-url:
      # 设置注册中心的地址,查询服务和注册服务都需要依赖这个地址
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

改启动类

/**
 * Eureka服务注册中心
 */

@EnableEurekaServer // 开启注册中心服务
@SpringBootApplication
public class EurekaServerApplication10010 {

    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication10010.class, args);
    }

}

启动该服务,访问URL:127.0.0.1:10010,出现如下界面就算搭建成功:

注册商品服务到注册中心

修改pom文件

        <!--Eureka-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

修改yml文件

eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10010/eureka/

注册订单服务到注册中心

 修改pom文件

        <!--Eureka-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

修改yml文件

eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10010/eureka/

把两个项目进行重新启动,再次观察Eureka的页面,发现:

硬编码解耦

订单服务中进行修改

@Slf4j
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    /*@Resource
    private RestTemplate restTemplate;

    @Override
    public Order getOrderById(Integer id) {
        Order order = this.getById(id);
        String url = "http://127.0.0.1:8001/product/query/" + order.getProductId();
        Product product = this.restTemplate.getForObject(url, Product.class);
        order.setProduct(product);
        return order;
    }*/

    private final String PRODUCT_SERVICE_NAME = "cloud-provider-payment8001";

    @Resource
    private RestTemplate restTemplate;

    @Resource
    private DiscoveryClient discoveryClient;

    @Override
    public Order getOrderById(Integer id) {
        // 获取订单
        Order order = this.getById(id);

        // 获取商品服务的实例
        List<ServiceInstance> instances = discoveryClient.getInstances(this.PRODUCT_SERVICE_NAME);
        // 输出日志查看获取到的实例有哪些内容
        log.info(instances.toString());
        // 获取第一个商品实例的uri
        String uri = instances.get(0).getUri().toString();
        log.info(uri);
        // 拼接url
        String url = uri + "/product/query/" + order.getProductId();
        // 远程调用
        Product product = this.restTemplate.getForObject(url, Product.class);
        order.setProduct(product);
        // 返回结果
        return order;
    }
    
}

在硬编码解耦中,其实就是将原来的IP和PORT进行改换。通过服务名字去注册中心查找实例然后进行调用,这样无论启动多少个实例,也不用对代码进行变动。

Eureka对于CAP理论来说,其实现的是AP理论,保证高可用。

总结与疑惑 

在我第一次学习了Eureka之后,感觉这个组件好好用,能减少代码的耦合,不过,随之而来又出现了一个问题就是当我启动多个实例之后,发现我依旧只能调用第一个服务,那原因是出在哪里呢。经过查看我的代码如下图发现,是在服务调用的时候写了只调用第一个。问题找打了,但是如何解决呢?写一个取余来判断?但是我又不确定又几个实例。在这里就不多说了,好奇的同学就赶快去看第二个组件负载均衡吧,他完美解决了这个问题。

再提一句,学习了Nacos和Consul之后,发现Eureka不香了,看到这里的同学是不是得来一句——经典白雪,赶快打在评论区吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/888101.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

dwceqos网络驱动性能优化

文章介绍 本文会分享一些在QNX系统下对io-pkt-v6-hc驱动模块cpu loading过高问题优化的经验&#xff0c;以及一些调优debug的方法。这些优化措施实施之后可以降低io-pkt-v6-hc在高负载的情况下的cpu loading。本文的调优是基于synopsys公司的dwceqos模块&#xff0c;理论上方法…

【Android 源码分析】Activity生命周期之onPause

忽然有一天&#xff0c;我想要做一件事&#xff1a;去代码中去验证那些曾经被“灌输”的理论。                                                                                  – 服装…

【STM32 HAL库】MPU6050 DMP库移植 与 自检失败的处理

【STM32 HAL库】MPU6050 DMP库移植 与 自检失败的处理 本文参考移植步骤文件配置代码修改inv_mpu.cinv_mpu.hinv_mpu_dmp_motion_driver.c 使用 自检失败怎么处理ret -1改正DEBUG过程 ret -9改正DEBUG过程 本文参考 B站 CSDN 移植步骤 文件配置 新建一个 dmp 文件夹 并将…

【Linux】进程地址空间、环境变量:从理论到实践(三)

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Linux 目录 &#x1f680; 前言一&#xff1a;&#x1f525; 环境变量 &#x1f95d; 基本概念&#x1f95d; 常见环境变量&#x1f95d; 查看环境变量方法 二&#xff1a;&#x1f525; 测试 &…

Nat. Commun.:飞秒激光书写受蚂蚁启发的可重构微型机器人集体

背景介绍生物在各种环境中的集体行为十分普遍&#xff0c;它们能够自发有序地完成单个个体难以完成的任务。目前&#xff0c;生物集体的形成主要分为两大类。第一类生物个体之间没有直接接触&#xff0c;如蜜蜂、鱼和鸟类&#xff0c;这导致这些集体不稳定&#xff0c;容易受到…

Linux网络编程 -- 网络基础

本文主要介绍网络的一些基础概念&#xff0c;不涉及具体的操作原理&#xff0c;旨在构建对网络的基础认识。 1、网络的早期发展历程 20世纪50年代 在这一时期&#xff0c;计算机主机非常昂贵&#xff0c;而通信线路和设备相对便宜。为了共享计算机主机资源和进行信息的综合处…

基于图像的3D动物重建与生成

一、背景与目标 3D-Fauna 是一款用于基于图像和视频进行四足动物3D重建与生成的开源方案。自然界展示了复杂的相似性与多样性,该方法通过学习来自网上图片的四足动物的3D形态,能够从单张图片生成可动画化的带有纹理的3D网格模型。其最终目标是通过大量扩展现有的解决方案,实…

数据库(MySQL):使用命令从零开始在Navicat创建一个数据库及其数据表(一).创建基础表

一. 使用工具和命令 1.1 使用的工具 Navicat Premium 17 &#xff1a;“Navicat”是一套可创建多个连接的数据库管理工具。 MySQL版本8.0.39 。 1.2 使用的命令 Navicat中使用的命令 命令命令解释SHOW DATABASES&#xff1b;展示所有的数据库CREATE DATABASE 数据库名称; 创…

基于STM32的数字温度传感器设计与实现

引言 STM32 是由意法半导体&#xff08;STMicroelectronics&#xff09;开发的基于 ARM Cortex-M 内核的微控制器系列&#xff0c;以其强大的处理能力、丰富的外设接口和低功耗著称&#xff0c;广泛应用于嵌入式系统设计中。在这篇文章中&#xff0c;我们将介绍如何基于 STM32…

深度学习:基于MindSpore实现ResNet50中药分拣

ResNet基本介绍 ResNet&#xff08;Residual Network&#xff09;是一种深度神经网络架构&#xff0c;由微软研究院的Kaiming He等人在2015年提出&#xff0c;并且在ILSVRC 2015竞赛中取得了很好的成绩。ResNet主要解决了随着网络深度增加而出现的退化问题&#xff0c;即当网络…

数据结构与算法——动态规划算法简析

1.初步了解动态规划 由于本篇博客属于动态规划的初阶学习&#xff0c;所以大多都是简单的表示&#xff0c;更深层次的学术用语会在之后深度学习动态规划之后出现&#xff0c;本文主要是带各位了解一下动态规划的大致框架 1.1状态表示 通常的我们会开辟一个dp数组来存储需要表示…

015 品牌关联分类

文章目录 后端CategoryBrandEntity.javaCategoryBrandController.javaCategoryBrandServiceImpl.javaCategoryServiceImpl.javaBrandServiceImpl.java删除 npm install pubsub-jsnpm install --save pubsub-js这个错误是由于在尝试安装 pubsub-js 时&#xff0c;npm 发现了项目…

数据结构(栈和队列的实现)

1. 栈&#xff08;Stack&#xff09; 1.1 栈的概念与结构 栈是一种特殊的线性表&#xff0c;其只允许固定的一段插入和删除操作&#xff1b;进行数据插入和删除的一段叫做栈顶&#xff0c;另一端叫栈底&#xff1b;栈中的元素符合后进先出LIFO&#xff08;Last In First Out&…

C++——模拟实现vector

1.查看vector的源代码 2.模拟实现迭代器 #pragma oncenamespace jxy {//模板尽量不要分离编译template <class T>class vector{public:typedef T* iterator;//typedef会受到访问限定符的限制typedef const T* const_iterator;//const迭代器是指向的对象不能修改&#xf…

透明物体的投射和接收阴影

1、让透明度测试Shader投射阴影 &#xff08;1&#xff09;同样我们使用FallBack的形式投射阴影&#xff0c;但是需要注意的是&#xff0c;FallBack的内容为&#xff1a;Transparent / Cutout / VertexLit&#xff0c;该默认Shader中会把裁剪后的物体深度信息写入到 阴影映射纹…

毕业设计_基于springboot+ssm+bootstrap的旅游管理系统【源码+SQL+教程+可运行】【41001】.zip

毕业设计_基于springbootssmbootstrap的旅游管理系统【源码SQL教程可运行】【41001】.zip 下载地址&#xff1a; https://download.csdn.net/download/qq_24428851/89828190 管理系统 url: http://localhost:8080/managerLoginPageuser: admin password: 123 用户门户网站…

【设计模式-解释模式】

定义 解释器模式是一种行为设计模式&#xff0c;用于定义一种语言的文法&#xff0c;并提供一个解释器来处理该语言的句子。它通过为每个语法规则定义一个类&#xff0c;使得可以将复杂的表达式逐步解析和求值。这种模式适用于需要解析和执行语法规则的场景。 UML图 组成角色…

SPDK从安装到运行hello_world示例程序

SPDK从安装到运行示例程序 #mermaid-svg-dwdwvhrJiTcgTkVf {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-dwdwvhrJiTcgTkVf .error-icon{fill:#552222;}#mermaid-svg-dwdwvhrJiTcgTkVf .error-text{fill:#552222;s…

android compose ScrollableTabRow indicator 指示器设置宽度

.requiredWidth(30.dp) Box(modifier Modifier.background(Color.LightGray).fillMaxWidth()) {ScrollableTabRow(selectedTabIndex selectedTabIndex, // 默认选中第一个标签containerColor ColorPageBg,edgePadding 1.dp, // 内容与边缘的距离indicator { tabPositions…

【本地缓存】Java 中的 4 种本地缓存

目录 1、手写一个简单的本地缓存1.1、封装缓存实体类1.2、创建缓存工具类1.3、测试 2、Guava Cache2.1、Guava Cache 简介2.2、入门案例2.2.1、引入 POM 依赖2.2.2、创建 LoadingCache 缓存 2.3、Guava Cache 的优劣势和适用场景 3、Caffeine3.1、Caffeine 简介3.2、对比 Guava…