【微服务】1、引入;注册中心;OpenFeign
微服务技术学习引入
- 微服务自2016年起搜索指数持续增长,已成为企业开发大型项目的必备技术,中高级java工程师招聘多要求熟悉微服务相关技术。
- 微服务架构介绍
- 概念:微服务是一种软件架构风格,以专注于单一职责的多个响应项目为基础,组合出复杂大型应用,与单体架构不同,其内部由多个小项目组合而成。
- 单体架构特点:业务功能和模块无论多复杂都写在一个项目中,项目体积随功能增加而增大,但始终是一个项目。
- 微服务架构特点:将单体架构项目按单一职责原则拆分成多个小项目,每个小项目独立开发、运行和部署,组合形成微服务集群。
- 服务拆分问题
- 架构选择问题:开发新项目时需考虑选择单体架构还是微服务架构,若选择微服务架构,需确定何时从单体架构转变以及如何拆分服务、确定服务拆分边界等。
- 拆分后的问题
- 跨服务远程调用:服务拆分后,业务功能在不同项目中,物理上隔绝,存在跨服务调用问题。
- 服务治理:服务间调用关系复杂,需要管理服务的状态和调用关系。
- 服务请求路由:单体项目时前端通过IP端口访问,微服务架构下有多个独立部署的服务,前端需明确访问路径,存在服务请求路由问题。
- 何时拆分单体架构项目
- 创业型项目
- 适合采用单体架构,因其需要快速开发、低成本试错。
- 确定的大型项目
- 如大厂开发网上商城,资金充足、目标明确,一上来就推荐使用微服务架构,可避免从单体架构再拆分的麻烦,后续开发更轻松。
- 创业型项目
- 如何拆分单体项目
- 拆分目标
- 高内聚:拆出的服务职责应单一,包含关联度高且完整度高的业务,即功能升级或迭代时大部分代码在服务内部修改,减少对其他服务影响。
- 低耦合:服务功能相对独立,减少对其他服务依赖,核心业务尽量在内部完成,跨服务合作业务应尽量减少,做到高内聚自然低耦合。
- 拆分方式
- 纵向拆分(垂直拆分):按业务模块拆分,如黑马商城按商品管理、用户管理、订单、支付、购物车等业务模块进行拆分。
- 横向拆分(水平拆分):抽取公共服务模块,避免重复开发,如登录、下单等业务中的风控和短信功能,可分别抽取成风控微服务和短信微服务,供其他业务共享。
- 拆分目标
基于Rest template的服务调用问题
- 调用方式说明:基于Rest template的服务调用需在代码中写死对方服务的IP地址、端口号和资源路径。
- 多实例部署问题:实际部署中,服务可能多实例部署,写代码时无法预知部署数量及地址,导致负载均衡失效,如商品服务多实例部署时,写死的代码可能无法访问到所有实例。
- 服务挂掉问题:服务挂掉后,代码写死地址无法动态切换,影响业务,如商品服务挂掉后,购物车服务因写死地址无法访问商品服务,业务出现问题。
- 新服务启动问题:新服务启动后,代码无法动态获取地址,如运维启动新的商品服务实例,端口变化后,购物车服务无法得知新地址。
注册中心解决服务治理问题
- 服务治理问题:包括服务提供者地址未知、服务状态变更无法感知、多实例负载均衡等。
- 注册中心技术:用于解决上述服务治理问题。
- 解决问题原理:服务提供者启动后向注册中心注册服务信息,服务调用者向注册中心订阅服务,注册中心返回实例列表,服务调用者通过负载均衡算法选择实例进行调用。
注册中心的工作原理
- 服务注册:服务提供者启动后向注册中心注册服务信息,包括服务名称、IP端口、提供的功能等,注册中心形成服务注册表记录这些信息。
- 服务订阅:服务调用者向注册中心订阅所需服务,注册中心返回实例列表。
- 负载均衡:服务调用者从实例列表中通过负载均衡算法选择一个实例进行调用,负载均衡算法包括随机、轮询、加权轮询等。
- 心跳机制与服务状态监控:服务与注册中心形成心跳机制,服务定期向注册中心报告健康状态,注册中心监控服务状态,服务挂掉后,注册中心剔除实例并推送变更给服务调用者;新服务启动后注册信息变更,注册中心推送新信息给服务调用者,使其感知服务状态变更。
负载均衡算法及注册中心的作用
- 负载均衡算法
- 随机算法:从多个实例中随机选择一个。
- 轮询算法:按顺序依次请求各个实例,实现均衡访问。
- 加权轮询或加权随机:根据实例权重分配访问概率,适用于硬件配置不同情况。
- 注册中心作用
- 接收服务注册信息,形成服务注册表。
- 监控服务状态变更,通过心跳机制实现。
- 服务状态变化时,剔除或添加实例信息并推送变更给服务调用者,实现服务治理。
注册中心原理回顾
- 原理回顾:注册中心原理类似家政中心,服务提供者注册服务,服务调用者订阅服务,通过负载均衡选择实例,服务与注册中心心跳维持状态监控,实现服务治理。服务治理涉及服务提供者、消费者、注册中心三个角色,注册中心记录监控服务状态并推送变更。
- 注册中心组件选择
- 介绍多种注册中心组件,如NFLICK公司的Eureka、Spring Cloud Consul、阿里巴巴的NEO等,它们都遵循Spring Cloud标准,使用差别不大。
- 介绍多种注册中心组件,如NFLICK公司的Eureka、Spring Cloud Consul、阿里巴巴的NEO等,它们都遵循Spring Cloud标准,使用差别不大。
OpenFeign
OpenFeign是一个声明式的HTTP客户端,在微服务架构中可简化跨服务调用的代码。以下是其主要内容总结:
OpenFeign引入背景
在微服务架构中,跨服务查询商品时,原始代码复杂,涉及根据服务名称获取服务实例、负载均衡、发送请求、解析结果等多个步骤,而单体架构实现类似查询仅需一行代码。为解决此问题,引入OpenFeign技术。
OpenFeign使用步骤
- 引入依赖
- spring cloud starter OpenFeign:OpenFeign组件依赖。
- spring cloud starter LoadBalancer:用于负载均衡,新版本使用,早期使用ribbon。
- 添加注解
- 在启动类上加@EnableFeignClients注解,开启OpenFeign功能。
- 定义FeignClient接口
- 这是一个接口,用于替代之前复杂代码。
- 接口上加@FeignClient注解并指定服务名称(如item service),OpenFeign会据此从注册中心拉取实例列表。
- 通过定义方法并加注解(如@GetMapping、@RequestParam等Spring MVC注解),标记请求方式、路径、参数等信息,降低学习成本。
- 方法返回值类型用于确定返回值类型,OpenFeign可将JSON结果转为相应Java对象。
- 该接口无需手动实现,OpenFeign会动态代理实现。
示例代码实现
- 在cut service的pom文件引入上述依赖。
- 在启动类添加@EnableFeignClients注解。
- 编写item client接口,如:
@FeignClient("item-service")
public interface ItemClient {@GetMapping("/items")Collection<ItemDTO> queryItemByIds(@RequestParam("ids") List<String> ids);
}
- 在调用处注入item client接口,直接调用接口方法(如itemClient.queryItemByIds())实现远程查询,一行代码搞定。
总结
OpenFeign可简化跨服务调用代码,让微服务之间的远程调用更简单,实现类似单体架构的调用便捷性。
连接池
最佳实践
OpenFeign使用问题及优化方案总结
1. OpenFeign使用问题引入
1.1当前使用方式存在的问题
- 多业务重复编写:在购物车和订单业务(未来拆分)中,都需编写类似查询商品服务的代码,造成代码重复编写,浪费资源。
- 功能变更影响大:商品服务功能变化时,所有编写了相关Feign客户端的微服务都需修改代码。
1.2优化目标
- 避免代码重复编写。
- 避免重复代码修改。
2. 优化方案一
2.1具体操作
- 商品微服务转变:将商品微服务(item service)变为纯pom类型模块。
- 创建子模块:在其下创建三个子模块,分别为item DQ(放实体类)、item p i(放API接口,如商品查询的Feign客户端)、item子模块(写商品服务业务代码)。
- 其他微服务引用:其他微服务(如购物车、订单服务)通过引用这两个模块坐标,实现远程调用商品服务功能。
2.2优点
- 代码编写优化:解决代码重复编写问题,由商品服务开发者维护DT和Feign客户端,更为合理。
- 低耦合:不同微服务间耦合度低,便于团队独立维护。
2.3缺点
- 项目结构复杂:每个微服务拆分成多个模块,会使项目结构变得复杂,如单体项目拆成20个微服务时,模块数量会从20个变为60个。
3. 优化方案二
3.1具体操作
- 创建通用API模块:名称为HMAPI,不属于任何微服务,是与其他模块同级的通用模块。
- 定义包及内容:模块内定义三个包(Client、config、dto),Client包中放整个商城每个微服务要暴露的客户端接口,DTO包放所有需要公共访问的DTO。
- 微服务引用:其他微服务(如购物车、订单服务)直接引用HMAPI模块依赖,即可调用相关功能。
3.2优点
- 代码重复解决:解决代码重复编写问题。
- 通用性强:具备代码通用性,方便统一管理。
3.3缺点
- 耦合度增加:代码耦合度相对较高,不同微服务接口需在同一模块维护。
4. 课堂演示选择及操作(基于方案二)
4.1创建模块
- 创建HM - API
4.2引入依赖
- 引入原购物车服务中有关OpenFeign和load balance依赖。
4.3创建包及拷贝代码
- 创建com.hm.api包及子包client、dt,将购物车服务中的DT和Feign客户端相关代码拷贝至对应包中。
4.4处理购物车服务报错
- 删除购物车服务中原有DT和客户端代码,在pom文件中引入HM - API模块依赖,解决业务报错。
5. 测试及问题解决
5.1测试出错
- 重启购物车服务测试时,出现错误,提示cart service实现类构造函数参数找不到bean。
5.2原因分析
- Feign客户端接口未被扫描到,其bean由动态代理实现,需被扫描包扫描,而购物车服务启动类扫描包与通用模块扫描包不同。
5.3解决方法
5.4测试成功
- 再次重启测试,成功访问接口,证明问题解决。
6. 总结与易错点强调
6.1两种模式总结
- 通用API模块模式:所有微服务对外暴露接口及相关DTO定义在通用模块,其他服务引用即可。
- 微服务拆分模式:在微服务内部创建子模块分别放DTO、Feign接口和实现类,供其他服务引用。
6.2选择建议
- 根据项目结构选择合适模式,如项目为聚合结构,可选择通用API模块模式;若项目结构为每个微服务是独立project,可选择微服务拆分模式。
6.3易错点
- 引用其他模块定义的Feign客户端时,默认扫描包扫不到,需在启动类的Feign开关上指定Feign客户端对应的扫描包,否则无法正确扫描创建对象使用。
OpenFeign日志输出与相关知识总结
-
日志输出问题提出
- 项目开发中日志输出重要,能帮助定位和解决问题。
- 以查询购物车功能为例,其远程调用商品服务时,当前仅看到一条SQL语句日志,未看到OpenFeign远程调用相关日志,不利于调试。
-
OpenFeign日志记录规范
- 默认输出条件:OpenFeign默认仅在thin client所在包的日志级别为debug时输出日志。
- 项目日志级别:项目中已将
com.hm
包定义为debug级别,但OpenFeign仍未输出日志,是因为其自身日志级别默认为NONE
,不记录任何信息。
-
OpenFeign日志级别介绍
- NONE:默认值,不记录任何日志信息。
- BASIC:仅记录请求方法、URL、显示状态码及执行时间等基础信息(即请求行部分信息,不包括请求头和请求体)。
- HEADERS:在BASIC基础上,额外记录请求和响应的头信息。
- FULL:记录请求行、请求头、请求体、响应行、响应头和响应体,涵盖HTTP协议所有相关数据。
-
OpenFeign日志级别配置步骤
- 定义日志级别bean:定义一个类,在类中声明一个类型为
log.level
(OpenFeign提供的日志级别枚举类型)的bean,并设置所需日志级别(如FULL)。此时该bean未生效,因为所在类缺少@Configuration
注解。 - 配置生效方式
- 局部配置:将配置类放到
@FeignClient
注解中,仅对该客户端生效。 - 全局配置:将配置类放到
@EnableFeignClients
注解上,对所有客户端生效。
- 局部配置:将配置类放到
- 通用模块配置示例:在通用模块定义配置类
DefaultFeignConfig
,设置日志级别为FULL,在启动类添加@EnableFeignClients(defaultConfiguration = DefaultFeignConfig.class)
实现全局生效。重启服务后,日志输出内容增多,方便调试,但日常运行不建议开启,因其输出内容多会影响性能。
- 定义日志级别bean:定义一个类,在类中声明一个类型为
-
OpenFeign知识回顾总结
- 远程调用步骤
- 引用OpenFeign和负载均衡器的依赖。
- 基于
@EnableFeignClients
注解开启OpenFeign效果。 - 编写
FeignClient
接口,基于Spring MVC注解定义方法,OpenFeign利用动态代理自动实现。 - 注入客户端进行调用。
- 连接池配置方法:引入依赖并在
yml
文件中打开OpenFeign连接池开关。 - 最佳实践方案
-
-拆分微服务为多个子模块,如在DTO模块放实体类、client模块放Feign接口、base模块放业务代码,其他微服务按需引用DT和client模块。
- 额外创建一个模块专门存放所有微服务的
client dt
,其他微服务引用该模块。课堂中采用在微服务里创建独立模块的方式。
- 额外创建一个模块专门存放所有微服务的
- 输出日志级别配置:定义类并在其中定义日志级别的bean(不加
@Configuration
注解),然后将配置类声明在@FeignClient
或@EnableFeignClients
注解上。
- 远程调用步骤
相关文章:

【微服务】1、引入;注册中心;OpenFeign
微服务技术学习引入 - 微服务自2016年起搜索指数持续增长,已成为企业开发大型项目的必备技术,中高级java工程师招聘多要求熟悉微服务相关技术。微服务架构介绍 概念:微服务是一种软件架构风格,以专注于单一职责的多个响应项目为基…...
01、Docker学习,第一天:简单入门与安装
Docker学习,第一天:简单入门与安装 一、Docker简介 环境配置如此之麻烦,换台机器,重来一次,费事费力。安装的时候,把原始环境一模一样的复制过来。开发人员利用Docker可以消除写作编码时,”在…...
C++STL中iomanip的使用与细节
C标准模板库(STL)中的<iomanip>头文件提供了一组用于格式化输入输出流的函数和操纵符。这些函数和操纵符可以用来控制输出的布局、精度、宽度等。以下是一些常用的<iomanip>函数及其使用方式: setprecision(n):设置浮…...
3.C语言变量的基础概念与使用
目录 1.变量名2.变量声明3.变量赋值4.变量作用域 1.变量名 本篇原文为:C语言变量的基础概念与使用 更多C进阶、rust、python、逆向等等教程,可点击此链接查看:酷程网 变量(variable)可以理解成一块内存区域的名字。…...
Go语言中的逃逸分析:深入浅出
Go语言中的逃逸分析:深入浅出 在Go语言中,逃逸分析(Escape Analysis)是一个非常重要且强大的编译器优化技术。它帮助编译器决定一个变量是在栈上分配还是在堆上分配,从而影响程序的性能和内存管理。本文将深入探讨Go语…...

【FlutterDart】 拖动改变 widget 的窗口尺寸大小GestureDetector~简单实现(10 /100)
上效果 预期的是通过拖动一条边界线改变窗口大小,类似vscode里拖动效果。这个是简单的拖动实现 上代码: import package:flutter/material.dart;class MyDraggableViewDemo extends StatelessWidget {const MyDraggableViewDemo({super.key});override…...

【论文笔记】LongLoRA: Efficient Fine-tuning of Long-Context Large Language Models
🍎个人主页:小嗷犬的个人主页 🍊个人网站:小嗷犬的技术小站 🥭个人信条:为天地立心,为生民立命,为往圣继绝学,为万世开太平。 基本信息 标题: LongLoRA: Efficient Fine…...

数据挖掘——朴素贝叶斯分类
数据挖掘——朴素贝叶斯分类 朴素贝叶斯分类极大后验假设独立性假设贝叶斯分类器总结 朴素贝叶斯分类 什么是分类? 找出描述和区分数据类或概念的模型,以便能够使用模型预测未知的对象的类标号 概念区分 分类与回归 分类是预测分类(离散、…...

unity中的UI系统---GUI
一、工作原理和主要作用 1.GUI是什么? 即即时模式游戏用户交互界面(IMGUI),在unity中一般简称为GUI,它是一个代码驱动的UI系统。 2.GUI的主要作用 2.1作为程序员的调试工具,创建游戏内调测试工具 2.2为…...

鸿蒙Flutter实战:15-Flutter引擎Impeller鸿蒙化、性能优化与未来
Flutter 技术原理 Flutter 是一个主流的跨平台应用开发框架,基于 Dart 语言开发 UI 界面,它将描述界面的 Dart 代码直接编译成机器码,并使用渲染引擎调用 GPU/CPU 渲染。 渲染引擎的优势 使用自己的渲染引擎,这也是 Flutter 与其…...
C语言冒泡排序教程简介
冒泡排序(Bubble Sort)是一种简单的排序算法,因其工作原理像气泡一样逐渐上浮而得名。其基本思想是通过一轮一轮地比较相邻的元素,将较大的元素逐步“冒泡”到数组的尾部。 在本篇博客中,我们将详细讲解冒泡排序的基本…...

Fabric链码部署测试
参考链接:运行 Fabric 应用程序 — Hyperledger Fabric Docs 主文档 (hyperledger-fabric.readthedocs.io) (2)fabric2.4.3部署运行自己的链码 - 知乎 (zhihu.com) Fabric2.0测试网络部署链码 - 辉哥哥~ - 博客园 (cnblogs.com) 1.启动测试…...

k620老显卡,装cuda.等。
CUDA安装教程(超详细)-CSDN博客 1.下载支持12.0以上的驱动 NVIDIA RTX Driver Release 550 R550 U12 (553.50) | Windows 11 解压。安装。一路下一步。查看结果 2.下载 cuda CUDA Toolkit Archive | NVIDIA Developer 安装cuda时,第一次…...

网站常用功能模块-鉴权
一:JWT是什么? 常用鉴权方式有很多种,今天主要介绍基于token的鉴权方式JWT(Json JSON Web Token)。因为这种方式实现起来方便快捷。整体实现逻辑如下 第一次登陆时,前端携带账号和密码请求登录接口。服务…...

直接插入排序、折半插入排序、2路插入排序、希尔排序
本篇是排序专栏博客的第一篇,主要探讨以 “插入” 为核心思想的排序算法该如何实现 文章目录 一、前言二、直接插入排序1. 算法思想与操作分析2. 代码实现version 1version 2 3. 复杂度分析 三、折半插入排序1. 算法思想与操作分析2. 代码实现3. 复杂度分析 四、2路…...
FQ-GAN代码解析
主要看 model 、loss 和 data 部分如何实现和处理的。 model—VQ_modelsVQModelEncoderVectorQuantizerDecoder loss—VQLoss_triple_codebook model—VQ_models 创建vq_model直接根据传入的模型压缩倍率8/16初始化对应的VQ_8/VQ_16,两者都是初始化一个VQModel的类…...

如何恢复已删除的 Telegram 消息 [iOSamp;Android]
Telegram 是一款功能强大的消息应用程序,因其易用性、隐私保护和众多炫酷功能而深受用户喜爱。然而,有时我们会不小心删除重要的消息。在这种情况下你应该做什么? 本文将为您提供简单有效的解决方案来恢复 Telegram 上已删除的消息ÿ…...
asp.net core中的 Cookie 和 Session
在 Web 开发中,用户会话管理是非常重要的,尤其是在需要保持用户状态和身份验证的应用中。ASP.NET Core 提供了多种状态管理技术,如 Cookie 和 Session,它们可以帮助你管理用户会话、存储数据并实现用户身份验证等功能。下面将详细…...
Python实现一个简单的 HTTP echo 服务器
一个用来做测试的简单的 HTTP echo 服务器。 from http.server import HTTPServer, BaseHTTPRequestHandler import jsonclass EchoHandler(BaseHTTPRequestHandler):def do_GET(self):# 构造响应数据response_data {path: self.path,method: GET,headers: dict(self.headers…...
Ruby 中文编码
Ruby 中文编码 在 Ruby 编程语言中处理中文编码是一个常见的需求,尤其是在中国和其他使用中文的地区。Ruby 是一种动态、开放源代码的编程语言,它支持多种字符编码,包括中文编码。本文将探讨在 Ruby 中处理中文编码的几种方法,以…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...

Unity中的transform.up
2025年6月8日,周日下午 在Unity中,transform.up是Transform组件的一个属性,表示游戏对象在世界空间中的“上”方向(Y轴正方向),且会随对象旋转动态变化。以下是关键点解析: 基本定义 transfor…...

Sklearn 机器学习 缺失值处理 获取填充失值的统计值
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 使用 Scikit-learn 处理缺失值并提取填充统计信息的完整指南 在机器学习项目中,数据清…...
面试高频问题
文章目录 🚀 消息队列核心技术揭秘:从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"?性能背后的秘密1.1 顺序写入与零拷贝:性能的双引擎1.2 分区并行:数据的"八车道高速公路"1.3 页缓存与批量处理…...
Python常用模块:time、os、shutil与flask初探
一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...