驾驭云端之风1——Spring Cloud微服务架构实践指南
- 本博客纯属个人总结,非原创。
- 喜欢技术交流的,可关注博主,武汉有后端开发群,可支持内推,了解武汉行情等。
前沿
优惠卷平台项目的整体功能和模块,以及每个功能点的技术选型和背后的依据。
搭建一个简化版的营销优惠计算系统,实现
- 优惠卷模版的创建,
- 用户领取优惠卷,
- 下单核销优惠卷
- 订单价格计算等功能。
实现一个领取优惠卷的功能,首先是要创建一个营销规则模版,这个模版就像一个模具一样,通过这个模具来铸造,并最终发放到用户手中。
.
使用模版的好处是可以对优惠卷规则做一层抽象,比如满减类,打折类,这些优惠卷是具体的优惠金额不同,但是玩法类似。我们把相类似的玩法功能抽象成一个模版,就可以简化具体优惠卷的创建和核销流程。
整个项目划分了优惠卷模版服务,计算服务,用户服务,平台类组件
优惠卷模版服务:模版规则是创建优惠卷的前置条件,每种类型的模版都是一个计算公式,这个公式约定了优惠计算的方式,模版服务实现了模版规则的创建,克隆,分页查找等功能,另外还可以在项目中定义满减,随机立减,满折,晚间双倍优惠等多种卷模版类型。
计算服务:根据用户购物车中的商品信息和优惠卷信息,来计算当前订单优惠后的价格,另外,如果用户有多张优惠卷,还提供了”优惠金额试算“,帮助用户挑选最省钱的优惠卷。
用户服务:暴露给外部用户使用的接口,它依赖于模版服务+计算服务,为了完成底层逻辑,主要业务场景是用户领卷,订单价格试算,下单核销,订单金额等功能。
平台类组件:包括一些与业务无关的中心化组件。
从整体来看,模版服务和计算服务是基础服务,用户服务是对用户开放的接口,他依赖于模版服务+计算服务来完成业务逻辑,而平台类组件提供了横向的微服务特性支持,比如微服务网关,链路追踪等功能,整体图如下:
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@ConditionalOnMissingBeanpublic NacosDiscoveryProperties nacosProperties() {return new NacosDiscoveryProperties();}//如下面代码NacosServiceDiscovery类@Bean@ConditionalOnMissingBeanpublic 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 添加到定时执行队列里的。
相关文章:
驾驭云端之风1——Spring Cloud微服务架构实践指南
本博客纯属个人总结,非原创。喜欢技术交流的,可关注博主,武汉有后端开发群,可支持内推,了解武汉行情等。 前沿 优惠卷平台项目的整体功能和模块,以及每个功能点的技术选型和背后的依据。 搭建一个简化版的…...
【计算机网络基础】
计算机网络基础网络的基本概念网络互联网IP地址MAC地址网络协议网络分层模型网络应用程序的通信流程网络的基本概念 网络 网络是由若干结点和链接这些结点的链路组成,网络中的结点可以是计算机,交换机,路由器等设备 网络设备:交…...
grep与nm命令的应用
相关知识拓展 Linux中grep的命令使用 在Linux中,grep可用于shell脚本,因为grep通过返回一个状态值来说明搜索状态,如果模板搜索成功,则返回0,如果搜索不成功,则返回1,如果搜索的文件不存在&…...
【linux】软硬链接
在linux中在磁盘中定位文件并不是根据文件名而是根据文件的inode,一个文件对应一个inode但是一个inode可以对应多个文件。硬链接硬链接是通过索引节点进行的链接。在Linux中,多个文件指向同一个索引节点是允许的,像这样的链接就是硬链接。硬链…...
骨传导蓝牙耳机排行,盘点几款性能不错的骨传导耳机
随着蓝牙耳机的普及,骨传导耳机也越来越受到欢迎,很多人也都开始在了解并尝试骨传导耳机。相比于其他类型耳机,在舒适度、安全方面有一定优势。尤其是在户外运动时,或者长时间佩戴运动时,使用骨传导耳机可以避免耳朵因…...
ARM中的寄存器
ARM工作模式 ARM有8个基本的工作模式 User 非特权模式,一般在执行上层的应用程序时ARM处于该模式FIQ 当一个高优先级中断产生后ARM将进入这种模式IRQ 当一个低优先级中断产生后ARM将进入这种模式SVC 当复位或执行软中断指令后ARM将进入这种模式Abort 当产生存取异常…...
git操作修改历史版本指定tag标签的代码,并发布新标签
场景: 当项目已经迭代多个版本之后,突然发现旧版本0.0.1出现了紧急bug,需要及时处理; 如果直接用新版本替换上去是存在极大隐患的,且时间来不及; 所以需要直接在0.0.1版本的基础上去修复bug,然…...
SpringMVC——响应处理(1)【包含源码分析】
Controller public class JsonReturnController {ResponseBodyGetMapping("/getPet")public Pet getPet(){Pet petnew Pet();pet.setAge(5);pet.setName("lily");return pet;} }项目启动后 浏览器输入 http://localhost:8080/getPet 。 debug DispatcherS…...
Normalization
1、BN(Batch Normalization) 深度网络参数训练时内部存在协方差偏移(Internal Covariate Shift)现 象:深度网络内部数据分布在训练过程中发生变化的现象。训练深度网络时,神经网络隐层参数更新会导致网络输…...
27K测试老鸟分享自己6年面试心得,四种公司、四种问题…
这里总结了下自己今年的面试情况 先说一下自己的个人情况,普通二本计算机专业毕业,懂python,会写脚本,会selenium,会性能。趁着金三银四跳槽季,面试字节跳动测试岗技术面都已经过了,本来以为是…...
中小企业数字化自动化转型的方法
自动化是我们国内未来的趋势。智能制造的实现主要依托两个基础能力,一个是工业制造技术,另一个就是工业互联网。而自动化是工业制造技术的重要组成部分,是高度智能制造装备的核心部分,与承接着制造单元与工业互联网这两大核心。懂…...
利用GPT-3 Fine-tunes训练专属语言模型
利用GPT-3 Fine-tunes训练专属语言模型 文章目录什么是模型微调(fine-tuning)?为什么需要模型微调?微调 vs 重新训练微调 vs 提示设计训练专属模型数据准备清洗数据构建模型微调模型评估模型部署模型总结什么是模型微调࿰…...
kubeadm方式安装k8s高可用集群(版本1.26x)
K8S官网:https://kubernetes.io/docs/setup/ 高可用Kubernetes集群规划 配置备注系统版本CentOS 7.9Docker版本20.10.xPod网段172.16.0.0/12Service网段10.103.10.0/16 主机IP说明k8s-master01 ~ 03192.168.77.101 ~ 103master节点 * 3k8s-master-lb192.168.77.2…...
分享5款堪称神器的免费软件,建议先收藏再下载
转眼间新年已经过去一个月了,最近陆陆续续收到好多小伙伴的咨询,这边也是抓紧整理出几个好用的软件,希望可以帮到大家。 1.电脑安全管家——火绒 火绒是一款电脑安全软件,病毒库更新及时,界面清晰干净,没…...
【项目实战】从0开始入门JDK源码 - LinkedList源码
一、源码位置 一般来说IDEA配置好JDK以后 ,JDK的源码其实也配置好了,本文是基于JDK1.8的源码说明 rt - java - util - LinkedList 二、 继承关系图 LinkedList public class LinkedList<E>extends AbstractSequentialList<E>implements...
Polygon zkEVM的gas定价
1. 引言 所有的zkEVM都存在一个有趣的问题: 如何给gas定价? 在Ethereum Virtual Machine (EVM)中,gas通过为每个计算设置economic fee,来保持网络安全。恶意行为,如拒绝服务(DoS)攻击&#x…...
stl中的智能指针类详解
C98/03的尝试——std::auto_ptr C11标准废弃了std::auto_ptr(在C17标准中被移除),取而代之的是std::unique_ptr, std::auto_ptr容易让人误用的地…...
Linux 阻塞和非阻塞 IO 实验
目录 一、阻塞和非阻塞简介 1、IO 概念 2、阻塞与非阻塞 二、等待队列 1、等待队列头 2、等待队列项 3、将队列项添加/移除等待队列头 4、等待唤醒 5、等待事件 三、轮询 1、应用程序的非阻塞函数 2、Linux 驱动下的 poll 操作函数 四、阻塞IO之等待事件唤醒 添加…...
你要的react+ts最佳实践指南
本文根据日常开发实践,参考优秀文章、文档,来说说 TypeScript 是如何较优雅的融入 React 项目的。 温馨提示:日常开发中已全面拥抱函数式组件和 React Hooks,class 类组件的写法这里不提及。 前沿 以前有 JSX 语法,…...
软件测试人员会被替代吗?IT行业哪个方向的前景最好?字节12年测开是这样说的
互联网测试从业12年,前来作答。 逻辑上来说,软件工程最初始只需要两个岗位,一个是产品经理。,一个是研发(开发),剩余的 所有岗位都是由他们衍生而来的。 第三个岗位大概率就是测试,…...
十六、vue3.0之富文本编辑器的选择
在工作过程中我们会遇到很多的时候会使用到富文本编辑器,市场上流行的也是各种各样的,那么究竟如何选择呢,今天就给大家讲讲有哪一些,方便大家的选择。 一、TinyMCE TinyMCE 是富文本编辑器领域的头部玩家之一,主流富文本编辑器,功能非常全,你需要的大多数功能它都支持…...
kafka(一) 的架构,各概念
Kafka架构 Kafak 总体架构图中包含多个概念: (1)ZooKeeper:Zookeeper负责保存broker集群元数据,并对控制器进行选举等操作。 (2)Producer: 生产者负责创建消息,将消息发…...
【ts的常用类型】
ts的常用类型前言安装ts常见类型原始类型 、数组、 any变量上的类型注解函数对象类型联合类型类型别名接口接口和类型别名的对比前言 typescript中为了使编写的代码更规范,更有利于维护,增加了类型校验,安装 安装 typescript npm i typescr…...
Hyper-V与安卓模拟器不共存
一是某些新的模拟器已经开始使用新接口开发,支持了共存,安装这种新的安卓模拟器即可。 对于不支持共存的模拟器,只得增加一个windows开机后的系统选项,如果需要切换这两种不同选项使用系统,每次切换都需要重启windows系…...
【图像分类】卷积神经网络之ZFNet网络模型结构详解
写在前面: 首先感谢兄弟们的关注和订阅,让我有创作的动力,在创作过程我会尽最大能力,保证作品的质量,如果有问题,可以私信我,让我们携手共进,共创辉煌。 1. 前言 由于AlexNet的提出,大型卷积网络开始变得流行起来,但是人们对于网络究竟为什么能表现的这么好,以及怎…...
亿级高并发电商项目-- 实战篇 --万达商城项目 十三(编写购物车、优化修改商品、下架商品方法、购物车模块监听修改商品、删除商品消息)
👏作者简介:大家好,我是小童,Java开发工程师,CSDN博客博主,Java领域新星创作者 📕系列专栏:前端、Java、Java中间件大全、微信小程序、微信支付、若依框架、Spring全家桶 Ǵ…...
springboot 虚拟线程demo
jd19支持虚拟线程,虚拟线程是轻量级的线程,它们不与操作系统线程绑定,而是由 JVM 来管理。它们适用于“每个请求一个线程”的编程风格,同时没有操作系统线程的限制。我们能够创建数以百万计的虚拟线程而不会影响吞吐。 做个 spri…...
CTFer成长之路之逻辑漏洞
逻辑漏洞CTF 访问url: http://1b43ac78-61f7-4b3c-9ab7-d7e131e7da80.node3.buuoj.cn/ 登录页面用随意用户名密码登录 访问url: http://1b43ac78-61f7-4b3c-9ab7-d7e131e7da80.node3.buuoj.cn/user.php 登陆后有商品列表,共三个商品,点击购买flag 钱…...
入门力扣自学笔记238 C++ (题目编号:1144)
1144. 递减元素使数组呈锯齿状 题目: 给你一个整数数组 nums,每次 操作 会从中选择一个元素并 将该元素的值减少 1。 如果符合下列情况之一,则数组 A 就是 锯齿数组: 每个偶数索引对应的元素都大于相邻的元素,即 A…...
蓝桥杯-寒假作业
没有白走的路,每一步都算数🎈🎈🎈 题目描述: 有四个等式,每个等式的运算规则已经定好了,也就是我们常见的小学的四则运算,但是能够用来四则运算的数字非常有限,包括1~13…...
临沂做网站设计的公司/重庆森林百度网盘
转自:爱数据学习社数据是企业最具价值的资产之一,而数据质量则直接影响数据的产出和数据价值的高低。因此,数据质量的管理对于企业决策、战略水平和业绩提升至关重要。今天我们就来聊一聊企业如何评估和提升数据质量。一、数据质量是什么国际…...
阿里云医疗网站建设/网页设计教程
判断你的文件是否为合法的PE文件和应用类型 http://www.vckbase.com/document/viewdoc/?id1893 C与Java混合编程 http://www.vckbase.com/document/viewdoc/?id1889 工作之余就是写文章自如自乐! 高手们就不要拍砖了!...
布吉附近做网站/搜索引擎优化举例说明
1.1 Docker 磁盘扩容 默认情况下,物理机下创建的docker容器的空间是10G(虚拟机下创建的docker容器空间就是虚拟机的空间)。 Docker容器动态扩展的优点: 1)不需要修改docker配置,不需要重启docker服务&#…...
网站做动态和静态哪个贵/外贸seo站
ASPNET Music Store application 是一个展示最新的.NET 平台(包括.NET Core/Mono等)上使用MVC 和Entity Framework的示例程序,本文将展示如何在CentOS上运行.NET Core版本的MusicStore,并通过Jexus对外发布。 上篇文章 《结合Jexu…...
漳州城乡和建设局网站首页/培训心得体会500字
零钱兑换 JS实现题目描述(LeetCode)动态规划题目描述(LeetCode) 先看下官方描述: 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/coin-change 给你一个整…...
哪个网站找做软件下载/windows系统优化软件
两种方法配置linux网络:一、图形化界面#nmtui修改网络参数二、修改配置文件#vi /etc/sysconfig/network-scripts/ifcfg-ens33TYPEEthernet #类型为以太网,常见有的Ethernet, BridgeBOOTPROTOstatic #静态ip或者DHCP动态获取…...