当前位置: 首页 > news >正文

ShardingSphere-Proxy 数据库协议交互解读

数据库协议对于大部分开发者来说算是比较冷门的知识,一般的用户、开发者都是通过现成的数据库客户端、驱动使用数据库,不会直接操作数据库协议。不过,对数据库协议的特点与流程有一些基本的了解,有助于开发者在排查数据库功能、性能问题的过程中提供一些发现问题的思路。

本文将简要介绍常用的 MySQL、PostgreSQL 等开源数据库协议的特点,并大致解读 ShardingSphere-Proxy 与客户端在数据库协议层面的交互。

文章目录

    • ShardingSphere 接入端介绍
    • 数据库协议特点简要介绍
      • MySQL 协议
      • PostgreSQL 协议
      • openGauss 协议
    • ShardingSphere-Proxy 前端交互流程解读
      • ShardingSphere-Proxy 与数据库协议的关系
      • 接入端整体流程
      • ShardingSphere-Proxy 前端流程
    • 如何向 ShardingSphere 社区反馈疑似 Proxy 协议问题?
      • 问题复现方式简单的可提供 Demo
      • 直接提交问题修复 PR
      • 使用抓包工具捕获客户端与 Proxy 的通讯流量

ShardingSphere 接入端介绍

Apache ShardingSphere 由 ShardingSphere-JDBC 和 ShardingSphere-Proxy 这 2 款既能够独立部署,又支持混合部署配合使用的产品组成。它们均提供标准化的基于数据库作为存储节点的增量功能,可适用于如 Java 同构、异构语言、云原生等各种多样化的应用场景。

在这里插入图片描述

ShardingSphere-JDBC 是一套基于 Java 开发的、实现了标准 JDBC 的 SDK,具备轻量级、高性能等特点,但局限性同样也很明显。不过,ShardingSphere-JDBC 在接入方面的局限性,在接入端 ShardingSphere-Proxy 得以解决:

  • ShardingSphere-Proxy 理论上支持通过任何数据库客户端、数据库驱动连接,不受限于 Java 等基于 JVM 的语言;
  • 简化数据管理。尤其在使用数据分片或加密等功能的场景,使用 ShardingSphere-Proxy 作为统一入口操作数据,无须考虑数据实际存储的节点或手动进行解密等;
  • 提供统一运维管控能力。集群模式下,可以使用 ShardingSphere-Proxy 统一管理 ShardingSphere 规则与配置;
  • 可执行重量级操作。ShardingSphere-JDBC 与应用在同一进程内,重量级计算和 I/O 操作可能会影响应用性能;而 ShardingSphere-Proxy 作为独立进程启动,支持水平扩展,执行重量级操作不影响应用性能。

数据库协议特点简要介绍

目前互联网上已有不少关于 MySQL 或 PostgreSQL 协议的具体解读,本文不再详细介绍,本节主要介绍各数据库协议的特点,例如协议对 Pipelining 的支持、批量操作在协议的体现等。

MySQL 协议

MySQL 协议是典型的“一问一答”协议,例如使用 Prepared Statement 执行一条 SQL,在协议层面需要分别执行 COM_STMT_PREPARECOM_STMT_EXECUTE
在这里插入图片描述

图片来源 MySQL 文档 https://dev.mysql.com/doc/dev/mysql-server/latest/mysqlx_protocol_use_cases.html

MySQL 自 5.7.12 起增加了一个 X Plugin,让 MySQL 在保持原本关系型存储的基础上,增加了文档类型存储的支持。
X Plugin 使用了一套新的通讯协议 X Protocol,默认使用端口 33060,协议支持 pipelining,即客户端一次可以发送一批命令给客户端,减少“一问一答”的模式带来的 RTT(Round-trip time,来回通讯延时)。例如使用 Prepared Statement 执行一条 SQL,在协议层面分为 Prepare 和 Execute 步骤,但在网络传输层面上,这两个步骤可以合并发送。相比原来的协议,理论上能够减少一次 RTT。
在这里插入图片描述
图片来源 MySQL 文档 https://dev.mysql.com/doc/dev/mysql-server/latest/mysqlx_protocol_use_cases.html

不过,目前 MySQL 的 X Plugin 看起来并没有流行的趋势,大多数场景下客户端和服务端还是基于原本的 MySQL 协议进行通讯。
在批量操作的场景下,MySQL 协议执行 Prepared Statement 语句的命令 COM_STMT_EXECUTE 每次只能发送一组参数,“一问一答”的方式显得效率有些低下:
在这里插入图片描述
图片来源 MySQL 文档 https://dev.mysql.com/doc/dev/mysql-server/latest/mysqlx_protocol_use_cases.html

协议本身设计对批量操作的不支持,只能在客户端层面对批量操作进行优化。

以 MySQL Connector/J 为例,参数 rewriteBatchedStatements 启用后,MySQL Connector/J 内部会把通过 addBatch 方法设置的多组参数,合并 insert values 或将 update / delete 组成多语句,在协议层面一次性发送。通过增加少量 CPU 的开销,换取 RTT 的减少。

例如,对一个 Prepared Statement insert 语句,添加多组参数执行:

INSERT INTO tbl VALUES (?, ?, ?);
addBatch [1, "foo", "bar"]
addBatch [2, "baz", "fuz"]

MySQL Connector/J 实际执行的语句:

INSERT INTO tbl VALUES (1, "foo", "bar"),(2, "baz", "fuz");

对于批量 update / delete,MySQL Connector/J 会通过 COM_QUERY 执行多语句,例如:

UPDATE tbl SET name = ? WHERE id = ?;
addBatch ["foo", 1]
addBatch ["bar", 2]

MySQL Connector/J 实际执行的语句:

UPDATE tbl SET name = "foo" WHERE id = 1;UPDATE tbl SET name = "bar" WHERE id = 2;

PostgreSQL 协议

与 MySQL 协议相比,PostgreSQL 协议定义看起来会更简单一些,而且 PostgreSQL 协议支持 Pipelining。
PostgreSQL 的 Extended Query 将 SQL 执行拆解为多个步骤,常用的几个操作有:

  • Parse:SQL 解析为 Prepared Statement;
  • Describe:获取 Prepard Statement 或 Portal 的元数据;
  • Bind:Prepared Statement 绑定实际参数,产生可执行的 Portal;
  • Execute:执行 Portal;
  • Close:关闭 Prepared Statement 或 Portal。

PostgreSQL JDBC 与数据库的协议交互示例如下:
在这里插入图片描述

在批量操作的场景下,客户端可以将多组参数以连续的 Bind、Execute 一次性发送,虽然在协议层上是多个数据包,但在 TCP 传输层面,每次可以发送一批数据包出去。
在这里插入图片描述

支持 Pipelining 的协议,结合 I/O 多路复用,在吞吐量上存在一定的优势。例如基于多路复用 I/O 的数据库驱动 Vert.x PostgreSQL 曾在 TechEmpower Benchmark 第 15 轮测试的 Single Query 场景(数据库点查)得到第一名的成绩。
在这里插入图片描述
图片来源 https://www.techempower.com/benchmarks/#section=data-r15&test=db

openGauss 协议

openGauss 在沿用 PostgreSQL Protocol 3.0 的情况下,增加了一个 Batch Bind 的消息。PostgreSQL 协议的 Bind 消息一次只能发送一组参数,openGauss 新增的 Batch Bind 支持同时发送多组参数。
在这里插入图片描述
另外,openGauss 在认证安全性方面进行了增强。协议总体流程与 PostgreSQL 一致。

ShardingSphere-Proxy 前端交互流程解读

ShardingSphere-Proxy 与数据库协议的关系

数据库协议如同 HTTP 等协议,是客户端与服务端之间通讯的标准。每个数据库都定义了自己的协议,例如 MySQL 数据库定义了一套自己的协议,还有基于 Protobuf 的 X Protocol;PostgreSQL 也定义了一套自己的协议……

一般用户或开发者都是使用现成的客户端或相应的驱动,协议对于他们来说相对透明。因此,ShardingSphere-Proxy 实现数据库协议并以此对外提供服务,对于用户来说,使用 ShardingSphere-Proxy 就如同使用数据库一样。

目前,ShardingSphere-Proxy 支持的数据库协议具体版本为:

  • MySQL Protocol 4.1(自 MySQL 4.1 起)
  • PostgreSQL Protocol 3.0(自 PostgreSQL 7.4 起)
  • openGauss Protocol 3.00 / 3.50 / 3.51

接入端整体流程

ShardingSphere-Proxy 与 ShardingSphere-JDBC 共用 ShardingSphere 内核模块,对用户提供了不同的接入方式。ShardingSphere-Proxy 是一个独立进程存在,以数据库协议对外提供服务;ShardingSphere-JDBC 是一套 SDK,用户直接通过代码调用。
在这里插入图片描述

ShardingSphere-Proxy 前端流程

ShardingSphere-Proxy 前端使用 Netty 实现数据库协议。基于 Netty 事件驱动的方式处理前端连接,让 ShardingSphere-Proxy 前端可以维护较大数量的客户端连接。协议的拆包、编码逻辑主要在 Netty EventLoop 线程内执行。由于 ShardingSphere-Proxy 后端仍然使用 JDBC 与数据库交互,为避免 Netty EventLoop 线程阻塞,协议数据拆包后,会使用专门的线程池执行 ShardingSphere 内核逻辑、数据库交互。
在这里插入图片描述

PacketCodec 主要进行数据的拆包和编码。在前面的数据库协议介绍提到,PostgreSQL 协议支持 pipelining,能够一次发送一批数据包。

示例:下图是 PostgreSQL 客户端使用 Prepared Statement 执行 select current_schema() 语句所对应的请求协议。Prepared Statement 的 SQL 解析、执行等步骤,由客户端一次性发送给服务端执行。
在这里插入图片描述
服务端接收到的就是一串字节流,如何能够把这一串字节流拆分为多个协议包?

以 PostgreSQL 协议格式为例,除了 Startup Message,每个协议包的格式都是 1 字节消息类型 + 4 字节数据长度(包含长度自身)+ 数据,结构如下:
在这里插入图片描述
MySQL 协议数据包格式与此相似。

PacketCodec 只需遵循协议格式定义,即可把接收到的字节流正确拆分。

字节流拆分后,剩余的步骤就是按照数据库协议解析数据,得到要执行的 SQL 与参数。有了 SQL 与参数后,剩余的执行流程就与通过 ShardingSphere-JDBC 执行 SQL 基本一致。

ShardingSphere-Proxy 后端通过 JDBC 执行 SQL 后,得到的结果集为 Java 对象,PacketCodec 会调用具体的编码逻辑,将 Java 对象按照数据库协议转换为字节流,组装成数据包后响应客户端。

在这里插入图片描述
以上就是 ShardingSphere-Proxy 前端数据库协议交互的大致流程。

如何向 ShardingSphere 社区反馈疑似 Proxy 协议问题?

由于 ShardingSphere-Proxy 与数据库的计算能力存在差异,Proxy 对数据库协议的实现尚未达到 100% 的支持度,在使用过程中难免会存在一些不支持的情况,且不支持的情况在不同的数据库客户端、数据库驱动之间存在一定差异。

当用户在使用 Proxy 的过程中,遇到疑似 Proxy 协议实现不完善导致的问题,本文给出一些反馈问题的建议。

问题复现方式简单的可提供 Demo

如果遇到的问题,能够通过构造出简单的代码复现(例如只需使用 Python 语言并安装一些简单的依赖),可以在 issue 中直接提供复现问题的代码与步骤。

案例:社区同学曾经提交过一个 Django.db 连接 ShardingSphere-Proxy MySQL 的事务问题 https://github.com/apache/shardingsphere/issues/18461

作者在 issue 中提供了复现的方式,为 ShardingSphere 团队修复该问题提供了帮助。

直接提交问题修复 PR

对于一些相对简单的问题,ShardingSphere 团队可以提供修复的思路,有条件的社区同学可以考虑直接提交 PR 修复。

案例:社区同学反馈了一个通过 Python asyncpg 连接 ShardingSphere-Proxy 报错的问题:https://github.com/apache/shardingsphere/issues/23885

该问题为 Python asyncpg 数据库驱动在向 ShardingSphere-Proxy 发送 client_encoding 时,在编码名称上增加了引号。由于 ShardingSphere-Proxy PostgreSQL 没有考虑到编码名称包含引号的情况(PostgreSQL 数据库支持这种情况),导致编码识别报错。
Issue 作者已经具备了复现问题的条件,加上作者具备修复该问题的技能,便在 ShardingSphere 团队的指导下,直接提交了 PR 修复该问题。

使用抓包工具捕获客户端与 Proxy 的通讯流量

对于一些使用异构语言的用户,在使用 ShardingSphere-Proxy 过程中可能会遇到和具体功能不相关、疑似协议层面的问题。由于用户与 ShardingSphere 团队存在技术栈上的差异,ShardingSphere 团队可能无法快速在本地完成问题的复现。此时可以考虑通过捕捉客户端与 ShardingSphere-Proxy 之间网络流量的方式,向 ShardingSphere 社区反馈问题。

抓包工具可以选择 Wireshark 或 tcpdump。工具的使用互联网上有大量资料,本文不展开介绍。

案例:社区同学前段时间提交了一个 .NET MySqlConnector 使用 ShardingSphere-Proxy 报错的问题:
https://github.com/apache/shardingsphere/issues/23857

Issue 中反馈了一个 .NET 连接 ShardingSphere-Proxy 报错的问题,根据堆栈,该报错是在 TryResetConnectionAsync 期间导致的,而且最后抛出异常的地方是在 Protocol 相关代码下,所以这可能是一个 ShardingSphere-Proxy 协议实现与 MySQL 表现不一致导致的问题。

    An error occurred using the connection to database .....MySqlConnector.MySqlProtocolException: Packet received out-of-order. Expected 1; got 2.at MySqlConnector.Protocol.Serialization.ProtocolUtility.<DoReadPayloadAsync>g__AddContinuation|5_0(ValueTask`1 readPacketTask, BufferedByteReader bufferedByteReader, IByteHandler byteHandler, F
unc`1 getNextSequenceNumber, ArraySegmentHolder`1 previousPayloads, ProtocolErrorBehavior protocolErrorBehavior, IOBehavior ioBehavior) in /_/src/MySqlConnector/Protocol/Serialization/ProtocolUtility.cs:
line 476at MySqlConnector.Core.ServerSession.ReceiveReplyAsyncAwaited(ValueTask`1 task) in /_/src/MySqlConnector/Core/ServerSession.cs:line 943at MySqlConnector.Core.ServerSession.TryResetConnectionAsync(ConnectionSettings cs, MySqlConnection connection, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnect
or/Core/ServerSession.cs:line 616

由于该问题的复现具备一定的环境搭建成本,不便于 ShardingSphere 团队在本地复现问题,社区同学也提供了客户端与 Proxy 之间协议通讯流量。

在这里插入图片描述

根据协议抓包结果,ShardingSphere 团队立即确认了该问题为 ShardingSphere-Proxy MySQL 数据包编码逻辑实现问题。


🔗 官方网站:
https://shardingsphere.apache.org

🔗 GitHub:
https://github.com/apache/shardingsphere

🔗 Slack:
https://apacheshardingsphere.slack.com

相关文章:

ShardingSphere-Proxy 数据库协议交互解读

数据库协议对于大部分开发者来说算是比较冷门的知识&#xff0c;一般的用户、开发者都是通过现成的数据库客户端、驱动使用数据库&#xff0c;不会直接操作数据库协议。不过&#xff0c;对数据库协议的特点与流程有一些基本的了解&#xff0c;有助于开发者在排查数据库功能、性…...

基于ubuntu20.4的wine的MDK5软件的安装

本文基于ubuntu20.4安装MDK5的keil软件&#xff0c;由于MDK不提供linux版本的安装软件&#xff0c;因此需要利用wine软件来安装MDK5软件&#xff0c;具体流程包括wine软件安装、MDK5安装及MDK5的lic添加等3部分内容。具体流程如下所示&#xff1a; &#xff08;一&#xff09;…...

Jmeter之直连数据库框架搭建简介

案例简介 通过直连数据库让程序代替接口访问数据库&#xff0c;如果二者预期结果不一致&#xff0c;就找到了程序的缺陷。 下面通过一个案例分析讲解如何实现&#xff1a;获取某个字段值&#xff0c;放在百度上搜索。 实现方式 1、Jmeter本身不具备直连数据库的功能&#xf…...

备战蓝桥杯【高精度乘法和高精度除法】

&#x1f339;作者:云小逸 &#x1f4dd;个人主页:云小逸的主页 &#x1f4dd;Github:云小逸的Github &#x1f91f;motto:要敢于一个人默默的面对自己&#xff0c;强大自己才是核心。不要等到什么都没有了&#xff0c;才下定决心去做。种一颗树&#xff0c;最好的时间是十年前…...

火眼审阅 | 基于NLP和OCR识别技术赋能合同审阅

合同作为确定权利义务的法律文件&#xff0c;贯穿企业内外部活动的所有环节&#xff0c;可见合同数据之于企业是非常重要的数据资产。 合同管理是企业营业中的重要部分&#xff0c;其中合同审核是企业法务的基本工作之一。而对于所有的法务人员一直存在一个问题&#xff1a;合…...

关于在集合中对象比较属性值的问题

关于在集合中对象比较属性值的问题1 问题说明2 问题排查3 总结及伪代码楼主在最近遇到一个场景&#xff0c;项目中有一个校验。 需要将数据库查询的集合对象与前端传递的集合对象进行比较&#xff0c;看数据是否被修改。 1 问题说明 基于上面项目需求&#xff0c;项目为较老的…...

java微信小程序旅游管理系统

本旅游服务软件,主要实现了管理员后端&#xff1a;首页、个人中心、旅游攻略管理、旅游资讯管理、景点信息管理、门票预定管理、用户管理、酒店信息管理、酒店预定管理、推荐路线管理、论坛管理、系统管理,用户前端&#xff1a;首页、景点信息、酒店信息、论坛中心、我的等。总…...

2023年要跟踪的11个销售管理关键指标

销售管理关键指标有&#xff1a;营销合格线索数量&#xff08;MQL&#xff09;、MQL 到 SQL 的转换率、商机赢单率、获客成本、总销售额、客户终身价值&#xff08;LTV&#xff09;、LTV 与 CAC 比率、赢单周期、每客户平均销售额&#xff08;平均客单价&#xff09;、每销售人…...

MongoDB--》基本常用命令使用

目录 数据库操作命令 选择和创建数据库 数据库的删除 集合操作命令 集合的显示创建 集合的隐式创建 集合的删除 文档基本的CRUD&#xff08;增删改查&#xff09; 文档的插入 文档的基本查询 文档的更新 删除文档 数据库操作命令 数据库常用的操作命令如下&#x…...

js浮点数四则运算精度丢失以及toFixed()精度丢失解决方法

js浮点数四则运算精度丢失以及tofixed精度丢失解决方法一、js浮点数计算精度丢失的一些例子1、四则运算精度丢失&#xff1a;2、toFixed() 四舍五入精度丢失&#xff1a;二、浮点数计算精度丢失的原因三、解决办法1、使用 big.js&#xff08;如果有大量连续的计算推荐使用&…...

高姿态下的面部表情识别系统

效果展示&#xff1a; python表情、性别识别面部表情识别 (FER) 在计算机安全、神经科学、心理学和工程学方面有大量应用。由于其非侵入性&#xff0c;它被认为是打击犯罪的有用技术。然而&#xff0c;FER 面临着几个挑战&#xff0c;其中最严重的是它在严重的头部姿势下的预测…...

English Learning - Day59 作业打卡 2023.2.13 周一

English Learning - Day59 作业打卡 2023.2.13 周一引言1. 我有一些急事要处理。2. 这个孩子无忧无虑。3. 那个骑在白马上的姑娘是我姐姐。4. 对方正在给我们公司施加压力迫使我们降价。5. 我的医生告诉我要少吃垃圾食品。6. 我从来不熬夜。7.我早就想跟你聊一聊了。8.我一定不…...

图机器学习

图机器学习1、图机器学习导论1.1图神经网络与普通神经网络的异同2、图的基本表示和特征工程2.1 图的基本表示2.1.1 图的本体设计2.1.2 图的种类2.1.3节点连接数&#xff08;度&#xff09;2.1.4图的基本表示&#xff08;邻接矩阵&#xff09;节点数量少使用2.1.5图的基本表示&a…...

ArcGIS中ArcMap创建渔网Create Fishnet:生成指定大小的格网矢量文件

本文介绍在ArcMap软件中&#xff0c;通过“Create Fishnet”工具创建渔网&#xff0c;从而获得指定大小的矢量格网数据的方法。 首先&#xff0c;我们在创建渔网前&#xff0c;需要指定渔网覆盖的范围。这里我们就以四川省为例&#xff0c;在这一范围内创建渔网&#xff1b;其中…...

TensorRT中的自定义层

TensorRT中的自定义层 文章目录TensorRT中的自定义层9.1. Adding Custom Layers Using The C API9.1.1. Example: Adding A Custom Layer With Dynamic Shape Support Using C重要提示&#xff1a;覆盖检查索引小于pos的连接的格式/类型&#xff0c;但绝不能检查索引大于pos的连…...

部署智能合约到公链

&#x1f341;博主简介&#xff1a; &#x1f3c5;云计算领域优质创作者 &#x1f3c5;2022年CSDN新星计划python赛道第一名 &#x1f3c5;2022年CSDN原力计划优质作者 &#x1f3c5;阿里云ACE认证高级工程师 &#x1f3c5;阿里云开发者社区专…...

Windows server——部署DNS服务(3)

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.管理DNS服务 1.子域 案例 2. 委派 案例 1&#xff09;添加主机记录 …...

9. QML_OpenGL--2. 在QQuick中搭建加载OpenGL框架

1. 说明&#xff1a; OPenGL一般在 QtWidget 中使用&#xff0c;但目前使用 QML 做界面开发是一种趋势&#xff0c;同时在QML中使用OPenGL进行渲染也是十分必要&#xff0c;文章简单介绍如何在QML中使用 OPenGL&#xff0c;搭建了一种基本的框架。整体思路和在 QtWidget 中类似…...

亚马逊云科技携手滴普科技,打造数据智能新标杆

随着企业数字化转型的不断深入&#xff0c;数据对于业务的价值和重要性也逐渐凸显。越来越多企业意识到&#xff0c;只有不断提升底层数据基础平台的性能和能力&#xff0c;才能构建数据驱动的业务&#xff0c;增强企业核心竞争力。作为湖仓一体数据智能基础软件独角兽企业&…...

CGO 跨平台静态编译

什么是跨平台编译&#xff1f; 跨平台编译&#xff1a;即交叉编译&#xff0c;是在一个平台上生成另一个平台上的可执行文件。所谓平台&#xff0c;实际上包含两个概念&#xff1a;体系架构(Architecture)、操作系统 (Operating System&#xff09;。同一个体系架构可以运行不同…...

股票买卖接口怎么来的?

现在股票买卖接口主要是在线上研发&#xff0c;有专业的开发团队进行源码开发和完善&#xff0c;但是&#xff0c;常常会在开发过程中出现问题&#xff0c;也就是遇到一些特殊的情况需要及时处理&#xff0c;那么股票买卖接口怎么开发实现出来的&#xff1f;一、股票买卖接口开…...

【Python学习笔记】29.Python3 面向对象

前言 Python从设计之初就已经是一门面向对象的语言&#xff0c;正因为如此&#xff0c;在Python中创建一个类和对象是很容易的。本章节我们将详细介绍Python的面向对象编程。 Python3 面向对象 如果你以前没有接触过面向对象的编程语言&#xff0c;那你可能需要先了解一些面…...

MySQL 索引

索引 索引是一种用于快速查询和检查数据的数据结构&#xff0c;其本质可以看成是一种排好序的数据结构。理解&#xff1a;索引的作用就相当于书的目录&#x1f4da;&#xff0c;可以根据目录快速定位到想要查看的位置。常见的索引结构&#xff1a;B Tree、B Tree、Hash、红黑树…...

学会使用LoadRunner录制脚本

1.LoadRunner安装 https://blog.csdn.net/weixin_48584088/article/details/129012469 2.Loadrunner的基本概念 LoadRunner是一种适用于许多软件体系架构的自动负载测试工具&#xff0c;从用户关注的响应时间、吞吐量&#xff0c; 并发用户和性能计数器等方面来衡量系统的性…...

产品经理必看的高效产品文档撰写指南

对于企业来说&#xff0c;如何推广自己的产品是一个非常重要的话题&#xff0c;而其中必要的就是创建企业产品宣传册&#xff0c;这对于产品宣传非常重要&#xff0c;尤其是一些大公司&#xff0c;非常重视这种产品展示方式。因为它可以更完整地展现产品&#xff0c;撰写一份合…...

Prometheus 的介绍和安装

介绍 Prometheus 是一个开源的监控和报警系统,最初由SoundCloud于2012年创建,随着越来越多的公司采用Prometheus以及非常活跃的社区,Prometheus于2016年加入云原生基金会,成为Kubernetes之后的第二个托管项目,并于2018年毕业。 特点 通过PromQL来对基于指标名称和键值对…...

ViewModel快速上手1-原生kotlin

ViewModel 原生支持 kotlin 案例 基本案例 viewmodel 是为了保存当当前 activity 切出或者销毁时&#xff0c;如何保存数据&#xff0c;以便下一次创建新的 activity 时进行调用 首先引入 lifecycle 依赖 implementation androidx.lifecycle:lifecycle-extensions:2.2.0 之后…...

Flutter(一)介绍、Dart语言简介

Flutter介绍 纯原生开发主要面临动态化更新和开发成本两个问题&#xff0c;而针对这两个问题&#xff0c;诞生了一些跨平台的动态化框架 跨平台技术简介 Flutter 是 Google 推出并开源的移动应用开发框架&#xff0c;主打跨平台、高保真、高性能。开发者可以通过 Dart 语言开…...

【数据结构】---顺序表的实现

最近学校开始学习数据结构了&#xff0c;没事就手搓一个顺序表。&#x1f308;线性表线性表是n个具有相同特性的数据元素的有限序列&#xff0c;是一种实际中广泛使用的数据结构&#xff0c;常见的线性表有顺序表、链表、栈、队列、字符串。线性表在逻辑上是线性结构&#xff0…...

JavaScript刷LeetCode拿offer-经典高频40题vaScript刷LeetCode拿offer-经典高频40题

工作太忙没有时间刷算法题&#xff0c;面试的时候好心虚。这里双手奉上40道LeetCode上经典面试算法题&#xff0c;整理的内容有点长&#xff0c;建议先收藏&#xff0c;慢慢消化&#xff0c;在来年顺利拿到满意的offer。 1、[LeetCode] 两数之和 给定一个整数数组和一个目标值…...

网站建设有趣小游戏/百度河南代理商

文章目录题目介绍题解1&#xff1a;先分割处理再计算题解2&#xff1a;先逆序再处理使用reverse函数字符串切片功能逆转字符串题解3&#xff1a;直接处理题目介绍 原题链接&#xff1a;HJ1 字符串最后一个单词的长度描述&#xff1a;计算字符串最后一个单词的长度&#xff0c;…...

网站开发进度计划/互联网销售是什么意思

一、什么是MVCC? Multiversion concurrency control (多版本并发控制) 并发访问(读或写)数据库时,对正在事务内处理的数据做多版本的管理.以用来避免写操作的堵塞,从而引发读操作的并发问题 二、 MVCC中的插入流程 数据行当中有隐藏的2列 DB_TRX_ID:数据行的版本号,即事务的…...

做网站需要准备的东西/百度网站怎么做

之前已经搞过了圆形进度条&#xff0c;现在再来看一下折线图的绘制方法。 前面我们已经使用过贝塞尔曲线去画圆了&#xff0c;这次我们就使用它来绘制折线吧。 其实这并不困难&#xff1a; _shapeLayerPath [[UIBezierPath alloc] init]; [_shapeLayerPath moveToPoint:CGPoi…...

wordpress 标题空格/学生个人网页设计模板

当多线程并发访问一个方法(函数)时的线程安全问题 首先, 所有线程访问的是同一个方法吗? NO, 方法之于线程 就好像 程序之于进程一样,每一次执行都是独立的, 是在某一个数据集上的一次执行.这样来看: 方法是一段程序代码,在内存某个空间,假设是0000H到0100H,线程a执行到…...

济宁做网站建设的公司/百度风云搜索榜

index.html页面: <!DOCTYPE html><html> <head> <meta charset"UTF-8"> <title>require.js封装轮播图</title> <style type"text/css">   *{     margin: 0;     padding: 0;     list-style: n…...

班级同学录网站建设/牡丹江网站seo

登录一个系统之后&#xff0c;如果需要在登录状态下进行一些操作&#xff0c;那么需要怎样保持会话呢&#xff1f; 可以使用Session() 举例如下&#xff1a; import requestssrequests.Session() url1http://127.0.0.1/wordpress/wp-login.phpdata1{log:xxxx,pwd:xxxxxx} #登录…...