开源的数据库增量订阅和消费的中间件——Cancl

news2024/9/22 21:27:06

目录

工作原理

MySQL主备复制原理

Canal 工作原理

主要功能和特点

应用场景

实验准备

安装JDK11

下载MySQL8.0

配置canal.admin

配置canal-deployer

测试数据读取

新增一台主机用做被同步的目标机器测试


官方地址:https://github.com/alibaba/canal?tab=readme-ov-file 

Canal 是一个阿里巴巴开源的数据同步工具,主要用于 MySQL 数据库的增量数据捕获(Change Data Capture, CDC)。Canal 能够模拟 MySQL 的主从复制协议,解析 MySQL 的 binlog 日志,实时捕获数据库的增量数据变化,并将这些变化数据提供给其他系统。  

 

工作原理

MySQL主备复制原理
  • MySQL master 将数据变更写入二进制日志( binary log, 其中记录叫做二进制日志事件binary log events,可以通过 show binlog events 进行查看)。MySQL 的 binlog 日志记录的是二进制格式的数据,但这些二进制数据并不直接是机器码或类似的低级别编码,而是 MySQL 自己定义的一种结构化二进制格式。
  • MySQL slave 将 master 的 binary log events 拷贝到它的中继日志(relay log)
  • MySQL slave 重放 relay log 中事件,将数据变更反映它自己的数据
Canal 工作原理

  • canal 模拟 MySQL slave 的交互协议,伪装自己为 MySQL slave ,向 MySQL master 发送dump 协议
  • MySQL master 收到 dump 请求,开始推送 binary log 给 slave (即 canal )
  • canal 解析 binary log 对象(原始为 byte 流)

 

主要功能和特点

 

实时捕获数据变更

  • Canal 能够通过解析 MySQL binlog 实时捕获数据库的数据变更,如增、删、改操作。

支持多种目标数据源

  • 捕获的数据变更可以同步到各种目标数据源,如 Elasticsearch、Kafka、RocketMQ、HBase 等,满足不同的实时数据处理需求。

主从复制机制模拟

  • Canal 模拟 MySQL 的从库,通过基于主从复制协议的方式来订阅和解析 binlog,实现数据捕获。

高可用与容错

  • 支持集群部署和高可用配置,能保证在单节点故障时,其他节点继续工作。

多种数据格式支持

  • 支持 JSON、Protobuf 等多种数据格式,方便与不同的数据处理系统集成。

 

应用场景

 

数据同步

  • 实现 MySQL 数据到其他数据库或大数据系统(如 HBase、Elasticsearch)的实时同步。

数据增量推送

  • 实现将 MySQL 数据库的增量更新实时推送到消息队列或缓存系统,以应对高并发读写场景。

多活数据中心

  • 通过 Canal 实现多个数据中心间的数据同步,保证各数据中心的数据一致性。

实时分析

  • 实现 MySQL 数据的实时采集与分析,常用于实时监控、报警等场景。

 

实验准备

 

一台新虚拟机,关闭防火墙和selinux,进行时间同步

主机名系统IP配置工具版本
master

Rocky_linux9.4

192.168.226.262核心4G内存-20G磁盘

MySQL8.0

canal.admin-1.1.7
canal.deployer-1.1.7

同步阿里云的镜像源

sed -e 's|^mirrorlist=|#mirrorlist=|g' \
      -e 's|^#baseurl=http://dl.rockylinux.org/$contentdir|baseurl=https://mirrors.aliyun.com/rockylinux|g' \
      -i.bak \
      /etc/yum.repos.d/rocky*.repo	  
  tput bold
  tput setaf 2
  echo "YUM 源配置已更新。"
  tput sgr0
  dnf makecache
  yum -y install epel-release

安装JDK11

Java Archive Downloads - Java SE 11

这里我已经上传好了

[root@master ~]# ll
total 164856
-rw-------. 1 root root       815 Jun  6 14:00 anaconda-ks.cfg
-rw-r--r--  1 root root 168807248 Jul 29 19:31 jdk-11.0.23_linux-x64_bin.rpm

安装

[root@master ~]# yum install -y jdk-11.0.23_linux-x64_bin.rpm

[root@master ~]# java -version
java version "11.0.23" 2024-04-16 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.23+7-LTS-222)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.23+7-LTS-222, mixed mode)

JDK的默认安装目录位置在:/usr/lib/jvm/jdk-11-oracle-x64/ 

下载MySQL8.0

 

下载mysql8.0

[root@master ~]# yum install -y mysql-server

修改配置文件

[root@master ~]# vim /etc/my.cnf.d/mysql-server.cnf   #最后面加入下述配置
default-authentication-plugin=mysql_native_password
server_id=1
log_bin=binlog
binlog_format=ROW

启动并设置开机自启

[root@master ~]# systemctl enable --now mysqld

登陆mysql,进行初始化配置

[root@master ~]# mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.36 Source distribution

Copyright (c) 2000, 2024, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY '1234';   -- 修改 root 用户的密码为 '1234'
Query OK, 0 rows affected (0.01 sec)

mysql> CREATE USER canal IDENTIFIED BY 'canal';    -- 创建一个名为 canal 的新用户,密码为 'canal'
Query OK, 0 rows affected (0.01 sec)

mysql> GRANT ALL PRIVILEGES ON *.* TO 'canal'@'%' WITH GRANT OPTION;  --给canal用户授权
Query OK, 0 rows affected (0.01 sec)

mysql> FLUSH PRIVILEGES;   -- 刷新权限表,使前面的更改生效
Query OK, 0 rows affected (0.00 sec)

配置canal.admin

 

下载当前时间最新稳定版本canal-1.1.7

https://github.com/alibaba/canal/releases/tag/canal-1.1.7

上传至虚拟机,这里我上传好了

[root@master ~]# ll
total 150272
-rw-------. 1 root root       815 Jun  6 14:00 anaconda-ks.cfg
-rw-r--r--  1 root root  45956395 Aug 16 13:19 canal.admin-1.1.7.tar.gz
-rw-r--r--  1 root root 107915086 Aug 16 13:20 canal.deployer-1.1.7.tar.gz

创建canal文件夹

[root@master ~]# mkdir -p /usr/local/canal/{canal-admin,canal-deployer} 

解压canal.admin

[root@master ~]# tar -xf canal.admin-1.1.7.tar.gz -C /usr/local/canal/canal-admin/

配置文件

[root@master ~]# vim /usr/local/canal/canal-admin/conf/application.yml  # 修改如下配置
server:
  port: 8089
spring:
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8

spring.datasource:
  address: 127.0.0.1:3306   # mysql主机的ip和端口,这里就是在本机上
  database: canal_manager
  username: canal
  password: canal
  driver-class-name: com.mysql.jdbc.Driver
  url: jdbc:mysql://${spring.datasource.address}/${spring.datasource.database}?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true  # 注意,在这里添加了时区和对mysql8.0的适配,useSSL=false后面的内容在mysql5.7中可以删除
  hikari:
    maximum-pool-size: 30
    minimum-idle: 1

canal:
  adminUser: admin
  adminPasswd: admin

导入sql

[root@master ~]# mysql -p1234 < /usr/local/canal/canal-admin/conf/canal_manager.sql

启动 Canal Admin 服务

[root@master ~]# cd /usr/local/canal/canal-admin/bin

[root@master bin]# sh startup.sh


[root@master bin]# ss -tnlp
State          Recv-Q         Send-Q                 Local Address:Port                   Peer Address:Port         Process                                     
LISTEN         0              128                          0.0.0.0:22                          0.0.0.0:*             users:(("sshd",pid=827,fd=3))              
LISTEN         0              100                          0.0.0.0:8089                        0.0.0.0:*             users:(("java",pid=15192,fd=108))          
LISTEN         0              70                                 *:33060                             *:*             users:(("mysqld",pid=15114,fd=21))         
LISTEN         0              128                             [::]:22                             [::]:*             users:(("sshd",pid=827,fd=4))              
LISTEN         0              151                                *:3306                              *:*             users:(("mysqld",pid=15114,fd=23)) 

日志目录:/usr/local/canal/canal-admin/logs 

浏览器访问IP+8089端口, 这里我访问:http://192.168.226.26:8089/

默认用户名:admin   默认登陆密码:123456

 

配置canal-deployer

部署canal-deployer

[root@master bin]# cd 

[root@master ~]# tar -xf canal.deployer-1.1.7.tar.gz -C /usr/local/canal/canal-deployer/

 配置文件

[root@master ~]# vim /usr/local/canal/canal-deployer/conf/canal_local.properties
# register ip
canal.register.ip = 192.168.226.26

# canal admin config
canal.admin.manager = 127.0.0.1:8089
canal.admin.port = 11110
canal.admin.user = admin
canal.admin.passwd = 4ACFE3202A5FF5CF467898FC58AAB1D615029441
# admin auto register
canal.admin.register.auto = true
canal.admin.register.cluster =
canal.admin.register.name = canal-admin

启动 Canal 部署器

[root@master ~]# cd /usr/local/canal/canal-deployer/bin/

[root@master bin]# sh startup.sh local

[root@master bin]# ss -tnlp
State          Recv-Q         Send-Q                 Local Address:Port                   Peer Address:Port         Process                                     
LISTEN         0              50                           0.0.0.0:11111                       0.0.0.0:*             users:(("java",pid=15793,fd=86))           
LISTEN         0              50                           0.0.0.0:11110                       0.0.0.0:*             users:(("java",pid=15793,fd=90))           
LISTEN         0              3                            0.0.0.0:11112                       0.0.0.0:*             users:(("java",pid=15793,fd=77))           
LISTEN         0              128                          0.0.0.0:22                          0.0.0.0:*             users:(("sshd",pid=827,fd=3))              
LISTEN         0              100                          0.0.0.0:8089                        0.0.0.0:*             users:(("java",pid=15192,fd=108))          
LISTEN         0              70                                 *:33060                             *:*             users:(("mysqld",pid=15114,fd=21))         
LISTEN         0              128                             [::]:22                             [::]:*             users:(("sshd",pid=827,fd=4))              
LISTEN         0              151                                *:3306                              *:*             users:(("mysqld",pid=15114,fd=23)) 

日志目录:/usr/local/canal/canal-deployer/logs/canal 

​
# 登录mysql查看binlog日志
[root@master ~]# mysql -p1234
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 71
Server version: 8.0.36 Source distribution

Copyright (c) 2000, 2024, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> SHOW MASTER STATUS;    --查看当前正在使用的 binlog 文件
+---------------+----------+--------------+------------------+-------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog.000003 |    29771 |              |                  |                   |
+---------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)


# 修改配置,将上方查到的binlog日志和位置数写进去
[root@master ~]# vim /usr/local/canal/canal-deployer/conf/example/instance.properties

canal.instance.master.journal.name=binlog.000003
canal.instance.master.position=29771

 

 页面查看server注册

 

 

测试数据读取

[root@master conf]# cd

[root@master ~]# yum install -y python-pip

[root@master ~]# pip3 install protobuf==3.20.1 canal-python -i https://mirrors.aliyun.com/pypi/simple/

[root@master ~]# vim client.py
import time

# 从 canal.client 和 canal.protocol 导入所需的模块
from canal.client import Client
from canal.protocol import EntryProtocol_pb2
from canal.protocol import CanalProtocol_pb2

# 创建 Canal 客户端实例
client = Client()

# 连接到 Canal 服务器
client.connect(host='127.0.0.1', port=11111)

# 检查客户端连接是否有效(无需提供用户名和密码)
client.check_valid(username=b'', password=b'')

# 订阅 Canal 实例(destination)和表的变更(filter)
client.subscribe(client_id=b'1001', destination=b'example', filter=b'.*\\..*')

# 循环获取数据并处理
while True:
    # 从 Canal 服务器获取数据,最多获取 100 条消息
    message = client.get(100)
    entries = message['entries']  # 提取消息中的 entries(数据库变更条目)

    # 遍历所有条目
    for entry in entries:
        entry_type = entry.entryType  # 获取条目的类型
        # 如果条目是事务开始或事务结束,则跳过
        if entry_type in [EntryProtocol_pb2.EntryType.TRANSACTIONBEGIN, EntryProtocol_pb2.EntryType.TRANSACTIONEND]:
            continue

        # 解析行变更数据
        row_change = EntryProtocol_pb2.RowChange()
        row_change.MergeFromString(entry.storeValue)  # 从字节流中解析 RowChange 数据

        event_type = row_change.eventType  # 获取事件类型
        header = entry.header  # 获取条目的头部信息
        database = header.schemaName  # 获取数据库名
        table = header.tableName  # 获取表名
        event_type = header.eventType  # 获取事件类型(与 RowChange 中的 eventType 一致)

        # 遍历所有行数据
        for row in row_change.rowDatas:
            format_data = dict()  # 初始化数据格式字典
            # 根据事件类型处理数据
            if event_type == EntryProtocol_pb2.EventType.DELETE:
                # 删除事件:仅处理删除前的数据
                for column in row.beforeColumns:
                    format_data = {
                        column.name: column.value
                    }
            elif event_type == EntryProtocol_pb2.EventType.INSERT:
                # 插入事件:仅处理插入后的数据
                for column in row.afterColumns:
                    format_data = {
                        column.name: column.value
                    }
            else:
                # 更新事件:处理更新前后的数据
                format_data['before'] = dict()  # 初始化删除前数据字典
                format_data['after'] = dict()   # 初始化插入后数据字典
                # 处理删除前数据
                for column in row.beforeColumns:
                    format_data['before'][column.name] = column.value
                # 处理插入后数据
                for column in row.afterColumns:
                    format_data['after'][column.name] = column.value
            
            # 构建数据字典
            data = dict(
                db=database,  # 数据库名
                table=table,  # 表名
                event_type=event_type,  # 事件类型
                data=format_data,  # 数据
            )
            print(data)  # 打印数据

    # 暂停 1 秒钟
    time.sleep(1)

# 断开与 Canal 服务器的连接
client.disconnect()

运行后会看到终端一些数据弹出,就是在读取展示

[root@master ~]# python3 client.py
connected to 127.0.0.1:11111
Auth succed
Subscribe succed
{'db': 'canal_manager', 'table': 'canal_config', 'event_type': 1, 'data': {'modified_time': '2024-08-16 16:27:01'}}
{'db': 'canal_manager', 'table': 'canal_instance_config', 'event_type': 1, 'data': {'modified_time': '2024-08-16 19:36:10'}}
。。。。。。
。。。
。

此时新开一个终端,尝试写入数据,然后回到运行的python代码终端查看

-- 创建数据库
CREATE DATABASE IF NOT EXISTS test_db;

-- 切换到新创建的数据库
USE test_db;

-- 创建表
CREATE TABLE IF NOT EXISTS employees (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    position VARCHAR(100),
    salary DECIMAL(10, 2),
    hire_date DATE
);

-- 插入几条数据
INSERT INTO employees (name, position, salary, hire_date)
VALUES 
    ('Alice', 'Software Engineer', 85000.00, '2023-02-15'),
    ('Bob', 'Project Manager', 95000.00, '2022-11-20'),
    ('Charlie', 'Data Analyst', 70000.00, '2024-01-10');

-- 查询表中的所有数据以确认插入成功
SELECT * FROM employees;

INSERT INTO employees (name, position, salary, hire_date) 
VALUES ('Charlie Zhang', 'Sales', 68000.00, '2021-12-01');

INSERT INTO employees (name, position, salary, hire_date) 
VALUES ('Alice Wang', 'Engineering', 75000.00, '2022-01-15');

INSERT INTO employees (name, position, salary, hire_date) 
VALUES ('Bob Li', 'HR', 72000.00, '2022-05-01');

UPDATE employees 
SET salary = 80000.00, position = 'Product' 
WHERE name = 'Alice Wang';

UPDATE employees 
SET position = 'HR', hire_date = '2022-05-10' 
WHERE name = 'Bob Li';

DELETE FROM employees 
WHERE name = 'Charlie Zhang';

DELETE FROM employees 
WHERE position = 'Sales';

查看运行python代码的终端

 

新增一台主机用做被同步的目标机器测试

新增一台新虚拟机,关闭防火墙和selinux,进行时间同步,配置阿里云的镜像源,安装jdk,这里不在赘述。

主机名系统IP配置工具版本
localhost

Rocky_linux9.4

192.168.226.292核心4G内存-20G磁盘

MySQL8.0
canal.deployer-1.1.7

下载mysql8.0并配置

[root@localhost ~]# yum install -y mysql-server

[root@localhost ~]# vim /etc/my.cnf.d/mysql-server.cnf  #加入下述配置
default-authentication-plugin=mysql_native_password
server_id=2
log_bin=binlog
binlog_format=ROW

[root@localhost ~]# systemctl enable --now mysqld

[root@localhost ~]# mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.36 Source distribution

Copyright (c) 2000, 2024, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY '123456';   -- 修改 root 用户的密码为 '123456'
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE USER canal IDENTIFIED BY 'canal';    -- 创建一个名为 canal 的新用户,密码为 'canal'
Query OK, 0 rows affected (0.01 sec)

mysql> GRANT ALL PRIVILEGES ON *.* TO 'canal'@'%' WITH GRANT OPTION;  --给canal用户授权
Query OK, 0 rows affected (0.01 sec)

mysql> FLUSH PRIVILEGES;   -- 刷新权限表,使前面的更改生效
Query OK, 0 rows affected (0.00 sec)

上传并解压canal.deployer-1.1.7.tar.gz

[root@localhost ~]# ll
total 105392
-rw-------. 1 root root       815 Jun  6 14:00 anaconda-ks.cfg
-rw-r--r--  1 root root 107915086 Aug 16 13:20 canal.deployer-1.1.7.tar.gz
[root@localhost ~]# mkdir -p /usr/local/canal
[root@localhost ~]# tar -xf canal.deployer-1.1.7.tar.gz -C /usr/local/canal/

编辑配置文件

# 找到如下三个字段,需要求修改即可
[root@localhost ~]# vim /usr/local/canal/conf/canal_local.properties

# Canal 注册的 IP 地址
# 用于 Canal 实例的注册过程中的 IP 地址
canal.register.ip = 192.168.226.29

# Canal 管理端的 IP 地址和端口
# 通过此 IP 和端口可以访问 Canal 管理界面
canal.admin.manager = 192.168.226.26:8089

# Canal 管理端的注册名称
# 用于标识 Canal 实例在注册过程中使用的名称
canal.admin.register.name = hello
[root@localhost ~]# sh /usr/local/canal/bin/startup.sh local

[root@localhost ~]# ss -tnlp
State          Recv-Q         Send-Q                 Local Address:Port                   Peer Address:Port         Process                                     
LISTEN         0              128                          0.0.0.0:22                          0.0.0.0:*             users:(("sshd",pid=850,fd=3))              
LISTEN         0              50                           0.0.0.0:11111                       0.0.0.0:*             users:(("java",pid=2045,fd=85))            
LISTEN         0              50                           0.0.0.0:11110                       0.0.0.0:*             users:(("java",pid=2045,fd=89))            
LISTEN         0              3                            0.0.0.0:11112                       0.0.0.0:*             users:(("java",pid=2045,fd=76))            
LISTEN         0              151                                *:3306                              *:*             users:(("mysqld",pid=14045,fd=24))         
LISTEN         0              70                                 *:33060                             *:*             users:(("mysqld",pid=14045,fd=21))         
LISTEN         0              128                             [::]:22                             [::]:*             users:(("sshd",pid=850,fd=4)) 
[root@localhost ~]# mysql -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 11
Server version: 8.0.36 Source distribution

Copyright (c) 2000, 2024, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> SHOW MASTER STATUS;
+---------------+----------+--------------+------------------+-------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog.000002 |     1370 |              |                  |                   |
+---------------+----------+--------------+------------------+-------------------+
1 row in set (0.01 sec)

 

现在回到192.168.226.26主机

[root@master ~]# vim client.py  # 修改这两处地方
client.connect(host='192.168.226.29', port=11111)
client.subscribe(client_id=b'1001', destination=b'hello', filter=b'.*\\..*')

再次运行python文件

[root@master ~]# python3 client.py

再回到192.168.226.29主机的mysql中,执行一些sql语句

-- 创建数据库
CREATE DATABASE people_db;

-- 使用数据库
USE people_db;

-- 创建表
CREATE TABLE people (
    id INT AUTO_INCREMENT PRIMARY KEY,
    first_name VARCHAR(50) NOT NULL,
    last_name VARCHAR(50) NOT NULL,
    date_of_birth DATE,
    email VARCHAR(100),
    phone_number VARCHAR(15)
);
-- 插入数据
INSERT INTO people (first_name, last_name, date_of_birth, email, phone_number) 
VALUES 
('Alice', 'Smith', '1990-05-15', 'alice.smith@example.com', '123-456-7890'),
('Bob', 'Johnson', '1985-08-20', 'bob.johnson@example.com', '234-567-8901'),
('Charlie', 'Williams', '2000-01-30', 'charlie.williams@example.com', '345-678-9012'),
('Diana', 'Brown', '1992-11-25', 'diana.brown@example.com', '456-789-0123');
-- 更新数据
UPDATE people 
SET email = 'bob.j.newemail@example.com', phone_number = '999-888-7777' 
WHERE first_name = 'Bob' AND last_name = 'Johnson';
-- 删除数据
DELETE FROM people 
WHERE first_name = 'Charlie' AND last_name = 'Williams';
-- 查询所有数据
SELECT * FROM people;

在192.168.226.26主机中,查看python运行代码的终端同步的结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2047052.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

极狐 GitLab 依赖扫描:助力开发者管理软件供应链

极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门面向中国程序员和企业提供企业级一体化 DevOps 平台&#xff0c;用来帮助用户实现需求管理、源代码托管、CI/CD、安全合规&#xff0c;而且所有的操作都是在一个平台上进行&#xff0c;省事省心省钱。可以一键安装极狐GitL…

LeetCode.22。括号生成

题目描述&#xff1a; 数字 n 代表生成括号的对数&#xff0c;请你设计一个函数&#xff0c;用于能够生成所有可能的并且 有效的 括号组 输入输出实例&#xff1a; 思路&#xff1a;对于这道题目我们可以用回溯法&#xff0c;创建一个函数backtrack(当前字符&#xff0c;左括…

解锁 Starknet 的深层洞察:利用 Dune 构建动态数据可视化

原文&#xff1a;https://dev.to/lordghostx/queries-to-insights-visualizing-starknet-data-with-dune-j8p 作者&#xff1a;LordGhostX 编译&#xff1a;TinTinLand Starknet 的链上数据为其区块链生态系统提供了丰富的洞察。它为用户活动、交易模式和网络交互提供了全面…

【k8s从节点报错】error: You must be logged in to the server (Unauthorized)

k8s主节点可以获取nodes节点信息&#xff0c;但是从节点无法获取&#xff0c;且报错“error: You must be logged in to the server (Unauthorized)” 排查思路&#xff1a; 当时证书过期了&#xff0c;只处理的主节点的证书过期&#xff0c;没有处理从节点的 kubeadm alpha …

ctfshow-web入门-sql注入(web221、web222、web223)limit 注入与 group 注入

目录 1、web221 2、web222 3、web223 1、web221 limit 注入 分页 sql 格式&#xff1a;select * from table limit (start-1)*pageSize,pageSize; 其中 start 是页码&#xff0c;pageSize 是每页显示的条数。 比如&#xff1a; 查询第1条到第10条的数据的sql是&#xff…

倒计时启动!2024东北医院信息网络大会即将在这里举办!

随着全球医疗行业步入信息化转型的新时代&#xff0c;2024年8月24日至25日&#xff0c;以“科技赋能&#xff0c;重塑未来医疗”为主题的2024东北医院信息网络大会将在长春开曼宴都酒店&#xff08;长春市高新区海外街1号&#xff09;隆重举行。此次大会与国家卫健委、中医药管…

Python青少年简明教程:输入输出

Python青少年简明教程&#xff1a;输入输出 Python的输入输出是编程中的基本操作。Python的标准输入输出主要通过内置的input()函数和print()函数来实现。这两个函数使得从用户那里接收输入和向用户展示输出变得非常简单。 输入&#xff08;Input&#xff09;函数 input()函数…

Denosing RayDN-对同一射线的误检测优化

Denosing操作理解 DN-DETR增加denosing操作&#xff0c;帮助快速拟合&#xff0c;提高了目标检测任务中的效率和精度。通过这种方式&#xff0c;DN-DETR 克服了原始 DETR 的一些限制&#xff0c;使其在实际应用中具有更好的性能和鲁棒性。 GTBoxes通过随机偏移H, L,W进行偏移&…

Nuxt3【路由中间件】middleware

路由中间件类似路由守卫&#xff0c;即在导航到特定路由之前运行一段代码 内联路由中间件 在页面中定义的路由中间件&#xff0c;因没有名称&#xff0c;所以也叫匿名路由中间件 definePageMeta({middleware: [function (to, from) {console.log("执行了内联路由中间件&q…

[Meachines] [Medium] Popcorn SQLI+Upload File+PAM权限提升

信息收集 IP AddressOpening Ports10.10.10.6TCP:22&#xff0c;80 $ nmap -p- 10.10.10.6 --min-rate 1000 -sC -sV PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 5.1p1 Debian 6ubuntu2 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: …

2024新型数字政府综合解决方案(七)

新型数字政府综合解决方案通过集成人工智能、大数据、区块链和云计算技术&#xff0c;创建了一个高度智能化和互联互通的政府服务平台&#xff0c;旨在全面提升行政效率、服务质量和透明度。该平台实现了跨部门的数据整合与实时共享&#xff0c;利用人工智能进行智能决策支持和…

RockerMQ学习

消息中间件以前常用RabbitMQ和ActiveMQ&#xff0c;由于业务需要&#xff0c;后期业务偏向大数据&#xff0c;现着重学习一下RocketMQ&#xff08;RocketqMQ原理同ctg-mq&#xff09;&#xff0c;后续更新Kafka 一、RocketMQ特性 Kafka特性 &#xff08;高性能分布式&#xff…

MySQL数据库进阶知识(三)《优化》

学习目标&#xff1a; 一周掌握SQL优化知识 学习内容&#xff1a; 一、插入数据 1.insert优化 批量插入 insert into tb_test values(1,Tom),(2,Cat),(3,Jerry);手动提交事务 start transaction; insert into tb_test values(1,Tom),(2,Cat),(3,Jerry); insert into tb_te…

03 网络编程 TCP传输控制协议

目录 1、TCP基本特征 2、TCP通信流程基本原理 &#xff08;1&#xff09;基本原理 &#xff08;2&#xff09;TCP通信代码实现 &#xff08;3&#xff09;核心API解析 1&#xff09;地址绑定--bind 2)设置监听-listen 3)等待连接请求-accept-产生一个已连接套接字 4&a…

WSL2与Windows之间的网络互访

文章目录 1.环境2.WSL访问Windows上的服务3.Windows访问WSL上的服务 1.环境 1.宿主机 Windows 10 2.WSL ubuntu 18.04 LTS 3.Windows 10上的 vEthernet (WSL) 已启用 2.WSL访问Windows上的服务 1.防火墙设置 2.查看访问Windows的IP 172.21.112.1, 使用该IP访问Windows上的服务…

玩机进阶教程-----回读 备份 导出分区来制作线刷包 回读分区的写入与否 修改xml脚本

很多工作室需要将修改好的系统导出来制作线刷包。前面分享过很多制作线刷包类的教程。那么一个机型中有很多分区。那些分区回读后要写入。那些分区不需要写入。强写有可能会导致不开机 不进系统的故障。首先要明白。就算机型全分区导出后在写回去 都不一定可以开机进系统。那么…

【JVM】JVM 实战调优指南赋案例(保姆篇)

文章目录 JVM 实战调优指南引言1. JVM基础知识1.1 JVM架构1.2 JVM垃圾回收 2. 垃圾回收调优2.1 垃圾回收日志2.2 GC日志分析2.3 调优策略2.3.1 调整堆大小2.3.2 选择合适的GC算法2.3.3 调整垃圾回收线程 3. 内存管理调优3.1 内存泄漏检测3.2 堆转储分析3.3 内存分配策略 4. 线程…

基于飞桨框架的稀疏计算使用指南

本文作者-是 Yu 欸&#xff0c;华科在读博士生&#xff0c;定期记录并分享所学知识&#xff0c;博客关注者5w。本文将详细介绍如何在 PaddlePaddle 中利用稀疏计算应用稀疏 ResNet&#xff0c;涵盖稀疏数据格式的础知识、如何创建和操作稀疏张量&#xff0c;以及如何开发和训练…

在阿里云上部署 Docker并通过 Docker 安装 Dify

目录 一、在服务器上安装docker和docker compose 1.1 首先关闭防火墙 1.2 安装docker依赖包 1.3 设置阿里云镜像源并安装docker-ce社区版 1.4 开启docker服务并设置开机自启动 1.5 查看docker版本信息 1.6 设置镜像加速 1.7 将docker compose环境复制到系统的bin目录下…

【计算机网络】应用层自定义协议与序列化

记得在上一节我们说过TCP中的读取时需要改进&#xff0c;这节就可以解决读取问题了。 目录 应用层再谈 "协议"网络版计算机方案一方案二 序列化 和 反序列化 重新理解 read、write、recv、send 和 tcp 为什么支持全双工 应用层 再谈 “协议” 我们在UDP与TCP中写的…