微服务思想以及实现

文章目录

  • 前言
  • 一、什么时候需要拆分微服务
    • 1. 创业型项目
    • 2. 大型项目
  • 二、怎么拆
    • 1. 拆分目标
    • 2. 拆分方式
  • 三、微服务之间远程调用
    • 1. 实现方式
    • 2. 手动发送Http请求(RestTemplate)
    • 3. 服务注册中心
      • 3.1 原理
      • 3.2 Nacos注册中心
      • 3.3 服务注册
      • 3.4 服务发现(DiscoveryClient)
    • 4. OpenFeign
      • 4.1 实现步骤
      • 4.2 连接池
    • 5. 抽取Fegin客户端
      • 实现方式
    • 6. 日志
      • 6.1 级别
      • 6.2 实现步骤


前言

什么时候去拆分微服务?怎么拆分?拆分后微服务项目之间的业务怎么调用?


一、什么时候需要拆分微服务

1. 创业型项目

如果是创业型公司,最好先用单体架构快速迭代开发,验证市场运作模型,快速试错。当业务跑通以后,随着业务规模扩大、人员规模增加,再考虑拆分微服务。

2. 大型项目

如果是大型企业,有充足的资源,可以在项目开始之初就搭建微服务架构。

二、怎么拆

1. 拆分目标

  • 高内聚:每个微服务的职责要尽量单一,包含的业务相互关联度高、完整度高。
  • 低耦合:每个微服务的功能要相对独立,尽量减少对其它微服务的依赖。

2. 拆分方式

  • 纵向拆分:按照业务模块来拆分
  • 横向拆分:抽取公共服务,提高复用性

三、微服务之间远程调用

1. 实现方式

  • 基于Http协议(不关心服务提供者的具体技术实现,只要对外暴露Http接口即可,更符合微服务的需要)
  • 基于Dubbo协议

2. 手动发送Http请求(RestTemplate)

Java发送http请求可以使用Spring提供的RestTemplate
实现步骤:
1、注入RestTemplate到Spring容器

@Bean
public RestTemplate restTemplate(){return new RestTemplate();
}

2、发起远程调用

// 利用RestTemplate发起http请求,得到http的响应
ResponseEntity<List<ItemDTO>> response = restTemplate.exchange("http://localhost:8081/items?ids={ids}",HttpMethod.GET,null,new ParameterizedTypeReference<List<ItemDTO>>() {},Map.of("ids", CollUtil.join(itemIds, ","))
);

3. 服务注册中心

问题引入:微服务项目a(服务提供者)多实例部署,每个实例其IP或端口不同,当微服务项目b(服务消费者)要远程调用a时不知道调用哪个。

3.1 原理

在这里插入图片描述
三个角色
服务提供者:暴露服务接口,供其它服务调用
服务消费者:调用其它服务提供的接口
注册中心:记录并监控微服务各实例状态,推送服务变更信息
流程

  1. 服务启动时就会注册自己的服务信息(服务名、IP、端口)到注册中心
  2. 调用者可以从注册中心订阅想要的服务,获取服务对应的实例列表(1个服务可能多实例部署)
  3. 调用者自己对实例列表负载均衡,挑选一个实例
  4. 调用者向该实例发起远程调用

服务状态变更
服务提供者通过心跳机制向注册中心报告自己的健康状态,当心跳异常时注册中心会将异常服务剔除,并通知订阅了该服务的消费者

3.2 Nacos注册中心

Alibaba公司出品,目前被集成在SpringCloudAlibaba中
基于Docker来部署Nacos的注册中心
(1)准备nacos.sql数据库表,并导入到sql客户端
(2)再将sql文件导入到Docker中的MySQL容器中

3.3 服务注册

1、引入依赖

  <!--nacos 服务注册发现--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>

2、配置Nacos地址

spring:application:name: item-service # 服务名称cloud:nacos:server-addr: 192.168.xxx.xxx:xxx   # nacos地址

3、启动服务实例
在这里插入图片描述

3.4 服务发现(DiscoveryClient)

服务的消费者要去nacos订阅服务,这个过程就是服务发现。
步骤(步骤1、2和前面一样)
1、引入依赖
2、配置Nacos地址
3、发现并调用服务
DiscoveryClient,SpringCloud已经自动装配,只要注入就好。
在这里插入图片描述

4. OpenFeign

问题引入:利用RestTemplate实现了服务的远程调用,代码复杂。如何让远程调用像本地方法调用一样简单
概念:声明式的http客户端,利用SpringMVC的常见注解,基于动态代理生成远程调用的代码,而无需手动再编写,非常方便。

4.1 实现步骤

1、引入依赖,包括OpenFeign和负载均衡组件SpringCloudLoadBalancer

  <!--openFeign--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!--负载均衡器--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency>

2、在启动类中添加@EnableFeignClients注解,启用OpenFeign功能

@EnableFeignClients(basePackages = "com.hmall.api.client", defaultConfiguration = DefaultFeignConfig.class)
//basePackages = "com.hmall.api.client"因为是把微服务项目业务抽取到hm-api这个模块中,要调用这个模块中的方法,需要扫描到这个包下,并在FeignClient中药声明服务名称
@MapperScan("com.hmall.cart.mapper")
@SpringBootApplication
public class CartApplication {public static void main(String[] args) {SpringApplication.run(CartApplication.class, args);}
}

3、声明接口,无需实现方法,在接口上添加FeignClient注解

@FeignClient("item-service")  //声明服务名称
public interface ItemClient {@GetMapping("/items")  //声明请求方式、请求路径List<ItemDTO> queryItemByIds(@RequestParam("ids") Collection<Long> ids);
}

4、使用FeignClient,实现远程调用

List<ItemDTO> items = itemClient.queryItemByIds(List.of(1,2,3))

4.2 连接池

Feign底层发起http请求,依赖于其它的框架。其底层支持的http客户端实现包括:

  • HttpURLConnection:默认实现,不支持连接池
  • Apache HttpClient :支持连接池
  • OKHttp:支持连接池
    使用OKHttp步骤
    1、引入依赖
<!--OK http 的依赖 -->
<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-okhttp</artifactId>
</dependency>

2、开启连接池

feign:okhttp:enabled: true # 开启OKHttp功能

5. 抽取Fegin客户端

问题引入:微服务项目之间的调用复杂,不同的微服务项目调用同一个微服务项目,会出现代码重复的问题。

实现方式

  • 思路1:抽取到微服务之外的公共module。结构清晰但耦合度偏高
  • 思路2:每个微服务自己抽取一个module。结构复杂但耦合度低
    在这里插入图片描述
    具体代码实现参考黑马微服务开发https://www.bilibili.com/video/BV1S142197x7?p=64&vd_source=d7aecc6c1f43adaae25fcb7e1a25fec2

6. 日志

FeignClient所在包的日志级别为DEBUG时,才会输出日志

6.1 级别

  • NONE:不记录任何日志信息,这是默认值。
  • BASIC:仅记录请求的方法,URL以及响应状态码和执行时间
  • HEADERS:在BASIC的基础上,额外记录了请求和响应的头信息
  • FULL:记录所有请求和响应的明细,包括头信息、请求体、元数据。

6.2 实现步骤

1、在抽取各个微服务通用业务的hm-api模块下新建一个配置类

package com.hmall.api.config;
import feign.Logger;
import org.springframework.context.annotation.Bean;
public class DefaultFeignConfig {@Beanpublic Logger.Level feignLogLevel(){return Logger.Level.FULL;}
}

2、配置,让日志级别生效
局部配置:在某个FeignClient中配置,只对当前FeignClient生效

@FeignClient(value = "item-service", configuration = DefaultFeignConfig.class)

全局配置:在@EnableFeignClients中配置,针对所有FeignClient生效

@EnableFeignClients(defaultConfiguration = DefaultFeignConfig.class)

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

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

相关文章

C语言中的静态库和动态库的制作和使用

什么是库文件 单一模型 将程序中所有功能全部实现于一个单一的源文件内部。 编译时间长&#xff0c;不易于维护和升级&#xff0c;不易于协作开发。 分离模型 将程序中的不同的功能模块划分到不同的源文件中。 缩短编译时间&#xff0c;易于维护和升级&#xff0c;易于协…

java spring 11 推断构造方法 createBeanInstance

1.doCreateBean方法&#xff1a;这一部分 BeanWrapper instanceWrapper null;if (mbd.isSingleton()) {// 有可能在本Bean创建之前&#xff0c;就有其他Bean把当前Bean给创建出来了&#xff08;比如依赖注入过程中&#xff09;instanceWrapper this.factoryBeanInstanceCache…

Open CASCADE 教程 – AIS:自定义呈现

文章目录 开始 (Getting Started)呈现构建器 (Presentation builders)基元数组 (Primitive arrays)基元外观 (Primitive aspects)二次构建器 (Quadric builders)计算选择 (Computing selection)突出显示选择所有者 (Highlighting selection owner)突出显示的方法 (Highlighting…

day10-Set集合

1.Set 那接下来我们来看Collection单列集合体系的第二部分 Set集合。 1.1 Set集合概述和特点 Set集合特点 1.可以去除重复 2.存取顺序不一致 3.没有带索引的方法&#xff0c;所以不能使用普通fori循环遍历&#xff0c;也不能通过索引来获取&#xff0c;删除Set集合里面的元…

【大数据】HDFS、HBase操作教程(含指令和JAVA API)

目录 1.前言 2.HDFS 2.1.指令操作 2.2.JAVA API 3.HBase 3.1.指令操作 3.2.JAVA API 1.前言 本文是作者大数据专栏系列的其中一篇&#xff0c;前文中已经详细聊过分布式文件系统HDFS和分布式数据库HBase了&#xff0c;本文将会是它们的实操讲解。 HDFS相关前文&#x…

Python 潮流周刊#50:我最喜欢的 Python 3.13 新特性!

本周刊由 Python猫 出品&#xff0c;精心筛选国内外的 250 信息源&#xff0c;为你挑选最值得分享的文章、教程、开源项目、软件工具、播客和视频、热门话题等内容。愿景&#xff1a;帮助所有读者精进 Python 技术&#xff0c;并增长职业和副业的收入。 本期分享了 12 篇文章&…

哈希算法在区块链中的应用

哈希算法是区块链技术的核心组件之一&#xff0c;它确保了区块链数据的不可篡改性和安全性。在本文中&#xff0c;我们将探讨哈希算法的基本原理&#xff0c;以及它在区块链中的具体应用。 哈希算法的基本原理 哈希算法是一种数学函数&#xff0c;它接收输入&#xff08;或“消…

【Apache Doris】周FAQ集锦:第 3 期

【Apache Doris】周FAQ集锦&#xff1a;第 3 期 SQL问题数据操作问题运维常见问题其它问题关于社区 欢迎查阅本周的 Apache Doris 社区 FAQ 栏目&#xff01; 在这个栏目中&#xff0c;每周将筛选社区反馈的热门问题和话题&#xff0c;重点回答并进行深入探讨。旨在为广大用户和…

【平台搭建+数据处理+数据可视化】

第一部分:大数据平台搭建 一、Hadoop 1、完全分布式Hadoop集群搭建: (1)在master主节点将/opt目录下的Hadoop安装包hadoop-3.1.4.tar.gz解压到/opt/software目录下。 mkdir -p /opt/software tar -zxf /opt/hadoop-3.1.4.tar.gz -C /opt/software (2)创建Hadoop临时数…

【每日随笔】人性 - 能屈能伸 ( 君子之道 能屈能伸 )

文章目录 一、君子之道 能屈能伸1、含义分析2、能屈3、能伸4、最佳实践 二、能屈能伸 - 应用场景1、个人层面2、国家层面 柳树随风摇曳 , 风再大也不会断 , 能屈能伸 ; 一个人行为处事 , 不能一直强硬 , 也不能一直妥协 , 该妥协的时候就要妥协让步 , 该硬的时候就要用于斗争 …

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-15.5讲 GPIO中断实验-通用中断驱动编写

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

学习Uni-app开发小程序Day8

前面几天&#xff0c;学习了vue的button组件、input组件&#xff0c;vue模版语法、计算属性等&#xff0c;在昨天又根据前面学习的&#xff0c;跟着做了一个小的购物车功能&#xff0c;今天学习了侦听器和计算属性 计算属性 computed computed是一个只读的状态,如果要修改…

Golang | Leetcode Golang题解之第77题组合

题目&#xff1a; 题解&#xff1a; func combine(n int, k int) (ans [][]int) {// 初始化// 将 temp 中 [0, k - 1] 每个位置 i 设置为 i 1&#xff0c;即 [0, k - 1] 存 [1, k]// 末尾加一位 n 1 作为哨兵temp : []int{}for i : 1; i < k; i {temp append(temp, i)}t…

uniapp音乐播放整理

一、前置知识点 1.1 音频组件控制-uni.createInnerAudioContext() 创建并返回内部 audio 上下文 innerAudioContext 对象。 主要用于当前音乐播放&#xff1b; 1.1.1 innerAudioContext属性 属性类型说明只读平台差异说明srcString音频的数据链接&#xff0c;用于直接播放…

深入探索CSS3 appearance 属性:解锁原生控件的定制秘密

CSS3 的 appearance 属性&#xff0c;作为一个强大的工具&#xff0c;让我们得以细致入微地控制元素的外观&#xff0c;特别是对于那些具有平台特定样式的表单元素&#xff0c;如按钮、输入框等。本文不仅会深入解析 appearance 属性的基本工作原理和使用场景&#xff0c;还将通…

TypeScript在前端项目的渐进式采用策略

渐进式采用 TypeScript 在前端项目中的策略通常包括: 引入TypeScript 如果我们有一个简单的JavaScript模块utils.js&#xff0c;它包含一个函数用于计算两数之和&#xff1a; // utils.js export function add(a, b) {return a b; }首先&#xff0c;我们将文件扩展名改为.t…

vue的css深度选择器 deep /deep/

作用及概念 当 <style> 标签有 scoped 属性时&#xff0c;它的 CSS 只作用于当前组件中的元素&#xff0c;父组件的样式将不会渗透到子组件。在vue中是这样描述的&#xff1a; 处于 scoped 样式中的选择器如果想要做更“深度”的选择&#xff0c;也即&#xff1a;影响到子…

vscode+clangd阅读Linux内核源码

1. 禁用或卸载官方C/C插件. 2. 安装clangd插件 3. 清除之前的产物 4. 生成.config文件 5.编译生成内核镜像 6.编译内核模块 7.编译设备树文件 8.生成compile_commands.json文件 运行上述命令后&#xff0c;在内核源码根目录生成了compile_commands.json文件 9.设置clangd插…

Verlog-串口发送-FPGA

Verlog-串口发送-FPGA 引言&#xff1a; ​ 随着电子技术的不断进步&#xff0c;串口通信已成为嵌入式系统和计算机外设中一种广泛使用的异步通信方式。串口通信因其简单性、可靠性以及对硬件资源的低要求&#xff0c;在数据传输领域扮演着重要角色。在FPGA&#xff08;现场可编…

记录一个git无法push的问题

今天准备写新功能&#xff0c;想把之前的代码push到远程仓库&#xff0c;但是git突然就不工作了&#xff0c;报错如下 OpenSSL SSL_connect: Connection was reset in connection to gitee.com:443 因为我昨天把项目目录改了&#xff0c;以为是目录修改的问题&#xff0c;但是…