Spring Cloud

1. 服务拆分和远程调用

  • 任何分布式架构都离不开服务的拆分,微服务也一样。
  • 服务拆分:一个单体架构按照功能模块进行拆分,变成多个服务。

微服务需要根据业务模块拆分,做到单一职责,不要重复开发相同业务。 

1.1 服务拆分原则 或 服务拆分注意事项:

  1. 不同的微服务,要做到单一职责(微服务拆分的目的就是单一职责),不要重复开发相同业务
  2. 微服务要做到数据独立,不同微服务都应该有自己独立的数据库,每个微服务都会有自己的数据库,不要访问其它微服务的数据库,做到了数据解耦。
  3. 微服务要对外暴露RESTful的业务接口,供其它微服务调用

1.2 实现微服务远程调用案例:

  • 需求:根据订单ID查询订单的同时,把订单所属的用户信息一起返回。

  • 要想实现跨服务远程调用,其实就是发送一次HTTP的请求~! 

1.3 服务间远程调用方式分析

微服务的调用方式: 

  • 基于RestTemplate发起的HTTP请求实现远程调用!
  • HTTP请求做远程调用是与语言无关的调用,只要知道对方的IP、端口、请求路径、请求参数即可!
转变为,如何在Java代码当中发送HTTP请求?
  • 利用Spring提供的RestTemplate来发送HTTP请求! 

因此,我们只能在order-service向user-service发起一个远程调用,发起一个HTTP的请求,调用根据ID查询用户的这个接口,远程调用的大概的步骤是这样的:

  1. 在需要发送远程调用模块的启动类当中注册一个RestyTemplate的实例到Spring容器
  2. 修改业务代码(在业务代码当中注入RestTemplate ),使用RestTemplate提供的API来发起HTTP请求:修改order-service服务中的OrderService类中的queryOrderById方法,根据Order对象中的userId查询User
  3. 将查询的User填充到Order对象,一起返回

1. 我们知道,Bean的注入只能放在配置类里面,而启动类就是一个配置类:

 

2.  在业务代码当中注入RestTemplate,使用RestTemplate提供的API来发起HTTP请求

1.4 提供者与消费者

在服务调用关系中,会有两个不同的角色:
  • 服务提供者:一次业务中,被其它微服务调用的服务(提供或暴露接口给其它微服务调用)
  • 服务消费者:一次业务中调用其它微服务的服务(调用其它微服务提供的接口) 
  • 服务提供者与服务消费者的角色是相对的,相对于具体的业务,业务不同,角色是会变化的!
服务消费者  调用  服务提供者
注意:
  • 服务提供者与服务消费者的角色并不是绝对的,而是相对于业务而言,一个服务既可以是提供者,也可以是消费者! 
  • 技术要跟业务相关联!
思考:服务A调用服务B,服务B调用服务C,那么服务B是什么角色?
  • 对于服务A调用服务B的业务而言,A是服务消费者,B是服务提供者
  • 对于服务B调用服务C的业务而言,B是服务消费者,C是服务提供者

因此,服务B既可以是服务提供者,也可以是服务消费者! 

总结:一个服务既可以是服务提供者,又可以是服务消费者! 

2. Eureka注册中心

2.1  远程调用的问题

回顾:
  • 订单服务(服务消费者需要远程调用我们的用户服务(服务提供者),之前定义的的URL路径中的IP、端口、请求路径等都是硬编码,写死的,不够灵活。
假如我们的服务提供者部署了多个实例,如图:
思考:
  1. 服务消费者在发起远程调用的时候,该如何得知服务提供者实例的IP地址和端口?
  2. 有多个服务提供者实例地址,服务消费者调用时该如何选择?
  3. 服务消费者如何得知服务提供者的健康状态?服务消费者如何得知某个服务提供者实例是否依然健康,是不是已经宕机? 

这些问题都需要利用Spring Cloud中的注册中心来解决其中最广为人知的注册中心就是Eureka。

2.2 Eureka注册中心原理 - Eureka的结构和作用

Eureka的结构如下:

服务注册与发现模型
在Eureka的结构或架构当中,有两类角色(微服务角色有两类): 
  1. 角色一:Eureka-Server注册中心(Eureka服务端):记录和管理这些微服务(记录服务信息、心跳监控)!
  2. 角色二:服务提供者和服务消费者,不管是服务提供者还是服务消费者,都是微服务,所以统称为Eureka的客户端 - Eureka Client端。

在Spring Cloud的生态中,采用服务注册与发现模型,来实现微服务之间的互相发现发现与调用: 

服务注册与发现模型

如上图所示,通过在微服务系统中引入一个叫注册中心的组件,来作为协调者。

其最简化的过程是,所有的微服务应用在启动过程中会将自身包含服务名称、主机IP地址和端口号等信息发送到注册中心中,这个叫服务注册,然后上游的微服务(服务消费者)在处理请求过程中,根据服务名称到注册中心中查找对应服务的所有实例IP地址和端口号(服务发现或服务拉取)来进行服务调用,从而让分散的微服务系统之间能像一个整体一样对外提供请求处理能力。 

回答之前的三个问题:

问题一:服务消费者在发起远程调用的时候,如何得知服务提供者实例的IP地址? 

获取地址信息的流程如下:

  • 所有的微服务应用的实例在启动过程中会将自身包含服务名称、主机IP地址和端口号等信息发送或注册到Eureka-Server注册中心(Eureka服务端)中,这个叫服务注册
  • Eureka-Server注册中心(Eureka服务端)保存服务名称到服务实例地址列表的映射关系;
  • 服务消费者根据服务名称,拉取服务列表,拉取对应服务的所有实例IP地址和端口号列表,这个叫服务发现或服务拉取。
问题二:服务消费者如何从多个服务提供者实例中选择具体的实例?
  • 服务消费者从实例列表中利用负载均衡算法选中一个实例地址(选中一个微服务),接着向该实例地址(微服务)发起远程调用! 
问题三:服务消费者如何得知某个服务提供者实例是否依然健康,是不是已经宕机?

心跳监控

  • 服务提供者(所有的微服务应用)会每隔一段时间(默认30秒)向Eureka-Server注册中心(Eureka服务端)发起或发送一次心跳请求,确认自己的健康状态,称为心跳;
  • Eureka会更新服务记录列表信息:当超过一定时间没有发送心跳时,Eureka-Server注册中心(Eureka服务端)会认为该微服务实例故障,会将该实例从服务列表中剔除(心跳不正常的会被剔除);
  • 这样,服务消费者在拉取服务时,就能将故障实例排除了。
注意:
  • 一个微服务,既可以是服务提供者,又可以是服务发现者,因此Eureka将服务注册、服务发现等功能统一封装到了Eureka-Client(Eureka客户端)!

因此,接下来我们动手实践的步骤包括: 

2.3 搭建EurekaServer

Eureka-Server - 注册中心服务端的搭建,必须创建一个独立的微服务! 

在cloud-demo父工程下,创建一个子模块:

填写模块信息:  

然后填写服务信息:

搭建Eureka - Server服务的步骤如下:

1. 创建项目,引入eureka-server依赖,引入Spring Cloud为eureka提供的starter依赖:spring-cloud-starter-netflix-eureka-server

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

2. 编写启动类,添加@EnableEurekaServer注解(EurekaServer自动装配的开关)

package cn.itcast.eureka;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

/**
 * 手动编写启动类
 * 给Eureka-Server服务编写一个启动类
 * 注意:一定要添加@EnableEurekaServer注解,开启Eureka的注册中心功能
 */
@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaApplication.class,args);
    }
}

3. 添加application.yml文件,在application.yml中配置eureka地址 或 编写下面的配置:

  • Eureka自己也是一个微服务,所以Eureka在启动的时候会将自己也注册到Eureka注册中心中,这是为了将来Eureka集群之间通信去用的。
  • 是为了做服务的注册采取配置的Eureka的服务名称以及Eureka的地址信息!
注意等级关系,否则配置会失效!!!
server:
  port: 10086  #服务的端口,随便给定一个端口号
spring:
  application:
    name: eureka-server #服务的名称(Eureka的服务名称)
eureka:
  client:
    service-url:  #Eureka的地址信息(如果是集群,则地址之间用逗号隔开,现在是单机)
      defaultZone: http://127.0.0.1:10086/eureka
启动服务:
  • 启动微服务,然后在浏览器访问:http://127.0.0.1:10086 

看到下面Eureka的管理页面就算是成功了:  

  • 实例:一个服务每部署一份儿就是一个实例! 
  • Eureka会记录一个服务的所有实例!

2.4 服务注册

下面,我们将服务提供者注册到eureka-server注册中心中去,服务注册需要经过两个步骤:

1. 在服务提供者的项目中引入eureka-client依赖,引入spring-cloud-starter-netfix-eureka-            client的依赖

<!-- eureka-client(Eureka客户端依赖)-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

2. 在application.yml文件中,添加服务名称以及配置eureka地址,编写下面的配置:

spring
  application:
    name: user-service #服务的名称
  eureka:
    client:
      service-url: #Eureka的地址信息(如果是集群,则地址之间用逗号隔开,现在是单机)
        defaultZone: http://127.0.0.1:10086/eureka

将服务消费者的信息也注册到EurekaServer中去,服务列表验证: 

一个服务启动多个实例的操作

  • 我们可以将一个服务多次启动,模拟多实例部署,但为了避免端口冲突,需要修改端口设置 

首先,复制原来的服务启动配置 - 复制配置:

然后,在弹出的窗口中,填写信息(重新配置一个端口以及修改服务名称):

  • -D代表就是参数了! 

添加成功:

 

查看Erueka-Server的管理页面:

总结:
  • 凡是引Eureka客户端依赖 + 配置Eureka地址就是在做服务的注册! 
  • 无论是服务消费者还是服务提供者,只要引入eureka-client依赖、配置eureka地址后,都可以完成服务注册!

2.5 服务发现 /  服务拉取

  • 服务拉取是基于服务名称获取服务列表,然后在对服务列表做负载均衡。 

下面,我们将服务消费者的逻辑修改:向eureka-server注册中心拉取服务提供者的信息,实现服务发现或服务拉取。 

服务消费者完成服务拉取的步骤: 

1. 在服务消费者的pom文件中,引入eureka-client依赖

  • 之前说过,服务发现或服务拉取、服务注册统一都封装在eureka-client依赖,因此这一步与服务注册时一致。 
<!-- eureka-client(Eureka客户端依赖)-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

2. 配置文件

  • 服务发现或服务拉取也需要知道Eureka地址,因此第二步与服务注册一样,都是配置Eureka信息,在服务消费者的application.yml文件中,添加服务名称以及eureka地址:
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
  application:
    name: order-service #服务的名称
eureka:
  client:
    service-url:  #Eureka的地址信息(如果是集群,则地址之间用逗号隔开,现在是单机)
      defaultZone: http://127.0.0.1:10086/eureka

3. 服务的拉取和负载均衡

  • 去eureka-server注册中心中拉取服务提供者的实例列表,并且实现负载均衡。 

3.1 修改服务消费者的业务代码,修改访问的URL路径,用服务提供者的服务名称代替IP以及端口        从而实现远程调用: 

3.2 在服务消费者项目的启动类中,给RestTemplate这个Bean添加负载均衡注解 -                              @LoadBalanced注解: 

  • LoadBalanced:负载均衡 

重启服务消费者,清空服务提供者实例的控制台日志,看看服务消费者到底访问的是哪一个服务提供者的实例? 

  • 发现发起两次请求,有时候会远程调用同一个服务实例,有时候会两个服务实例都被远程调用! 

Spring会自动帮助我们从eureka-server端,根据服务名称来获取服务实例列表,而后完成负载均衡! 

 

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

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

相关文章

【论文阅读】(CGAN)Conditional Generative Adversarial Nets

论文地址&#xff1a;[1411.1784] Conditional Generative Adversarial Nets (arxiv.org) - 条件生成式对抗网络&#xff1b; 解读&#xff1a; 这篇论文中的Conditional GAN和原生GAN在结构上没有太大差别&#xff0c;时间也是紧随着原生GAN出来的&#xff0c;它的思想应该后…

理解Vue源码,从0开始撸了一个简版Vue

vue 的双向绑定、虚拟dom、diff算法等等面试常见问题你可能在几年前就学过了&#xff0c;其中有些人可能看过Vue的源码&#xff0c;了解过Vue是如何实现数据监听和数据绑定这些技术的。不过让从零开始实现一个 vue&#xff0c;你可以吗? 模板语法其实早就存在&#xff0c;在V…

03-学成在线内容管理模块之课程查询

课程查询 需求分析 教学机构人员点击课程管理按钮进入课程查询界面,在课程列表页面输入查询条件查询课程的信息 当不输入查询条件时默认会全部课程信息,输入查询条件会查询符合条件的课程信息,约束条件是本教学机构查询本机构的课程信息 数据模型(model工程) 课程查询功能…

MAT工具定位分析Java堆内存泄漏问题方法

原创/朱季谦 一、MAT概述与安装 MAT&#xff0c;全称Memory Analysis Tools&#xff0c;是一款分析Java堆内存的工具&#xff0c;可以快速定位到堆内泄漏问题。该工具提供了两种使用方式&#xff0c;一种是插件版&#xff0c;可以安装到Eclipse使用&#xff0c;另一种是独立版…

论文浅尝 | 用于开放式文本生成的事实增强语言模型

笔记整理&#xff1a;李煜&#xff0c;东南大学硕士&#xff0c;研究方向为知识图谱 链接&#xff1a;https://proceedings.neurips.cc/paper_files/paper/2022/hash/df438caa36714f69277daa92d608dd63-Abstract-Conference.html 1. 动机 生成式语言模型&#xff08;例如 GPT-3…

【图论】最小生成树(python和cpp)

文章目录 一、声明二、简介三、代码C代码Python代码 一、声明 本帖持续更新中如有纰漏望指正&#xff01; 二、简介 &#xff08;a&#xff09;点云建立的k近邻图&#xff08;b&#xff09;k近邻图上建立的最小生成树 最小生成树 (Minimum Spanning Tree&#xff0c;简称 M…

使用Tauri开发桌面应用

本文是对视频 Tauri入门教程[1]的学习与记录 Tauri官网[2] 对 node版本有要求 创建项目及目录介绍: 项目的目录结构如下 可以安装推荐的插件 执行npm run tauri build出错,根据 https://github.com/tauri-apps/tauri/issues/7430 执行 yarn add -D tauri-apps/cli && y…

缺陷预测(一)——论文复现

运行CGCN文件 问题一&#xff1a;CNN输入维度的问题出现的问题解决问题原因 问题二&#xff1a;mix时&#xff0c;输入的train_in和train_gen.inputs数据格式不一致出现的问题解决问题 最终结果 问题一&#xff1a;CNN输入维度的问题 出现的问题 数据集改好之后&#xff0c;出…

Python Flask: 构建轻量级、灵活的Web应用

大家好&#xff0c;我是涛哥&#xff0c;今天为大家分享 Python Web开发框架 Flask&#xff0c;文章3400字&#xff0c;阅读大约15分钟&#xff0c;大家enjoy~~ Flask是一个流行的Python Web框架&#xff0c;以其轻量级、灵活和易学的特性受到开发者的喜爱。本文将深入探讨Flas…

微服务简单理解与快速搭建

分布式和微服务 含义 微服务架构 微服务架构风格是一种将一个单一应用程序开发为一组小型服务的方法&#xff0c;每个服务运行在自己的进程中&#xff0c;服务间通信采用轻量级通信机制(通常用HTTP资源API)。这些服务围绕业务能力构建并且可通过全自动部署机制独立部署。这些服…

C语言进阶之指针(2)

✨ 猪巴戒&#xff1a;个人主页✨ 所属专栏&#xff1a;《C语言进阶》 &#x1f388;跟着猪巴戒&#xff0c;一起学习C语言&#x1f388; 目录 前情回顾 1.数组参数&#xff0c;指针参数 1.1一维数组传参 1.2二维数组传参 1.3一级指针传参 1.4二级指针传参 思考&#xf…

算法萌新闯力扣:同构字符串

力扣题&#xff1a;同构字符串 开篇 对于字符串相关的题目&#xff0c;哈希表经常会使用到&#xff0c;这道题更是如此&#xff0c;还用到了两个哈希表。拿下它&#xff0c;你对字符串题目的理解就会更上一层楼。 题目链接:205.同构字符串 题目描述 代码思路 看完题目后&a…

Django实战项目-学习任务系统-任务完成率统计

接着上期代码内容&#xff0c;继续完善优化系统功能。 本次增加任务完成率统计功能&#xff0c;为更好的了解哪些任务完成率高&#xff0c;哪些任务完成率低。 该功能完成后&#xff0c;学习任务系统1.0版本就基本完成了。 1&#xff0c;编辑urls配置文件&#xff1a; ./mysi…

原论文一比一复现 | 更换 RT-DETR 主干网络为 【ResNet-50】【ResNet-101】【ResNet-152】| 对比实验必备

本专栏内容均为博主独家全网首发,未经授权,任何形式的复制、转载、洗稿或传播行为均属违法侵权行为,一经发现将采取法律手段维护合法权益。我们对所有未经授权传播行为保留追究责任的权利。请尊重原创,支持创作者的努力,共同维护网络知识产权。 更深层的神经网络更难训练。…

香港科技大学广州|机器人与自主系统学域博士招生宣讲会—电子科技大学专场!!!(暨全额奖学金政策)

在机器人和自主系统领域实现全球卓越—机器人与自主系统学域 硬核科研实验室&#xff0c;浓厚创新产学研氛围&#xff01; 教授亲临现场&#xff0c;面对面答疑解惑助攻申请&#xff01; 一经录取&#xff0c;享全额奖学金1.5万/月&#xff01; &#x1f559;时间&#xff1a;…

基于谐波参数空间的卷积神经网络自动三维牙齿分割

论文连接&#xff1a;https://www.sciencedirect.com/science/article/abs/pii/S1524070320300151 机构&#xff1a; a英国卡迪夫大学计算机科学与信息学院 b中国科学院大学北京 c中国科学院计算技术研究所北京 d深圳大数据研究院&#xff0c;深圳518172 代码链接&#x…

4路光栅尺磁栅尺编码器解码转换5MHz高速差分信号转Modbus TCP网络模块 YL97-RJ45

特点&#xff1a; ● 光栅尺磁栅尺解码转换成标准Modbus TCP协议 ● 光栅尺5V差分信号直接输入&#xff0c;4倍频计数 ● 模块可以输出5V的电源给光栅尺供电 ● 高速光栅尺磁栅尺计数&#xff0c;频率可达5MHz ● 支持4个光栅尺同时计数&#xff0c;可识别正反转 ● 可网…

Looking for downloadable pre-built shared indexes关闭

这个功能很烦,把他关闭就行了 PyCharm的“Looking for downloadable pre-built shared indexes”是指PyCharm IDE中的一个功能&#xff0c;用于搜索和下载可共享的预构建索引。 这个功能的主要用途是帮助开发人员在开发过程中快速地获取和使用预构建的索引&#xff0c;以提高…

算法笔记-第七章-链表(未完成)

算法笔记-第七章-链表 链表的遍历链表结点的个数链表的头插法!链表删除元素链表反转例题思路一:原地反转思路二:头插法链表去除重复元素(有些复杂了)思路题目一题目二链表的遍历 #include<cstdio> const int N = 100; struct Node {int data, next;//表示的是当前数据和…

基于K7的PXIPXIe数据处理板(Kintex-7 FMC载板)

基于PXI&PXIe总线架构的高性能数据预处理FMC 载板&#xff0c;板卡具有 1 个 FMC&#xff08;HPC&#xff09;接口&#xff0c;1 个 X8 PCIe 和1个PCI主机接口&#xff1b;板卡采用 Xilinx 的高性能 Kintex-7 系列 FPGA 作为实时处理器&#xff0c;实现 FMC 接口数据的采集…