驾驭云端之风1——Spring Cloud微服务架构实践指南

news2024/11/16 7:55:39
  • 本博客纯属个人总结,非原创。
  • 喜欢技术交流的,可关注博主,武汉有后端开发群,可支持内推,了解武汉行情等。

前沿

优惠卷平台项目的整体功能和模块,以及每个功能点的技术选型和背后的依据。
搭建一个简化版的营销优惠计算系统,实现

  • 优惠卷模版的创建,
  • 用户领取优惠卷,
  • 下单核销优惠卷
  • 订单价格计算等功能。

实现一个领取优惠卷的功能,首先是要创建一个营销规则模版,这个模版就像一个模具一样,通过这个模具来铸造,并最终发放到用户手中。
.
使用模版的好处是可以对优惠卷规则做一层抽象,比如满减类,打折类,这些优惠卷是具体的优惠金额不同,但是玩法类似。我们把相类似的玩法功能抽象成一个模版,就可以简化具体优惠卷的创建和核销流程。

整个项目划分了优惠卷模版服务,计算服务,用户服务,平台类组件

优惠卷模版服务:模版规则是创建优惠卷的前置条件,每种类型的模版都是一个计算公式,这个公式约定了优惠计算的方式,模版服务实现了模版规则的创建,克隆,分页查找等功能,另外还可以在项目中定义满减,随机立减,满折,晚间双倍优惠等多种卷模版类型。

计算服务:根据用户购物车中的商品信息和优惠卷信息,来计算当前订单优惠后的价格,另外,如果用户有多张优惠卷,还提供了”优惠金额试算“,帮助用户挑选最省钱的优惠卷。

用户服务:暴露给外部用户使用的接口,它依赖于模版服务+计算服务,为了完成底层逻辑,主要业务场景是用户领卷,订单价格试算,下单核销,订单金额等功能。

平台类组件:包括一些与业务无关的中心化组件。

从整体来看,模版服务和计算服务是基础服务,用户服务是对用户开放的接口,他依赖于模版服务+计算服务来完成业务逻辑,而平台类组件提供了横向的微服务特性支持,比如微服务网关,链路追踪等功能,整体图如下:
在这里插入图片描述

SpringCloud实战项目全景规划

在这里插入图片描述

  • 第一阶段:搭建基础的微服务功能,实现微服务之间的通信
  • 第二阶段:为各个模块构建服务容错,分布式配置中心,分布式链路追踪能力
  • 第三阶段:进一步实现微服务网关,消息驱动和分布式事务

第一阶段:实现微服务通信

将用户微服务,优惠卷模版服务和订单计算服务拆分为独立部署的业务系统,通过注册中心来实现服务实现和服务发现。让各个微服务可以互相调用,涉及到的技术:nacos注册中心,loadbalance负载均衡组件,openFeign服务间调用。

  • nacos注册中心:是注册中心组件,负责收集所有服务节点的地址信息,并维护服务注册表,所有服务上线后都会向他汇报状态。
  • loadbalance负载均衡:在客户端发送服务调用的时候,他会负责从nacos的注册表中挑选一台目标服务器。
  • openFeign:基于HTTP的远程服务调用,让我们就像本地接口一样方便地发起远程服务调用。

为什么选择nacos+loadbalance作为选型方案。
第一:早期是eureka+ribbon作为服务治理+负载均衡组件,但netfix正退出springcloud的历史舞台,eureka+Ribbon已经进入不维护状态(断更),在考虑技术选型时,选择后劲更大,更新最活跃的nacos和loadbalance组件。

服务治理:服务治理的重点是搭建基础的跨服务调用功能,把用户服务,计算服务,订单服务改造成可以独立启动的微服务,并借助nacos的服务发现功能,通过Webflux组件中的webClient实现基于HTTP的跨服务间的调用。

负载均衡

简化服务调用:使用OpenFeign组件对用户服务进行改造,将原先复杂的WebClient调用替换为简洁的OpenFeign调用。


第二阶段:服务容错,链路追踪,分布式配置

利用服务容错提高微服务架构的可用性,搭建全链路的分布式链路追踪能力,实现统一的配置管理和动态属性推送,涉及的组件:nacos config,Sentinel,Sleuth+Zipkin+Elk。

在微服务架构中,
服务容错:保证高可用的重要手段,推荐使用:Sentinel作为容错组件,可以实现降级,熔断,容量整形等多种服务容错途径。

后期会搭建:Sentinel Dashboard控制台,通过控制台将降级规则和流量整形规则应用到业务埋点中。

链路追踪:推荐使用Sleuth组件,线上异常排查全靠它,使用全局唯一标记将跨微服务调用链上的各个环节全部串联起来,结合Zipkin组件实现调用链的可视化检索,将调用链上各个阶段的请求按顺序显示在页面上,目前业界主流的ELK组合(es + logstash + kibana)作为日志检索系统。

分布式配置”:使用Nacos Config组件,实现配置项的远程获取和动态推送。


第三阶段:统一流量入口,消息驱动,分布式事务

流量入口:采用Gateway,担任路由转发,同时它提供丰富的谓词组合实现复杂的路由判断逻辑,可以在网关层定义拦截器,做特殊处理。

消息驱动:采用Stream

分布式事务:Seata组件,保证微服务环境下的事务一致性,Seata分布式事务解决方案有两种,第一:没有代码侵入的Seata AT方案,第二:补偿性的Seata TCC方案。

项目细节

1:对于境内电商行业来说,金额往往是以分为单位的,这样我们可以直接使用 Long 类型参与金额的计算,比如 100 就代表 100 分,也就是一块钱。这比使用 Double 到处转换 BigDecimal 省了很多事儿。

2:尽可能减少级联配置,用单表查询取而代之,如果一个查询需要 join 好几张表,最好的做法就通过重构业务逻辑来简化 DB 查询的复杂度。

3:在做大型应用架构的时候,我们通常会把计算密集型服务与 IO/ 存储密集型服务分割开来,这样做的一个主要原因是提高资源利用率。

比如有两个:计算密集型的微服务A,IO密集型微服务B,大促流量来时,如果微服务A的压力比较大,我们可以调配高性能CPU和内存去定向扩容A集群,如果微服务B压力吃紧,我们可以定向分配资源给B。
计算型:不吃网络IO和磁盘空间,主要占用CPU,内存等资源。

微服务组件

服务治理

解决的首要任务就是:服务注册+服务发现,通过这两项技术,我们能让服务之间发起面对面的直接调用。

服务A怎么知道服务B中每台机器的地址呢?
我们需要搭建一个中心化的服务注册中心,服务B要将自己的信息添加到注册中心里,服务A就能从注册中心获取到服务B的所有节点。
服务B集群向注册中心发起注册,将自己的信息注册到注册中心,这个过程就是服务注册
每隔一段时间,服务A就会从注册中心中获取服务B集群的服务列表,这个过程叫服务发现
最后服务A根据本地负载均衡策略,从服务列表中选取某一个服务B的节点,发起服务调用
在这里插入图片描述

注册中心是一个中心化的信息管理者,所有的微服务节点在启动后都会将自己的地址信息添加注册到注册中心,在服务注册的过程中,有两个关键信息很重要。

  • 服务名称:服务名称通常默认是spring.application.name属性,在服务注册过程中我们必须将应用服务名上报到注册中心,这样其他服务才能根据服务名找到对应的节点列表。
  • 地址信息:包括服务节点的ip地址和端口。

容错机制

在这里插入图片描述
所有的服务都要在注册中心注册,而且每个节点都需要每隔一段时间向注册中心同步自己当前的状态,简称:心跳。
如果节点持续发送心跳信息,则一切正常,如果注册中心有一段时间未收到心跳包,则视为下线,该服务从服务列表中剔除。
当服务节点关闭或重启的时,会发送一条**“服务下线”**指令给注册中心,也视为下线。

nacos体系架构

三个核心:领域模式,数据模型,基本架构。

领域模型

Nacos的领域模型描述了服务与实例之间的边界和层级关系。Nacos的服务领域模型是以“服务”为维度来构建的。

这个服务并不是指集群中的单个服务器,而是指微服务的服务名称。

在这里插入图片描述
服务,集群,实例是Nacos的核心概念。

  • 服务
    在服务的基础上,可以配置元数据和服务保护阈值(0~1)等信息,当服务的健康实例数/总比例数是小于保护阈值时,说明当前服务还能提供的机器已经不多了,Nacos会开启服务保护模式,不再主动剔除服务实例。

  • 集群
    一个服务是由多个服务实例组成的,在每个服务实例启动的时候,可以设置它所属的集群,可以配置元数据,还可以为持久化节点设置健康检查模式。

  • 实例
    实例对应的就是服务节点,我们可以通过Nacos控制台查看每个实例的IP地址和端口,编辑实例的元数据信息,修改它的上线/下线状态等。

上述都存在元数据,它是包含了服务描述信息和自定义标签的数据集合。

数据模型

在这里插入图片描述

  • Namespace
    命名空间,他是最顶层的数据结构,用来区分开发,预发,生产环境。
    默认情况下所有的服务都部署到一个叫做“public”的公共命令空间。
  • Group
    在命名空间之下有一个分组结构。
    默认情况下所有的服务都属于"default_group"这个分组,不同分组间的微服务是相互隔离的。
  • Data ID
    在分组之下,就是具体的微服务了,比如订单服务,商品服务等。
Nacos的基础架构

Nacos的两大核心:Naming Service和Config Service
在这里插入图片描述

一致性

Nacos的一致性保证Nacos集群中各个节点之间的数据一致性。

  • 侧重一致性的Raft协议,基于集群中选举出来的Leader节点进行数据写入。
  • 临时节点的Distro协议,他是最终一致性的分布式一致性协议。
自动装配原理

在早期SpringCloud版本中,需要在启动类加上@EnableDiscoveryClient注解,才能开启服务治理功能。
在新版本中,我们只需要通过配置项就可以开启。

  • NacosDiscoveryAutoConfiguration
    服务发现的自动装配器。
    主要是:加载Nacos配置项,申明NacosService Discovery类用作服务发现
    源码如下:
@Configuration(proxyBeanMethods = false)
@ConditionalOnDiscoveryEnabled //默认是true,可通过配置项制为false
@ConditionalOnNacosDiscoveryEnable //默认是true,可通过配置项制为false
public class NacosDiscoveryAutoConfiguration {

	//@ConfigurationProperties("spring.cloud.nacos.discovery")
	//通过上面的注解,读取配置文件中nacos相关的配置项封装进NacosDiscoveryProperties类
	@Bean
	@ConditionalOnMissingBean
	public NacosDiscoveryProperties nacosProperties() {
		return new NacosDiscoveryProperties();
	}
	//如下面代码NacosServiceDiscovery类
	@Bean
	@ConditionalOnMissingBean
	public NacosServiceDiscovery nacosServiceDiscovery(
			NacosDiscoveryProperties discoveryProperties,
			NacosServiceManager nacosServiceManager) {
		return new NacosServiceDiscovery(discoveryProperties, nacosServiceManager);
	}
}

//返回值:根据服务名称获取所有已注册的服务,返回所有服务的服务名称,一般是给调用方使用的,
//提供服务发现功能。
public class NacosServiceDiscovery {
   // 封装了Nacos配置项的类
   private NacosDiscoveryProperties discoveryProperties;
   // 另一个自动装配器声明的核心服务治理类
   private NacosServiceManager nacosServiceManager;

   // 根据服务名称获取所有已注册服务
   public List<ServiceInstance> getInstances(String serviceId) throws NacosException {
      String group = discoveryProperties.getGroup();
      List<Instance> instances = namingService().selectInstances(serviceId, group,
            true);
      return hostToServiceInstanceList(instances, serviceId);
   }

   // 返回所有服务的服务名称
   public List<String> getServices() throws NacosException {
      String group = discoveryProperties.getGroup();
      ListView<String> services = namingService().getServicesOfServer(1,
            Integer.MAX_VALUE, group);
      return services.getData();
   }
   // 省略部分代码...
}
  • NacosServiceAutoConfiguration
    声明核心服务治理类:NacosServiceManager。
    主要是通过serviceId,group等一系列获取已注册的服务列表

  • NacosServiceRegistryAutoConfiguration
    Nacos服务注册的自动装配器。

在这里插入图片描述
关闭服务,服务下线:主要靠注解@PreDestroy实现
NacosServiceRegistryAutoConfiguration->NacosAutoServiceRegistration->AbstractAutoServiceRegistration.destroy()

Nacos服务发现底层实现

Nacos Client通过一种主动轮训的机制,从nacos server获取服务注册信息,包括地址列表,group分组,cluster名称等一系列数据。
Nacos Client会开启一个本地的定时任务,每间隔一段时间,就尝试从Nacos server查询服务注册表,并将最新的注册信息更新到本地。
负责拉取服务的任务是UpdateTask类,它实现了Runable方法,Nacos以开启线程的方式调用了UpdateTask类中的run方法,触发本地的服务发现查询请求。

首先在 spring.factory 文件中配置了 NacosDiscoveryClientConfiguration 类,用于 springboot 的初始化时的自动装配。在 NacosDiscoveryClientConfiguration 类中会向 spring 容器中添加 NacosWatch 这个 bean。顺着 NacosWatch 的 start 方法一路往下,就能看到:NacosWatch#start ->NacosNamingService#subscribe -> HostReactor#subscribe -> HostReactor#addTask;UpdateTask 就是作为 task 添加到定时执行队列里的。

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

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

相关文章

窃密恶意软件Raccoon最新样本Stealer v2分析

Raccoon 是一个恶意软件家族&#xff0c;2019 年来一直在地下犯罪论坛中以恶意软件即服务的身份进行售卖。2022 年 7 月&#xff0c;该恶意软件家族发布了 C 语言编写的新版本 Raccoon Stealer v2&#xff0c;打破了以往使用 C 开发的传统。 Raccoon 是一个信息窃密恶意软件&a…

JavaEE高阶---Redis

一:缓存简介 1.1 缓存定义 缓存是一个高速数据交换的存储器&#xff0c;使用它可以快速的访问和操作数据 . 1.2 程序中的缓存 当没有使用缓存时 : 但随着业务的发展&#xff0c;公司的框架慢慢变成了多个程序调用一个数据库的情况了&#xff1a; 这是大部分公司的普遍的架构…

设备加密狗

场景描述 随着科技的飞速发展&#xff0c;越来越多的智能设备走进生产加工车间。例如智能雕刻机、钣金机、榫槽机、钻孔机、磨刀机等等。 这些智能设备存在很大共性&#xff0c;就是都内嵌完整的操作系统。有的是windows&#xff0c;有的是linux。设备制造商提供的专业软件运…

pycharm的下载讲解以及安装步骤

目录 Python安装 这时&#xff0c;有人要问了&#xff0c;下载pycharm一定要下载Python么&#xff1f; Python官网 Pycharm安装 完成 推荐书籍 写在最后 Python安装 首先我们进入Python的官方下载网站 这时&#xff0c;有人要问了&#xff0c;下载pycharm一定要下载Py…

算法设计与分析期末考试复习(五)

回溯法 回溯法是一种试探法&#xff0c;将n元问题P的状态空间E表示成为一棵高为n的带权有序数T&#xff0c;把在E中求问题P的解转换为在T中搜索问题P的解。 解题方法&#xff1a;按选优条件对T进行深度优先搜索&#xff0c;以达到目标。 从根节点出发深度优先搜索解空间树。当…

初学网络安全不可不知的:10款开源安全工具

随着互联网的不断发展&#xff0c;安全问题也越来越受到企业的重视。但安全问题往往需要大量资金的投入&#xff0c;例如聘请安全工程师&#xff0c;产品研发&#xff0c;测试等流程。这对于那些原本就资金紧缺的企业而言&#xff0c;是绝对无法接受的。因此&#xff0c;为了减…

Python3+Selenium3自动化测试-(准备)

最近在学习selenium自动化测试相关的内容&#xff0c;所以将实际准备情况做一记录&#xff0c; # 系统&#xff1a;win10(64位) # 浏览器&#xff1a;Chrome(67.0)、Firefox(61.0)、IE # python版本&#xff1a;3.6.5 # Selenium&#xff1a;3.13.0Selenium简介 Selenium是一…

JUC并发编程——线程安全问题

目录一、共享问题1.1 共享带来的问题1.2 临界区与竞态条件二、解决方案2.1 上下文切换——synchronized-解决2.2 上下文切换——synchronized-理解2.3 上下文切换——synchronized-思考2.4 锁面向对象改进2.5 方法上的 synchronized三、synchronized习题3.1 synchronized-加在方…

记住这些快捷键,让你轻松玩转mac(macOS 常用快捷键分享)

适当运用键盘快捷键可以帮助用户提高效率&#xff0c;这里小编为大家带来了一些macOS 常用快捷键&#xff0c;掌握这些快捷键可以帮你解放鼠标手&#xff0c;成为键盘侠&#xff0c;一起来看看吧&#xff01; 快捷键标识简介 当你在应用菜单中发现部分操作项后边有一些特殊标…

搜广推 AutoRec与 Deep Crossing - 推荐系统深度学习模型开篇

😄 AutoRec:2015年由澳大利亚国立大学提出。【后文简称AR】 😄 DeepCrossing:2016年,微软基于ResNet的经典DNN结构。【后文简称DC】 文章目录 1、AutoRec1.1、原理1.2、优点1.3、缺点2、Deep Crossing2.1、原理2.2、优点:2.3、缺点:Reference1、AutoRec 1.1、原理 -…

IEEE SLT 2022论文丨如何利用x-vectors提升语音鉴伪系统性能?

分享一篇IEEE SLT 2022收录的声纹识别方向的论文&#xff0c;《HOW TO BOOST ANTI-SPOOFING WITH X-VECTORS》由AuroraLab&#xff08;极光实验室&#xff09;发表。 来源丨AuroraLab AuroraLab源自清华大学电子工程系与新疆大学信息科学与工程学院&#xff0c;以说话人识别和…

Qt 第9课、计算器中缀转后缀算法

计算器核心算法&#xff1a; 1、将中缀表达式进行数字和运算符的分离 2、将中缀表达式转换成后缀表达式 3、通过后缀表达式计算最后的结果 二、计算器中缀转后缀算法 计算器中缀转后缀算法的意义在于把中缀表达式转换成后缀表达式&#xff0c;能够更好地计算 算法的基本思路…

【RabbitMQ笔记08】消息队列RabbitMQ之防止消息丢失的三种方式(生产者消息确认、消费者消息确认、消息持久化)

这篇文章&#xff0c;主要介绍消息队列RabbitMQ之防止消息丢失的三种方式&#xff08;生产者消息确认、消费者消息确认、消息持久化&#xff09;。 目录 一、防止消息丢失 1.1、消息确认机制&#xff08;生产者&#xff09; &#xff08;1&#xff09;生产者丢失消息 &…

字节跳动软件测试岗4轮面经(已拿34K+ offer)...

没有绝对的天才&#xff0c;只有持续不断的付出。对于我们每一个平凡人来说&#xff0c;改变命运只能依靠努力幸运&#xff0c;但如果你不够幸运&#xff0c;那就只能拉高努力的占比。 2021年10月&#xff0c;我有幸成为了字节跳动的一名测试工程师&#xff0c;从外包辞职了历…

一文读懂自动驾驶运行设计域ODD

/ 导读 /在自动驾驶技术发展如此迅速的今天&#xff0c;很多量产车上已经配备了多种的辅助驾驶功能&#xff0c;例如自适应巡航ACC、紧急制动AEB、车道居中保持LKA等等&#xff0c;很多的车主也都体验到了技术带给驾驶的改变。另一方面&#xff0c;由于现在的自动驾驶技术还处于…

量化选股——基于动量因子的行业风格轮动策略(第2部分—策略回测)

文章目录1. 交易策略2. Backtrader回测程序3. 回测效果3.1 2020年1月1日 - 2021年1月1日3.2 2021年1月1日 — 2022年1月1日3.3 2022年1月1日 — 2023年1月1日动量因子的概述与测算&#xff0c;阿隆指标测算请参考&#xff1a;https://blog.csdn.net/weixin_35757704/article/de…

react源码解析1.开篇介绍和面试题

怎样学习react源码 作为前端最常用的js库之一&#xff0c;熟悉react源码成了高级或资深前端工程师必备的能力&#xff0c;如果你不想停留在api的使用层面或者想在前端技能的深度上有所突破&#xff0c;那熟悉react源码将是你进步的很好的方式。 react的纯粹体现在它的api上&a…

【神经网络】LSTM

1.什么是LSTM 长短期记忆&#xff08;Long short-term memory, LSTM&#xff09;是一种特殊的RNN&#xff0c;主要是为了解决长序列训练过程中的梯度消失和梯度爆炸问题。简单来说&#xff0c;相比普通的RNN&#xff0c;LSTM能够在更长的序列中有更好的表现。 LSTM区别于RNN地方…

Java查漏补缺(09)异常概述、Java异常体系、常见的错误和异常、异常的处理、手动抛出异常对象:throw、自定义异常

Java查漏补缺&#xff08;09&#xff09;异常概述、Java异常体系、常见的错误和异常、异常的处理、手动抛出异常对象&#xff1a;throw、自定义异常本章专题与脉络1. 异常概述1.1 什么是生活的异常1.2 什么是程序的异常1.3 异常的抛出机制1.4 如何对待异常2. Java异常体系2.1 T…

【JAVA】xxl-job服务搭建

xxl-job服务搭建 1.下载xxl-job项目 https://github.com/xuxueli/xxl-job 2.数据库表创建 3.修改配置 注意&#xff1a;这是两个项目&#xff0c;一个是xxl-job前台&#xff0c;一个是xxl-job执行器&#xff0c;找到这两个项目得配置文件&#xff0c;修改配置。 配置文件地址…