Spring Cloud Netflix Eureka的参数调优
下面主要分为Client端和Server端两大类进行简述,Eureka的几个核心参数
客户端参数
Client端的核心参数
| 参数 | 默认值 | 说明 |
|---|---|---|
| eureka.client.availability-zones | 告知Client有哪些region以及availability-zones,支持配置修改运行时生效 | |
| eureka.client.filter-only-up-instances | true | 是否过滤出InstanceStatus为UP的实例 |
| eureka.client.region | us-east-1 | 指定该应用实例所在的region,AWS datacenters适用 |
| eureka.client.register-with-eureka | true | 是否将该应用实例注册到Eureka Server |
| eureka.client.prefer-szme-zone-eureka | true | 是否优先使用与该实例处于相同zone的Eureka Server |
| eureka.client.on-demand-update-status-change | true | 是够将本地实例状态更新通过ApplicationInfoManager实时触发同步到Eureka Server |
| eureka.instance.metadata-map | 指定应用实例的元数据信息 | |
| eureka.instance.prefer-ip-address | false | 指定优先使用ip地址替代host name作为实例的hostName字段值 |
| eureka.instance.lease-expiration-duration-in-seconds | 90 | 指定Eureka Client间隔多久需要向Eureka Server发送心跳来告知Eureka Server该实例还存活 |
定时任务参数
| 参数 | 默认值 | 说明 |
|---|---|---|
| eureka.client.cache-refresh-executor-thread-pool-size | 2 | 刷新缓存的CacheRefreshThread的线程池大小 |
| eureka.client.cache-refresh-executor-exponential-back-off-bound | 10 | (刷新缓存)调度任务执行超时时下次的调度的延迟时间 |
| reka.client.heartbeat-executor-thread-pool-size | 2 | 心跳线程HeartBeatThread的线程池大小 |
| eureka.client.heartbeat-executor-exponential-back-off-bound | 10 | (心跳执行)调度任务超时时下次的调度的延时时间 |
| eureka.client.registry-fetch-interval-seconds | 30 | CacheRefreshThread线程调度频率 |
| eureka.client.eureka-service-url-poll-interval-seconds | 5*60 | AsyncResolver.updateTask刷新Eureka Server地址的时间间隔 |
| eureka.client.initial-instance-info-replication-interval-seconds | 40 | InstanceInfoReplicator将实例信息变更同步到Eureka Server的初始延时时间 |
| eureka.client.instance-info-replication-interval-seconds | 30 | InstanceInfoReplicator将实例信息变更同步到Eureka Server的时间间隔 |
| ureka.instance.lease-renewal-interval-in-seconds | 30 | Eureka Client向Eureka Server发送心跳的时间间隔 |
http参数
Eureka Client底层httpClient与Eureka Server通信,提供的先关参数
| 参数 | 默认值 | 说明 |
|---|---|---|
| eureka.client.eureka-server-connect-timeout-seconds | 5 | 连接超时时间 |
| eureka.client.eureka-server-read-timeout-seconds | 8 | 读超时时间 |
| eureka.client.eureka-server-total-connections | 200 | 连接池最大活动连接数 |
| eureka.client.eureka-server-total-connections-per-host | 50 | 每个host能使用的最大链接数 |
| eureka.client.eureka-connection-idle-timeout-seconds | 30 | 连接池中链接的空闲时间 |
服务端端参数
主要包含这几类:基本参数、response cache参数、peer相参数、http参数
基本参数
| 参数 | 默认值 | 说明 |
|---|---|---|
| eureka.server.enable-self-perservation | true | 是否开启自我保护模式 |
| eureka.server.renewal-percent-threshold | 0.85 | 指定每分钟需要收到续约次数的阈值 |
| eureka.instance.registry.expected-number-of-renews-per-min | 1 | 指定每分钟需要接收到的续约次数值,实际该值在其中被写死为count*2,另外也会被更新 |
| eureka.server.renewal-threshold-update-interval-ms | 15分钟 | 指定updateRenewalThreshold定时任务的调度频率,来动态更新expectedNumberOfRenewsPerMin及numberOfRenewsPerminThreshold值 |
| eureka.server.eviction-interval-timer-in-ms | 60*1000 | 指定EvictionTask定时任务的调度频率,用于剔除过期的实例 |
response cache参数
Eureka Server为了提升自身REST API接口的性能,提供了两个缓存:一个是基于ConcurrentMap的readOnlyCacheMap,一个是基于Guava Cache的readWriteCacheMap。其相关参数如下:
| 参数 | 默认值 | 说明 |
|---|---|---|
| eureka.server.use-read-only-response-cache | true | 是否使用只读的response-cache |
| eureka.server.response-cache-update-interval-ms | 30*1000 | 设置CacheUpdateTask的调度时间间隔,用于从readWriteCacheMap更新数据到readOnlyCacheMap。仅仅在eureka.server.use-read-only-response-cache为true的时候生效 |
| eureka.server.response-cache-auto-expiration-in-seconds | 180 | 设置readWriteCacheMap的expireAfterWrite参数,指定写入多长时间过过期 |
peer相关参数
| 参数 | 默认值 | 说明 |
|---|---|---|
| eureka.server.peer-eureka-nodes-update-interval-ms | 10分钟 | 指定peersUpdateTask调度的时间间隔,用于从配置文件刷新peerEurekaNodes节点的配置信息(‘eureka.client.serviceUrl相关zone的配置’) |
| eureka.server.peer-eureka-status-refresh-time-interval-ms | 30*1000 | 指定更新peer node状态信息的时间间隔 |
http参数
Eureka Server需要与其他peer节点进行通信,复制实例信息,其底层使用httpClient,提供相关的参数
| 参数 | 默认值 | 说明 |
|---|---|---|
| eureka.server.peer-node-connect-timeout-ms | 200 | 连接超时时间 |
| eureka.server.peer-node-read-timeout-ms | 200 | 读超时时间 |
| eureka.server.peer-node-total-connections | 1000 | 连接池最大活动连接数 |
| eureka.server.peer-node-total-connections-per-host | 500 | 每个host能使用的最大连接数 |
| eureka.server.peer-node-connection-idle-timeout-seconds | 30 | 连接池中连接的空闲时间 |
参数调优
常见问题
1.为什么服务下线了,Eureka Server接口返回的信息还会存在?
2.为什么服务上线了,Eureka Client不能及时获取到?
3.为什么会有一下提示:
EMERGENCY!EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY’RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE
解决方法:
1.Eureka Server并不是强一致的,因此registry中会议保留过期的实例信息。原因如下:
- 应用实例异常挂掉,没能在挂掉之前告知Eureka Server要下线掉该服务实例信息。这个就需要依赖Eureka Server的EvictionTask去剔除。
- 应用实例下线是有告知Eureka Server下线,但是由于Eureka Server的REST API有response cache,因此需要等待缓存过期才能更新。
- 由于Eureka Server开启并以入了SELF PRESERVATION(自我保护)模式,导致registry的信息不会因为过期而被剔除掉,直到退出SELF PRESERVATION(自我保护)模式。
针对Client下线而没有通知Eureka Server的问题,可以调整EvictionTask的调度频率,比如把默认的时间间隔60s,调整为5s:
eureka:server:eviction-interval-timer-in-ms: 5000
针对response cache的问题,可以根据情况考虑关闭readOnlyCacheMap:
eureka:server:use-read-only-response-cache: false
或者调整readWriteCacheMap的过期时间:
eureka:server:response-cache-auto-expiration-in-seconds: 60
针对SELF PRESERVATION(自我保护)的问题,在测试环境可以将enable-self-preservation设置为false:
eureka:server:enable-self-preservation: false
关闭之后会提示:
THE SELF PRESER VAT ION MODE IS TURNED OFF. THIS MAY NOT PRO TECT INSTANCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.
或者:
RENEWALS ARE LESSER THAN THE THRESHOLD.THE SELF PRESERVATION MODE IS TURNED OFF.THIS MAY NOT PROTECT INSTANCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.
2.针对新服务上线,Eureka Client获取不及时的问题,在测试环境,可以适当提高client端拉取Server注册信息的频率,例如下面将默认的30s改为5s:
eureka:client:registry-fetch-interval-seconds: 5
3.在实际生产过程中,经常会有网络抖动等问题造成服务实例与Eureka Server的心跳未能如期保持,但是服务实例本身是健康的,这个时候如果按照租约剔除机制剔除的话,会造成误判无果大范围误判的话,可能导致整个服务注册列表的大部分注册信息被删除,从而没有可用服务。Eureka为了解决这个问题引入了SELF PRESERVATION机制,当最近一分钟接收到的租约次数小于等于指定阈值的话,则关闭租约失效剔除,禁止定时任务失效的实例,从而保护注册信息。
在生产环境下,可以吧renewwalPercentThreshold及leaseRenewalIntervalInSeconds参数调小一点,从而提高触发SELF PRESERVATION机制的阈值。
eureka:instance:lease-renewal-interval-in-seconds: 10 #默认是30renewal-percent-threshold: 0.49 #默认是0.85
监控指标
Eureka内置了基于servo的指标统计,具体在com.netflix.eureka.util.EurekaMonitors。Spring Boot 2.x版本改为使用Micrometer,不再支持Neflix Servo,转而支持Neflix Servo的替代品Neflix Spectator。不过对于Servo,可以通过DefaultMonitorRegistry.getInstance().getRegisteredMonitors来获取所有注册了的Monitor,进而获取其指标值。
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//package com.netflix.eureka.util;import com.netflix.appinfo.AmazonInfo;
import com.netflix.appinfo.ApplicationInfoManager;
import com.netflix.appinfo.DataCenterInfo;
import com.netflix.appinfo.AmazonInfo.MetaDataKey;
import com.netflix.appinfo.DataCenterInfo.Name;
import com.netflix.servo.DefaultMonitorRegistry;
import com.netflix.servo.annotations.DataSourceType;
import com.netflix.servo.annotations.Monitor;
import com.netflix.servo.monitor.Monitors;
import java.util.concurrent.atomic.AtomicLong;public enum EurekaMonitors {// 自启动以来收到的总续约次数RENEW("renewCounter", "Number of total renews seen since startup"),// 自启动以来收到的总取消租约次数CANCEL("cancelCounter", "Number of total cancels seen since startup"),// 自启动以来查询registry的总次数GET_ALL_CACHE_MISS("getAllCacheMissCounter", "Number of total registery queries seen since startup"),// 自启动以来delta查询registry的总次数GET_ALL_CACHE_MISS_DELTA("getAllCacheMissDeltaCounter", "Number of total registery queries for delta seen since startup"),// 自启动以来使用remote region查询registry的总次数GET_ALL_WITH_REMOTE_REGIONS_CACHE_MISS("getAllWithRemoteRegionCacheMissCounter", "Number of total registry with remote region queries seen since startup"),// 自启动以来使用remote region及delta方式查询registry的总次数GET_ALL_WITH_REMOTE_REGIONS_CACHE_MISS_DELTA("getAllWithRemoteRegionCacheMissDeltaCounter", "Number of total registry queries for delta with remote region seen since startup"),// 自启动以来查询delta的总次数GET_ALL_DELTA("getAllDeltaCounter", "Number of total deltas since startup"),// 自启动以来传递regions查询delta的总次数GET_ALL_DELTA_WITH_REMOTE_REGIONS("getAllDeltaWithRemoteRegionCounter", "Number of total deltas with remote regions since startup"),// 自启动以来查询'/{version}/apps'的次数GET_ALL("getAllCounter", "Number of total registry queries seen since startup"),// 自启动以来传递regions参数查询'/{version}/apps'的次数GET_ALL_WITH_REMOTE_REGIONS("getAllWithRemoteRegionCounter", "Number of total registry queries with remote regions, seen since startup"),// 自启动以来请求/{version}/apps/{appId}的总次数GET_APPLICATION("getApplicationCounter", "Number of total application queries seen since startup"),// 自启动以来register的总次数REGISTER("registerCounter", "Number of total registers seen since startup"),// 自启动以来剔除过期实例的总次数EXPIRED("expiredCounter", "Number of total expired leases since startup"),// 自启动以来statusUpdate的总次数STATUS_UPDATE("statusUpdateCounter", "Number of total admin status updates since startup"),// 自启动以来deleteStatusOverride的总次数STATUS_OVERRIDE_DELETE("statusOverrideDeleteCounter", "Number of status override removals"),// 自启动以来收到cancel请求时对应实例找不到的次数CANCEL_NOT_FOUND("cancelNotFoundCounter", "Number of total cancel requests on non-existing instance since startup"),// 自启动以来收到renew请求时对应实例找不到的次数RENEW_NOT_FOUND("renewNotFoundexpiredCounter", "Number of total renew on non-existing instance since startup"),REJECTED_REPLICATIONS("numOfRejectedReplications", "Number of replications rejected because of full queue"),FAILED_REPLICATIONS("numOfFailedReplications", "Number of failed replications - likely from timeouts"),// 由于开启rate limiter被丢弃的请求数量RATE_LIMITED("numOfRateLimitedRequests", "Number of requests discarded by the rate limiter"),// 如果开启rate limiter的话,将被丢弃的请求数RATE_LIMITED_CANDIDATES("numOfRateLimitedRequestCandidates", "Number of requests that would be discarded if the rate limiter's throttling is activated"),// 开启rate limiter时请求全量registry被丢弃的请求数RATE_LIMITED_FULL_FETCH("numOfRateLimitedFullFetchRequests", "Number of full registry fetch requests discarded by the rate limiter"),// 如果开启rate limiter时请求全量registry将被丢弃的请求数RATE_LIMITED_FULL_FETCH_CANDIDATES("numOfRateLimitedFullFetchRequestCandidates", "Number of full registry fetch requests that would be discarded if the rate limiter's throttling is activated");private final String name;private final String myZoneCounterName;private final String description;@Monitor(name = "count",type = DataSourceType.COUNTER)private final AtomicLong counter = new AtomicLong();@Monitor(name = "count-minus-replication",type = DataSourceType.COUNTER)private final AtomicLong myZoneCounter = new AtomicLong();private EurekaMonitors(String name, String description) {this.name = name;this.description = description;DataCenterInfo dcInfo = ApplicationInfoManager.getInstance().getInfo().getDataCenterInfo();if (dcInfo.getName() == Name.Amazon) {this.myZoneCounterName = ((AmazonInfo)dcInfo).get(MetaDataKey.availabilityZone) + "." + name;} else {this.myZoneCounterName = "dcmaster." + name;}}public void increment() {this.increment(false);}public void increment(boolean isReplication) {this.counter.incrementAndGet();if (!isReplication) {this.myZoneCounter.incrementAndGet();}}public String getName() {return this.name;}public String getZoneSpecificName() {return this.myZoneCounterName;}public String getDescription() {return this.description;}public long getCount() {return this.counter.get();}public long getZoneSpecificCount() {return this.myZoneCounter.get();}public static void registerAllStats() {EurekaMonitors[] var0 = values();int var1 = var0.length;for(int var2 = 0; var2 < var1; ++var2) {EurekaMonitors c = var0[var2];Monitors.registerObject(c.getName(), c);}}public static void shutdown() {EurekaMonitors[] var0 = values();int var1 = var0.length;for(int var2 = 0; var2 < var1; ++var2) {EurekaMonitors c = var0[var2];DefaultMonitorRegistry.getInstance().unregister(Monitors.newObjectMonitor(c.getName(), c));}}
}
相关文章:
Spring Cloud Netflix Eureka的参数调优
下面主要分为Client端和Server端两大类进行简述,Eureka的几个核心参数 客户端参数 Client端的核心参数 参数默认值说明eureka.client.availability-zones告知Client有哪些region以及availability-zones,支持配置修改运行时生效eureka.client.filter-o…...
Wireshark不显示Thrift协议
使用Wireshark对thrift协议进行抓包,但是只显示了传输层的tcp协议: "右键" -> "Decode As" 选择thrift的tcp端口 将“当前”修改为Thrift,然后点击“确定” 设置后,可以发现Wireshark里面显示的协议从Tcp变…...
VMware虚拟机安装openEuler系统(一)(2024)
目录 一、下载ISO镜像 二、开始创建虚拟机 通过实践是学习openEuler开源Linux系统的最佳方式。因此我们首先得搭建一个openEuler实战环境,文章是在Windows系统上使用VMware Workstation虚拟化软件,安装和学习openEuler开源Linux操作系统。 使用虚拟机…...
Rust入门
文章目录 一、HelloWorld二、控制台输入 以最简单的两个Rust程序例子入门Rust。首先需要下载安装Rust,之后在VSCode或Clion中运行Rust需要下载Rust插件 一、HelloWorld fn main(){println!("Hello World!"); }二、控制台输入 use std::io::stdin; fn …...
RabiitMQ延迟队列(死信交换机)
Dead Letter Exchange(死信交换机) 在MQ中,当消息成为死信(Dead message 死掉的信息)后,消息中间件可以将其从当前队列发送到另一个队列中,这个队列就是死信队列。而 在RabbitMQ中,由…...
浅谈应该遵守的伦敦银交易规则
做伦敦银投资的朋友应遵守伦敦银交易规则,伦敦银交易规则不是指那些伦敦银交易技巧,而是在这个市场中要遵循的一些约定,下面我们就来讨论一下。 风险管理。风险管理即指投资者控制自己一笔乃至整体交易的风险,没有风险管理意识的投…...
安装opencart
一、安装模板 Install SO Emarket Opencart 4 Theme 一:so_emarket_quick2 二:theme package installation 1、installed opencart Default 2、Extensions->Installer->Upload->so_emarket_theme_oc4011_home21_to_home35_v2.0.3->so_theme…...
Qt PCL学习(一):环境搭建
参考 (QT配置pcl)PCL1.12.1QT5.15.2vs2019cmake3.22.4vtk9.1.0visual studio2019Qt5.15.2PCL1.12.1vtk9.1.0cmake3.22.2 本博客用到的所有资源 版本一览:Visual Studio 2019 Qt 5.15.2 PCL 1.12.1 VTK 9.1.0https://pan.baidu.com/s/1xW7xCdR5QzgS1_d1NeIZpQ?pw…...
代码随想录算法训练营第四十二天 | 416. 分割等和子集
题目链接:416. 分割等和子集 文章讲解:代码随想录 416. 分割等和子集讲解 视频讲解:动态规划之背包问题,这个包能装满吗?| LeetCode:416.分割等和子集 思路和解法 题目: 给你一个 只包含正整…...
Spring GateWay
概述简介 能干什么 反向代理 鉴权 流量控制 熔断 日志监控 Spring Cloud Gateway 与Zuul的区别 在SpringCloud Finchley正式版之前,Spring Cloud推荐的网关是 Netflix提供的Zuul: 1、Zuul 1.x,是一个基于阻塞Ⅳ/O的APl Gateway 2、Zuul 1.x基于Servl…...
介绍一个关于 JSON 可视化的网站
最近在看到一个比较好玩的网站,可以将 JSON以可视化的方式展现出现,比如存在一下JSON数据: {"id": "f3bbc3bc-9f34-4bf7-8a0f-7e6f6e6fbb9a","isActive": false,"age": 25,"name": "…...
系统架构设计师-22年-上午答案
系统架构设计师-22年-上午答案 更多软考资料 https://ruankao.blog.csdn.net/ 1 ~ 10 1 云计算服务体系结构如下图所示,图中①、②、③分别与 SaaS PaaS Iaas相对应,图中①、②、③应为(1) #mermaid-svg-xqMbIVMC8pWrne2L {font-family:"trebuch…...
2024 年改变行业的人工智能主要趋势
1、导读 当我们迈入 2024 年时,了解人工智能趋势至关重要。它们不仅仅涉及技术进步;还涉及技术进步。它们意味着我们解决问题、做出决策和展望未来的方式发生了转变。本文旨在探索这些变革趋势,并强调人工智能如何不断突破可能性的界限&…...
【Linux Day15 TCP网络通讯】
TCP网络通讯 TCP编程流程 接口介绍 socket()方法是用来创建一个套接字,有了套接字就可以通过网络进行数据的收发。创建套接字时要指定使用的服务类型,使用 TCP 协议选择流式服务(SOCK_STREAM)。 **bind()方法是用来指定套接字使…...
力扣:78. 子集
回溯解法思路: 1.跟前面的组合题目有相同的点,主要区别在于:组合题目是遍历到符合条件的组合时加入li1集合中,子集题目是每递归一次就要把结果加入到li1集合中,并遍历但nums数组的最后。其他点和组合问题一样。 clas…...
(29)数组异或操作
文章目录 每日一言题目解题思路方法一方法二 代码方法一方法二 结语 每日一言 泉涸,鱼相与处于陆,相呴以湿,相濡以沫,不如相忘于江湖。 --庄子内篇大宗师 题目 题目链接:数组异或操作 给你两个整数,n 和…...
mac检查CPU温度和风扇速度软件:Macs Fan Control Pro 1.5.17中文版
Macs Fan Control Pro for Mac是一款专业的电脑风扇控制工具,旨在帮助Mac用户有效控制电脑的风扇速度,提高电脑的运行效率和稳定性。 软件下载:Macs Fan Control Pro 1.5.17中文版 该软件支持多种风扇控制模式和预设方案,用户可以…...
数据结构——单链表详解
目录 前言 一.什么是链表 1.概念 编辑 2.分类 二.单链表的实现(不带头单向不循环链表) 2.1初始化 2.2打印 2.3创建新节点 2.4头插、尾插 2.5头删、尾删 2.6查找 2.7在指定位置之前插入 2.8在指定位置之后插入 2.9删除pos位置 2.10删除pos之后的 2.11销毁链表…...
Unity接入GVoice腾讯实时语音
Unity接入GVoice腾讯实时语音 一、介绍二、注册GVoice创建项目语音服务1.创建项目2.申请语音权限3.项目管理查看SDK初始化的一些参数和基本信息4.GVoice检测 三、SDK下载SDK是分为两种类型:独立版集成板 SDK放入Unity工程中 四、语音代码写法五、GVoice踩坑语音权限…...
【Spring基础】从0开始学习Spring(2)
前言 在上篇文章,我已经讲了Spring中最核心的知识点:IoC(控制反转)以及DI(依赖注入)。这篇文章,我将讲一下关于Spring框架中的其它比较琐碎但是又还是挺重要的知识点,因此ÿ…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...
comfyui 工作流中 图生视频 如何增加视频的长度到5秒
comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗? 在ComfyUI中实现图生视频并延长到5秒,需要结合多个扩展和技巧。以下是完整解决方案: 核心工作流配置(24fps下5秒120帧) #mermaid-svg-yP…...
Axure 下拉框联动
实现选省、选完省之后选对应省份下的市区...
Linux基础开发工具——vim工具
文章目录 vim工具什么是vimvim的多模式和使用vim的基础模式vim的三种基础模式三种模式的初步了解 常用模式的详细讲解插入模式命令模式模式转化光标的移动文本的编辑 底行模式替换模式视图模式总结 使用vim的小技巧vim的配置(了解) vim工具 本文章仍然是继续讲解Linux系统下的…...
PostgreSQL 与 SQL 基础:为 Fast API 打下数据基础
在构建任何动态、数据驱动的Web API时,一个稳定高效的数据存储方案是不可或缺的。对于使用Python FastAPI的开发者来说,深入理解关系型数据库的工作原理、掌握SQL这门与数据库“对话”的语言,以及学会如何在Python中操作数据库,是…...
Spring事务传播机制有哪些?
导语: Spring事务传播机制是后端面试中的必考知识点,特别容易出现在“项目细节挖掘”阶段。面试官通过它来判断你是否真正理解事务控制的本质与异常传播机制。本文将从实战与源码角度出发,全面剖析Spring事务传播机制,帮助你答得有…...
