使用LVS+NGinx+Netty实现数据接入
数据接入
链接参考文档 LVS+Keepalived项目
车辆数据上收,TBox通过TCP协议连接到TSP平台 建立连接后进行数据上传。也可借由该连接实现远程控制等操作。
通过搭建 LV—NGinx—Netty实现高并发数据接入
- LVS:四层负载均衡(位于内核层):根据请求报文中的目标地址和端口进行调度
- NGinx:七层负载均衡(位于应用层):根据请求报文的内容进行调度,这种调度属于「代理」的方式
组件 | 角色 | 主机名称 | 虚拟ip/端口 |
---|---|---|---|
LVS+keepalived | active | -0007 | |
LVS+keepalived | backup | -0006 | |
Nginx | 负载 | -0005 | 8050 |
Nginx | 负载 | -0004 | 8050 |
Netty | 真实服务器 | -0003 | 8050 |
Netty | 真实服务器 | -0002 | 8050 |
Netty | 真实服务器 | -0003 | 8092 |
Netty | 真实服务器 | -0002 | 8092 |
Netty | 真实服务器 | -0001 | 8092 |
Netty | 真实服务器 | -0001 | 8092 |
使用华为云服务器 安装LVS 需要有VPC服务(免费),在控制台页面做虚拟ip绑定
一、安装LVS 服务
使用的是 DR 模式
- NET模式:LVS将数据请求包转发给真实服务器的时候,会修改成真实服务器的IP地址;在回复时真实服务器会把回复包发往LVS调度服务器 再发往客户端。
- TUN隧道模式:将原始数据包封装并添加新的包头(内容包括新的源地址及端口、目标地址及端口),从而实现将一个目标为调度器的VIP地址的数据包封装,通过隧道转发给后端的真实服务器(RealServer)感觉很复杂。
- DR模式:要求LVS调度服务器要和后端服务器在同一局域网下,为后端服务器添加lo回环地址为VIP(虚拟IP地址)这样回复给客户端 客户端会以为是连接的VIP进行回复的
DR模式不支持端口映射
#查看网卡 eth0
ifconfig
#执行 虚拟ip:172.25.94.187 广播地址(不变):172.25.94.191 子网掩码(不变):255.255.255.192 up:立即启用vip(虚拟ip)
ifconfig eth0:1 172.25.94.187 broadcast 172.25.94.191 netmask 255.255.255.192 up
#查看当前网卡信息
ip a
#安装keepalived
sudo yum install keepalived
#启动keepalived
systemctl start keepalived
#加入开机启动keepalived
systemctl enable keepalived
#重新启动keepalived
systemctl restart keepalived
#查看keepalived状态
systemctl status keepalived
LVS 模块内嵌lvs模块,只需要ipvsadm和keepalived安装
#查看Linux 内核版本
uname -r
#查看内核是否集成lvs模块
find /lib/modules/$(uname -r)/ -iname "**.ko*" | cut -d/ -f5-
#安装LVS管理工具:ipvsadm
yum install -y gcc gcc-c++ makepcre pcre-devel kernel-devel openssl-devel libnl-devel popt*
yum -y install ipvsadm
#启动ipvs
sudo ipvsadm
#查看是否支持lvs
sudo lsmod |grep ip_vs
#查看ipvsadm 版本
ipvsadm -v
#服务器添加路由规则
route add -host 172.25.94.187 dev ens33:0
route add -host 172.25.110.124 dev eth:0#启用系统的包转发功能 #1:启用ip转发,0:禁止ip转发
echo "1" >/proc/sys/net/ipv4/ip_forward
#清除原有转发规则
systemctl restart keepalived
systemctl status ipvsadm
ipvsadm --clear
#添加虚拟ip规则 rr:负载均衡算法 轮询ipvsadm -A -t 172.25.94.187:8043 -s rripvsadm -a -t 172.25.94.187:8043 -r 172.25.94.151:8043 -gipvsadm -a -t 172.25.94.187:8043 -r 172.25.94.152:8043 -gipvsadm -l#配置tcp/tcpfin/udp超时时间ipvsadm --set 900 120 300#添加虚机IP规则也可以通过修改文件实现vim /etc/keepalived/keepalived.conf
global_defs {router_id chery_21
}
vrrp_instance VI_1 {state MASTERinterface eth0virtual_router_id 51priority 100advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {172.25.110.124}
}
virtual_server 172.25.110.124 8050 {delay_loop 6lb_algo rrlb_kind DRpersistence_timeout 50protocol TCPreal_server 172.25.110.19 8050 {weight 1TCP_CHECK {connect_timeout 30delay_before_retry 3}
}real_server 172.25.110.18 8050 {weight 2TCP_CHECK {connect_timeout 30}
}
}
全局定义(global_defs)
router_id chery_21
:定义了当前Keepalived实例的路由ID,这是唯一的标识符,用于在VRRP组中区分不同的Keepalived实例。
VRRP实例(vrrp_instance VI_1)
-
state MASTER
:设置当前实例的初始状态为MASTER。在VRRP组中,MASTER负责处理对虚拟IP的流量。 -
interface eth0
:指定VRRP通信使用的网络接口。 -
virtual_router_id 51
:虚拟路由的ID,用于在VRRP组中标识不同的虚拟路由器。 -
priority 100
:设置当前实例的优先级,优先级高的实例将成为MASTER。 -
advert_int 1
:VRRP通告的间隔时间,单位为秒。MASTER每隔这个时间会向其他节点发送VRRP通告。 -
authentication
:VRRP认证配置,确保只有授权的设备可以加入VRRP组。
auth_type PASS
:使用密码认证。auth_pass 1111
:认证密码。
-
virtual_ipaddress
:定义了虚拟IP地址,即VIP,客户端将访问此IP地址来访问服务。
虚拟服务器(virtual_server)
172.25.110.124 8050
:定义了虚拟服务器的IP地址和端口号,这里与VRRP的VIP相同,表明这个虚拟服务器是通过VIP来访问的。delay_loop 6
:健康检查的时间间隔,单位为秒。lb_algo rr
:负载均衡算法,这里使用的是轮询(rr)。lb_kind DR
:负载均衡类型,这里使用的是直接路由(DR),需要确保后端服务器(real_server)配置正确以支持DR模式。persistence_timeout 50
:会话保持时间,单位为秒。在指定时间内,来自同一客户端的请求将被转发到同一台后端服务器。protocol TCP
:使用TCP协议进行健康检查和负载均衡。
后端服务器(real_server)
-
定义了多个后端服务器,每个服务器都配置了IP地址、端口号、权重和健康检查设置。
-
weight
:权重,用于负载均衡时决定服务器的优先级。 -
TCP_CHECK
:TCP健康检查配置。
connect_timeout 30
:连接超时时间,单位为秒。delay_before_retry 3
:在重试之前等待的时间,单位为秒。
LVS负载均衡(LVS简介、三种工作模式、十种调度算法)
#列出当前LVS表中的所有配置,包括虚拟服务器和真实服务器的信息。
ipvsadm -Ln
#显示统计信息,包括已转发的连接数、入包个数、出包个数等。
ipvsadm -L --stats
#显示转发速率信息,包括每秒连接数、每秒入包个数、每秒出包个数等
ipvsadm -L --rate
#keepalived 日志
vim /var/log/message
二、安装nginx 服务
在nginx服务器和后端服务器 配置lo回环地址 否则回复将不成功
服务器上一般还需要修改lo网卡 配置成虚拟IP。华为云服务器使用的是Centos 8版本 没有 lo配置文件,通过 ifconfig lo:0 172.25.94.187 netmask 255.255.255.255 broadcast 172.25.94.187 up 华为云服务器不支持修改网卡,所以修改了 eth0网卡配置 ip addr add 172.25.94.187/24 dev eth0
yum -y nginx
#检查是否有 stream
nginx -V 2>&1 | grep --color -o with-stream
#如果没有stream需要对nginx源码安装进行二次编译
tar -zxvf nginx-*.tar.gz
cd nginx-*
./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-stream
make
sudo make install
#重新加载Nginx配置文件
nginx -s reload
#强制停止Nginx服务
nginx -s stop
#重启nginx
nginx -s reopen
#修改配置文件
vim /etc/nginx/nginx.confnetstat -anput | grep nginxnginx -c nginx.conf
三、Netty服务
**1、在Linux上部署启用了 epoll **
epoll:是Linux内核为处理大批量文件描述符而作的改进的poll,是Linux下多路复用IO接口select/poll的增强版本
应用于Linux系统下的应用程序,特别是需要处理大量并发连接的高性能网络服务器。
BIO:同步阻塞IO,也就是传统阻塞型的IO,服务器实现模式是一个连接对应一个线程。客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个链接不做任何事情会造成不必要的线程开销。
NIO:同步非阻塞IO,服务器实现模式是一个线程处理多个请求,客户端发送的链接请求都会注册到多路复用器上,多路复用器轮询到链接有IO请求就进行处理。
AIO:异步非阻塞,AIO引入了异步通道的概念,采用了Proactor模式,简化了程序编写,有效的请求才启动线程,他的特点是先由操作系统完成后才通知服务端程序启动线程去处理,一般适用于连接数较多且链接时间较长的应用。
public class NettyServer {private static final Logger logger = LoggerFactory.getLogger(NettyServer.class);@Resourceprivate NettyServerInitializer nettyServerInitializer;ServerBootstrap serverBootstrap = new ServerBootstrap();EventLoopGroup boss = null;EventLoopGroup worker = null;ChannelFuture future = null;ChannelFuture future2 = null;//厂商编码Integer factoryCode = null;@Value("${netty.server.use-epoll}")boolean epoll = false;@Value("${netty.server.port1}")private int port = 8030;@Value("${netty.server.port2}")private int port2 = 8050;@PreDestroypublic void stop() {if (future != null) {future.channel().close().addListener(ChannelFutureListener.CLOSE);future.awaitUninterruptibly();boss.shutdownGracefully();worker.shutdownGracefully();future = null;logger.info(" 服务关闭 ");}}public void start() {logger.info(" nettyServer 正在启动");if (epoll) {logger.info(" nettyServer 使用epoll模式");boss = new EpollEventLoopGroup(4);//指定线程32worker = new EpollEventLoopGroup(32);} else {logger.info(" nettyServer 使用nio模式");boss = new NioEventLoopGroup(4);worker = new NioEventLoopGroup(32);}logger.info("netty服务器在[" + this.port + "]端口启动监听");logger.info("netty服务器在[" + this.port2 + "]端口启动监听");serverBootstrap.group(boss, worker)// tcp缓冲区:将不能处理的客户端连接请求放到队列里等待.option(ChannelOption.SO_BACKLOG, 10240)//多个进程或者线程绑定到同一端口,提高服务器程序的性能.option(EpollChannelOption.SO_REUSEPORT, true)//打印info级别的日志
// .handler(new LoggingHandler(LogLevel.INFO))// 将网络数据积累到一定的数量后,服务器端才发送出去,会造成一定的延迟。希望服务是低延迟的,建议将TCP_NODELAY设置为true.childOption(ChannelOption.TCP_NODELAY, true)// 可以确保连接在因网络问题中断时能够被及时检测并处理。.childOption(ChannelOption.SO_KEEPALIVE, false)// 配置ByteBuf内存分配器.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)// 配置 编码器、解码器、业务处理.childHandler(nettyServerInitializer);if (epoll) {serverBootstrap.channel(EpollServerSocketChannel.class);} else {serverBootstrap.channel(NioServerSocketChannel.class);}try {future = serverBootstrap.bind(port).sync();future2 = serverBootstrap.bind(port2).sync();future.channel().closeFuture().addListener(new ChannelFutureListener() {@Overridepublic void operationComplete(ChannelFuture future) throws Exception { //通过回调只关闭自己监听的channelfuture.channel().close();}});future2.channel().closeFuture().addListener(new ChannelFutureListener() {@Overridepublic void operationComplete(ChannelFuture future) throws Exception {future.channel().close();}});// 等待服务端监听端口关闭// future.channel().closeFuture().sync();} catch (Exception e) {logger.info("nettyServer 启动时发生异常---------------{}", e);logger.info(e.getMessage());} finally {//这里一定要注释,因为上面没有阻塞了,不注释的话,这里会直接关闭的//boss.shutdownGracefully();//worker.shutdownGracefully();}}
2、超时配置
protected void initChannel(SocketChannel socketChannel) throws Exception {ChannelPipeline pipeline = socketChannel.pipeline();// readerIdleTimeSeconds 读超时;writerIdleTimeSeconds 写超时;allIdaleTimes 读写全超时 300 秒;断开连接pipeline.addLast(new IdleStateHandler(0, 0, 300, TimeUnit.SECONDS));pipeline.addLast(new LengthFieldBasedFrameDecoder(64 * 1024, 22, 2, 1, 0));//根据端口动态的选择解码器Integer localPort = socketChannel.localAddress().getPort();if (localPort == 8050 || localPort == 8055) {pipeline.addLast("authHandler", authHandler);pipeline.addLast("messageHandler", messageHandler);} else if (localPort == 8030 || localPort == 8035) {pipeline.addLast("authHandler", authHandler2);pipeline.addLast("messageHandler", messageHandler2);}}
在处理器中的应用
/*** 用户事件触发,发现读超时会调用 根据心跳检测状态去关闭连接*/@Overridepublic void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {if (evt instanceof IdleStateEvent) {IdleStateEvent event = (IdleStateEvent) evt;String clientId = ChannelStore.getClientId(ctx);Attribute<Integer> timesAttr = ctx.channel().attr(AttributeKey.valueOf("times"));Integer timeInt = timesAttr.get();if (timeInt == null) {timeInt = 0;}String eventDesc = null;switch (event.state()) {case READER_IDLE:eventDesc = "读空闲";break;case WRITER_IDLE:eventDesc = "写空闲";break;case ALL_IDLE:eventDesc = "读写空闲";break;}//获取ip地址信息InetAddress ip = InetAddress.getLocalHost();String hostAddress = ip.getHostAddress();log.info(clientId + " 地址:" + hostAddress + "发生超时事件--" + eventDesc);timeInt++;timesAttr.set(timeInt);if (timeInt > 1) {//删除ip地址信息String redisIpAddress = redisTemplateNew.get(clientId + "_IP");boolean hostBoolean = hostAddress.equals(redisIpAddress);log.info(hostBoolean + "check :" + clientId + " redisTemplateNewDelete:" + hostAddress + "redisIP:" + redisIpAddress);if (redisIpAddress != null && hostBoolean) {redisTemplateNew.delete(clientId + "_IP");}log.info(clientId + " 地址:" + hostAddress + ":" + ctx.channel().remoteAddress() + "空闲次数为" + timeInt + "次 关闭连接 " + clientId);ctx.channel().close();}}}
3、下行API
public class SendApi {@Resourceprivate RedisTemplateNew redisTemplateNew;@Resourceprivate KafkaTemplate<String, String> kafkaTemplate;@GetMapping(value = "/userinfo")public UserDto gerUserInfo() {UserDto user = new UserDto();user.setUserId("888888");user.setUserName("holmium");user.setSex("1");return user;}
}
}
}
}
相关文章:

使用LVS+NGinx+Netty实现数据接入
数据接入 链接参考文档 LVSKeepalived项目 车辆数据上收,TBox通过TCP协议连接到TSP平台 建立连接后进行数据上传。也可借由该连接实现远程控制等操作。 通过搭建 LV—NGinx—Netty实现高并发数据接入 LVS:四层负载均衡(位于内核层&#x…...

云手机结合自主ADB命令接口 提升海外营销效率
现在,跨境电商直播已经成为在线零售的重要渠道,在大环境下,确保直播应用的稳定性和用户体验至关重要。 云手机支持自主ADB命令接口,为电商直播营销提供了技术支持,使得应用开发、测试、优化和运维更加高效。 什么是A…...
【计算机视觉前沿研究 热点 顶会】CVPR 2024中与域适应、分布外目标检测相关的论文
测试时间线性分布外检测 分布外( OOD)检测旨在通过在输入样本显著偏离训练分布(分布中)时触发警报来解决神经网络的过度置信度预测,这表明输出可能不可靠。当前的 OOD 检测方法探索各种线索来识别 OOD 数据࿰…...
首次由国产8K摄像机服务巴黎奥运会8K公用信号
法国巴黎时间16日上午,中央广播电视总台“中国红”8K转播车穿越大半个地球,抵达法兰西体育场,顺利完成与奥林匹克转播公司(OBS)的交接。 (1)“中国红”8K转播车 作为适合户外露天项目的“移动制作域”,“…...

idea怎么配置gradle多个版本
1.背景 gradle版本很多,而且很多时候版本是不兼容的,我们希望拉取下来的代码就包含已经配置好的版本,而不是去配置本机的gradle版本..... 意思就是要实现项目A可以用6.X版本 项目B可以使用7.X版本 项目C可以用9.X版本..... 2.配置方式 步骤一:项目根路径下保留一个文件夹…...

SpringCloudAlibaba-Seata2.0.0与Nacos2.2.1
一、下载 ## 下载seata wget https://github.com/apache/incubator-seata/releases/download/v2.0.0/seata-server-2.0.0.tar.gz## 解压 tar zxvf seata-server-2.0.0.tar.gz二、执行sql文件 ## 取出sql文件执行 cd /seata/script/server/db/mysql ## 找个mysql数据库执行三、…...
【编程语言】C++和C的异同点
文章目录 相同点不同点cin和scanf()结构体struct指针:NULL、nullptr、void* 有一段时间没有发博客了,从笔记里摘录一些发两篇。 相同点 C有很多从C继承过来的东西,因此C书(《C Primer》、《C Primer Plus》)中有一些基础的东西讲的并没有C书…...

【日常记录】【插件】excel.js导出的时候给单元格设置下拉选择、数据校验等
文章目录 1. 代码基本结构2. 导出的excel 某单元格的值设置为下拉选择3. 如何把下拉选择项设置为动态4. 单元格设置校验、提示5. 在WPS上的设置 1. 代码基本结构 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><…...

分布式 I/O 系统Modbus TCP 耦合器BL200
BL200 耦合器是一个数据采集和控制系统,基于强大的 32 位微处理器设计,采用 Linux 操作系统,可以快速接入现场 PLC、SCADA 以及 ERP 系统, 内置逻辑控制、边缘计算应用,支持标准 Modbus TCP 服务器通讯,以太…...

人工智能导论-机器学习
机器学习概述 概述 本章主要介绍的机器学习的概念、发展历程、发展趋势、相关应用,着重拓展机监督学习和无监督学习的相关知识。 重点:机器学习的定义和应用; 难点:机器学习算法及分类。 机器学习 - 重要性 MachineLeaning出…...

计算机网络——网络层(路由选择协议、路由器工作原理、IP多播、虚拟专用网和网络地址转换)
目录 路由选择协议 因特网的路由选择协议特点 路由信息协议RIP RIP衡量目的网络距离 RIP选择路由器的方式 RIP具有以下三个重要特点 RIP的基本工作流程 RIP的距离向量算法 编辑 编辑 RIP存在的问题——“坏消息传播得慢” RIP的封装 开放最短路径优先协议OSPF…...

对接企业微信API自建应用配置企业可信IP
前言 为了实现系统调用团队会议功能,组织发起企业微信会议,于是需要和企业微信做API对接。对接过程很难受,文档不清晰、没有SDK、没有技术支持甚至文档报文和实际接口报文都不匹配,只能说企业微信的API是从业以来见过的最难用的AP…...

Windows右键新建Markdown文件类型配置 | Typora | VSCode
🙋大家好!我是毛毛张! 🌈个人首页: 神马都会亿点点的毛毛张 今天毛毛张分享的是如何在右键的新建菜单中添加新建MarkdownFile文件,这是毛毛张分享的关于Typora软件的相关知识的第三期 文章目录 1.前言🏝…...
PyTorch构建一个肺部CT图像分类模型来分辨肺癌
当你有5万个标注的肺部CT DICOM图像数据,并且希望使用PyTorch构建一个肺部CT图像分类模型来分辨肺癌,以下是详细的步骤和示例代码: 数据准备 首先,确保你的数据集被正确分为训练集、验证集和测试集,并且每个图像都有相…...

MySQL简介及数据库
mysql简介 mysql是一个轻量级关系型数据库管理系统,具有体积小,速度快,开源的优点 sql是一种结构化查询语言(Structured Query Language),专门用来管理和处理关系型数据库的标准化编程语言,mysql实现了SQL标准…...

服务器基础1
服务器基础复习01 1.环境部署 系统:华为欧拉系统 网络简单配置nmtui 因为华为欧拉系统密码需要复杂度 所以我们可以进入后更改密码 echo 123 | passwd --stdin root也可以 echo "root:123" | chpasswd2.关闭防火墙,禁用SElinux 首先先关…...

<数据集>光伏板缺陷检测数据集<目标检测>
数据集格式:VOCYOLO格式 图片数量:2400张 标注数量(xml文件个数):2400 标注数量(txt文件个数):2400 标注类别数:4 标注类别名称:[Crack,Grid,Spot] 序号类别名称图片数框数1Crack8688922Grid8248843S…...

leetcode 513. 找树左下角的值
给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 示例 1: 输入: root [2,1,3] 输出: 1示例 2: 输入: [1,2,3,4,null,5,6,null,null,7] 输出: 7提示: 二叉树的节点个数的范围是 [1,104]-231 < Node.val &…...
C++并发编程实战学习笔记
一、C的并发: 多进程并发: 将应用程序分为多个独立的进程,它们在同一时刻运行,就像同 时进行网页浏览和文字处理一样。独立的进程可以通过进程间常规的通信渠道传递讯息(信号、套接字、文件、管道等等)。不过,这种进程…...

【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【25】【分布式事务】
持续学习&持续更新中… 守破离 【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【25】【分布式事务】 本地事务事务的基本性质事务的隔离级别(下面四个越往下,隔离级 别越高,并发能力越差)事务的传播行为(是否…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...

跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
Java毕业设计:WML信息查询与后端信息发布系统开发
JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发,实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构,服务器端使用Java Servlet处理请求,数据库采用MySQL存储信息࿰…...

GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
比较数据迁移后MySQL数据库和OceanBase数据仓库中的表
设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...

在 Spring Boot 中使用 JSP
jsp? 好多年没用了。重新整一下 还费了点时间,记录一下。 项目结构: pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...
Pydantic + Function Calling的结合
1、Pydantic Pydantic 是一个 Python 库,用于数据验证和设置管理,通过 Python 类型注解强制执行数据类型。它广泛用于 API 开发(如 FastAPI)、配置管理和数据解析,核心功能包括: 数据验证:通过…...