什么情况下使用微服务?
单体架构图参考网络:
1. 什么是单体应用
单体应用就是将应用程序的所有功能都打包成一个独立的单元,最终以一个WAR包或JAR包存在,没有外部的任何依赖,里面包含DAO、Service、UI等所有的逻辑。
优点:
1.便于开发:只需要借助IDE的开发,调试功能即可。
2.易于测试:只需要通过单元测试或浏览器即可完成测试。
3.易于部署:打包成单一可执行jar包,执行jar包即可完成部署。
可是,这种简单的单元有很大的局限性。应用随着业务需求迭代,功能的追加扩展,最终成为一个庞然大物,变得更加复杂,逻辑耦合很严重,难以理解。团队开发人员职责不清,部署困难,回归测试成本巨大,交付率大大降低,总结下来单体应用有以下5大缺点:
1.复杂性高
代码难以理解 部署困难 应用越来越大 测试越来越难
在业务规模和团队规模发展到一定阶段,这些不足表现的更加明显。单体架构的不足表现在复杂性上,maven模块增多,多个模块耦合在一起,代码结构混乱,很难理解整个代码逻辑,容易导致代码质量低,复杂性进一步增加,同时代码复用度降低,不清楚某段代码的修改后的影响范围。
代码难以被修改和重构
不理解代码当然也写不出高内聚低耦合的代码,代码质量持续下降;复杂性进一步增加,然后耦合度越来越高,代码牵一而动全身,代码就很难修改和重构了。
团队职责不清楚
高度耦合的单体工程使得逻辑边界模糊不清,新的业务需求开发任务无法有效分配到人,团队人员职责不清楚,沟通成本增加。
2.交付效率低
构建和部署耗时长,难以定位问题,开发效率低。代码比较庞大,编译时间就会很长,开发调试将大部分时间花在重新编译上,代码量的增加又很难定位bug,导致开发效率进一步降低,在代码合并过程中很容易造成代码冲突,又花不少时间解决代码冲突,这些都可以导致开发效率降低。还有就是当我们开发一个新的功能或者修复一个bug,代码的变更影响是很难预估的,每次发布之前都要进行全部功能的回归测试;部署耗时长,影响范围广,风险大,发布频次低也会造成产品不能及时呈现给用户,甚至被对手赶超。
3.伸缩性(scalable)差
单体应用只能按整体横向扩展,无法分模块垂直扩展。IO密集型模块和CPU密集模块无法独立升级和扩容。业务模块对资源的需求是不一样的,比如图片压缩,加解密这些 都是cpu资源密集的应该升级CPU,而IO密集型的模块比如日志收集服务IO操作比较多需要更大的内存,使用比如SSD性能更好的磁盘。
4.可靠性差
一个bug有可能引起整个应用的崩溃。比如一个不重要的部分的内存泄露就会导致所有应用实例一个个宕机掉
5.阻碍技术创新
受技术栈限制,团队成员使用同一框架和语言。升级和变革技术框架困难。
2. 什么是微服务
2.1 微服务的定义
微服务架构图参考网络:
微服务架构是将单体应用拆分为多个高内聚低耦合的小型服务,每个服务运行在独立的进程,可由不同的团队开发和维护,服务间采用轻量通信机制,独立自动部署,可以采用不同的语言及存储。
单体架构整个团队为何开发一个大工程和一个单库,在微服务架构中,用户请求经过API Gateway被路由到下游服务,服务之间以轻量级通信协议进行通信,服务通过注册中心发现彼此,每个服务都有专门的开发维护团队,每个服务都可以有自己独立的数据库,服务独立开发,部署,上线。
微服务的优点
1.易于开发与维护:微服务相对较小,易于理解,启动时间短,开发效率高。
2.独立部署:一个服务的修改不需要协调其他服务
3.伸缩性强:可以横向和纵向扩展
4.与组织结构匹配:更好的将架构和组织匹配,每个团队独立负责某些服务。
5.技术异构性:使用最适合该服务的技术,降低尝试新技术的成本。
说完优点,那么微服务有什么挑战呢?
2.2 微服务的挑战
1.服务拆分
拆分原则:领域模型,限定上下文,单一职责,组织结构,康威定律。
现实中没有一个具体明确的方法可以将拆分一步到位,而是遵守一定的规则。服务拆分的同时还要考虑到数据库也要独立(如果需要),当每个服务服务直接读写数据库中同一张表时,对这些表做任何改动都需要协调这些相关服务的部署。共享的数据存储很容易不经意间造成耦合。每个服务需要有自己的私有数据。这一点违背了服务相互独立这一原则。比如订单表被订单服务和商品服务所共享,商品服务单独做统计并不知道自己一天多少商品被卖出,不知道哪些数据由本服务产生的,就无法进行技术产品规划,对表结构的修改也要通知多个服务,这是所不能容忍的。每个服务需要自己的数据库,但这些数据库可共置在一台共享的数据服务器上,数据库私有的重点在于不应让服务知道其他服务底层数据库的存在。可用一台共享数据服务器先开始开发,以后如果数据量和并发量变大,服务器可以进行隔离。服务器隔离后,只要更改配置即可将不同服务的数据库隔离起来。确定服务边界也是一个难题,需要对自己的产品和业务有足够的了解才能确定最自然的服务边界确定服务边界坚持的原则是要高内聚弱耦合,弱耦合就是一个服务与其他服务的任何通信都应通过公开暴露的接口(API、事件等)实现,这些接口需要妥善设计以隐藏内部细节。这样我们的服务之间保持独立,在未来我们可以轻松重构,高内聚力就是密切相关的多个功能应尽量包含在同一个服务中,这样可将服务之间的干扰降至最低。
2.数据一致性
在单体架构中,我们通过数据库事务完成的操作放在分布式微服务架构下无法完成了,因为实例被部署不同服务器上,比如订单服务进行下单操作,下单操作和扣减库存应该放在同一个事务中。在微服务架构下,下单操作和扣库存操作被分布在不同服务器上,就需要进行分布式事务操作,而分布式事务具有延迟较高、nosql数据库不支持等缺点。
这些缺点导致分布式事务无法应用到微服务中在微服务场景下,我们通常使用最终一致性来代替强
一致性:
- 可靠性事件模式
- 补偿模式-sagas模式
3.服务通信
通信技术方案: RPC vs REST vs 异步消息
RPC、REST API、异步消息,异步消息我们可以借助一些消息队列框架来实现比如kafka、rrabbitMQ,那现在我们说下rpc和使用http协议的类似REST API之间 如何选择,TTP的好处是方便调试、跨语言、门槛低、广泛接受,同样缺点是协议文档不好维护,协议较为繁琐,性能较TCP要差是http协议的不足。
Rpc通信通常基于Tcp,常用的技术选型是thrift、grpc、dubbo,像thrift、grpc需要定义idl文件,通过idl文件来生成java代码,通过rpc的好处是IDE友好,有代码提示,协议维护在代码中,传参和响应结果都通过代码可以知道。但同时也有缺点比如很多rpc方案不知道跨语言,所支持的语言有限,需要定义和维护idl文件,且有一定的学习成本,另外rpc不容易方便的调试和测试。
服务注册和发现
在服务实例变化不定的环境中,用硬编码指定IP地址的方式是行不通的,需要通过某种发现机制让服务能相互查找。这就需要我们将我们的服务信息注册到一个分布式存储中,这些服务信息就叫做服务注册表服务注册表可以作为信息的权威来源。其中包含有关可用服务的信息,以及服务网络位置比如ip、端口号这些信息。那借助什么组件进行实现呢,一般有Eureka,zookeeper,Nocas,除此之外我们还可以借助etcd,consul,redis这些。
负载均衡
有了注册发现功能,客户端通过服务注册表发现实例清单并决定要连接哪个实例,在客户端做负载均衡,基于客户端做负载均衡相比服务端负载均衡有诸多好处:首先节省了硬件均衡设备,减少了运维成本,其次可以实现多种负载均衡策略比如响应感知的负载均衡策略。
4.服务网关
API Gateway
我们的微服务如果和终端用户通信,势必要考虑到身份认证,安全防御等方面,如果每个微服务都与终端用户打交道,那么这些方面代码需要拷贝多份植入到每个微服务业务代码中。造成了业务代码和身份认证代码的耦合,降低了代码的复用性。这就需要在网络边界实现一个服务网关(这里的网络边界可以认为是内网和外网之间的边界),将身份认证,安全防御,流量控制这些功能放到服务网关中,向业务服务屏蔽网络边界服务的细节,使得业务服务专注于业务逻辑的开发维护和测试。
为前端服务的后端(Backends For Forntends)
服务网关可以根据终端产品形态来划分,比如公共API,桌面客户端,移动客户端分别对应一个服务网关,而服务网关可以是API Gateway只输出api,或者是为前端服务的后端,这里的为前端服务的后端,比如将来自多个服务的数据聚合到一起返回给前端。
身份认证、路由服务、限流防刷、日志统计
5.高可观察
健康检测、集中监控
每个服务和使用的组件都有提供健康检测机制,使得我们可以及时发现异常的节点,然后做出判断和调整,将所有的监控指标进行聚合输出可视化图表和界面帮助我们快速直观发现问题。
日志聚合及检索
比如在电商app我们发现无法进行下单操作,在分布式架构下,日志散落在多个服务多个服务器中,我们不知道错误日志打在哪台服务器上,如果每台服务器去登陆去看是极其低效的。这要求我们做到日志格式标准化,并通过一些手段聚合到一起进行检索查询。同时可跨越所有服务、特定的某个服务,或服务的某个实例搜索日志;将日志发送至集中化日志系统所用的代码可包含在共享库中或通过代码脚手架提供。
分布式追踪
在微服务架构场景中,一个客户端发起的请求要经过多个服务的调用最终聚合数据结构返回给客户端,但我们不知道这个请求不知道经过哪些服务,调用哪个服务出现了问题,每个服务的输入输出是什么,这给我们定位问题带来了困扰,除此以外,如果一个请求耗时较长,我们不知道到底哪个服务耗时最长,好有针对性的性能优化。随着架构的演进,我们在架构设计规划时需要知道 服务之间的依赖关系,这有需要什么技术来实现呢,这就是我们要介绍的分布式追踪,分布式追踪借助关联id,在请求源头创建这个关联id,并且在服务间进行透传,最终将关联id等信息聚合到一起进行查询分析。
6.可靠性
在讲单体的过程中,我们讲到,一个业务模块的内存泄露会导致整个进程退出。在微服务场景下,如果一个服务出现内存泄露是不会影响 没有依赖关系的服务的。但是却可以因为该异常服务的僵死或不可用造成上游服务线程hang住,进而产生级联效应,故障进一步向上游传播。
流量控制,超时控制
可靠性技术通过流量的控制和超时控制,保证服务消费者不被下游服务拖慢,及时对业务线程循环复用。
舱壁隔离,熔断机制
熔断是指服务调用出错次数在一定时间达到一定数量,自动关闭对该服务的调用开关,改为返回错误或者将请求转交给降级方法,降低资源耗尽的风险,当服务不可用时,作为服务消费者应该对接口方法编写一个降级方法。
服务降级, 幂等重试
由于服务间通信是通过网络传输的,网络异常和网络分区故障 就会经常出现,我们遇到这种情况可以进行调用重试,重试时要注意两点,一个是接口必须是幂等的,无论运行一次或多次,最终结果必须相同。幂等性保证了重试不会产生负面影响。在重试过程时休眠时间应该是指数增长的,否则会产生惊群效应,比如:故障后的服务恢复上线后,如果有大量其他服务正在同一个重试窗口内重试,此时很容易给系统造成巨大压力。
提炼代码脚手架
除了开发业务逻辑,我们还需要搭建一套微服务工程可用框架,这样是是为了加快团队工作效率,微服务解决方案保持统一,增强代码复用性,统一进行优化,微服务要解决的问题非常多,所以抽取服务代码模板是有必要的,它包括服务注册发现、服务通信、监控、日志、异常处理等等。
从单体迁移到微服务
1、何时迁移微服务?
讲了这么多微服务的好处,我们是不是可以从此抛弃单体架构,一切项目直接投向微服务的怀抱了呢?
Martin Fowler在《MicroservicePremium》一文说:
“don’t even consider microservices unless you have a system that’s too complex to manage as a monolith”,翻译过来就是:如果你的系统不到足够复杂的程度不要考虑使用微服务。
当业务不复杂,团队规模不大的时候,单块架构比微服务架构具有更高的生产率(productivity)。因为建立微服务架构需要额外的开销来支持和管理微服务,从而降低生产率;但是随着业务复杂性的增加和团队规模的扩大,单块架构比微服务架构的生产率下降更趋明显。
当复杂性达到一个临界点,微服务架构的生产率会优于单块架构,因为微服务的松散耦合自治特性减缓了生产率的下降趋势。
所以我们在做项目时,一定要根据自己的团队和业务复杂性来判断,何时应用微服务。
以我的经验给大家的建议时,一个全新项目在1-3团队时,可以先拆分成一个API 网关和一个集合所有业务的后端服务,API网关关注鉴权和路由、处理部分失败;后端服务要划分好业务模块;项目初期,由于流量不多,可以不必添加流量控制和断路器等组件。
同时即使向微服务架构迁移之后,拆分的粒度也要由粗到细演进式发展,一定要根据自己的业务规模复杂性和团队规模来定。
2.如何迁移到微服务上来?
一个策略是:不要大规模(big bang)重写代码(只有当你承担重建一套全新基于微服务的应用时候可以采用重写这种方法)。重写代码听起来很不错,但实际上充满了风险最终可能会失败,就如Martin Fowler所说:“the only thing a Big Bang rewrite guarantees is a Big Bang!”相反,应该采取逐步迁移单体式应用的策略,通过逐步生成微服务新应用,与旧的单体式应用集成,随着时间推移,单体式应用在整个架构中比例逐渐下降直到消失或者成为微服务架构一部分。这个策略有点像在高速路上限速到70迈对车做维护,尽管有挑战,但是比起重写的风险小很多。
Martin Fowler将这种现代化策略成为绞杀应用,名字来源于雨林中的绞杀藤(strangler vine),也叫绞杀榕(strangler fig)。绞杀藤为了爬到森林顶端都要缠绕着大叔生长,一段时间后,树死了,留下树形藤。这种应用也使用同一种模式,围绕着传统应用开发了新型微服务应用,传统应用会渐渐退出舞台。
SOA VS 微服务
SOA和微服务的对比是一个老生常谈的话题,我认为两者最大的不同是提出时所处的技术背景和环境。
SOA的出现其实是为了解决历史问题:企业在信息化的过程中会有各种各样互相隔离的系统,需要有一种机制将他们整合起来,所以才会有ESB的出现。同样的,也成了SOA初期的服务是很大的概念,通常指定的一个可以独立运作的系统。
微服务没有历史包袱,服务的尺寸通常不会太大。从服务粒度来讲,SOA更像是单体的简单组合,而微服务是粒度更细小的服务,其次数据拆分SOA倾向于共享数据库,微服务一个服务对应一个数据库。
3. 为什么采用Spring Cloud Alibaba
Spring Cloud Alibaba架构图参考网络:
3.1 Spring Cloud Alibaba 真实应用场景
- 大型复杂的系统,例如大型电商系统(原因:业务复杂)
- 高并发系统,例如大型门户,秒杀系统(原因:去中心化,能够承载更高的负载压力,并且提供个一款很好用的容错组件`Sentinel`可以进一步提升应用可用性、容错性)
- 需求不明确,且变更很快的系统,例如创业公司业务系统(原因:修改模块方便)
3.2 Spring Cloud Alibaba 和 Spring Cloud 有什么区别和联系呢?
Spring Cloud Alibaba
是Spring Cloud
的子项目Spring Cloud Alibaba
是Spring Cloud
的子项目
Spring Cloud 第一代 | 状态 | Spring Cloud Alibaba | 状态 |
---|---|---|---|
Eureka | 2.0孵化失败 | Nacos Discovery | 性能强劲,感知更快 |
Ribbon | 进去维护状态,预计2020年1月停止维护,新的标准已形成:spring-clound-loadbalancer,但暂无参考实现。Spring Clound Hoxton 才会孵化出替代品 | ||
Hystrix/Hystrix Dashboard/Turbine | 进入维护状态,预计2020年1月停止维护 | Sentinel | 可视化配置,上手更简单 |
Zuul | 进入维护状态,预计2020年1月停止维护 | Spring Cloud Gateway | 性能是Zuul的1.6倍 |
Spring Clound Config | 搭建复杂,约定多,设计繁重,没有洁面,难维护,难以上手 | Nacos Config | 搭建简单,有可视化界面,配置管理更高效,学习曲线低 |
总体来将 Spring Cloud Alibaba
组件性能更强,良好的可视化界面,搭建简单,学习曲线低,文档丰富并且是中文
3.3 Spring Clound Alibaba 的重要组件
服务发现 Nacos | 实现负载均衡 Ribbon | 声明式HTTP客户端-Feign |
---|---|---|
服务发现原理 | 负载均衡的常见模式剖析 | 如何使用Feign |
Nacos Server/Client | RestTemplate整合Ribbon | Feign配置自定义 |
高可用Nacos搭建 | Ribbon配置自定义 | 如何扩展Feign |
0 | 如何扩展 Ribbon | 0 |
服务容错 Sentinel | 消息驱动 RocketMQ | API网关 Gateway |
---|---|---|
服务容错原理 | Spring Clound Stream | 整合Gateway |
Sentinel | 实现异步消息推送与消费 | 三大核心 |
Sentinel Dashboard | 聚合微服务请求 | |
Sentinel 核心原理分 |
用户认证与授权 | 配置管理 Nacos | 调用链监控Sleuth |
---|---|---|
认证授权的常见方案 | 配置如何管理 | 调用链监控原理剖析 |
改造Gateway | 配置动态刷新 | Sleuth使用 |
扩展Feigh Dashboard | 配置管理的最佳实践 | Ziplin使用 |
相关文章:

什么情况下使用微服务?
单体架构图参考网络: 1. 什么是单体应用 单体应用就是将应用程序的所有功能都打包成一个独立的单元,最终以一个WAR包或JAR包存在,没有外部的任何依赖,里面包含DAO、Service、UI等所有的逻辑。 优点: 1&…...

【Linux】Ubuntu美化主题【教程】
【Linux】Ubuntu美化主题【教程】 文章目录 【Linux】Ubuntu美化主题【教程】1. 安装优化工具Tweak2.下载自己喜欢的主题3. 下载自己喜欢的iconReference 1. 安装优化工具Tweak 首先安装优化工具Tweak sudo apt-get install gnome-tweak-tool安装完毕后在菜单中打开Tweak 然后…...
spring-boot2.x,使用EnableWebMvc注解导致的自定义HttpMessageConverters不可用
在json对象转换方面,springboot默认使用的是MappingJackson2HttpMessageConverter。常规需求,在工程中使用阿里的FastJson作为json对象的转换器。 FastJson SerializerFeatures WriteNullListAsEmpty :List字段如果为null,输出为[],而非nu…...

2023-09-20 Android CheckBox 让文字显示在选择框的左边
一、CheckBox 让文字在选择框的左边 ,在布局文件里面添加下面一行就可以。 android:layoutDirection"rtl" 即可实现 android:paddingStart"10dp" 设置框文间的间距 二、使用的是left to right <attr name"layoutDirection">&…...
目标检测YOLO实战应用案例100讲-基于改进YOLOv5的口罩人脸检测
目录 前言 国内外研究现状 目标检测研究发展 国内外口罩人脸检测研究现状...

CentOS7 yum安装报错:“Could not resolve host: mirrorlist.centos.org; Unknown error“
虚拟机通过yum安装东西的时候弹出这个错误: 1、查看安装在本机的网卡 网卡ens33处于disconnected的状态 nmcli d2、输入命令: nmtui3、选择网卡,然后点击edit 4、移动到Automatically connect按空格键选择,然后移动到OK键按空格…...
关于token续签
通常我们会对token设置一个有效期,于是,就有了token续签的问题。由于token并没有续时机制,如果不能及时的替换掉过期的token,可能会拦截用户正常的请求,用户只能重新登录,如果提交的信息量很大,…...

淘宝分布式文件存储系统( 二 ) -TFS
淘宝分布式文件存储系统( 二 ) ->>TFS 目录 : 大文件存储结构哈希链表的结构文件映射原理及对应的API文件映射头文件的定义 大文件存储结构 : 采用块(block)文件的形式对数据进行存储 , 分成索引块,主块 , 扩展块 。所有的小文件都是存放到主块中的 ,扩展块…...

Java中synchronized:特性、使用、锁机制与策略简析
目录 synchronized的特性互斥性可见性可重入性 synchronized的使用方法synchronized的锁机制常见锁策略乐观锁与悲观锁重量级锁与轻量级锁公平锁与非公平锁可重入锁与不可重入锁自旋锁读写锁 synchronized的特性 互斥性 synchronized确保同一时间只有一个线程可以进入同步块或…...
记一次clickhouse手动更改分片数异常
背景:clickhouse中之前是1分片1副本,随着数据量增多,想将分片数增多,于是驻场人员手动添加了分片数的节点信息 <clickhouse><!-- 集群配置 --><clickhouse_remote_servers><feihuang_ck_cluster><sha…...

深度学习论文: ISTDU-Net:Infrared Small-Target Detection U-Net及其PyTorch实现
深度学习论文: ISTDU-Net:Infrared Small-Target Detection U-Net及其PyTorch实现 ISTDU-Net:Infrared Small-Target Detection U-Net PDF: https://doi.org/10.1109/LGRS.2022.3141584 PyTorch代码: https://github.com/shanglianlm0525/CvPytorch PyTo…...

图像识别-YOLO V8安装部署-window-CPU-Pycharm
前言 安装过程中发现,YOLO V8一直在更新,现在是2023-9-20的版本,已经和1月份刚发布的不一样了。 eg: 目录已经变了,旧版预测:在ultralytics/yolo/v8/下detect 新版:ultralytics/models/yolo/detect/predict.py 1.安…...
js禁用F1至F12、禁止缩放、取消选中并且取消右键操作、打印、拖拽、鼠标点击弹出自定义信息、禁用开发者工具js
禁用js //禁止缩放 //luwenjie hualun window.addEventListener(mousewheel, function (event) {if (event.ctrlKey true || event.metaKey) {event.preventDefault();} }, {passive: false});//firefox window.addEventListener(DOMMouseScroll, function (event) {if (even…...

Zabbix5.0_介绍_组成架构_以及和prometheus的对比_大数据环境下的监控_网络_软件_设备监控_Zabbix工作笔记
z 这里Zabbix可以实现采集 存储 展示 报警 但是 zabbix自带的,展示 和报警 没那么好看,我们可以用 grafana进行展示,然后我们用一个叫睿象云的来做告警展示, 会更丰富一点. 可以看到 看一下zabbix的介绍. 对zabbix的介绍,这个zabbix比较适合对服务器进行监控 这个是zabbix的…...

百度SEO优化TDK介绍(分析下降原因并总结百度优化SEO策略)
TDK是SEO优化中很重要的部分,包括标题(Title)、描述(Description)和关键词(Keyword),为百度提供网页内容信息。其中标题是最重要的,应尽量突出关键词,同时描述…...

搭建自动化 Web 页面性能检测系统 —— 设计篇
页面性能对于用户体验、用户留存有着重要影响,当页面加载时间过长时,往往会伴随着一部分用户的流失,也会带来一些用户差评。性能的优劣往往是同类产品中胜出的影响因素,也是一个网站口碑的重要评判标准。 一、名称解释 前端监控…...

记一次 mysql 数据库定时备份
环境:Centos 7.9 数据库:mysql 8.0.30 需求:生产环境 mysql 数据(约670MB)备份。其中存在大字段、longblob字段 参考博客:Linux环境下使用crontab实现mysql定时备份 - 知乎 一、数据库备份 1. 备份脚本。创…...

淘宝分布式文件存储系统(一) -TFS
淘宝分布式文件存储系统( 一 ) ->>TFS 目录 : 什么是文件系统文件存储的一些概念文件的结构系统读取文件的方式为什么采用大文件结构的原因 文件系统 : 将我们的数据整合成目录或者文件,提供对文件的存取接口,基于文件的权限进行访问,简单的说,文件系统就是对文件进行…...

LLM各层参数详细分析(以LLaMA为例)
网上大多分析LLM参数的文章都比较粗粒度,对于LLM的精确部署不太友好,在这里记录一下分析LLM参数的过程。 首先看QKV。先上transformer原文 也就是说,当h(heads) 1时,在默认情况下, W i Q W_i…...
linux ansible(三)
ansible 配置详解 3.1 ansible 安装方式 ansible安装常用两种方式,yum安装和pip程序安装 3.1.1 使用 pip(python的包管理模块)安装 需要安装一个python-pip包,安装完成以后,则直接使用pip命令来安装我们的ansible包 …...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...

stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...

Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...
【JavaSE】多线程基础学习笔记
多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...

Golang——9、反射和文件操作
反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一:使用Read()读取文件2.3、方式二:bufio读取文件2.4、方式三:os.ReadFile读取2.5、写…...

Visual Studio Code 扩展
Visual Studio Code 扩展 change-case 大小写转换EmmyLua for VSCode 调试插件Bookmarks 书签 change-case 大小写转换 https://marketplace.visualstudio.com/items?itemNamewmaurer.change-case 选中单词后,命令 changeCase.commands 可预览转换效果 EmmyLua…...