【Rust基础】Rust后端开发常用库
使用Rust有一段时间了,期间尝试过使用Rust做后端开发、命令行工具开发,以及做端侧模型部署,也尝试过交叉编译、FFI调用等,也算是基本入门了。在用Rust做后端接口开发时,常常会找不到一些合适库,而这些库在Java中却很常见,于是在此汇总一下后Rust后端开发中常用的一些库。
-
基础框架
首先是基础web开发框架,在Java中,最常用的就是Spring了,而Spring其实不单单是一个开发框架,而是一整个完整的生态。其中的SpringBoot更是做了很好的封装,屏蔽了非常多的细节,这也导致了从Java系的web开发转到Rust时会遇到很多问题。而在Rust中,显然没有向Spring一样完整的生态支持,所以需要我们自己把各个模块组装在一起。
可选项:axum、actix-web、warp、rocket
从使用方式和使用难度上来说大同小异,axum和rocket可能会更容易上手一点,个人目前使用rocket稍微多一点,它也支持通过类似于Spring注解的方式来定义接口,支持参数映射。但是,它似乎没有和SpringBoot类似的参数校验工具,比如校验最大最小值、参数长度等,目前只能自己实现相关trait来校验了,还没有发现一个很好用的校验库来实现自定义返回错误码的功能。
-
数据库
基本上主流的数据库Rust都是支持的,都有Rust客户端,而我们开发时更多关注的是ORM框架,在Java中最常用的非MyBatis莫属了,其实Rust中有一个类似于MyBatis的库,叫做rbatis,目前还没有尝试过,看起来还不错,也支持动态SQL,只是从xml格式变为html感觉怪怪的。另一个比较常用的就是diesel,性能确实不错,支持流式处理,也支持联表,类型安全,但是,不怎么支持动态SQL,所以针对一些复杂查询可能会写的比较费力。可选项:diesel、rbatis、sqlx
其实sqlx不能算作ORM框架,但是它比较简单且灵活,适合一些小项目使用吧。
-
缓存
缓存算是中间件了,基本上就是看其是否有支持Rust的驱动或者SDK了。常用的Redis,有Rust版本的驱动,也叫redis。另一个是moka,一个内存缓存库,也很好用。可选项:redis、moka
除了以上两个常用的外,其他缓存大部分也都有Rust版的驱动,可以在crates.io上找到
-
池化
数据库连接、Redis连接以及其他涉及到网络连接的,基本都会用到连接池,Java里有Hikari、C3P0、DBCP等,这些池化工具常常被用来做连接复用,连接复用的好处一是能减少频繁创建连接带来的消耗,二是可以限制连接数量,在有限的系统资源下维持系统的稳定。而在Rust中,最常用的一个池化工具就是r2d2,它本身支持了许多连接的池化,如redis、diesel、sqlx以及postgres和oracle等。我们也可以实现它的trait来管理自定义的需要池化的对象,还是很方便的可选项:r2d2、deadpool
除了r2d2外,还有一个就是deadpool,它是支持异步的,而r2d2目前看是同步的,所以在并发性能上会有所提升。
-
多线程和异步
Rust支持async/await关键字来实现异步,但这只是一个语法,它需要一个异步的runtime来支持异步操作,最常用的莫过于tokio了,这个名字初次看到感觉也是有点怪怪的。大部分的需要异步的库都集成了tokio。要实现异步,只需要为函数加上asnyc即可,需要注意的是,要对async函数使用.await才会触发执行,否则是不会执行的,而.await又需要在async中才可以使用,所以层层嵌套到最外层到main函数,它就需要是async的了,我们可以使用#[tokio::main]来开启异步runtime。具体的tokio异步相关的一些问题,后面会再总结一下。
可选项:tokio
对于tokio中的spwan,它和Java线程池中的submit提交一个任务类似,spwan提交一个任务后,由tokio去调度执行,spwan会返回一个JoinHandle,有多个任务时,使用join!(task1,task2,…)来并发执行即可。使用上还是蛮简单的。
说到多线程,那免不了线程间的通信,有一个库叫crossbeam,提供了一些原子包装类型,以及线程安全的channel,可以很方便的在多线程中交互,比标准库中的channel好用一些。
-
错误处理
在Java中,错误处理一般是自定义的Exception,结合业务状态码,封装一个统一的响应格式。在Rust中,没有异常的概念,虽然有panic,但是,正常来讲,在后端服务中,应该确保不会发生panic,也就是必须要手动处理错误。Rust的每一个库都会有一个它自己的自定义的异常,这些异常(即Error)会暴露给调用方来处理,我们可以通过match来匹配指定的Error,或者if let来处理对应的Error,如果函数使用Result作为返回值,还可将Error返回给外层,或者用问号?来返回给外层。但是我们通常会使用多个库,一个函数里会有多个不同类型的错误,这就需要自定义个错误枚举,来实现std下的Error,给不同的Error类型包装成统一的自定义Error,或者结合Box+dyn实现动态包裹Error。而这些操作,也可以通过第三方的库来实现,常用的就是anyhow。
可选项:anyhow、eyre
anyhow其实依赖于thiserror,而thiserror提供了一些宏来包裹不同类型的错误,用法也很简单。我们可以将std::result::Result替换为anyhow的Result,返回anyhow!()或者bail!(“”),这样就可以将错误向外传递。
-
单元测试
Rust中的单元测试使用上比较简单,#[test]即可开启测试,对于异步的测试,使用#[tokio::test]即可开启。需要注意的是,如果使用IDE点击运行开始测试的话,依赖的feature不会自动检测到,可能会报错,需要配置一下。其他测试库还没有常见用到,后续有用到了再补充。
-
序列化/反序列化
主要是指Json的序列化和反序列化,Java中有FastJson和Jackson,Rust中有serde_json。serde是一个通用的序列化和反序列化库,支持常见的Json、Yaml,但是好像不支持XML。使用上很简单,在struct上加上#[derive(Serialize, Deserialize)]即可支持序列化和反序列化,需要注意的是,struct里边的字段也需要支持序列化和反序列化,常用的基础数据类型是已经都实现了了的。
可选项:serde、serde_json、serde_yaml
除了Json外,还有protobuf,Rust也支持,叫做prost,可以很方便的进行encode和decode,它也支持从proto文件生成rs文件,构建工具叫做prost-build,我们可以在build.rs中配置需要生成的内容。
还有arrow格式,这个是一种跨平台的数据格式,Rust也是支持的,如果需要跨进程传输数据,可以使用这个。
-
消息队列
消息队列也算是中间件,常用的kafka、rabbitmq、rocketmq等都有rust版的客户端实现。说到消息队列,除了这几个外,还有个库叫做zmq,用来做网络通信,也很不错,简单易用,支持多种TCP连接模式,也支持IPC,对于跨进程或者不同机器之间高效通信很适合。
可选项:kafka、rabbitmq、rocketmq、zmq
-
日志
最后,就是日志库了,无论是Java还是Rust中,日志库都很多,Java中的Log4j可以对于Rust中的log库,都定义了统一的接口,有着不同的实现。常用的有env_logger、tracing、log4rs,tracing还未曾使用过,不过看介绍,似乎比较复杂一些,而env_logger则相对简单很多。env_logger支持不同级别的日志输出,支持按model过滤日志级别,支持彩色日志,但是,不支持输出到文件。所以log4rs可能更适合,它也支持通过yaml配置日志格式,支持不同的输出,支持滚动日志,看起来是比较适合web后端日志的。
可选项:tracing、env_logger、log4rs
-
其他
除了以上了解到库外,还有其他一些使用到的库,也记录一下。
- rand:随机数生成库
- image: 图像处理
- imageproc:实现了一些图像处理相关的算法
- base64:base64编码解码
- chrono:日期时间库,这个很常用,提供了大量的日期和时间操作API
- once_cell:全局静态变量初始化。Rust中static类型不能像Java一样很方便的定义全局静态变量,这个库提供了简单的静态变量初始化方式,并且线程安全,确保只被初始化一次。
- strum:枚举遍历以及枚举值映射
- reqwest:用于简单的http请求
- tokio-cron-scheduler:定时任务
- dashmap:简化并发编程中的hashmap带来的问题
Rust做Web开发,有好处也有坏处,先说好处。首先确实能够节约机器成本,一个Rust包通常来说会比Jar包小很多,而运行时占用的内存就比Java小的更多了,能够减小5倍左右;其次,Rust写的程序,确实会比Java稳定,能够规避一些潜在的问题,例如NPE等,当然前提是不要到处unwrap,否则一样会崩。另外,对于客户端来说,Tauri使用Rust构架,如果做客户端开发,前端使用Vue,后端使用Rust还是很方便的。还有就是在部署层面,Rust可以跨平台编译,使用musl工具链编译后,基本上可以部署到任何linux系统上,对于需要支持不同平台的应用来说,非常方便,而对于Java来说还需要JVM的环境,虽然Java21已经支持原生应用编译了,但是依赖于泛型的框架来说,编译可能还是有些坑的。
再说不好的地方,一是学习成本,Rust的确没有Java容易学,尤其是对Java越熟悉的,转Rust可能反而会比较麻烦,因为很多概念两者并不相通,这是学习成本,并非开发成本,因为如果熟悉了Rust的话,开发速度其实并不慢,我们更多需要的是在开发初期做好设计,不论架构还是API,否则后续修改起来还是比较痛苦的。所以这也就是Rust做Web开发的另一个不好的地方,不能快速适应业务上的变化,由于本身的语法限制,你不能向Java一样运用各种设计模式来应对业务变化,而需要花费更多的时间去衡量是否需要重构或者其他方案,换句话说,可能对于我们做开发的要求会变高,考虑的东西也会变多,比如改用String还是&str?不过,从另一种角度看,这也提高了我们的编程的严谨性和系统的稳定性吧。
最近也在尝试使用Rust在嵌入式设备上部署例如Yolo等模型,以及一些大模型,想尝试使用ONNX简化部署流程,期间也遇到了很多问题,比如OpenCV交叉编译、Rust的交叉编译、FFI调用、跨进程通信等问题。看起来有点混乱,这些后续有时间再总结一下。本身是从5年的Java转Rust,目前看Rust国内只有量化和区块链这两个方向稍微多一点,其他的几乎没有岗位,也是一脸迷茫,期待后续Rust能够在不同领域发展起来,多一些工作机会吧。
相关文章:
【Rust基础】Rust后端开发常用库
使用Rust有一段时间了,期间尝试过使用Rust做后端开发、命令行工具开发,以及做端侧模型部署,也尝试过交叉编译、FFI调用等,也算是基本入门了。在用Rust做后端接口开发时,常常会找不到一些合适库,而这些库在J…...
【附JS、Python、C++题解】Leetcode面试150题(9)——三数之和
一、题目 15. 三数之和 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足: i!j、i!k 且 j! k ,同时还满足:nums[i] nums[j] nums[k] 0 。请你返回所有和为 0 且不重复的三元组。 注意…...
脑电波控制设备:基于典型相关分析(CCA)的脑机接口频率精准解码方法
文章目录 前言一、CCA的用途二、频率求解思路三、输入数据结构四、判断方法五、matlab实践1.数据集获取及处理2.matlab代码3.运行及结果 六、参考文献 前言 在脑机接口(BCI)领域,有SSVEP方向,中文叫做稳态视觉诱发电位,当人观看闪烁的视觉刺激…...
Golang学习笔记_44——命令模式
Golang学习笔记_41——观察者模式 Golang学习笔记_42——迭代器模式 Golang学习笔记_43——责任链模式 文章目录 一、核心概念1. 定义2. 解决的问题3. 核心角色4. 类图 二、特点分析三、适用场景1. 事务管理系统2. 多媒体遥控器3. 操作审计系统 四、Go语言实现示例五、高级应用…...
vue项目如何实现条件查询?
目录 1.前端 2.后端 3.mybatis的sql语句 结语 1.前端 说白了就是,无论该参数是否是空字符串,都会传递到后端。(反正不是null就行)。 2.后端 在controller层中,使用RequestParam注解接收名为registerName的参数&…...
windows平台的ffmpeg编译使用
windows平台的ffmpeg编译使用 一、现状 本人使用libgdx开发galGame,发现扩展包gdx-video不支持mp4,不能忍,正好看到官网有支持自定义编译的文档,所以操作一下,自定义编译。本文重点在于操作windows平台,linux平台太简单了。 整个过程包括如下几个步骤。 二、代码下载…...
Android 14 昼夜色切换多屏时候非主屏的Activity无法收到onConfigurationChanged
记录一下遇见的这个问题和查看源码的过程 首先先说遇见的问题 Android 14 昼夜色切换多屏时候 非主屏的Activity 会经常收不到 onConfigurationChanged的回调 分析原因源码中ActivityThread::performActivityConfigurationChanged 里面 private Configuration performActivi…...
NLP常见任务专题介绍(4)-ConditionalGeneration和CasualLM区别
在 transformers 库中,ConditionalGeneration 和 CausalLM 是两种不同类型的语言模型,各自适用于不同的任务: 类别Conditional Generation (条件生成)CausalLM (因果语言模型)核心区别依赖输入 条件 生成文本只能 自回归 生成文本训练方式Encoder-Decoder(编码-解码) 结构…...
【vue+excel】导出excel(目前是可以导出两个sheet)
项目里经常用到的导出ecxel功能是默认导出一个sheet页 现在需要导出两个sheet,一个是总计,另一个是明细 效果如下: 我就在现有的单个导出的功能上改造了一下,只支持导出两个(代码不够灵活,如果需要多个&…...
【数据结构】6栈
0 章节 3.1到3.3小节。 认知与理解栈结构; 列举栈的操作特点。 理解并列举栈的应用案例。 重点 栈的特点与实现; 难点 栈的灵活实现与应用 作业或思考题 完成学习测试2,? 内容达成以下标准(考核…...
【C++】每日一练(有效的括号)
本篇博客给大家带来的是用C语言来解答有效的括号! 🐟🐟文章专栏:每日一练 🚀🚀若有问题评论区下讨论,我会及时回答 ❤❤欢迎大家点赞、收藏、分享! 今日思想:不服输的少年…...
数字化新零售与 AI 大模型,如何重塑大健康赛道?
在数字化浪潮中,大健康赛道正经历深刻变革。数字化新零售营销模式的兴起,与 AI 大模型的强大能力相结合,为大健康领域带来了全新的发展机遇。 数字化新零售营销模式融合线上线下,运用大数据、云计算分析消费者行为,实…...
Android实现Socket通信
问题: 我在Android端对接后端Socket服务实现消息模块的时候,使用WebSocketClient 库,手动构造了订阅和发送消息的 STOMP 帧,,Socket连接成功建立,但是当用户发送消息的时候,对方无法接受到。 …...
✅ Vue 3 响应式写法小抄表(Composition API 实战模板)
📦 引入核心响应式工具 import { ref, reactive, computed, watch, toRefs } from vue1️⃣ 基本类型(string / number / boolean) → 推荐使用 ref() const username ref() const count ref(0) const isLoading ref(false)2️⃣ 对象/表…...
Python数据分析之数据可视化
Python 数据分析重点知识点 本系列不同其他的知识点讲解,力求通过例子让新同学学习用法,帮助老同学快速回忆知识点 可视化系列: Python基础数据分析工具数据处理与分析数据可视化机器学习基础 四、数据可视化 图表类型与选择 根据数据特…...
TCP协议支持全双工原因TCP发送接收数据是生产者消费者模型
一、TCP支持全双工的原因 TCP协议支持全双工,即使用TCP协议进行通信时,服务端和客户端可以同时进行数据的发送和接收,互不干扰,实现同时双向传输数据。 这是因为使用TCP协议通信时,读写套接字的文件描述符既用来发送…...
【ODHead】BEVDet的 CenterHead的推理和拓展到蒸馏损失的算法细节
文章目录 背景常识1、BEVDet的CenterHead整体方案2、蒸馏部分3、输出 preds_dicts 部分3.1、headmap3.2、bbox3.3、Mask掩膜3.4、损失 背景常识 在BEVDet和BEVFormer里,使用了不同的3D detection head(BEVDet用了centerhead,BEVFormer用了de…...
在 CentOS 7 上安装 PHP 7.3
在 CentOS 7 上安装 PHP 7.3 可以按照以下步骤进行操作: 1. 安装必要的依赖和 EPEL 仓库 EPEL(Extra Packages for Enterprise Linux)是为企业级 Linux 提供额外软件包的仓库,yum-utils 用于管理 yum 仓库。 sudo yum install -…...
vue+dhtmlx-gantt 实现甘特图-快速入门【甘特图】
文章目录 一、前言二、使用说明2.1 引入依赖2.2 引入组件2.3 引入dhtmlx-gantt2.4 甘特图数据配置2.5 初始化配置 三、代码示例3.1 Vue2完整示例3.2 Vue3 完整示例 四、效果图 一、前言 dhtmlxGantt 是一款功能强大的甘特图组件,支持 Vue 3 集成。它提供了丰富的功…...
关于ModbusTCP/RTU协议对接Ethernet/IP(CIP)协议的方案
IGT-DSER智能网关模块支持西门子、倍福(BECKHOFF)、罗克韦尔AB,以及三菱、欧姆龙等各种品牌的PLC之间通讯,支持Ethernet/IP(CIP)、Profinet(S7),以及FINS、MC等工业自动化常用协议,同时也支持PLC与Modbus协议的工业机器人、智能仪…...
python-leetcode 49.二叉树中的最大路径和
题目: 二叉树中的路径被定义为一条节点序列,序列中每对相邻节点之间都存在一条边,同一个节点在一条路径序列中至多出现一次,该路径至少包含一个节点,且不一定经过根节点。 路径和是路径中各节点值得总和,…...
C语言基础知识04
指针 指针概念 指针保存地址,地址是字节的编号 指针类型和保存的地址类型要一直 使用时注意,把地址转换为&变量的格式来看 int a[3]; a转为&a[0] 指针的大小 64bit 固定8字节, 32bit 固定4字节 指针…...
使用 Golang 操作 MySQL
在Go语言中,操作SQL数据库,通常会用到一些第三方库来简化数据库的连接、查询和操作过程。其中原生的 database/sql go-sql-driver/mysql 库更符合sql语句使用习惯。 安装 go get github.com/go-sql-driver/mysql 直接上代码来演示基本的创建ÿ…...
前端面试:cookie 可以实现不同域共享吗?
在前端开发中,Cookie 不能直接实现不同域之间的共享。Cookie 的作用域受到域的限制,浏览器不会允许一个域下的 Cookie 被另一个域访问。这是为了保护用户隐私及安全,防止跨站请求伪造(CSRF)等安全问题。 Cookie 的基本…...
MyBatis-Plus接入和简单使用
如何接入 https://baomidou.com/getting-started/ 简单使用方法 使用 MyBatis-Plus 时,大多数场景下不需要编写 XML 和 SQL,因为它提供了强大的通用 CRUD 操作和条件构造器。但以下情况可能需要手动编写 SQL: 1. 不需要写 XML/SQL 的场景 …...
【Go万字洗髓经】Golang内存模型与内存分配管理
本文目录 1. 操作系统中的虚拟内存分页与进程管理虚拟内存与内存隔离 2. Golang中的内存模型内存分配流程内存单元mspan线程缓存mcache中心缓存mcentral全局堆缓存mheapheapArena空闲页索引pageAlloc 3. Go对象分配mallocgc函数tiny对象分配内存 4.结合GMP模型来看内存模型tiny…...
mov格式视频如何转换mp4?
mov格式视频如何转换mp4?在日常的视频处理中,经常需要将MOV格式的视频转换为MP4格式,以兼容更多的播放设备和平台。下面给大家分享如何将MOV视频转换为MP4,4款视频格式转换工具分享。 一、牛学长转码大师 牛学长转码大师是一款功…...
鸿蒙OS开发ForEach循环渲染
摘要 在ForEach循环渲染过程中,如果修改列表项中的数据,但是UI页面不会刷新。在最近开发公司app时遇到了这个问题,经过查看官方文档找到了解决方式 官方地址:数据变化不刷新 一、具体解决方案 思路:通过父子组件传…...
【算法】DFS、BFS、拓扑排序
⭐️个人主页:小羊 ⭐️所属专栏:算法 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~ 目录 持续更新中...1、DFS2、BFSN 叉树的层序遍历二叉树的锯齿形层序遍历二叉树最大宽度 3、多源BFS腐烂的苹果 4、拓扑排序 持续更新中…...
【Godot4.0】贝塞尔曲线在游戏中的实际应用
概述 之前研究贝塞尔曲线绘制,完全是以绘图函数,以及实现节点连接为思考。并没有实际考虑贝塞尔曲线在游戏中的应用。今日偶然看到悦千简一年多前发的一个用贝塞尔曲线实现追踪弹或箭矢效果,还有玩物不丧志的老李杀戮尖塔系列中的卡牌动态箭…...
MongoDB 数据导出与导入实战指南(附完整命令)
1. 场景说明 在 MongoDB 运维中,数据备份与恢复是核心操作。本文使用 mongodump 和 mongorestore 工具,演示如何通过命令行导出和导入数据,解决副本集连接、路径指定等关键问题。 2. 数据导出(mongodump) 2.1 导出命…...
『Rust』Rust运行环境搭建
文章目录 rust编译工具rustupVisual Studio VS Code测试编译手动编译VSCode编译配置 参考完 rust编译工具rustup https://www.rust-lang.org/zh-CN/tools/install 换源 RUSTUP_DIST_SERVER https://rsproxy.cn RUSTUP_UPDATE_ROOT https://rsproxy.cn修改rustup和cargo的安…...
CPU+GPU结合的主板设计思路与应用探讨
在高性能计算和图形处理需求不断增长的背景下,CPUGPU结合的主板设计逐渐成为硬件架构的重要趋势。本文将探讨基于CPUGPU架构的主板设计思路、关键技术考量以及应用前景。 1. 设计思路概述 CPU(中央处理器)擅长处理复杂的逻辑运算和多任务控制…...
latex问题汇总
latex问题汇总 环境问题1 环境 texlive2024 TeXstudio 4.8.6 (git 4.8.6) 问题1 编译过程有如下错 ! Misplaced alignment tab character &. l.173 International Conference on Infrared &Millimeter Waves, 2004: 667--... I cant figure out why you would wa…...
学习springboot-Bean管理(Bean 注册,Bean 扫描)
Bean 扫描 可以浏览下面的博客链接 :spring 学习 (注解)-CSDN博客 在学习spring 注解时,我们使用 Component ,Service,Controller等 这样的注解,将目标类信息,传递给IOC容器,为其创…...
iOS开发,SQLite.swift, Missing argument label ‘value:‘ in call问题
Xcode16中,集成使用SQLite.swift,创建表的时候: let id Expression<Int64>("id"),报错Missing argument label value: in call 直接使用SQLite.Expression<Int64>("id") 或者定义一个全局typ…...
【GIT】重新初始化远程仓库
有的时候我们克隆远端仓库会出错: git clone --depth 1 git116.*.*.*:/srv/customs.git D:\dev\projects\kdy\customs11\customs Cloning into D:\dev\projects\kdy\customs11\customs... remote: Enumerating objects: 1494, done. remote: Counting objects: 100…...
Vue3中 ref 与 reactive区别
ref 用途: ref 通常用于创建一个响应式的基本类型数据(如 string、number、boolean 等),但它也可以用于对象或数组 返回值: ref 返回一个带有 .value 属性的对象,访问或修改数据需要通过 .value 进行 使用场景: …...
apollo3录音到wav播放解决方法
SDK DEMO项目:ap3bp_evb_vos_pcm_recorder_20210901 pcm_recorder.c //***************************************************************************** // // Options // //***************************************************************************** #define PRINT…...
信号处理抽取多项滤波的数学推导与仿真
昨天的《信号处理之插值、抽取与多项滤波》,已经介绍了插值抽取的多项滤率,今天详细介绍多项滤波的数学推导,并附上实战仿真代码。 一、数学变换推导 1. 多相分解的核心思想 将FIR滤波器的系数 h ( n ) h(n) h(n)按相位分组,每…...
Java网络多线程
网络相关概念: 关于访问: IP端口 因为一个主机上可能有多个服务, 一个服务监听一个端口,当你访问的时候主机通过端口号就能知道要和哪个端口发生通讯.因此一个主机上不能有两个及以上的服务监听同一个端口. 协议简单来说就是数据的组织形式 好像是两个人交流一样,要保证自己说…...
linux centos 忘记root密码拯救
在CentOS 7中,如果忘记root密码,可以通过修改系统启动参数进入单用户模式或紧急模式进行重置。以下是两种常用方法,适用于物理机或虚拟机环境: 方法一:通过rd.break参数重置密码 步骤: 重启系统并进入GRU…...
C# 事件使用详解
总目录 前言 在C#中,事件(Events)是一种基于委托的重要机制,用于实现对象之间的松耦合通信。它通过发布-订阅模式(Publisher-Subscriber Pattern),允许一个对象(发布者)…...
flink cdc同步mysql数据
一、api 添加依赖 <dependency><groupId>org.apache.flink</groupId><artifactId>flink-connector-mysql-cdc</artifactId><!-- 请使用已发布的版本依赖,snapshot 版本的依赖需要本地自行编译。 --><version>3.3-SNAP…...
tomcat负载均衡配置
这里拿Nginx和之前做的Tomcat 多实例来实现tomcat负载均衡 1.准备多实例与nginx tomcat单机多实例部署-CSDN博客 2.配置nginx做负载均衡 upstream tomcat{ server 192.168.60.11:8081; server 192.168.60.11:8082; server 192.168.60.11:8083; } ser…...
Ceph(1):分布式存储技术简介
1 分布式存储技术简介 1.1 分布式存储系统的特性 (1)可扩展 分布式存储系统可以扩展到几百台甚至几千台的集群规模,而且随着集群规模的增长,系统整体性能表现为线性增长。分布式存储的水平扩展有以下几个特性: 节点…...
16、JavaEE核心技术-EL与 JSTL
EL与 JSTL 实践 一. EL(Expression Language) EL(表达式语言)是 JSP 2.0 中引入的一种简单的脚本语言,用于在 JSP 页面中简化数据的访问和显示。它通过一种类似于 JavaScript 的语法,允许开发者在 JSP 页面…...
RabbitMQ报错:Shutdown Signal channel error; protocol method
报错信息: Shutdown Signal: channel error; protocol method: #method<channel.close>(reply-code406, reply-textPRECONDITION_FAILED - unknown delivery tag 1, class-id60, method-id80) 原因 默认情况下 RabbitMQ 是自动ACK(确认签收&…...
使用DeepSeek完成一个简单嵌入式开发
开启DeepSeek对话 请帮我使用Altium Designer设计原理图、PCB,使用keil完成代码编写;要求:使用stm32F103RCT6为主控芯片,控制3个流水灯的原理图 这里需要注意,每次DeepSeek的回答都不太一样。 DeepSeek回答 以下是使…...
NLP技术介绍
NLP技术介绍 语言分析技术分词词性标注命令实体识别句法分析语义分析文本处理技术文本分类文本聚类情感分析文本生成机器翻译对话系统与交互技术聊天机器人问答系统语音识别与合成知识图谱与语义理解技术知识图谱语义搜索语义推理深度学习与预训练模型循环神经网络(RNN)及其变…...