etcd实现大规模服务治理应用实战
导读:服务治理目前越来越被企业建设所重视,特别现在云原生,微服务等各种技术被更多的企业所应用,本文内容是百度小程序团队基于大模型服务治理实战经验的一些总结,同时结合当前较火的分布式开源kv产品etcd,不仅会深入剖析ectd两大核心技术Raft与boltdb的实现原理,也会披露服务治理真实实践的经验,希望帮助大家在服务治理的道路上获得更多帮助。
一、服务治理概念介绍
服务治理是IT治理的一部分,它关注服务生命周期中的相关要素,其重点环节包括服务注册和发现、服务平滑升级、流量监控、流量管控、故障定位、安全性等。
需要框架源码的朋友可以看我个人简介联系我。推荐分布式架构源码
服务是需要"治理"的,但是治理是需要成本的,如果一个服务的业务逻辑简单,运行流程清晰,出现问题也能及时定位和回滚,那么该服务治理的成本可能非常低,甚至只需要人工处理就行,但是在复杂业务中,服务的提供者和服务的使用者可能分别运行在不同的进程中(甚至在不同的物理节点上),并由不同的团队开发和维护。团队协作和服务协同,都需要进行大量的协调工作。协调工作越多,复杂度越高,这样就有了服务治理的需求,通过建设统一的服务治理平台,就可以有有效的提升业务的服务治理能力,包括协同的规范化、实时监控,不断优化调用链路的效率,以及辅助降低依赖复杂度,规避风险等。在大型业务系统中,服务治理已经是技术架构中必不可缺的一部分,也是整个业务系统最重要的基础设施之一。
上图是网上流传的netflix的服务拓扑图,图中密密麻麻的白色小点就是netflix的服务节点,节点之间的连线表明服务之间有调用,节点和连线构成了复杂的服务调用链,如此庞大的应用系统必须要通过一个强力的服务治理平台来进行管理。
服务治理本质上是对服务生命周期的管控,因而服务治理平台的核心需求就是如何解决服务生命周期中的痛点问题,其包括以下几个方面:
1、注册和发现
服务调用方在调用服务之前必须要得到服务提供方的地址,也就是调用方需要通过一种方式“发现“服务提供方,这就是服务发现。而要完成服务发现,就需要将服务提供方的信息存储到某个载体,这个存储的动作即是”服务注册“,而存储的载体则称为”服务注册中心“。在任何一个服务治理平台中,"注册中心"是必不可少的一个模块。服务注册和发现是服务治理中最基础的功能,在服务生命周期中,它负责服务的初始环节。
2、流量监控
在服务注册发现之后,就是服务的调用,大量的服务调用,形成了流量。流量监控就是对众多服务间的调用关系、状态的清晰掌控。其主要包括了调用拓扑关系、调用追踪、日志、监控告警等,服务治理通过调用拓扑来整体监控服务调用关系,通过建立监控体系来快速发现、定位问题,从而在整体上感知业务系统的运行状况。在服务生命周期中,流量监控负责服务的运行态感知。
3、流量调度
在业务系统运行过程中,经常会有比如促销、秒杀、明星绯闻等热点问题,或者机房断网、断电、系统大范围升级等突发事件,带来业务系统中局部服务的流量突增突降,这样就需要对服务的流量进行调度和管理。流量管理包括两个方面:从微观的单个服务来说,就是服务调用过程的管理,包括在何时采用何种均衡负载策略、路由策略以及熔断限流策略,这些策略统称为调用策略;从宏观上来说,就是流量分发的管理,可以根据某些流量特征和流量占比进行灰度发布、蓝绿发布等,这些称为流量分发策略。服务调用策略、流量分发策略,都需要通过流量监控收集的调用数据进行分析,从而制定出决策,然后在服务治理平台上落地。流量调度负责服务的运行态管理。
4、服务控制
流量调度的策略如何在服务的提供方和调用方生效,可以重启生效,也可以在运行态实时生效,这就是看服务治理平台对服务的控制力度,服务治理平台在充分建设服务治理能力后,能实时把服务治理的策略向服务进行分发并立即生效。
5、服务安全
每个服务都承载自身的业务职责,一些业务敏感的服务,需要对其他服务的访问进行认证与鉴权,也就是安全问题。
本文把拥有成千上万的服务称之为大型应用系统,该系统的特征是大量的服务、大量的服务实例、以及海量的服务调用,服务治理平台在管理这类业务系统的服务时,需要面对以下巨大的挑战:
1. 高可靠性
大型业务系统,海量的服务调用,错综复杂的调用关系,对服务的可靠性要求很高,很多基层的服务都要求99.99%的可靠性,因而维护这些服务的服务治理平台,其可靠性的要求也非常高,而要达到这么高的可靠性,服务治理平台本身也需要做到多级部署、多地热备、降级隔离、平滑上线等方案。
2. 高性能
在保证可靠性的前提下,服务治理还必须有很高的性能,比如在监控数据中,快速准确的感知到某个服务的出现了单点故障,从而能够将流量分发到该服务的其他进程上去。如果业务系统的服务数不多,调用量不高,那么监控数据量也不会很大,服务的单点故障很容易就能查到,但是在实时的海量调用数据中,一些常规的查询手段要花费大量的时间,等感知到单点故障时,可能已经造成了不可挽回的业务损失。所以性能是考量服务治理平台治理能力的一项重要指标,如何保证高性能,高速的存储、多级缓存、线性部署都是必不可少的。
3. 高扩展
高扩展包含两个方面:大型应用系统的服务,可能是由多个团队在开发运维,其水平和技术能力也是参差不齐的,因而服务治理平台需要提供兼容和扩展的能力,通过扩展性,尽可能的把不同的服务治理起来;同时,在业务系统服务量增长时,服务治理平台也应该具备同步扩展的能力,来保证其高可靠和高性能。
面对海量服务的治理挑战,服务治理平台也需要有一个强大好用的存储工具来应对,etcd就是一个不错的选择。
二、etcd介绍
2.1 etcd发展背景与相关竞品介绍
2013年CoreOS创业团队在构建一款开源,轻量级的操作系统ContainerLinux时,为了应对用户服务多副本之间协调的问题,自研开发的一款用于配置共享和服务发现的高可用KV分布式存储组件——ETCD。
下面我们也针对Zookeeper和Consul两个选型做了一下对比:
· ZooKeeper
ZooKeeper从高可用性,数据一致性,功能这三个方面而言是完全符合需求的,但CoreOS还是坚持自研etcd的原因总结有以下两点:
1. ZooKeeper不支持通过API安全地变更成员,需要人工修改节点配置并重启进程.如果操作有误,有可能导致脑裂等线上故障,同时CoreOS对适配云环境,集群规模的平滑调整,运行时配置的在线变更都是有期望目标的,这方面ZooKeeper的维护成本比较高。
- 高负载读写性能,ZooKeeper在大规模的实例连接情况下性能表现并不佳。
etcd名字是由“/etc”文件夹和”d”分布式系统组成。“/etc”文件夹是用来存储单系统配置数据的,而“etcd”用于存储大规模分布式系统的配置数据,etcd集群可提供高稳定性,高可靠性,高伸缩性和高性能的分布式KV存储服务。etcd是基于复制状态机实现的,由Raft一致性模块,日志模块,基于boltdb持久化存储的状态机组成,可应用于分布式系统的配置管理,服务发现,分布式一致性等等。
ZooKeeper与etcd一样,可解决分布式系统一致性和元数据存储等问题,但是etcd相较于ZooKeeper有以下几点优势:
1. 动态集群成员关系重新配置
2. 高负载下稳定的读写能力
3. 多版本并发控制数据模型
4. 可靠的键监控
5. Lease(租约)原语将连接和会话分离
6. 分布式锁保证API安全性
7. ZooKeeper使用自己的RPC协议,使用受限;而etcd客户端协议是基于gRPC的,可支持多种语言。
· Consul
Consul与etcd解决的是不同的问题,etcd用于分布式一致性KV存储,而Consul侧重于端到端的服务发现,它提供了内置的健康检查,失败检测和DNS服务等等,另外Consul通过RESTfulHTTPAPIs提供KV存储能力.但是当KV使用量达到百万级时,会出现高延迟和内存压力等问题。
一致性算法方面,etcd、Consul基于Raft算法实现数据复制,ZooKeeper则是基于Zab算法实现。Raft算法由Leader选举,日志同步,安全性组成,而Zab协议则由Leader选举、发现、同步、广播组成。
分布式CAP方面,etcd、Consul和ZooKeeper都是CP系统,发生网络分区时,无法写入新数据。
下表是针对三者的关键能力做了一下对比分析:
2.2 etcd核心技术介绍
基于Raft协议实现数据高可用和强一致性
早期数据存储服务引入多副本复制技术方案来解决单点问题,但是无论是主从复制还是去中性化复制,都存在一定的缺陷。主从复制运维困难,且一致性与可用性难以兼顾;去中心化复制,存在各种写入冲突问题需要业务处理。而分布式一致性算法,正是解决多副本复制存在问题的关键。分布式一致性算法,又称为共识算法,最早是基于复制状态机背景下提出来的。Paxos作为第一个共识算法,过于复杂,不容易理解,难以在工程上落地。斯坦福大学的Diego提出的Raft算法,通过将问题拆解为三个子问题,易于理解,降低了工程落地难度。这三个子问题是:Leader选举,日志复制,安全性。
Leader选举
etcd(版本3.4+)中Raft协议定义集群节点有4种状态:Leader、Follower、Candidate、PreCandidate。
正常情况下,Leader节点会按照心跳间隔时间,定时广播心跳消息给Follower节点,以维持Leader身份。Follower收到后回复心跳应答包消息给Leader。Leader都会带有一个任期号(term),任期表示从一次选举开始,赢得选举的节点在该任期内担当Leader。任期号单调递增,在Raft算法中充当逻辑时钟,用于比较各个节点数据新旧,识别过期Leader等等。
当Leader节点异常时,Follower节点会接收Leader的心跳消息超时,当超时时间大于竞选超时时间后,会进入PreCandidate状态,不自增任期号,仅发起预投票(民意调查,防止由于节点数据远远落后于其他节点而发起无效选举),获得大多数节点认可后,进入Candidate状态.进入Candidate状态的节点,会等待一个随机时间,然后发起选举流程,自增任期号,投票给自己,并向其他节点发送竞选投票信息。
当节点B收到节点A竞选消息后,有2种情况:
1. 节点B判断节点A的数据至少和自己一样新,节点A任期号大于节点B任期号,并且节点B未投票给其他候选者,即可投票给节点A,节点A获得集群大多数节点支持,可成为新Leader。
2. 如果节点B也发起了选举,并投票给自己,那么它将拒绝投票给节点A。此时若没有节点可以得到大多数投票支持,则只能等待竞选超时,开启新一轮选举。
日志复制
Raft日志结构如下图所示:
Raft日志由有序索引的一个个条目组成,每个日志条目包含了任期号和提案内容.Leader通过维护两个字段来追踪各个Follower的进度信息.一个是NextIndex,表示Leader发送给该Follower节点的下一个日志条目索引;另一个是MatchIndex,表示该Follower节点已复制的最大日志条目索引。
本文以Client提交“hello=world”提案,至接收到响应的整个流程为例,简单介绍etcd日志复制流程:
1. 当Leader接收到Client提交的提案信息后,生成日志条目,同时遍历各个Follower的日志进度,生成对各个Follower追加日志的RPC消息;
2. 通过网络模块将追加日志的RPC消息广播给各个Follower;
3. Follower接收到追加日志消息并持久化之后,回复Leader已复制最大日志条目索引,即MatchIndex;
4. Leader接收到Follower应答后,更新对应Follower的MatchIndex;
5. Leader根据各个Follower提交的MatchIndex信息,计算出日志条目已提交索引位置,该位置代表日志条目被一半以上节点持久化;
6. Leader通过心跳告知各个Follower已提交日志索引位置;
7. 当Client的提案,被标识为已提交后,Leader回复Client该提案通过。
通过以上流程,Leader同步日志条目给各个Follower,保证etcd集群的数据一致性。
安全性
etcd通过给选举和日志复制增加了一系列规则,来保证Raft算法的安全性。
选举规则:
1. 一个任期号,只能有一个Leader被选举,Leader选举需要集群一半以上节点支持;
2. 节点收到选举投票时,如果候选者最新日志条目的任期号小于自己,拒绝投票,任期号相同但是日志比自己短,同样拒绝投票。
日志复制规则:
1. Leader完全特性,如果某个日志条目在某个任期号中已被提交,则这个日志条目必然出现在更大任期号的所有Leader中;
2. 只附加原则,Leader只能追加日志条目,不能删除已持久化的日志条目;
3. 日志匹配特性,Leader发送日志追加信息时,会带上前一个日志条目的索引位置(用P表示)和任期号,Follower接收到Leader的日志追加信息后,会校验索引位置P的任期号与Leader是否一致,一致才能追加。
boltdb存储技术
ectd的另一个核心技术是boltdb存储,提供高效的b+树的检索能力,同时支持事务操作,他是支撑etcd高性能读写的关键能力之一。
boltdb的实现参见了LMDB(LightningMemory-MappedDatabase)设计思路,基于高效快速的内存映射数据库方案.基于B+树的结构设计。数据文件设计上bolt使用一个单独的内存映射的文件,实现一个写入时拷贝的B+树,这能让读取更快。而且,BoltDB的载入时间很快,特别是在从crash恢复的时候,因为它不需要去通过读log(其实它压根也没有)去找到上次成功的事务,它仅仅从两个B+树的根节点读取ID。
文件存储设计
由于采用了单文件映射存储,所以bolt对文件按指定长度进行分块处理,每块存储不同的内容类型。默认使用4096字节的长度进行分块。每一块的开头有单独的pageid(int64)标识。
文件块的类型有以下几种:
数据文件全景结构
说明:
-
metapage固定在page0与page1位置
-
Pagesize大小固定在4096字节
-
bolt的文件写入采用了本地序(小端序)的模式,比如16进制0x0827(2087)写入的内容为2708000000000000
单文件方案的优势就是不需要做文件的合并删除等操作,只需要在原文件上追加扩展长度就可以了。
查询设计
boltdb提供了非常高效的查询能力,可以先看一下它的对象设计:
从对象设计上,boltdb在加载时,会先loadmeta数据进内存,然后根据bucket,来定位数据块所在的位置,然后再根据key的值,来定位branchnode的位置,然后定位到叶子值节点。
我们以查询为例,来讲解一下,下面是一个基本的查询示例代码:
tx, err := db.Begin(true) // 开启事务if err != nil {return}b := tx.Bucket([]byte("MyBucket")) // 根据名称查询bucketv := b.Get([]byte("answer20")) // 根据key进行查询 fmt.Println(string(v))tx.Commit()
对应上面的代码,下面的序列图,可以更详细的了解一次查询的操作流程:
上面最关键的代码就是search方法,下面是主要的代码片断,已添加了注释说明方便阅读。
func (c *Cursor) search(key []byte, pgid pgid) {p, n := c.bucket.pageNode(pgid)if p != nil && (p.flags&(branchPageFlag|leafPageFlag)) == 0 {panic(fmt.Sprintf("invalid page type: %d: %x", p.id, p.flags))}// 把当前查询节点(page,node)压入栈e := elemRef{page: p, node: n}c.stack = append(c.stack, e)// If we're on a leaf page/node then find the specific node.if e.isLeaf() {c.nsearch(key)return}// if node cached seach by node's inodes fieldif n != nil {c.searchNode(key, n)return}// recursively to load branch page and call search child node againc.searchPage(key, p)
}
三、百度基于etcd打造大规模服务治理建设思路
3.1 具体的挑战
天路是百度小程序团队开发打造的面向大型业务服务治理需求的一套解决方案,其目标之一就是打造成百度的服务治理规范样板。天路由注册中心、可视化管理平台、SDK框架、统一网关、tianlu-mesher五个部分组成,目前已经接入了150+产品线,实例数已达数十万级别。随着接入平台的团队数增多、以及服务实例的快速增长,大量团队间如何轻松的协作以及实现大规模服务治理平台的高可用、高性能一直是天路持续面临的挑战。
3.2 整体架构建设思路与方案
天路作为一个服务治理平台,核心理念是为所有的服务提供便捷的调用,统一的服务监控管理,简化服务的开发和维护成本。我们从以下不同的方面思考基于etcd打造大规模服务治理平台:高可用、高性能、高扩展、易用性。
· 高可用
-
考虑到etcd跨机房调用的高网络延时,我们采用单机房部署,同时我们也实现了主备集群切换的方案,解决在单机房实例全部宕机的情况下,etcd集群不可用的问题。
-
为了降低平台对etcd的强依赖,我们做了etcd降级使用缓存的方案。在监控到etcd集群的性能无法支持当前平台的时候,使用缓存存储实例数据,能够让运维人员在恢复etcd之前,系统不受影响正常运行;etcd恢复之后,切换回etcd集群继续工作。
· 高性能
-
etcd集群的kv查询性能很高,qps能达到10000以上。为了解决在极端并发下的性能问题,注册中心采用多级缓存提升查询效率,降低对etcd的访问压力。
-
服务间调用使用直连的方式,请求不需要经过注册中心进行转发,调用基本没有时间损耗。
· 高扩展
- 考虑到将来服务实例数达到百万级别,我们需要考虑架构的高扩展性。
· 易用性
-
用户通过可视化的管理平台可以查看已注册的服务,也可通过管理平台实时更新服务治理策略的配置,实时调整服务治理策略。
-
将调用日志接入trace平台,用户可通过traceId在trace平台查到整个调用链的记录,便于出错时进行快速的问题定位。
-
多语言 SDK,支持多种rpc技术,包括百度自研的rpc技术brpc和http jsonrpc协议等
架构方案图
3.3 关键的指标与运维目标
此外针对更好的实施服务治理平台的运维,还需要以下的关键考核指标与运维要求。
关键指标:
· 可用性达99.99以上;
· 平响100ms以下。
运维目标:
-
故障发现早
· 配置监控告警,包括注册中心实例健康、etcd平响、内存和cpu监控。
-
故障处理快
· 自动处理:通过noah的回调机制,自动处理一些故障,提高处理速度。
· 手动处理:值班机制。
四、总结
服务治理目前越来越被企业建设所重视,特别现在云原生,微服务等各种技术被更多的企业所应用,但是要真正在应用好,融合好,还是有非常多的挑战,除了一套成熟的服务治理产品外,包括团队整体对服务治理的认知,技术经验的深淀,遵循服务化的设计能力水平的能力等,都会影响到最终的实施效果。本文也仅在服务治理产品选型上给大家一些启发,希望在服务治理的道路上帮大家走得更好更稳。
相关文章:

etcd实现大规模服务治理应用实战
导读:服务治理目前越来越被企业建设所重视,特别现在云原生,微服务等各种技术被更多的企业所应用,本文内容是百度小程序团队基于大模型服务治理实战经验的一些总结,同时结合当前较火的分布式开源kv产品etcd,…...

目标检测中 anchor base和anchor free
目标检测中两种不同anchor的生成 趋势:anchor free越来越受到实时性检测的青睐,,,...

TypeC拓展设计方案|TypeC转HDMI设计方案|CS5261/CS5265芯片设计参数对比
集睿智远CS5261/CS5265都可以用于设计TypeC转HDMI方案,低成本TypeC扩展坞设计方案,而两者也有些差异:1.CS5261支持DP1.4输入,一个HDMI1.4输出,即HDMI输出为4K30HZ ;CS5265DP1.4到HDMI2.0转换芯片,即HDMI输出…...

SQL Developer中的Active Data Guard
这篇文章 Display Data Guard configuration in SQL Developer 中,用SQL Developer展示了多种ADG的拓扑。 今天自己也试了一下,还蛮简单的,其实最麻烦的部分在于搭建一个ADG环境。 假设我已有一个ADG环境,即最典型的环境&#x…...
谈谈FFT到底有何用
谈谈FFT到底有何用 FFT快速傅里叶变换是数字信号处理的经典算法,学过DSP或者芯片设计的人大多知道这个算法;但是,大家是否想过,为什么数字信号处理会有那么多FFT呢有人会说,为了分析信号的频谱;那么下边的问题就是,分析频谱对我们的日常需求,比如手机打电话,雷达测量速度和方向…...

MATLAB | 如何绘制这样的描边散点图?
part.-1 前前言 最近略忙可能更新的内容会比较简单,见谅哇,今日更新内容: part.0 前言 看到gzhBYtools科研笔记(推荐大家可以去瞅瞅,有很多有意思的图形的R语言复现!!)做了这样一张图: 感觉很…...

偶数科技与白鲸开源完成兼容性认证
近日,偶数科技自主研发的云原生分布式数据库 OushuDB v5.0 完成了与白鲸开源集成调度工具 WhaleStudio v2.0 的兼容性相互认证测试。 测试结果显示,双方产品相互良好兼容,稳定运行、安全,同时可以满足性能需求,为企业级…...

【机器学习】Feature scaling and Learning Rate (Multi-variable)
Feature scaling and Learning Rate 1、数据集2、学习率2.1 α \alpha α 9.9e-72.2 α \alpha α 9e-72.3 α \alpha α 1e-7 3、特征缩放3.1 特征缩放的原因3.2 Z-score 归一化3.3 预测3.4 损失等值线 导入所需的库 import numpy as np np.set_printoptions(precision…...

windows编译ncnn
官方代码https://github.com/Tencent/ncnn/wiki/how-to-build#build-for-windows-x64-using-visual-studio-community-2017 编译工具 visual studio 2017 一、编译protobuf 1、下载protobuf protobuf-3.11.2:https://github.com/google/protobuf/archive/v3.11…...

C++和Lua交互总结
C和Lua交互总结 Chapter1. C和Lua交互总结一、Lua与C的交互机制——Lua堆栈二、堆栈的操作三、C 调用 Lua1)C获取Lua值2)C调用Lua函数示例: 四、Lua 调用 C包装C函数 最后总结一下 Chapter1. C和Lua交互总结 原文链接:https://bl…...

nvm安装和切换node版本
1、nvm list查看已安装的node版本 2、查看当前使用的npm和node版本 3、安装某版本的node 4、 切换node版本...

每日一题8.2 2536
2536. 子矩阵元素加 1 给你一个正整数 n ,表示最初有一个 n x n 、下标从 0 开始的整数矩阵 mat ,矩阵中填满了 0 。 另给你一个二维整数数组 query 。针对每个查询 query[i] [row1i, col1i, row2i, col2i] ,请你执行下述操作:…...

适配器模式(Adapter)
适配器模式用于将一个接口转换成用户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。 Adapter is a structural design pattern that…...

Spring学习笔记——1
Spring学习笔记——1 一、Spring入门1.1、学习路线1.2、传统Javaweb开发困惑及解决方法1.3、三种思想的提出和框架概念1.3.1、IoC、DI和AOP思想提出1.3.2、框架的基本特点 1.4、Spring概述1.5、BeanFactory快速入门1.6、ApplicationContext快速入门1.7、BeanFactory与Applicati…...

leetcode 406. 根据身高重建队列
2023.8.2 这题一开始有点让人懵逼的是有两个维度,一个是身高,还一个是前面人高于自己的人数。这种题一般需要先固定一个维度,再去确定另外一个维度,不要想着兼顾。 经过纸上模拟,我的思路是先通过身高进行从大到小排序…...
Matlab实现AGNES算法
在数据分析和机器学习中,聚类是一种常用的无监督学习方法,它可以将数据点按照某种相似度标准进行分组,从而发现数据中的结构和模式。聚类算法有很多种,其中一种比较经典的是AGNES算法,它是一种基于层次的聚类算法&…...

STM32F4_外部SRAM
目录 前言 1. SRAM控制原理 1.1 SRAM功能框图 1.2 SRAM读写时序 2. FSMC简介 2.1 FSMC架构 2.2 FSMC地址映射 2.3 FSMC控制SRAM时序 3. FSMC结构体 4. 库函数配置FSMC 5. 实验程序 5.1 main.c 5.2 SRAM.c 5.3 SRAM.h 前言 STM32F4自带了192K字节的SRAM࿱…...

Java的代理模式
java有三种代理模式 静态代理 jdk动态代理 cglib实现动态代理 代理模式的定义: 为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的…...
FilterAttributeOnClassMethod
目录 1 BadMethodFilterAttribute 2 FilterAttributeOnClassMethod 2.1 OnMethodExecuted 2.2 OnMethodExecutedAsync 2.3 OnMethodExecuting BadMethodFilterAttribute using System; using System.Threading.Tasks; namespace Flatwhite.Core.Tests.Attributes …...
springboot + (mysql/pgsql) + jpa 多数据源(不同类数据源)
配置文件: spring:datasource:primary:jdbc-url: jdbc:mysql://host:3306/数据库?useUnicodetrue&characterEncodingUTF-8&autoReconnecttrue&failOverReadOnlyfalse&serverTimezoneAsia/Shanghai&zeroDateTimeBehaviorconvertToNullusername…...

使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...

页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...

select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...
NPOI Excel用OLE对象的形式插入文件附件以及插入图片
static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...

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、写…...
Java 与 MySQL 性能优化:MySQL 慢 SQL 诊断与分析方法详解
文章目录 一、开启慢查询日志,定位耗时SQL1.1 查看慢查询日志是否开启1.2 临时开启慢查询日志1.3 永久开启慢查询日志1.4 分析慢查询日志 二、使用EXPLAIN分析SQL执行计划2.1 EXPLAIN的基本使用2.2 EXPLAIN分析案例2.3 根据EXPLAIN结果优化SQL 三、使用SHOW PROFILE…...