使用Debezium、Postgres和Kafka进行数据实时采集(CDC)
码匠君
9小时前
1. 背景
一直在完善自己的微服务架构,其中包含分布式工作流服务的建设,目前采用的是Camunda工作流引擎。使用Camunda工作流,就会涉及到工作流引擎的用户体系如何与现有用户体系集成的问题(Flowable、Activity也类似)。现有设计中,工作流定位偏重于企业内部流程的流转,因此系统中设计了单位、部门、人员以及人事归属与Camunda工作流用户体系对应。
功能设计完成,就面临另外一个问题,如何解决现有人事体系数据如何【`实时`】同步至Camunda工作流引擎中。如果现有体系数据与工作流数据在同一个库中,相对比较好解决。而微服务架构中,不同服务的数据通常存放在不同数据库中,那么就需要进行数据的同步。采用的方式不同,可以取得的效果也相同。
最初考虑如下两种方案,但是都略感不足:
ETL:使用ETL工具进行数据同步是典型的方式,可以选择工具也比较多。开源的ETL工具增量同步问题解决的并不理想,不使用增量同步数那么数据同步始终存在时间差;商业的ETL工具增量同步解决的比较好,但是庞大且昂贵。
消息队列:消息队列是多系统集成普遍采用的方式,可以很好地解决数据同步的实时问题。但是数据同步的两端都需要自己编写代码,一端写生产代码一端写消费代码,生产端代码还要捆绑现有体系数据所有操作,需要的编写量比较大。
查询对比的大量的资料,最终选择了Debezimu来解决以上问题以及未来更多数据同步的问题。
2. Debezium介绍
RedHat开源的Debezium是一个将多种数据源实时变更数据捕获,形成数据流输出的开源工具。
它是一种CDC(Change Data Capture)工具,工作原理类似大家所熟知的Canal, DataBus, Maxwell等,是通过抽取数据库日志来获取变更的。
官方介绍为:
Debezium is an open source distributed platform for change data capture. Start it up, point it at your databases, and your apps can start responding to all of the inserts, updates, and deletes that other apps commit to your databases. Debezium is durable and fast, so your apps can respond quickly and never miss an event, even when things go wrong
Debezium是一个分布式平台,它将您现有的数据库转换为事件流,因此应用程序可以看到数据库中的每一个行级更改并立即做出响应。Debezium构建在Apache KAFKA之上,并提供Kafka连接兼容的连接器来监视特定的数据库管理系统。
Debezium现在已支持以下数据库:
MySQL
MongoDB
PostgreSQL
Oracle
SQL Server
Db2
Cassandra
Vitess
与ETL不同,Debezimu只支持在生产端连接数据库,消费端不支持连接数据库,而是需要自己编写代码接收Kafka消息数据。分析下来这种方式更加灵活,还可以很好利用现有微服务架构中的Kafka。
3. 快速搭建Debezimu测试环境。
目前,Debezium最新的Stable版本是1.6。 Debezium已经把要用到的Component打包成了Docker的Image,因此,我们只需要安装并启动Docker后就可以按下面的步骤快速搭建测试环境了。
3.1 运行Zookeeper
docker run -it --name zookeeper -p 2181:2181 -p 2888:2888 -p 3888:3888 debezium/zookeeper:1.6
3.2 运行Kafka
docker run -it --name kafka -p 9092:9092 --link zookeeper:zookeeper debezium/kafka:1.6
3.3 运行PostgreSQL
docker run -it --rm --name postgres -p 5432:5432 -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres debezium/example-postgres:1.6
上面代码中使用的是:
debezium/example-postgres:1.6,查看Debezimu官方文档以及其它示例都是这个。实际上Debezimu对postgresql 9~13都进行了Docker封装,可以根据自己的需要在Docker Hub中选择相应的PostgreSQL版本。
debezium/postgres很小,使用也比较方便,而且也进行了必要的设置,无须再进行额外的配置就可以直接使用。
3.4 运行Debezimu Connect
docker run -it --rm --name connect -p 8083:8083 -e GROUP_ID=1 -e CONFIG_STORAGE_TOPIC=my_connect_configs -e OFFSET_STORAGE_TOPIC=my_connect_offsets -e STATUS_STORAGE_TOPIC=my_connect_statuses --link zookeeper:zookeeper --link kafka:kafka --link postgres:postgres debezium/connect:1.6
Debezium的container启动时需要传入如下环境变量:
GROUP_ID: 分组ID,若需要启动多个Debezium的实例组成集群,那么它们的GROUP_ID必须被设置为一样
CONFIG_STORAGE_TOPIC:下面需要调用Debezium提供的RestFUL API管理connector,connector的信息就是保存在CONFIG_STORAGE_TOPIC指定的kafka topic下。
OFFSET_STORAGE_TOPIC: connector监控数据流的offset,若我们使用的是PostgreSQL Connector,那么OFFSET_STORAGE_TOPIC指定的topic中存的就是PostgreSQL的lsn。
3.5 创建Connector
经过上面4个步骤后,Debezium的测试环境就搭建好了,现在需要调用Debezium提供的API创建connector,使Debezium与数据库之间建立关系。我们把下面的payload POST到`http://:8083/connectors/`。
{
"name": "fulfillment-connector",
"config": {
"connector.class": "io.debezium.connector.postgresql.PostgresConnector",
"database.hostname": "192.168.99.100",
"database.port": "5432",
"database.user": "postgres",
"database.password": "postgres",
"database.dbname" : "postgres",
"database.server.name": "fulfillment",
"table.include.list": "public.inventory"
}
}
"name":注册到Kafka Connect服务的Connector名称
"connector.class":PostgreSQL connector class名称
"database.hostname":PostgreSQL 数据库地址
"database.port":PostgreSQL 数据库端口
"database.user":PostgreSQL 数据库用户名
"database.password":PostgreSQL数据密码
"database.dbname":连接的PostgreSQL数据库
"database.server.name":虚拟的数据库Server名称,可以根据实际需求定义,消费Kafka数据时要使用该值
"table.include.list":监听的数据表列表,以","分割。PostgreSQL要将表名写全,格式"."。如果没有特定的Schema,那么就是默认的`public`
下面为完成的curl命令:
curl -i -X POST -H "Accept:application/json" -H "Content-Type:application/json" localhost:8083/connectors/ -d '{"name": "fulfillment-connector", "config": {"connector.class": "io.debezium.connector.postgresql.PostgresConnector", "database.hostname": "192.168.99.100", "database.port": "5432", "database.user": "postgres", "database.password": "postgres", "database.dbname" : "postgres", "database.server.name": "fulfillment", "table.include.list": "public.inventory" }}'
上面是示例,因为使用的是Windows,个人觉得curl不方便,换用postman:
3.6 Docker Compose 配置
为了方便使用,将以上Docker命令整合为Docker Compose配置,具体如下:
version: "3"
services:
postgres:
image: debezium/postgres:13
container_name: postgres
hostname: postgres
environment:
POSTGRES_USER: herodotus
POSTGRES_PASSWORD: herodotus
ports:
- 5432:5432
zookeeper:
image: debezium/zookeeper:1.6
container_name: zookeeper
restart: always
ports:
- 2181:2181
- 2888:2888
- 3888:3888
kafka:
image: debezium/kafka:1.6
container_name: kafka
restart: always
ports:
- 9092:9092
environment:
ZOOKEEPER_CONNECT: zookeeper:2181
BOOTSTRAP_SERVERS: kafka:9092
depends_on:
- zookeeper
connect:
image: debezium/connect:1.6
container_name: connect
restart: always
ports:
- 8083:8083
environment:
GROUP_ID: 1
CONFIG_STORAGE_TOPIC: herodotus_connect_configs
OFFSET_STORAGE_TOPIC: herodotus_connect_offsets
STATUS_STORAGE_TOPIC: herodotus_connect_statuses
BOOTSTRAP_SERVERS: kafka:9092
depends_on:
- kafka
4. 外部数据库配置
上一章节,介绍了Debezimu测试环境的方式,其中使用的debezium/postgres是已经进行过配置的,所以使用起来比较方便。在实际使用过程中,很多时候是使用独立搭建PostgreSQL,那么就需要对PostgreSQL进行配置。
4.1 以Docker的方式运行基础组件
本章节主要介绍Debezimu与独立的PostgreSQL数据库连接,因此除了PostgreSQL以外,Zookeeper、Kafka、Debezimu Connect仍旧使用Docker方式部署。具体部署的Docker Compose配置如下:
version: "3"
services:
zookeeper:
image: debezium/zookeeper:1.6
container_name: zookeeper
hostname: zookeeper
environment:
ZOOKEEPER_SERVER_ID: 1
ports:
- 2181:2181
- 2888:2888
- 3888:3888
kafka:
image: debezium/kafka:1.6
container_name: kafka
hostname: kafka
ports:
- 9092:9092
environment:
BROKER_ID: 1
ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_LISTENERS: LISTENER_INNER://kafka:29092,LISTENER_OUTER://0.0.0.0:9092
KAFKA_ADVERTISED_LISTENERS: LISTENER_INNER://kafka:29092,LISTENER_OUTER://192.168.101.10:9092
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: LISTENER_INNER:PLAINTEXT,LISTENER_OUTER:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME: LISTENER_INNER
KAFKA_ALLOW_PLAINTEXT_LISTENER: 'yes'
KAFKA_AUTO_CREATE_TOPICS_ENABLE: 'true'
depends_on:
- zookeeper
connect:
image: debezium/connect:1.6
container_name: connect
hostname: connect
ports:
- 8083:8083
environment:
GROUP_ID: 1
CONFIG_STORAGE_TOPIC: herodotus_connect_configs
OFFSET_STORAGE_TOPIC: herodotus_connect_offsets
STATUS_STORAGE_TOPIC: herodotus_connect_statuses
BOOTSTRAP_SERVERS: kafka:9092
depends_on:
- kafka
其中Kafka Listener相关的配置,是为了解决Spring Kafka连接Kafka会出现:`Connection to node -1 could not be established. Broker may not be available.`问题。
4.2 修改PostgreSQL配置
Logical Decoding功能是PostgreSQL在9.4加入的,它是一种机制,允许提取提交到事务日志的更改,并在输出插件的帮助下以用户友好的方式处理这些更改。输出插件使客户机能够使用更改。
PostgreSQL connector 读取和处理数据库变化主要包含两个部分:
Logical Decoding 输出插件:根据选择可能需要安装输出插件。运行PostgreSQL服务之前,必须配置`replication slot `来启用你所选择的输出插件,有以下几个输出插件供选择:
decoderbufs: 是基于`Protobuf`的,目前由Debezimu社区维护
wal2json :是基于`JSON`的,目前由wal2json社区维护
pgoutput:在PostgreSQL 10及以上版本中是标准的Logical Decoding 输出插件。是由PostgreSQL社区维护,由PostgreSQL自己用于Logical Replication。这个插件是内置安装的,所以不需要额外安装。
Java代码(就是连接Kafka Connect的代码):负责读取由Logical Decoding 输出插件产生的数据。
Logical Decoding 输出插件不支持DDL变更,这意味着Connector不能把DDL变更事件发送给消费者
Logical Decoding Replicaiton Slots支持数据库的`primary`服务器。因此如果是PostgreSQL服务的集群,Connector只能在`primary`服务器激活。如果`primary`服务器出现问题,那么connector就会停掉。
4.2.1 修改PostgreSQL配置
在${PostgreSQL_HOME}/13/data目录下,找到postgresql.conf。
修改以下配置:
wal_level=logical
max_wal_senders=1
max_replication_slots=1
wal_level:通知数据库使用 logical decoding 读取预写日志
max_wal_senders: 通知数据库独立处理WAL变更的独立进程数量
max_replication_slots: 通知数据库处理WAL变更流所允许最大replication slots数目
配置完成后记得重启数据库
4.2.2 设置数据库权限
需要给PostgreSQL 用户分配replication权限。定义一个PostgreSQL role,至少分配REPLICATION和LOGION两项权限,示例代码如下:
CREATE ROLE REPLICATION LOGIN;
具体操作可以参考以下脚本:
-- pg新建用户
CREATE USER user WITH PASSWORD 'pwd';
-- 给用户复制流权限
ALTER ROLE user replication;
-- 给用户登录数据库权限
grant CONNECT ON DATABASE test to user;
-- 把当前库public下所有表查询权限赋给用户
GRANT SELECT ON ALL TABLES IN SCHEMA public TO user;
4.3 创建Connector
把下面的payload POST到http://:8083/connectors/
{
"name": "herodotus-connector",
"config": {
"connector.class": "io.debezium.connector.postgresql.PostgresConnector",
"database.hostname": "192.168.101.10",
"database.port": "15432",
"database.user": "athena",
"database.password": "athena",
"database.dbname" : "athena",
"database.server.name": "herodotus",
"slot.name": "herodotus_slot",
"table.include.list": "public.sys_organization",
"publication.name": "herodotus_public_connector",
"publication.autocreate.mode": "filtered",
"plugin.name": "pgoutput"
}
}
postman 界面操作如下图:
下面结合本例子中connector的配置信息对几个重点属性进行进一步说明:
Slot.name
按照上例Debezium会在PostgreSQL创建一个名为`herodotus_slot`的复制槽,本例中创建的connector需要通过该复制槽获取数据变更的信息。
可以通过以下sql查看复制槽的信息:
select * from pg_replication_slots;
上图中,active_pid为14200,即进程ID为14200的wal_sender进程已经在使用该复制槽与Debezium交互了
database.server.name和table.include.list
当connector获取到数据变更的信息后,会把该信息转化为统一的数据格式,并发布到Kafka的topic中。Debezium规定一个表对应一个topic,topic的名字的格式为 ..,本例中的表的数据变更消息将保存到Kafka的topic
herodotus.public.sys_organization中。
可以通过以下代码查看接收到的信息:
@KafkaListener(topics = {"herodotus.public.sys_organization"}, groupId = "herodotus.debezium")
public void received(String message) {
log.info("[Herodotus] |- Recived message from Debezium : [{}]", message);
}
5. 运行测试
现在,可以基于以上环境的配置,进行Debezium捕获数据效果的测试。可以进入到Kafka容器中,使用使用Kafka提供的kafka-console-consumer.sh查看Topic接收到的数据。具体命令如下:
bin/kafka-console-consumer.sh --bootstrap-server 192.168.101.10:9092 --topic herodotus.public.sys_organization
5.1 Insert 测试
在数据库sys_organization 表中插入一条数据
Kafka的消费者命令行工具收到了来自Debezium发布的数据变更消息:
格式化后的消息体如下,其中schema字段在此先忽略,重点放payload.before,payload.after及payload.op字段上:
{
"schema": {
...
},
"payload": {
"before": null,
"after": {
"organization_id": "4",
"create_time": null,
"ranking": null,
"update_time": null,
"description": null,
"is_reserved": null,
"reversion": null,
"status": 1,
"a4_biz_org_id": null,
"biz_org_code": null,
"biz_org_desc": null,
"biz_org_id": null,
"biz_org_name": null,
"biz_org_type": null,
"organization_name": "AAAAA",
"parent_id": null,
"partition_code": null,
"short_name": null
},
"source": {
"version": "1.6.0.Final",
"connector": "postgresql",
"name": "herodotus",
"ts_ms": 1626594964405,
"snapshot": "false",
"db": "athena",
"sequence": "[\"63461608\",\"63461608\"]",
"schema": "public",
"table": "sys_organization",
"txId": 2460,
"lsn": 63461896,
"xmin": null
},
"op": "c",
"ts_ms": 1626594964846,
"transaction": null
}
}
由于是insert操作,所以op为c (create),before为null,after为我们插入的数据。
5.2 Update 测试
在数据库sys_organization表中修改一条数据
Kafka的消费者命令行工具收到了来自Debezium发布的数据变更消息:
格式化后的消息体如下:
{
"schema": {
...
},
"payload": {
"before": null,
"after": {
"organization_id": "4",
"create_time": null,
"ranking": null,
"update_time": null,
"description": null,
"is_reserved": null,
"reversion": null,
"status": 1,
"a4_biz_org_id": null,
"biz_org_code": null,
"biz_org_desc": null,
"biz_org_id": null,
"biz_org_name": null,
"biz_org_type": null,
"organization_name": "BBBBB",
"parent_id": null,
"partition_code": null,
"short_name": null
},
"source": {
"version": "1.6.0.Final",
"connector": "postgresql",
"name": "herodotus",
"ts_ms": 1626595173601,
"snapshot": "false",
"db": "athena",
"sequence": "[\"63466888\",\"63466888\"]",
"schema": "public",
"table": "sys_organization",
"txId": 2461,
"lsn": 63467176,
"xmin": null
},
"op": "u",
"ts_ms": 1626595173825,
"transaction": null
}
}
进行更新产品信息的操作后,consumer将收到一条op为u (update)的信息,after为修改后的数据。
5.3 Delete测试
在数据库sys_organization表中删除一条数据
Kafka的消费者命令行工具收到了来自Debezium发布的数据变更消息:
格式化后的消息体如下:
{
"schema": {
...
},
"payload": {
"before": {
"organization_id": "3",
"create_time": null,
"ranking": null,
"update_time": null,
"description": null,
"is_reserved": null,
"reversion": null,
"status": null,
"a4_biz_org_id": null,
"biz_org_code": null,
"biz_org_desc": null,
"biz_org_id": null,
"biz_org_name": null,
"biz_org_type": null,
"organization_name": null,
"parent_id": null,
"partition_code": null,
"short_name": null
},
"after": null,
"source": {
"version": "1.6.0.Final",
"connector": "postgresql",
"name": "herodotus",
"ts_ms": 1626594566933,
"snapshot": "false",
"db": "athena",
"sequence": "[\"63461120\",\"63461120\"]",
"schema": "public",
"table": "sys_organization",
"txId": 2458,
"lsn": 63461176,
"xmin": null
},
"op": "d",
"ts_ms": 1626594567136,
"transaction": null
}
}
进行删除产品信息的操作后,consumer将收到一条op为d (delete)的信息,before为删除前的数据,after为null。
6.总结
通过Debezimu进行数据同步,不仅解决了传统ETL时效性不高的问题,还解决了基于消息队列需要两端编写代码的工程量,而且基于容器的方式更适合微服务架构的使用,使用Kafka进行消费端的整合,使得整合方式更加灵活便捷、终端类型更加丰富。
示例代码地址:
[Gitee](https://gitee.com/herodotus/eurynome-cloud)
[Github](https://github.com/herodotus-cloud/eurynome-cloud)
搜索
你可能感兴趣的:(数据库数据变动实时监听)
【unity游戏开发——网络】网络游戏通信方案——强联网游戏(Socket长连接)、 弱联网游戏(HTTP短连接)
向宇it
【unity游戏开发——网络】 网络 unity 游戏 游戏引擎 c# 编辑器 http
注意:考虑到热更新的内容比较多,我将热更新的内容分开,并全部整合放在【unity游戏开发——网络】专栏里,感兴趣的小伙伴可以前往逐一查看学习。文章目录一、联网游戏类型划分二、核心通信协议对比三、开发选择指南专栏推荐完结一、联网游戏类型划分类型通信特点代表游戏技术本质弱联网游戏按需连接,单次请求后立即断开消消乐、卡牌类(如《刀塔传奇》)短连接通信强联网游戏持续连接,实时双向数据交换《王者荣耀》《和平
TCP/UDP通信调试实战工具
本文还有配套的精品资源,点击获取简介:TCP调试助手是一款旨在协助程序员和网络管理员进行TCP和UDP协议调试的网络通信工具。TCP作为一种面向连接、可靠的协议,具有诸如连接管理、数据分片与重组、流量和拥塞控制等特点。该工具支持TCPServer和TCPClient两种模式,允许用户模拟服务器和客户端进行通信测试。同时,它也支持UDP通信模式,适合实时性要求高而数据完整性要求不高的场合。通过TCP
数字孪生:未来城市管理的革命性技术
大有数据可视化
信息可视化
一、数字孪生技术概述数字孪生技术是一种通过创建虚拟模型与物理实体之间实时交互的技术。它借助物联网、大数据、云计算、人工智能等前沿技术,实现对物理实体的精准映射与动态仿真。数字孪生的核心在于构建一个与物理世界相对应的虚拟模型,该模型能够实时反映物理实体的状态,并通过数据分析与模拟优化其性能。在城市管理领域,数字孪生技术为城市管理者提供了一种全新的视角和工具。城市是一个复杂的巨系统,涉及基础设施、交通
(SERIES1) MacOS Terminal远程SSH连接Aliyun ECS服务器纯命令行模式下部署DM8教程(服务器环境Ubuntu 20.04LTS )
Ender-Shadows
达梦 数据库 ubuntu macos 阿里云
1DM数据库版本介绍1.1版本区别 DM8目前的版本主要包括标准版、企业版、安全版和开发版。前三项的比较如表1-1所示。以适用场景为角度进行分类,标准版适用于小型应用开发,企业版适合生产环境级应用,安全版则在具备所有企业版基础上加入了对四权分立、强制访问控制、审计和实时侵害检测等功能上的补全,在安全性方面实现了更加全面完善的安全策略;至于开发版则专供开发者学习、测试、开发用途,有1年免费试用期,
Webpack中plugin详解
aiguangyuan
Webpack 前端开发 Webpack
1.Plugin基础1.1.基础使用Webpack通过Plugin机制让其更加灵活,以适应各种应用场景。在Webpack运行的生命周期中会广播出许多事件,Plugin可以监听这些事件,在合适的时机通过Webpack提供的API改变输出结果。一个最基础的Plugin的代码是这样的:classBasicPlugin{//在构造函数中获取用户给该插件传入的配置constructor(options){}
如何设计一个聊天系统?
设计一个聊天系统涉及多个模块,包括消息传输、用户管理、存储策略、状态同步、高可用等。下面我从系统设计角度为你分层展开一个具备扩展性与高可用能力的聊天系统设计方案:✅一、需求定义(可根据实际调整)1.1基础功能用户注册/登录一对一私聊群聊离线消息消息撤回/删除在线状态显示多端同步(Web、移动、桌面)1.2非功能需求高并发(百万连接)实时性(RTT<100ms)高可用/可扩展消息可靠性保证支持水平扩
推客系统小程序全栈开发:从架构设计到功能落地实践
wx_ywyy6798
python java 编辑器 推客系统 推客系统开发 推客 微小店推客系统开发
在流量为王的时代,推客系统作为高效的营销裂变工具,正成为企业数字化转型的关键抓手。本文将结合实战案例,深度拆解推客系统小程序从0到1的开发全流程,涵盖需求分析、技术选型、核心功能实现及性能优化方案,为技术人提供可复用的开发思路。一、项目背景与需求剖析推客系统小程序旨在构建一个“用户推广-佣金结算-数据追踪”的闭环生态。某电商平台的实际需求中,需要实现多级分销机制、实时订单同步、智能佣金计算、可视化
概述-1-数据库的相关概念
He.ZaoCha
MySQL 数据库 mysql
数据库的相关概念用户通过SQL操作数据库管理系统,再通过数据库管理系统操作数据库以及数据库中的数据。数据库数据库是存储数据的仓库,数据是有组织的进行存储,DataBase简称(DB)数据库管理系统操纵和管理数据库的大型软件,DataBaseManagementSystem简称(DBMS)主流的关系型数据库管理系统DB-EnginesRanking根据数据库管理系统的受欢迎程度对其进行排名。排名每月
TRICONEX 4409 | 安全管理模块
Lucky 19389860630
嵌入式硬件 模块 自动化
产品概述TRICONEX4409是TRICONEX产品组合中的关键组件,专为安全关键型自动化设置而设计。作为安全管理模块(SMM),它在确保工业过程的可靠运行中起着关键作用。该模块是TRICONEX系统的一个组成部分,该系统以其高冗余和容错能力而闻名。在工业自动化环境中,TRICONEX4409负责监测和控制与安全相关的功能。它与各种传感器和执行器接口,收集数据并做出实时决策,以维护整个系统的安全
TinyWebserver学习(6)-线程监听函数eventListen()
THMOM91
c++
六、线程监听函数eventListen()一、相关知识总结1、setsockopt()函数setsockopt是用于设置套接字(socket)选项的系统调用,允许应用程序对套接字的行为进行更细粒度的控制。它通常用于配置网络通信的参数,例如超时、缓冲区大小、地址复用等。以下是详细的解析#include#includeintsetsockopt(intsockfd,intlevel,intoptnam
Cursor黑科技:AI编程实战技术文章
yuehui001
科技 AI编程
引言概述AI编程工具的发展现状Cursor在AI编程领域的独特定位文章目标:展示Cursor的核心功能与实战应用Cursor的核心功能解析智能代码补全:基于上下文的代码生成能力自然语言转代码:通过对话式交互生成完整功能模块代码重构与优化:自动化识别并改进代码质量错误诊断与修复:实时分析代码逻辑并提供解决方案实战场景一:快速原型开发需求描述转化为可执行代码的流程示例:构建一个简易待办事项应用对比传统
C语言MySQL API使用详解
吸嘎嘎能手
mysql 数据库 c++ c语言
连接数据库的步骤众所周知,MySQL数据库是一个典型的C/S结构,即:客户端和服务器端。如果我们部署好了MySQL服务器,想要在客户端访问服务器端的数据,在编写程序的时候就可以通过官方提供的C语言的API来实现。在程序中连接MySql服务器,主要分为已经几个步骤:初始化连接环境连接mysql的服务器,需要提供如下连接数据:服务器的IP地址服务器监听的端口(默认端口是3306)连接服务器使用的用户名
如何利用Web Compoent封装一个自定义右键菜单?
程序员小寒
前端 javascript 开发语言
一、右键菜单是什么所谓右键菜单,就是指我们在浏览器页面中,点击鼠标右键后弹出来的包含一系列功能键的组合框。二、核心代码核心就是监听contextmenu事件。最最核心的代码如下:document.addEventListener('contextmenu',function(e){e.preventDefault();//阻止默认的右键菜单弹出showMyMenu(e);//显示自定义菜单})三、
JavaScript异步编程:理解和使用Promise、Async/Await
小码快撩
javascript 开发语言 ecmascript
JavaScript是一种单线程语言,这意味着它一次只能执行一个任务。然而,在Web开发中,我们经常需要处理异步操作,例如网络请求、定时器、事件监听等。JavaScript提供了多种方式来处理异步编程,包括回调函数、Promise、Async/Await等。回调函数回调函数是最基本的异步编程方式。当一个异步任务完成时,它会调用一个回调函数。这种方式的问题是回调地狱,即回调函数嵌套过多,难以理解和维
AI编程实战:Cursor黑科技全解析
ithadoop
python 开发语言
Cursor黑科技:AI编程实战核心技术解析2025年智能编程工具效能革命白皮书一、核心功能架构语义驱动开发基于CodeGraph技术构建跨文件语义图谱,实现类/函数级上下文感知实时生成UML时序图辅助架构设计(快捷键Ctrl+Alt+U)多模态编程#输入:"PyTorch实现ResNet50猫狗分类,带数据增强"@AI生成代码transform=transforms.Compose([trans
srs+ffmpeg+flv.js查看实时监控
nov4th
rtmp ffmpeg http-flv srs
一、Linux中搭建srs服务器1、在Linux中下载srsgitclonehttps://github.com/ossrs/srs#下载很慢可以使用下面的地址gitclonehttps://gitee.com/winlinvip/srs.oschina2、编译srs#进入trunk目录cdsrs/trunk#编译./configure&&make3、创建自己的flv配置文件,可以从官方给的去复制
ThinkPHP6.0 如何使用日志
小叔哥哥
问题 PHP thinkphp
日志遵循PSR-3规范,除非是实时写入的日志,其它日志都是在当前请求结束的时候统一写入的所以不要在日志写入之后使用exit等中断操作会导致日志写入失败。一.写入日志的几种方法1.助手函数trace/***记录日志信息*@parammixed$loglog信息支持字符串和数组*@paramstring$level日志级别(error/info/notice)*@returnarray|void*/t
基于机器学习的超音速流场实时控制——Python/C++混合编程实战
莱歌数字
数字化转型 # 职场经验 # 结构热设计 机器学习 python c++
作者简介:科技自媒体优质创作者个人主页:莱歌数字-CSDN博客公众号:莱歌数字个人微信:yanshanYH211、985硕士,职场15年+从事结构设计、热设计、售前、产品设计、项目管理等工作,涉足消费电子、新能源、医疗设备、制药信息化、核工业等领域涵盖新能源车载与非车载系统、医疗设备软硬件、智能工厂等业务,带领团队进行多个0-1的产品开发,并推广到多个企业客户现场落地实施。专题课程Flotherm
铺补调是鞋服企业在商品上柜并开始产生销售后,根据实际销售情况和库存状态,对产品进行分、铺、补、调的库存调整计划。
流量留
电商系统 大数据 人工智能
**一、铺补调核心定义与目标*****定义**:铺补调系统专注于鞋服企业在商品上柜销售后依据,实际销售状况和库存水平,对产品实施分、铺、补、调的库存调整计划,是对传统库存管理流程的精细化升级,使其更加贴合市场动态变化的需求。***核心目标***动态优化库存分布,满足市场需求:实时跟踪销售数据和库存状态,将商品精准分配到需求旺盛的地区和门店,确保市场供应的及时性和充足性,提高市场响应速度和客户满意度
zabbix监控jmx
寰宇001
监控/自动化工具
介绍背景:目前公司用的主要语言就是java,然后在运维过程中会遇到频繁的内存溢出的情况,之前使用过elk日志分析系统可以实时的判断出内存溢出的情况,但是无法查看内存的使用情况,只能通过dump文件查看内存溢出的时候dump下来的文件去分析。这样也无法准确的判断出问题。zabbix可以监控java,并且将内存的使用情况实时的展现出来,这是一个不错的选择。JMX的全称是JavaManagementEx
口扫系统软件的架构设计流程
老猿的春天
三维 c++ 口扫 三维重建
[结构光图像流]↓解码结构光图案↓三角测量计算深度↓点云生成并去噪滤波↓实时配准/拼接(可选ICP/Odometry)↓网格重建(如MarchingCubes或BallPivoting)↓GPU显示(OpenGL/Open3D/VTK)
充电桩 APP 开发:技术架构与核心功能
一品威客网
架构
随着新能源汽车的普及,充电桩APP成为连接用户与充电设施的关键枢纽。这类APP的开发需兼顾用户体验与运营效率,以下从技术实现与功能设计两方面展开分析。技术架构设计实时数据交互:采用MQTT协议实现充电桩状态(空闲/充电中/故障)的实时推送,确保用户获取最新信息。定位与地图服务:集成高德/Baidu地图SDK,通过POI搜索与路径规划算法,优化充电桩位置展示与导航体验。支付系统:对接微信/支付宝支付
物流运输企业如何构建数字化管理系统
在数字化浪潮下,物流运输企业构建数字化管理系统成为提升竞争力的关键。当前,企业常面临信息传递滞后、资源调配低效、运输监控不足等问题,构建数字化管理系统可有效解决这些难题。系统搭建需涵盖多个核心模块。运输管理模块通过智能调度算法,根据货物信息、车辆状态、路线情况,优化运输路径,实现车辆高效调配,减少空载率;仓储管理模块利用物联网技术,实时监控货物存储状态、库存数量,结合数据分析实现智能补货,提升仓储
安装部署zabbix监控ELK日志:(centos 7 )完整文档
Liberation-army
linux zabbix elk
今天接到公司领导要求,要求用zabbix能够实时的监控所有服务器的报错报警日志。但是因为服务器数量较大,日志量很大,单独做脚本分析日志来上报的话消耗资源可能会比较大,因此就使用了已经部署了的elk来把错误的日志单独整理上报,然后就在网上查询资料找到了ZABBIX+ELK的部署,经过十几个小时的尝试和测试,已经能够成功的监控到错误和告警日志了,因为部署过程中踩了很多坑,因此整理整个流程把相关的内容发
NAT穿透 P2P通信 介绍
ccCoKOll
p2p 网络协议 网络
NAT穿透与P2P通信是互联网通信领域中的关键技术,特别是在多点通信、实时互动以及设备间的直接连接中。NAT(网络地址转换)技术在保护网络安全和解决IP地址稀缺问题的同时,也对P2P(对等网络)通信带来了挑战。P2P通信则是一种网络架构,其中每个节点既是服务的提供者也是消费者,它们之间可以直接交换数据,无需通过中央服务器。在P2P网络中,每个节点都有自己的唯一标识,通常是IP地址和端口号。但在NA
API编排在AI原生应用中的5大核心应用场景解析
API编排在AI原生应用中的5大核心应用场景解析关键词:API编排、AI原生应用、微服务架构、工作流自动化、服务集成、智能决策、实时数据处理摘要:本文深入探讨API编排在AI原生应用中的核心应用场景,揭示其如何成为连接智能服务的关键纽带。我们将从基础概念出发,通过5个典型场景分析,展示API编排如何提升AI应用的灵活性、可扩展性和智能化水平,并辅以实际代码示例和架构图解。背景介绍目的和范围本文旨在
微信小程序实现下拉刷新首页数据、上拉加载下一页数据
花铛
微信小程序 微信小程序
下拉刷新首页数据:使用页面的下拉,刷新首页数据:首先需要在页面对应的JSON文件中配置"enablePullDownRefresh":true。然后在页面对应的JS文件中使用微信小程序提供的onPullDownRefresh(){}监听用户下拉动作。//本质是获取首页的数据onPullDownRefresh(){this.setData({pageNum:1},this.getList)},get
Python如何调用港股行情接口
kk_stoper
python 开发语言 java javascript 数据结构
1.接口信息接口类型:实时综合行情接口支持品种:贵金属,商品期货,外汇,A股,港股,美股查询方式:HTTP,WebSocket申请密钥:https://infoway.io官方对接文档:https://infoway.readme.io/reference/ws-subscription2.获取股票清单这个接口用来查询股票的名单,比如我可以获取美股清单:importrequestsurl="htt
全网最全学习Zephyr开发中文教程资料汇总-从基础文档视频到上手实操示例
聆思科技AI芯片
Zephyr保姆级上手教程 zephyr AIGC 多模态 嵌入式硬件 iot 硬件工程 驱动开发
Zephyr作为一款开源且极具灵活性与可扩展性的实时操作系统(RTOS),拥有原生的BLE协议栈、完整的Net协议栈,涵盖TCP/IP与应用层协议,具备出色的实时性,支持硬实时任务调度,确保系统响应的确定性延迟,并且内存占用极小。丰富的通信机制、深度集成的电源管理模式等,也进一步提升了其在嵌入式领域的竞争力。然而,要深入掌握Zephyr开发并非一蹴而就之事。为了方便大家顺利踏上Zephyr开发之路
《JMS事务性会话彻底解析:消息监听中的 commit、rollback 和幂等设计》
G探险者
java 中间件 分布式
大家好,我是G探险者!场景引入在实际项目中,我们常常面临以下挑战:监听MQ消息失败了,希望自动重试?消费MQ消息后,要写数据库,但中间报错了?消息处理必须要么成功要么失败,否则可能导致脏数据?消息是幂等的吗?可以重复投递处理吗?这些都需要事务性会话+容器回滚机制+幂等控制组合拳来解决。✅一、什么是JMS的事务性会话?事务性会话(transacted=true)是一种将消息的接收与处理放入事务中控制
枚举的构造函数中抛出异常会怎样
bylijinnan
java enum 单例
首先从使用enum实现单例说起。
为什么要用enum来实现单例?
这篇文章(
http://javarevisited.blogspot.sg/2012/07/why-enum-singleton-are-better-in-java.html)阐述了三个理由:
1.enum单例简单、容易,只需几行代码:
public enum Singleton {
INSTANCE;
CMake 教程
aigo
C++
转自:http://xiang.lf.blog.163.com/blog/static/127733322201481114456136/
CMake是一个跨平台的程序构建工具,比如起自己编写Makefile方便很多。
介绍:http://baike.baidu.com/view/1126160.htm
本文件不介绍CMake的基本语法,下面是篇不错的入门教程:
http:
cvc-complex-type.2.3: Element 'beans' cannot have character
Cb123456
spring Webgis
cvc-complex-type.2.3: Element 'beans' cannot have character
Line 33 in XML document from ServletContext resource [/WEB-INF/backend-servlet.xml] is i
jquery实例:随页面滚动条滚动而自动加载内容
120153216
jquery
<script language="javascript">
$(function (){
var i = 4;$(window).bind("scroll", function (event){
//滚动条到网页头部的 高度,兼容ie,ff,chrome
var top = document.documentElement.s
将数据库中的数据转换成dbs文件
何必如此
sql dbs
旗正规则引擎通过数据库配置器(DataBuilder)来管理数据库,无论是Oracle,还是其他主流的数据都支持,操作方式是一样的。旗正规则引擎的数据库配置器是用于编辑数据库结构信息以及管理数据库表数据,并且可以执行SQL 语句,主要功能如下。
1)数据库生成表结构信息:
主要生成数据库配置文件(.conf文
在IBATIS中配置SQL语句的IN方式
357029540
ibatis
在使用IBATIS进行SQL语句配置查询时,我们一定会遇到通过IN查询的地方,在使用IN查询时我们可以有两种方式进行配置参数:String和List。具体使用方式如下:
1.String:定义一个String的参数userIds,把这个参数传入IBATIS的sql配置文件,sql语句就可以这样写:
<select id="getForms" param
Spring3 MVC 笔记(一)
7454103
spring mvc bean REST JSF
自从 MVC 这个概念提出来之后 struts1.X struts2.X jsf 。。。。。
这个view 层的技术一个接一个! 都用过!不敢说哪个绝对的强悍!
要看业务,和整体的设计!
最近公司要求开发个新系统!
Timer与Spring Quartz 定时执行程序
darkranger
spring bean 工作 quartz
有时候需要定时触发某一项任务。其实在jdk1.3,java sdk就通过java.util.Timer提供相应的功能。一个简单的例子说明如何使用,很简单: 1、第一步,我们需要建立一项任务,我们的任务需要继承java.util.TimerTask package com.test; import java.text.SimpleDateFormat; import java.util.Date;
大端小端转换,le32_to_cpu 和cpu_to_le32
aijuans
C语言相关
大端小端转换,le32_to_cpu 和cpu_to_le32 字节序
http://oss.org.cn/kernel-book/ldd3/ch11s04.html
小心不要假设字节序. PC 存储多字节值是低字节为先(小端为先, 因此是小端), 一些高级的平台以另一种方式(大端)
Nginx负载均衡配置实例详解
avords
[导读] 负载均衡是我们大流量网站要做的一个东西,下面我来给大家介绍在Nginx服务器上进行负载均衡配置方法,希望对有需要的同学有所帮助哦。负载均衡先来简单了解一下什么是负载均衡,单从字面上的意思来理解就可以解 负载均衡是我们大流量网站要做的一个东西,下面我来给大家介绍在Nginx服务器上进行负载均衡配置方法,希望对有需要的同学有所帮助哦。
负载均衡
先来简单了解一下什么是负载均衡
乱说的
houxinyou
框架 敏捷开发 软件测试
从很久以前,大家就研究框架,开发方法,软件工程,好多!反正我是搞不明白!
这两天看好多人研究敏捷模型,瀑布模型!也没太搞明白.
不过感觉和程序开发语言差不多,
瀑布就是顺序,敏捷就是循环.
瀑布就是需求、分析、设计、编码、测试一步一步走下来。而敏捷就是按摸块或者说迭代做个循环,第个循环中也一样是需求、分析、设计、编码、测试一步一步走下来。
也可以把软件开发理
欣赏的价值——一个小故事
bijian1013
有效辅导 欣赏 欣赏的价值
第一次参加家长会,幼儿园的老师说:"您的儿子有多动症,在板凳上连三分钟都坐不了,你最好带他去医院看一看。" 回家的路上,儿子问她老师都说了些什么,她鼻子一酸,差点流下泪来。因为全班30位小朋友,惟有他表现最差;惟有对他,老师表现出不屑,然而她还在告诉她的儿子:"老师表扬你了,说宝宝原来在板凳上坐不了一分钟,现在能坐三分钟。其他妈妈都非常羡慕妈妈,因为全班只有宝宝
包冲突问题的解决方法
bingyingao
eclipse maven exclusions 包冲突
包冲突是开发过程中很常见的问题:
其表现有:
1.明明在eclipse中能够索引到某个类,运行时却报出找不到类。
2.明明在eclipse中能够索引到某个类的方法,运行时却报出找不到方法。
3.类及方法都有,以正确编译成了.class文件,在本机跑的好好的,发到测试或者正式环境就
抛如下异常:
java.lang.NoClassDefFoundError: Could not in
【Spark七十五】Spark Streaming整合Flume-NG三之接入log4j
bit1129
Stream
先来一段废话:
实际工作中,业务系统的日志基本上是使用Log4j写入到日志文件中的,问题的关键之处在于业务日志的格式混乱,这给对日志文件中的日志进行统计分析带来了极大的困难,或者说,基本上无法进行分析,每个人写日志的习惯不同,导致日志行的格式五花八门,最后只能通过grep来查找特定的关键词缩小范围,但是在集群环境下,每个机器去grep一遍,分析一遍,这个效率如何可想之二,大好光阴都浪费在这上面了
sudoku solver in Haskell
bookjovi
sudoku haskell
这几天没太多的事做,想着用函数式语言来写点实用的程序,像fib和prime之类的就不想提了(就一行代码的事),写什么程序呢?在网上闲逛时发现sudoku游戏,sudoku十几年前就知道了,学生生涯时也想过用C/Java来实现个智能求解,但到最后往往没写成,主要是用C/Java写的话会很麻烦。
现在写程序,本人总是有一种思维惯性,总是想把程序写的更紧凑,更精致,代码行数最少,所以现
java apache ftpClient
bro_feng
java
最近使用apache的ftpclient插件实现ftp下载,遇见几个问题,做如下总结。
1. 上传阻塞,一连串的上传,其中一个就阻塞了,或是用storeFile上传时返回false。查了点资料,说是FTP有主动模式和被动模式。将传出模式修改为被动模式ftp.enterLocalPassiveMode();然后就好了。
看了网上相关介绍,对主动模式和被动模式区别还是比较的模糊,不太了解被动模
读《研磨设计模式》-代码笔记-工厂方法模式
bylijinnan
java 设计模式
声明: 本文只为方便我个人查阅和理解,详细的分析以及源代码请移步 原作者的博客http://chjavach.iteye.com/
package design.pattern;
/*
* 工厂方法模式:使一个类的实例化延迟到子类
* 某次,我在工作不知不觉中就用到了工厂方法模式(称为模板方法模式更恰当。2012-10-29):
* 有很多不同的产品,它
面试记录语
chenyu19891124
招聘
或许真的在一个平台上成长成什么样,都必须靠自己去努力。有了好的平台让自己展示,就该好好努力。今天是自己单独一次去面试别人,感觉有点小紧张,说话有点打结。在面试完后写面试情况表,下笔真的好难,尤其是要对面试人的情况说明真的好难。
今天面试的是自己同事的同事,现在的这个同事要离职了,介绍了我现在这位同事以前的同事来面试。今天这位求职者面试的是配置管理,期初看了简历觉得应该很适合做配置管理,但是今天面
Fire Workflow 1.0正式版终于发布了
comsci
工作 workflow Google
Fire Workflow 是国内另外一款开源工作流,作者是著名的非也同志,哈哈....
官方网站是 http://www.fireflow.org
经过大家努力,Fire Workflow 1.0正式版终于发布了
正式版主要变化:
1、增加IWorkItem.jumpToEx(...)方法,取消了当前环节和目标环节必须在同一条执行线的限制,使得自由流更加自由
2、增加IT
Python向脚本传参
daizj
python 脚本 传参
如果想对python脚本传参数,python中对应的argc, argv(c语言的命令行参数)是什么呢?
需要模块:sys
参数个数:len(sys.argv)
脚本名: sys.argv[0]
参数1: sys.argv[1]
参数2: sys.argv[
管理用户分组的命令gpasswd
dongwei_6688
passwd
NAME: gpasswd - administer the /etc/group file
SYNOPSIS:
gpasswd group
gpasswd -a user group
gpasswd -d user group
gpasswd -R group
gpasswd -r group
gpasswd [-A user,...] [-M user,...] g
郝斌老师数据结构课程笔记
dcj3sjt126com
数据结构与算法
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
yii2 cgridview加上选择框进行操作
dcj3sjt126com
GridView
页面代码
<?=Html::beginForm(['controller/bulk'],'post');?>
<?=Html::dropDownList('action','',[''=>'Mark selected as: ','c'=>'Confirmed','nc'=>'No Confirmed'],['class'=>'dropdown',])
linux mysql
fypop
linux
enquiry mysql version in centos linux
yum list installed | grep mysql
yum -y remove mysql-libs.x86_64
enquiry mysql version in yum repositoryyum list | grep mysql oryum -y list mysql*
install mysq
Scramble String
hcx2013
String
Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty substrings recursively.
Below is one possible representation of s1 = "great":
跟我学Shiro目录贴
jinnianshilongnian
跟我学shiro
历经三个月左右时间,《跟我学Shiro》系列教程已经完结,暂时没有需要补充的内容,因此生成PDF版供大家下载。最近项目比较紧,没有时间解答一些疑问,暂时无法回复一些问题,很抱歉,不过可以加群(334194438/348194195)一起讨论问题。
----广告-----------------------------------------------------
nginx日志切割并使用flume-ng收集日志
liyonghui160com
nginx的日志文件没有rotate功能。如果你不处理,日志文件将变得越来越大,还好我们可以写一个nginx日志切割脚本来自动切割日志文件。第一步就是重命名日志文件,不用担心重命名后nginx找不到日志文件而丢失日志。在你未重新打开原名字的日志文件前,nginx还是会向你重命名的文件写日志,linux是靠文件描述符而不是文件名定位文件。第二步向nginx主
Oracle死锁解决方法
pda158
oracle
select p.spid,c.object_name,b.session_id,b.oracle_username,b.os_user_name from v$process p,v$session a, v$locked_object b,all_objects c where p.addr=a.paddr and a.process=b.process and c.object_id=b.
java之List排序
shiguanghui
list排序
在Java Collection Framework中定义的List实现有Vector,ArrayList和LinkedList。这些集合提供了对对象组的索引访问。他们提供了元素的添加与删除支持。然而,它们并没有内置的元素排序支持。 你能够使用java.util.Collections类中的sort()方法对List元素进行排序。你既可以给方法传递
servlet单例多线程
utopialxw
单例 多线程 servlet
转自http://www.cnblogs.com/yjhrem/articles/3160864.html
和 http://blog.chinaunix.net/uid-7374279-id-3687149.html
Servlet 单例多线程
Servlet如何处理多个请求访问?Servlet容器默认是采用单实例多线程的方式处理多个请求的:1.当web服务器启动的