SpringCloud 微服务全栈体系(二)

第三章 Eureka 注册中心

  • 假如我们的服务提供者 user-service 部署了多个实例,如图:

在这里插入图片描述

  • 思考几个问题:

    • order-service 在发起远程调用的时候,该如何得知 user-service 实例的 ip 地址和端口?
    • 有多个 user-service 实例地址,order-service 调用时该如何选择?
    • order-service 如何得知某个 user-service 实例是否依然健康,是不是已经宕机?

一、Eureka 的结构和作用

  • 这些问题都需要利用 SpringCloud 中的注册中心来解决,其中最广为人知的注册中心就是 Eureka,其结构如下:

在这里插入图片描述

  • 回答之前的各个问题:

  • 问题 1:order-service 如何得知 user-service 实例地址?

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

      • user-service 服务实例启动后,将自己的信息注册到 eureka-server(Eureka 服务端)。这个叫服务注册
      • eureka-server 保存服务名称到服务实例地址列表的映射关系
      • order-service 根据服务名称,拉取实例地址列表。这个叫服务发现或服务拉取
  • 问题 2:order-service 如何从多个 user-service 实例中选择具体的实例?

    • order-service 从实例列表中利用负载均衡算法选中一个实例地址
    • 向该实例地址发起远程调用
  • 问题 3:order-service 如何得知某个 user-service 实例是否依然健康,是不是已经宕机?

    • user-service 会每隔一段时间(默认 30 秒)向 eureka-server 发起请求,报告自己状态,称为心跳
    • 当超过一定时间没有发送心跳时,eureka-server 会认为微服务实例故障,将该实例从服务列表中剔除
    • order-service 拉取服务时,就能将故障实例排除了

注意:一个微服务,既可以是服务提供者,又可以是服务消费者,因此 eureka 将服务注册、服务发现等功能统一封装到了 eureka-client 端

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

在这里插入图片描述

二、搭建 eureka-server

  • 首先注册中心服务端:eureka-server,这必须是一个独立的微服务

1. 创建 eureka-server 服务

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

在这里插入图片描述

  • 填写模块信息:

在这里插入图片描述

  • 然后填写服务信息:

在这里插入图片描述

2. 引入 eureka 依赖

  • 引入 SpringCloud 为 eureka 提供的 starter 依赖:
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

3. 编写启动类

  • 给 eureka-server 服务编写一个启动类,一定要添加一个@EnableEurekaServer 注解,开启 eureka 的注册中心功能:
package com.alex.eureka;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {public static void main(String[] args) {SpringApplication.run(EurekaApplication.class, args);}
}

4. 编写配置文件

  • 编写一个 application.yml 文件,内容如下:
server:port: 10086
spring:application:name: eureka-server
eureka:client:service-url:defaultZone: http://127.0.0.1:10086/eureka

5. 启动服务

  • 启动微服务,然后在浏览器访问:http://127.0.0.1:10086

  • 看到下面结果应该是成功了:

在这里插入图片描述

三、服务注册

  • 下面,我们将 user-service 注册到 eureka-server 中去。

1. 引入依赖

  • 在 user-service 的 pom 文件中,引入下面的 eureka-client 依赖:
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

2. 配置文件

  • 在 user-service 中,修改 application.yml 文件,添加服务名称、eureka 地址:
spring:application:name: userservice
eureka:client:service-url:defaultZone: http://127.0.0.1:10086/eureka

3. 启动多个 user-service 实例

  • 为了演示一个服务有多个实例的场景,我们添加一个 SpringBoot 的启动配置,再启动一个 user-service。

  • 首先,复制原来的 user-service 启动配置:

在这里插入图片描述

  • 然后,在弹出的窗口中,填写信息:

在这里插入图片描述

  • 现在,SpringBoot 窗口会出现两个 user-service 启动配置:

在这里插入图片描述

  • 不过,第一个是 8081 端口,第二个是 8082 端口。

  • 启动两个 user-service 实例:

在这里插入图片描述

  • 查看 eureka-server 管理页面:

在这里插入图片描述

四、服务发现

  • 下面,我们将 order-service 的逻辑修改:向 eureka-server 拉取 user-service 的信息,实现服务发现。

1. 引入依赖

  • 之前说过,服务发现、服务注册统一都封装在 eureka-client 依赖,因此这一步与服务注册时一致。

  • 在 order-service 的 pom 文件中,引入下面的 eureka-client 依赖:

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

2. 配置文件

  • 服务发现也需要知道 eureka 地址,因此第二步与服务注册一致,都是配置 eureka 信息:

  • 在 order-service 中,修改 application.yml 文件,添加服务名称、eureka 地址:

spring:application:name: orderservice
eureka:client:service-url:defaultZone: http://127.0.0.1:10086/eureka

3. 服务拉取和负载均衡

  • 最后,我们要去 eureka-server 中拉取 user-service 服务的实例列表,并且实现负载均衡。

  • 不过这些动作不用我们去做,只需要添加一些注解即可。

  • 在 order-service 的 OrderApplication 中,给 RestTemplate 这个 Bean 添加一个@LoadBalanced 注解:

在这里插入图片描述

  • 修改 order-service 服务中的 com.alex.order.service 包下的 OrderService 类中的 queryOrderById 方法。修改访问的 url 路径,用服务名代替 ip、端口:

在这里插入图片描述

  • spring 会自动帮助我们从 eureka-server 端,根据 userservice 这个服务名称,获取实例列表,而后完成负载均衡。

第四章 Ribbon 负载均衡

  • 上一章中,我们添加了@LoadBalanced 注解,即可实现负载均衡功能,这是什么原理呢?

一、负载均衡原理

  • SpringCloud 底层其实是利用了一个名为 Ribbon 的组件,来实现负载均衡功能的。

在这里插入图片描述

  • 那么我们发出的请求明明是 http://userservice/user/1,怎么变成了 http://localhost:8081 的呢?

二、源码跟踪

  • 为什么我们只输入了 service 名称就可以访问了呢?之前还要获取 ip 和端口。

  • 显然有人帮我们根据 service 名称,获取到了服务实例的 ip 和端口。它就是LoadBalancerInterceptor,这个类会在对 RestTemplate 的请求进行拦截,然后从 Eureka 根据服务 id 获取服务列表,随后利用负载均衡算法得到真实的服务地址信息,替换服务 id。

  • 我们进行源码跟踪:

1. LoadBalancerInterceptor

在这里插入图片描述

  • 可以看到这里的 intercept 方法,拦截了用户的 HttpRequest 请求,然后做了几件事:

    • request.getURI():获取请求 uri,本例中就是 http://user-service/user/8
    • originalUri.getHost():获取 uri 路径的主机名,其实就是服务 id,user-service
    • this.loadBalancer.execute():处理服务 id,和用户请求。
  • 这里的this.loadBalancerLoadBalancerClient类型,我们继续跟入。

2. LoadBalancerClient

  • 继续跟入 execute 方法:

在这里插入图片描述

  • 代码是这样的:

    • getLoadBalancer(serviceId):根据服务 id 获取 ILoadBalancer,而 ILoadBalancer 会拿着服务 id 去 eureka 中获取服务列表并保存起来。
    • getServer(loadBalancer):利用内置的负载均衡算法,从服务列表中选择一个。本例中,可以看到获取了 8082 端口的服务
  • 放行后,再次访问并跟踪,发现获取的是 8081:

在这里插入图片描述

  • 果然实现了负载均衡。

3. 负载均衡策略 IRule

  • 在刚才的代码中,可以看到获取服务使通过一个getServer方法来做负载均衡:

在这里插入图片描述

  • 我们继续跟入:

在这里插入图片描述

  • 继续跟踪源码 chooseServer 方法,发现这么一段代码:

在这里插入图片描述

  • 我们看看这个 rule 是谁:

在这里插入图片描述

  • 这里的 rule 默认值是一个RoundRobinRule,看类的介绍:

在这里插入图片描述

  • 这不就是轮询的意思嘛。

  • 到这里,整个负载均衡的流程我们就清楚了。

4. 总结

  • SpringCloudRibbon 的底层采用了一个拦截器,拦截了 RestTemplate 发出的请求,对地址做了修改。用一幅图来总结一下:

在这里插入图片描述

  • 基本流程如下:

    • 拦截我们的 RestTemplate 请求 http://userservice/user/1
    • RibbonLoadBalancerClient 会从请求 url 中获取服务名称,也就是 user-service
    • DynamicServerListLoadBalancer 根据 user-service 到 eureka 拉取服务列表
    • eureka 返回列表,localhost:8081、localhost:8082
    • IRule 利用内置负载均衡规则,从列表中选择一个,例如 localhost:8081
    • RibbonLoadBalancerClient 修改请求地址,用 localhost:8081 替代 userservice,得到 http://localhost:8081/user/1,发起真实请求

三、负载均衡策略

1. 负载均衡策略

  • 负载均衡的规则都定义在 IRule 接口中,而 IRule 有很多不同的实现类:

在这里插入图片描述

  • 不同规则的含义如下:
内置负载均衡规则类规则描述
RoundRobinRule简单轮询服务列表来选择服务器。它是 Ribbon 默认的负载均衡规则。
AvailabilityFilteringRule对以下两种服务器进行忽略: (1)在默认情况下,这台服务器如果 3 次连接失败,这台服务器就会被设置为“短路”状态。短路状态将持续 30 秒,如果再次连接失败,短路的持续时间就会几何级地增加。 (2)并发数过高的服务器。如果一个服务器的并发连接数过高,配置了 AvailabilityFilteringRule 规则的客户端也会将其忽略。并发连接数的上限,可以由客户端的..ActiveConnectionsLimit 属性进行配置。
WeightedResponseTimeRule为每一个服务器赋予一个权重值。服务器响应时间越长,这个服务器的权重就越小。这个规则会随机选择服务器,这个权重值会影响服务器的选择。
ZoneAvoidanceRule以区域可用的服务器为基础进行服务器的选择。使用 Zone 对服务器进行分类,这个 Zone 可以理解为一个机房、一个机架等。而后再对 Zone 内的多个服务做轮询。
BestAvailableRule忽略那些短路的服务器,并选择并发数较低的服务器。
RandomRule随机选择一个可用的服务器。
RetryRule重试机制的选择逻辑
  • 默认的实现就是 ZoneAvoidanceRule,是一种轮询方案

2. 自定义负载均衡策略

  • 通过定义 IRule 实现可以修改负载均衡规则,有两种方式:
2.1 代码方式
  • 在 order-service 中的 OrderApplication 类中,定义一个新的 IRule:
@Bean
public IRule randomRule(){return new RandomRule();
}
2.2 配置文件方式
  • 在 order-service 的 application.yml 文件中,添加新的配置也可以修改规则:
userservice: # 给某个微服务配置负载均衡规则,这里是userservice服务ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则

注意,一般用默认的负载均衡规则,不做修改。

四、饥饿加载

  • Ribbon 默认是采用懒加载,即第一次访问时才会去创建 LoadBalanceClient,请求时间会很长。

  • 而饥饿加载则会在项目启动时创建,降低第一次访问的耗时,通过下面配置开启饥饿加载:

ribbon:eager-load:enabled: trueclients: userservice

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Cloud Studio连接MySQL,Access denied for一系列问题

官方文档有写如何安装Mysql $ apt update $ apt install mysql-server mysql-client -y$ service mysql start mysql -uroot -p123456进入MySQL命令行 问题出在连接数据库这一步&#xff0c;命令行能进去&#xff0c;但是数据库插件和代码都连不上 Access denied for 大概率…

mybatisplus开启sql打印的三种方式

1、在application.yml文件中添加mybatisplus的配置文件 使用mybatisplus自带的log-impl配置&#xff0c;可以在控制台打印出sql语句、执行结果的数据集、数据结果条数等详细信息&#xff0c;这种方法适合再调试的时候使用&#xff0c;因为这个展示的信息详细&#xff0c;更便于…

攻防世界web篇-cookie

看到cookie立马就会想到F12键看cookie的一些信息 我这个实在存储里面看的&#xff0c;是以.php点缀结尾&#xff0c;可以试一下在链接中加上.php 得到的结果是这样 这里&#xff0c;我就只能上csdn搜索一下了&#xff0c;看到别人写的是在get请求中可以看到flag值

如何使用VSCode将iPad Pro转化为功能强大的开发工具?

文章目录 前言1. 本地环境配置2. 内网穿透2.1 安装cpolar内网穿透(支持一键自动安装脚本)2.2 创建HTTP隧道 3. 测试远程访问4. 配置固定二级子域名4.1 保留二级子域名4.2 配置二级子域名 5. 测试使用固定二级子域名远程访问6. iPad通过软件远程vscode6.1 创建TCP隧道 7. ipad远…

网络协议--ARP:地址解析协议

4.1 引言 本章我们要讨论的问题是只对TCP/IP协议簇有意义的IP地址。数据链路如以太网或令牌环网都有自己的寻址机制&#xff08;常常为48 bit地址&#xff09;&#xff0c;这是使用数据链路的任何网络层都必须遵从的。一个网络如以太网可以同时被不同的网络层使用。例如&#…

短视频矩阵系统源码(搭建)

短视频矩阵源码的开发路径分享如下&#xff1a; 1、首先&#xff0c;确定项目需求和功能&#xff0c;包括用户上传、编辑、播放等。 2、其次&#xff0c;搭建开发环境&#xff0c;选择合适的开发工具和框架。 3、然后&#xff0c;进行项目架构设计和数据库设计&#xff0c;确…

【力扣周赛】第 367 场周赛(⭐二维数组当成一维数组,前后缀分解)

文章目录 竞赛链接Q1&#xff1a;100096. 找出满足差值条件的下标 I竞赛时代码——暴力双循环 Q2&#xff1a;100084. 最短且字典序最小的美丽子字符串竞赛时代码——双指针 Q3&#xff1a;100101. 找出满足差值条件的下标 II竞赛时代码——记录可用最大最小值下标 Q4&#xff…

会议OA小程序【首页布局】

目录 一. Flex布局介绍 1.1 什么是Flex布局 1.2 基本概念 1.3 Flex属性 二. 会议OA首页轮播图的实现 配置 Mock工具 swiper 效果展示 三. 会议OA首页会议信息布局 index.js index.wxml index.wxss 首页整体效果展示 一. Flex布局介绍 布局的传统解决方案&#x…

怎样正确做 Web 应用的压力测试?

Web应用&#xff0c;通俗来讲就是一个网站&#xff0c;主要依托于浏览器来访问其功能。 那怎么正确做网站的压力测试呢&#xff1f; 提到压力测试&#xff0c;我们想到的是服务端压力测试&#xff0c;其实这是片面的&#xff0c;完整的压力测试包含服务端压力测试和前端压力测…

059:mapboxGL监听键盘事件,通过eastTo控制左右旋转

第059个 点击查看专栏目录 本示例是介绍演示如何在vue+mapbox中监听键盘事件,通过eastTo控制左右旋转。 本例通过easeTo方法来加减一定数值的bearing角度,通过.addEventListener的方法来监听键盘的按键动作。这里一定要设置interactive: false, 否则展现不出来旋转效果。 直…

成功解决ModuleNotFoundError: No module named ‘docx.text.hyperlink‘

成功解决ModuleNotFoundError: No module named docx.text.hyperlink 目录 解决问题 解决思路 解决方法 解决问题 ModuleNotFoundError: No module named ‘docx.text.hyperlink‘ 解决思路 No module named docx.text.hyperlink"。这个错误通常表示你的代码中缺少了…

互联网Java工程师面试题·Java 总结篇·第十一弹

目录 90、简述一下你了解的设计模式。 91、用 Java 写一个单例类。 92、什么是 UML&#xff1f; 93、UML 中有哪些常用的图&#xff1f; 94、用 Java 写一个冒泡排序。 95、用 Java 写一个折半查找。 90、简述一下你了解的设计模式。 所谓设计模式&#xff0c;就是一套被…

AIO开放接口平台免费畅享ChatGPT聊天、联网互动、学术等服务!更有DALL·E 3最强AI绘图功能!

免费畅享&#xff01; AIO平台ChatGPT联网、聊天、学术等服务&#xff01; AIO开放接口平台 | 服务介绍 ALL IN ONE &#xff08;AIO&#xff09;API服务是LLM(大语言模型)开放接口平台&#xff1a;持续接入各种主流的大模型接口&#xff0c;并提供简单、易用、统一的API交互…

<蓝桥杯软件赛>零基础备赛20周--第1周

报名明年年4月蓝桥杯软件赛的同学们&#xff0c;如果你是大一零基础&#xff0c;目前懵懂中&#xff0c;不知该怎么办&#xff0c;可以看看本博客系列。 每个周末发1个博客&#xff0c;共20周&#xff0c;到明年3月初结束。跟上本博客的节奏&#xff0c;省赛三等奖跑不掉。 每周…

自然语言处理基础——词表示

词表示 把自然语言中最基本的语言单元——词转换为机器能够理解的 词表示能完成以下两个能力 词相似度计算 词与词之间语义的关系 近义词&上位词 使用近义词或上位词表示的问题 遗漏差异 遗漏新的释义 带有主观性 数据吸收 需要大量人工构建 One-Hot Representation …

spark获取hadoop服务token

spark 作业一直卡在accepted 问题现象问题排查1.查看yarn app日志2.问题分析与原因 问题现象 通过yarn-cluster模式提交spark作业&#xff0c;客户端日志一直卡在submit app&#xff0c;没有运行 问题排查 1.查看yarn app日志 appid已生成&#xff0c;通过yarn查看app状态为…

evilhiding:一款好用的shellcode免杀工具

文章目录 evilhiding工具浅析项目地址用法免杀测试声明 evilhiding shellcode loader,bypassav,免杀工具&#xff0c;一款基于python的shellcode免杀加载器 工具浅析 远控条件触发防沙箱花指令干扰loader和shellcode进行fernet加密触发器混淆干扰特征码自动刷新ico图片的md5…

王道计算机考研 操作系统学习笔记 + 完整思维导图篇章三: 内存管理

目录 内存管理概念 内存的基础知识 什么是内存&#xff1f;有何作用&#xff1f; 补充知识:几个常用的数量单位 指令的工作原理 三种装入方式 绝对装入 可重定位装入 动态重定位 从写程序到程序运行 链接的三种方式 总结 内存管理的概念 内存保护 内存空间的扩充 覆盖技…

基于SSM的教务管理系统运行教程

文章目录 1、前期必备1.1、所需软件版本说明1.2、下载源码1.3、下载开发工具1.4、下载JDK并配置环境变量1.5、安装数据库和数据库管理工具1.6、安装配置Maven 2、将SQL文件导入到数据库2.1、新建MySQL连接2.2、新建数据库并导入SQL 3、用Eclipse运行程序3.1、导入educationalMa…

极值点偏移2

已知 f ( x ) ln ⁡ x x f\left(x\right) \frac{\ln x}{x} f(x)xlnx​&#xff0c;若 f ( x ) a f\left(x\right) a f(x)a有两个不用的零点 x 1 , x 2 x_1, x_2 x1​,x2​&#xff0c;且 x 1 < x 2 x_1<x_2 x1​<x2​&#xff0c;求证&#xff1a; &#xff08;1…