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

0103水平分片-jdbc-shardingsphere-中间件

1 准备服务器

随着系统业务的发展,t_order表数据快速增长,服务器压力增大,影响系统性能,我需要对server-order进行分库分表。

服务器规划:

在这里插入图片描述

  • 服务器:容器名server-order0,端口号3310
  • 服务器:容器名server-order1,端口号3311

1.1 创建server-order0容器

  • step1:创建挂载文件夹

    mkdir -p server-order0/conf/conf.d
    mkdir server-order0/data
    
  • Step2:创建容器

    docker run -it -p 3310:3306 --name server-order0 --privileged=true -v /Users/gaogzhen/data/docker/mysql/mysql8/server-order0/conf/conf.d:/etc/mysql/conf.d -v /Users/gaogzhen/data/docker/mysql/mysql8/server-order0/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql
    
    • step3:登录MySQL服务器:
    #进入容器:
    docker exec -it server-order0 env LANG=C.UTF-8 /bin/bash
    #进入容器内的mysql命令行
    mysql -uroot -p
    #修改默认密码插件
    ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
    
    • step4:创建数据库:

    注意:水平分片的id需要在业务层实现,不能依赖数据库的主键自增

    CREATE DATABASE db_order;
    USE db_order;
    CREATE TABLE t_order0 (id BIGINT,order_no VARCHAR(30),user_id BIGINT,amount DECIMAL(10,2),PRIMARY KEY(id) 
    );
    CREATE TABLE t_order1 (id BIGINT,order_no VARCHAR(30),user_id BIGINT,amount DECIMAL(10,2),PRIMARY KEY(id) 
    );
    

1.2 创建server-order1容器

  • step1:创建挂载文件夹

    mkdir -p server-order1/conf/conf.d
    mkdir server-order1/data
    
  • Step2:创建容器

    docker run -it -p 3311:3306 --name server-order1 --privileged=true -v /Users/gaogzhen/data/docker/mysql/mysql8/server-order1/conf/conf.d:/etc/mysql/conf.d -v /Users/gaogzhen/data/docker/mysql/mysql8/server-order1/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql
    
    • step3:登录MySQL服务器:
    #进入容器:
    docker exec -it server-order0 env LANG=C.UTF-8 /bin/bash
    #进入容器内的mysql命令行
    mysql -uroot -p
    #修改默认密码插件
    ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
    
    • step4:创建数据库:

    注意:水平分片的id需要在业务层实现,不能依赖数据库的主键自增

    CREATE DATABASE db_order;
    USE db_order;
    CREATE TABLE t_order0 (id BIGINT,order_no VARCHAR(30),user_id BIGINT,amount DECIMAL(10,2),PRIMARY KEY(id) 
    );
    CREATE TABLE t_order1 (id BIGINT,order_no VARCHAR(30),user_id BIGINT,amount DECIMAL(10,2),PRIMARY KEY(id) 
    );
    

2、基本水平分片

2.1、基本配置

#========================基本配置
# 应用名称
spring.application.name=sharging-jdbc-demo
# 开发环境设置
spring.profiles.active=dev
# 内存模式
spring.shardingsphere.mode.type=Memory
# 打印SQl
spring.shardingsphere.props.sql-show=true

2.2、数据源配置

#========================数据源配置
# 配置真实数据源
spring.shardingsphere.datasource.names=server-user,server-order0,server-order1# 配置第 1 个数据源
spring.shardingsphere.datasource.server-user.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.server-user.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.server-user.jdbc-url=jdbc:mysql://192.168.100.201:3301/db_user
spring.shardingsphere.datasource.server-user.username=root
spring.shardingsphere.datasource.server-user.password=123456# 配置第 2 个数据源
spring.shardingsphere.datasource.server-order0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.server-order0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.server-order0.jdbc-url=jdbc:mysql://192.168.100.201:3310/db_order
spring.shardingsphere.datasource.server-order0.username=root
spring.shardingsphere.datasource.server-order0.password=123456# 配置第 3 个数据源
spring.shardingsphere.datasource.server-order1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.server-order1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.server-order1.jdbc-url=jdbc:mysql://192.168.100.201:3311/db_order
spring.shardingsphere.datasource.server-order1.username=root
spring.shardingsphere.datasource.server-order1.password=123456

2.3、标椎分片表配置

#========================标准分片表配置(数据节点配置)
# spring.shardingsphere.rules.sharding.tables.<table-name>.actual-data-nodes=值
# 值由数据源名 + 表名组成,以小数点分隔。多个表以逗号分隔,支持 inline 表达式。
# <table-name>:逻辑表名
spring.shardingsphere.rules.sharding.tables.t_user.actual-data-nodes=server-user.t_user
spring.shardingsphere.rules.sharding.tables.t_order.actual-data-nodes=server-order0.t_order0,server-order0.t_order1,server-order1.t_order0,server-order1.t_order1

修改Order实体类的主键策略:

//@TableId(type = IdType.AUTO)//依赖数据库的主键自增策略
@TableId(type = IdType.ASSIGN_ID)//分布式id

测试:保留上面配置中的一个分片表节点分别进行测试,检查每个分片节点是否可用

/*** 水平分片:插入数据测试*/
@Test
public void testInsertOrder(){Order order = new Order();order.setOrderNo("20230822001");order.setUserId(1L);order.setAmount(new BigDecimal(100));orderMapper.insert(order);
}

2.4、行表达式

优化上一步的分片表配置

https://shardingsphere.apache.org/document/5.1.1/cn/features/sharding/concept/inline-expression/

#========================标准分片表配置(数据节点配置)
# spring.shardingsphere.rules.sharding.tables.<table-name>.actual-data-nodes=值
# 值由数据源名 + 表名组成,以小数点分隔。多个表以逗号分隔,支持 inline 表达式。
# <table-name>:逻辑表名
spring.shardingsphere.rules.sharding.tables.t_user.actual-data-nodes=server-user.t_user
spring.shardingsphere.rules.sharding.tables.t_order.actual-data-nodes=server-order$->{0..1}.t_order$->{0..1}

2.5、分片算法配置

水平分库:

分片规则:order表中user_id为偶数时,数据插入server-order0服务器user_id为奇数时,数据插入server-order1服务器。这样分片的好处是,同一个用户的订单数据,一定会被插入到同一台服务器上,查询一个用户的订单时效率较高。

#------------------------分库策略
# 分片列名称
spring.shardingsphere.rules.sharding.tables.t_order.database-strategy.standard.sharding-column=user_id
# 分片算法名称
spring.shardingsphere.rules.sharding.tables.t_order.database-strategy.standard.sharding-algorithm-name=alg_inline_userid#------------------------分片算法配置
# 行表达式分片算法
# 分片算法类型
spring.shardingsphere.rules.sharding.sharding-algorithms.alg_inline_userid.type=INLINE
# 分片算法属性配置
spring.shardingsphere.rules.sharding.sharding-algorithms.alg_inline_userid.props.algorithm-expression=server-order$->{user_id % 2}# 取模分片算法
# 分片算法类型
spring.shardingsphere.rules.sharding.sharding-algorithms.alg_mod.type=MOD
# 分片算法属性配置
spring.shardingsphere.rules.sharding.sharding-algorithms.alg_mod.props.sharding-count=2

为了方便测试,先设置只在 t_order0表上进行测试

xxx.actual-data-nodes=server-order$->{0..1}.t_order0

测试:可以分别测试行表达式分片算法和取模分片算法

/*** 水平分片:分库插入数据测试*/
@Test
public void testInsertOrderDatabaseStrategy(){for (long i = 0; i < 4; i++) {Order order = new Order();order.setOrderNo("20230821001");order.setUserId(i + 1);order.setAmount(new BigDecimal(100));orderMapper.insert(order);}}

水平分表:

分片规则:order表中order_no的哈希值为偶数时,数据插入对应服务器的t_order0表order_no的哈希值为奇数时,数据插入对应服务器的t_order1表。因为order_no是字符串形式,因此不能直接取模。

#------------------------分表策略
# 分片列名称
spring.shardingsphere.rules.sharding.tables.t_order.table-strategy.standard.sharding-column=order_no
# 分片算法名称
spring.shardingsphere.rules.sharding.tables.t_order.table-strategy.standard.sharding-algorithm-name=alg_hash_mod#------------------------分片算法配置
# 哈希取模分片算法
# 分片算法类型
spring.shardingsphere.rules.sharding.sharding-algorithms.alg_hash_mod.type=HASH_MOD
# 分片算法属性配置
spring.shardingsphere.rules.sharding.sharding-algorithms.alg_hash_mod.props.sharding-count=2

测试前不要忘记将如下节点改回原来的状态

xxx.actual-data-nodes=server-order$->{0..1}.t_order$->{0..1}

测试:

/*** 水平分片:分表插入数据测试*/
@Test
public void testInsertOrderTableStrategy(){for (long i = 1; i < 5; i++) {Order order = new Order();order.setOrderNo("gaogzhen" + i);order.setUserId(1L);order.setAmount(new BigDecimal(100));orderMapper.insert(order);}for (long i = 5; i < 9; i++) {Order order = new Order();order.setOrderNo("gaogzhen" + i);order.setUserId(2L);order.setAmount(new BigDecimal(100));orderMapper.insert(order);}
}/*** 测试哈希取模*/
@Test
public void testHash(){//注意hash取模的结果是整个字符串hash后再取模,和数值后缀是奇数还是偶数无关System.out.println("gaogzhen001".hashCode() % 2);System.out.println("gaogzhen0011".hashCode() % 2);
}

查询测试:

/*** 水平分片:查询所有记录* 查询了两个数据源,每个数据源中使用UNION ALL连接两个表*/
@Test
public void testShardingSelectAll(){List<Order> orders = orderMapper.selectList(null);orders.forEach(System.out::println);
}/*** 水平分片:根据user_id查询记录* 查询了一个数据源,每个数据源中使用UNION ALL连接两个表*/
@Test
public void testShardingSelectByUserId(){QueryWrapper<Order> orderQueryWrapper = new QueryWrapper<>();orderQueryWrapper.eq("user_id", 1L);List<Order> orders = orderMapper.selectList(orderQueryWrapper);orders.forEach(System.out::println);
}

2.6、分布式序列算法

雪花算法:

https://shardingsphere.apache.org/document/5.1.1/cn/features/sharding/concept/key-generator/

水平分片需要关注全局序列,因为不能简单的使用基于数据库的主键自增。

这里有两种方案:一种是基于MyBatisPlus的id策略;一种是ShardingSphere-JDBC的全局序列配置。

基于MyBatisPlus的id策略:将Order类的id设置成如下形式

@TableId(type = IdType.ASSIGN_ID)
private Long id;

基于ShardingSphere-JDBC的全局序列配置:和前面的MyBatisPlus的策略二选一

#------------------------分布式序列策略配置
# 分布式序列列名称
spring.shardingsphere.rules.sharding.tables.t_order.key-generate-strategy.column=id
# 分布式序列算法名称
spring.shardingsphere.rules.sharding.tables.t_order.key-generate-strategy.key-generator-name=alg_snowflake# 分布式序列算法配置
# 分布式序列算法类型
spring.shardingsphere.rules.sharding.key-generators.alg_snowflake.type=SNOWFLAKE
# 分布式序列算法属性配置
#spring.shardingsphere.rules.sharding.key-generators.alg_snowflake.props.xxx=

此时,需要将实体类中的id策略修改成以下形式:

//当配置了shardingsphere-jdbc的分布式序列时,自动使用shardingsphere-jdbc的分布式序列
//当没有配置shardingsphere-jdbc的分布式序列时,自动依赖数据库的主键自增策略
@TableId(type = IdType.AUTO)

3、多表关联

3.1、创建关联表

server-order0、server-order1服务器中分别创建两张订单详情表t_order_item0、t_order_item1

我们希望同一个用户的订单表和订单详情表中的数据都在同一个数据源中,避免跨库关联,因此这两张表我们使用相同的分片策略。

那么在t_order_item中我们也需要创建order_nouser_id这两个分片键

CREATE TABLE t_order_item0(id BIGINT,order_no VARCHAR(30),user_id BIGINT,price DECIMAL(10,2),`count` INT,PRIMARY KEY(id)
);CREATE TABLE t_order_item1(id BIGINT,order_no VARCHAR(30),user_id BIGINT,price DECIMAL(10,2),`count` INT,PRIMARY KEY(id)
);

3.2、创建实体类

package com.gaogzhen.shardingjdbcdemo.entity;@TableName("t_order_item")
@Data
public class OrderItem {//当配置了shardingsphere-jdbc的分布式序列时,自动使用shardingsphere-jdbc的分布式序列@TableId(type = IdType.AUTO)private Long id;private String orderNo;private Long userId;private BigDecimal price;private Integer count;
}

3.3、创建Mapper

package com.gaogzhen.shargingjdbcdemo.mapper;@Mapper
public interface OrderItemMapper extends BaseMapper<OrderItem> {}

3.4、配置关联表

t_order_item的分片表、分片策略、分布式序列策略和t_order一致

#------------------------标准分片表配置(数据节点配置)
spring.shardingsphere.rules.sharding.tables.t_order_item.actual-data-nodes=server-order$->{0..1}.t_order_item$->{0..1}#------------------------分库策略
# 分片列名称
spring.shardingsphere.rules.sharding.tables.t_order_item.database-strategy.standard.sharding-column=user_id
# 分片算法名称
spring.shardingsphere.rules.sharding.tables.t_order_item.database-strategy.standard.sharding-algorithm-name=alg_mod#------------------------分表策略
# 分片列名称
spring.shardingsphere.rules.sharding.tables.t_order_item.table-strategy.standard.sharding-column=order_no
# 分片算法名称
spring.shardingsphere.rules.sharding.tables.t_order_item.table-strategy.standard.sharding-algorithm-name=alg_hash_mod#------------------------分布式序列策略配置
# 分布式序列列名称
spring.shardingsphere.rules.sharding.tables.t_order_item.key-generate-strategy.column=id
# 分布式序列算法名称
spring.shardingsphere.rules.sharding.tables.t_order_item.key-generate-strategy.key-generator-name=alg_snowflake

3.5、测试插入数据

同一个用户的订单表和订单详情表中的数据都在同一个数据源中,避免跨库关联

/*** 测试关联表插入*/
@Test
public void testInsertOrderAndOrderItem(){for (long i = 1; i < 3; i++) {Order order = new Order();order.setOrderNo("gaogzhen" + i);order.setUserId(1L);orderMapper.insert(order);for (long j = 1; j < 3; j++) {OrderItem orderItem = new OrderItem();orderItem.setOrderNo("gaogzhen" + i);orderItem.setUserId(1L);orderItem.setPrice(new BigDecimal(10));orderItem.setCount(2);orderItemMapper.insert(orderItem);}}for (long i = 5; i < 7; i++) {Order order = new Order();order.setOrderNo("gaogzhen" + i);order.setUserId(2L);orderMapper.insert(order);for (long j = 1; j < 3; j++) {OrderItem orderItem = new OrderItem();orderItem.setOrderNo("gaogzhen" + i);orderItem.setUserId(2L);orderItem.setPrice(new BigDecimal(1));orderItem.setCount(3);orderItemMapper.insert(orderItem);}}}

4、绑定表

**需求:**查询每个订单的订单号和总订单金额

4.1、创建VO对象

package com.gaogzhen.shardingjdbcdemo.entity;@Data
public class OrderVo {private String orderNo;private BigDecimal amount;
}

4.2、添加Mapper方法

  • OrderMapper.java
package com.gaogzhen.shardingjdbcdemo.mapper;@Mapper
public interface OrderMapper extends BaseMapper<Order> {/*** 计算订单金额* @return 订单金额列表*/List<OrderVO> getOrderAmount();}
  • OrderMapper.xml

        <select id="getOrderAmount" resultType="com.gaogzhen.shardingjdbcdemo.vo.OrderVO">selectt1.order_no,sum(t2.price * t2.count) amountfromt_order t1join t_order_item t2 on t2.order_no = t1.order_nogroup byt1.order_no</select>
    

4.3、测试关联查询

/*** 测试关联表查询*/
@Test
public void testGetOrderAmount(){List<OrderVo> orderAmountList = orderMapper.getOrderAmount();orderAmountList.forEach(System.out::println);
}

查询结果

2023-08-23 20:10:40.015  INFO 27448 --- [           main] ShardingSphere-SQL                       : Logic SQL: selectt1.order_no,sum(t2.price * t2.count) amountfromt_order t1join t_order_item t2 on t2.order_no = t1.order_nogroup byt1.order_no
2023-08-23 20:10:40.015  INFO 27448 --- [           main] ShardingSphere-SQL                       : SQLStatement: MySQLSelectStatement(table=Optional.empty, limit=Optional.empty, lock=Optional.empty, window=Optional.empty)
2023-08-23 20:10:40.015  INFO 27448 --- [           main] ShardingSphere-SQL                       : Actual SQL: server-order1 ::: selectt1.order_no,sum(t2.price * t2.count) amountfromt_order0 t1join t_order_item0 t2 on t2.order_no = t1.order_nogroup byt1.order_no ORDER BY t1.order_no ASC 
2023-08-23 20:10:40.015  INFO 27448 --- [           main] ShardingSphere-SQL                       : Actual SQL: server-order1 ::: selectt1.order_no,sum(t2.price * t2.count) amountfromt_order1 t1join t_order_item0 t2 on t2.order_no = t1.order_nogroup byt1.order_no ORDER BY t1.order_no ASC 
2023-08-23 20:10:40.015  INFO 27448 --- [           main] ShardingSphere-SQL                       : Actual SQL: server-order1 ::: selectt1.order_no,sum(t2.price * t2.count) amountfromt_order0 t1join t_order_item1 t2 on t2.order_no = t1.order_nogroup byt1.order_no ORDER BY t1.order_no ASC 
2023-08-23 20:10:40.015  INFO 27448 --- [           main] ShardingSphere-SQL                       : Actual SQL: server-order1 ::: selectt1.order_no,sum(t2.price * t2.count) amountfromt_order1 t1join t_order_item1 t2 on t2.order_no = t1.order_nogroup byt1.order_no ORDER BY t1.order_no ASC 
2023-08-23 20:10:40.015  INFO 27448 --- [           main] ShardingSphere-SQL                       : Actual SQL: server-order0 ::: selectt1.order_no,sum(t2.price * t2.count) amountfromt_order0 t1join t_order_item0 t2 on t2.order_no = t1.order_nogroup byt1.order_no ORDER BY t1.order_no ASC 
2023-08-23 20:10:40.015  INFO 27448 --- [           main] ShardingSphere-SQL                       : Actual SQL: server-order0 ::: selectt1.order_no,sum(t2.price * t2.count) amountfromt_order1 t1join t_order_item0 t2 on t2.order_no = t1.order_nogroup byt1.order_no ORDER BY t1.order_no ASC 
2023-08-23 20:10:40.015  INFO 27448 --- [           main] ShardingSphere-SQL                       : Actual SQL: server-order0 ::: selectt1.order_no,sum(t2.price * t2.count) amountfromt_order0 t1join t_order_item1 t2 on t2.order_no = t1.order_nogroup byt1.order_no ORDER BY t1.order_no ASC 
2023-08-23 20:10:40.015  INFO 27448 --- [           main] ShardingSphere-SQL                       : Actual SQL: server-order0 ::: selectt1.order_no,sum(t2.price * t2.count) amountfromt_order1 t1join t_order_item1 t2 on t2.order_no = t1.order_nogroup byt1.order_no ORDER BY t1.order_no ASC 
OrderVO(orderNo=gaogzhen1, amount=40.00)
OrderVO(orderNo=gaogzhen2, amount=40.00)
OrderVO(orderNo=gaogzhen5, amount=6.00)
OrderVO(orderNo=gaogzhen6, amount=6.00)

4.4、配置绑定表

在原来水平分片配置的基础上添加如下配置:

#------------------------绑定表
spring.shardingsphere.rules.sharding.binding-tables[0]=t_order,t_order_item

配置完绑定表后再次进行关联查询的测试:

  • **如果不配置绑定表:测试的结果为8个SQL。**多表关联查询会出现笛卡尔积关联。

  • 如果配置绑定表:测试的结果为4个SQL。 多表关联查询不会出现笛卡尔积关联,关联查询效率将大大提升。

绑定表:指分片规则一致的一组分片表。 使用绑定表进行多表关联查询时,必须使用分片键进行关联,否则会出现笛卡尔积关联或跨库关联,从而影响查询效率。

目前测试还是查询8个SQL, 配置未生效,暂时没找到解决方法

5、广播表

4.1、什么是广播表

指所有的分片数据源中都存在的表,表结构及其数据在每个数据库中均完全一致。 适用于数据量不大且需要与海量数据的表进行关联查询的场景,例如:字典表。

广播具有以下特性:

(1)插入、更新操作会实时在所有节点上执行,保持各个分片的数据一致性

(2)查询操作,只从一个节点获取

(3)可以跟任何一个表进行 JOIN 操作

4.2、创建广播表

在server-order0、server-order1和server-user服务器中分别创建t_dict表

CREATE TABLE t_dict(id BIGINT,dict_type VARCHAR(200),PRIMARY KEY(id)
);

4.3、程序实现

4.3.1、创建实体类

package com.gaogzhen.shardingjdbcdemo.entity;@TableName("t_dict")
@Data
public class Dict {//可以使用MyBatisPlus的雪花算法@TableId(type = IdType.ASSIGN_ID)private Long id;private String dictType;
}

4.3.2、创建Mapper

package com.gaogzhen.shardingjdbcdemo.mapper;@Mapper
public interface DictMapper extends BaseMapper<Dict> {
}

4.3.3、配置广播表

#数据节点可不配置,默认情况下,向所有数据源广播
spring.shardingsphere.rules.sharding.tables.t_dict.actual-data-nodes=server-user.t_dict,server-order$->{0..1}.t_dict# 广播表
spring.shardingsphere.rules.sharding.broadcast-tables[0]=t_dict

4.4、测试广播表

@Autowired
private DictMapper dictMapper;/*** 广播表:每个服务器中的t_dict同时添加了新数据*/
@Test
public void testBroadcast(){Dict dict = new Dict();dict.setDictType("type1");dictMapper.insert(dict);
}/*** 查询操作,只从一个节点获取数据* 随机负载均衡规则*/
@Test
public void testSelectBroadcast(){List<Dict> dicts = dictMapper.selectList(null);dicts.forEach(System.out::println);
}

5 配置文件方式

  • application.properties
#----------------------- 基础配置
# 项目名称
spring.application.name=sharding-jdbc-demo
spring.profiles.active=dev
# shardingsphere 配置
# 模式
spring.shardingsphere.mode.type=Memory# 数据源名称
spring.shardingsphere.datasource.names=server-user,server-order0,server-order1#------------------------ 数据源配置
# 配置第1个数据源
spring.shardingsphere.datasource.server-user.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.server-user.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.server-user.jdbc-url=jdbc:mysql://127.0.0.1:3301/db_user?allowPublicKeyRetrieval=true&useSSL=false
spring.shardingsphere.datasource.server-user.username=root
spring.shardingsphere.datasource.server-user.password=123456# 配置第2个数据源
spring.shardingsphere.datasource.server-order0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.server-order0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.server-order0.jdbc-url=jdbc:mysql://127.0.0.1:3310/db_order?allowPublicKeyRetrieval=true&useSSL=false
spring.shardingsphere.datasource.server-order0.username=root
spring.shardingsphere.datasource.server-order0.password=123456# 配置第3个数据源
spring.shardingsphere.datasource.server-order1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.server-order1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.server-order1.jdbc-url=jdbc:mysql://127.0.0.1:3311/db_order?allowPublicKeyRetrieval=true&useSSL=false
spring.shardingsphere.datasource.server-order1.username=root
spring.shardingsphere.datasource.server-order1.password=123456#------------------------数据节点配置
## 标准分配表配置
# spring.shardingsphere.rules.sharding.tables.<table-name>.actual-data-nodes=值
# 值由数据源名 + 表名组成,以小数点分隔。多个表以逗号分隔,支持 inline 表达式。
# <table-name>:逻辑表名
spring.shardingsphere.rules.sharding.tables.t_user.actual-data-nodes=server-user.t_user
spring.shardingsphere.rules.sharding.tables.t_order.actual-data-nodes=server-order$->{0..1}.t_order$->{0..1}
#spring.shardingsphere.rules.sharding.tables.t_order.actual-data-nodes=server-order$->{0..1}.t_order0#------------------------分库策略
# 分片列配置
spring.shardingsphere.rules.sharding.tables.t_order.database-strategy.standard.sharding-column=user_id
# 分片算法名称
spring.shardingsphere.rules.sharding.tables.t_order.database-strategy.standard.sharding-algorithm-name=alg_inline_userid#------------------------分片算法配置
# 行表达式分片算法
# 分片算法类型
spring.shardingsphere.rules.sharding.sharding-algorithms.alg_inline_userid.type=INLINE
# 分片算法属性配置
spring.shardingsphere.rules.sharding.sharding-algorithms.alg_inline_userid.props.algorithm-expression=server-order$->{user_id % 2}# 取模分片算法
# 分片算法类型
spring.shardingsphere.rules.sharding.sharding-algorithms.alg_mod.type=MOD
# 分片算法属性配置
spring.shardingsphere.rules.sharding.sharding-algorithms.alg_mod.props.sharding-count=2#------------------------分表策略
# 分片列名称
spring.shardingsphere.rules.sharding.tables.t_order.table-strategy.standard.sharding-column=order_no
# 分片算法名称
spring.shardingsphere.rules.sharding.tables.t_order.table-strategy.standard.sharding-algorithm-name=alg_hash_mod#------------------------分片算法配置
# 哈希取模分片算法
# 分片算法类型
spring.shardingsphere.rules.sharding.sharding-algorithms.alg_hash_mod.type=HASH_MOD
# 分片算法属性配置
spring.shardingsphere.rules.sharding.sharding-algorithms.alg_hash_mod.props.sharding-count=2#------------------------分布式序列策略配置
# 分布式序列列名称
spring.shardingsphere.rules.sharding.tables.t_order.key-generate-strategy.column=id
# 分布式序列算法名称
spring.shardingsphere.rules.sharding.tables.t_order.key-generate-strategy.key-generator-name=alg_snowflake# 分布式序列算法配置
# 分布式序列算法类型
spring.shardingsphere.rules.sharding.key-generators.alg_snowflake.type=SNOWFLAKE
# 分布式序列算法属性配置
#spring.shardingsphere.rules.sharding.key-generators.alg_snowflake.props.xxx=#------------------------标准分片表配置(数据节点配置)
spring.shardingsphere.rules.sharding.tables.t_order_item.actual-data-nodes=server-order$->{0..1}.t_order_item$->{0..1}#------------------------分库策略
# 分片列名称
spring.shardingsphere.rules.sharding.tables.t_order_item.database-strategy.standard.sharding-column=user_id
# 分片算法名称
spring.shardingsphere.rules.sharding.tables.t_order_item.database-strategy.standard.sharding-algorithm-name=alg_mod#------------------------分表策略
# 分片列名称
spring.shardingsphere.rules.sharding.tables.t_order_item.table-strategy.standard.sharding-column=order_no
# 分片算法名称
spring.shardingsphere.rules.sharding.tables.t_order_item.table-strategy.standard.sharding-algorithm-name=alg_hash_mod#------------------------分布式序列策略配置
# 分布式序列列名称
spring.shardingsphere.rules.sharding.tables.t_order_item.key-generate-strategy.column=id
# 分布式序列算法名称
spring.shardingsphere.rules.sharding.tables.t_order_item.key-generate-strategy.key-generator-name=alg_snowflake#------------------------绑定表
spring.shardingsphere.rules.sharding.binding-tables=t_order,t_order_item# 广播表
spring.shardingsphere.rules.sharding.broadcast-tables[0]=t_dict# 打印日志
spring.shardingsphere.props.sql-show=true# mybatis plus 配置
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.gaogzhen.shardingjdbcdemo.entity
  • application.properties+applicaton-dev.yml

    #----------------------- 基础配置
    # 项目名称
    spring.application.name=sharding-jdbc-demo
    spring.profiles.active=dev# mybatis plus 配置
    mybatis.mapper-locations=classpath:mapper/*.xml
    mybatis.type-aliases-package=com.gaogzhen.shardingjdbcdemo.entity
    
    spring:shardingSphere:mode:type: Memoryschema:name: horizontal-shardingdatasource:names: server_user,server-order0,server-order1server-user:type: com.zaxxer.hikari.HikariDataSourcedriverClassName: com.mysql.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3301/db_user?allowPublicKeyRetrieval=true&useSSL=falseusername: rootpassword: 123456server-order0:type: com.zaxxer.hikari.HikariDataSourcedriverClassName: com.mysql.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3310/db_order?allowPublicKeyRetrieval=true&useSSL=falseusername: rootpassword: 123456server-order1:type: com.zaxxer.hikari.HikariDataSourcedriverClassName: com.mysql.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3311/db_order?allowPublicKeyRetrieval=true&useSSL=falseusername: rootpassword: 123456rules:sharding:tables:t_user:actualDataNodes: server-user.t_usert_order:actualDataNodes: server-order$->{0..1}.t_order$->{0..1}databaseStrategy:standard:shardingColumn: user_idshardingAlgorithmName: alg-inline-useridtableStrategy:standard:shardingColumn: order_noshardingAlgorithmName: alg-hash-modkeyGenerateStrategy:column: idkeyGeneratorName: alg-snowflaket_order_item:actualDataNodes: server-order$->{0..1}.t_order_item$->{0..1}databaseStrategy:standard:shardingColumn: user_idshardingAlgorithmName: alg-modtableStrategy:standard:shardingColumn: order_noshardingAlgorithmName: alg-hash-modkeyGenerateStrategy:column: idkeyGeneratorName: alg-snowflakekeyGenerators:alg-snowflake:type: SNOWFLAKEshardingAlgorithms:alg-inline-userid:type: INLINEprops:algorithm-expression: server-order$->{user_id % 2}alg-mod:type: MODprops:sharding-count: 2alg-hash-mod:type: HASH_MODprops:sharding-count: 2binding-tables: t_order,t_order_itembroadcast-tables: t_dictprops:sqlShow: true
    

6 问题集

6.1 简述

sharding-jdbc 报错多半报错因为配置文件引起的,除了个人粗心大意外,多半和官方给的配置字段名有关。官方文档配置字段名有的给驼峰形式,有的给”-“连接形式,这里建议统一用”-"连接的形式。

  • props下的所有配置需要使用"-"连接的形式,不然报错或者不生效

6.1 Parameter index out of range

报错内容如下:

### Error updating database.  Cause: java.sql.SQLException: Parameter index out of range (1 > number of parameters, which is 0).
### The error may exist in com/gaogzhen/shardingjdbcdemo/mapper/OrderItemMapper.java (best guess)
### The error may involve com.gaogzhen.shardingjdbcdemo.mapper.OrderItemMapper.insert-Inline
### The error occurred while setting parameters
### SQL: INSERT INTO t_order_item0  ( order_no, user_id, price, count )  VALUES  ( ?, ?, ?, ? )
### Cause: java.sql.SQLException: Parameter index out of range (1 > number of parameters, which is 0).
; Parameter index out of range (1 > number of parameters, which is 0).; nested exception is java.sql.SQLException: Parameter index out of range (1 > number of parameters, which is 0).at com.gaogzhen.shardingjdbcdemo.HorizontalShardingTest.testInsertOrderAndOrderItem(HorizontalShardingTest.java:102)
Caused by: java.sql.SQLException: Parameter index out of range (1 > number of parameters, which is 0).at com.gaogzhen.shardingjdbcdemo.HorizontalShardingTest.testInsertOrderAndOrderItem(HorizontalShardingTest.java:102)

可能出现问题原因

  1. 首选确保官网文档固定的配置项不出现错误,比如table-strategy 大小写,下划线或驼峰形式
  2. 对于自定义的数据源名称、逻辑表名称注意前后一致
  3. 然后MybatisPlus实体类表名注解@TableName(value =“t_order_item”) 其中表名为配置的逻辑表名,非真实表名

6.2 No implementation class load from SPI

  • 报错内容:
org.apache.shardingsphere.spi.exception.ServiceProviderNotFoundException: No implementation class load from SPI `org.apache.shardingsphere.sharding.spi.ShardingAlgorithm` with type `null`.

6.3 Error creating bean with name ‘org.apache.shardingsphere.spring.boot.ShardingSphereAutoConfiguration’

  • 报错内容:
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.apache.shardingsphere.spring.boot.ShardingSphereAutoConfiguration': Initialization of bean failed; nested exception is java.lang.NullPointerException
Caused by: java.lang.NullPointerException
  • 出错原因

    # 按照官网文档配置的数据源如下datasource:names: server_user,server_order0,server_order1server_user:dataSourceClassName: com.zaxxer.hikari.HikariDataSourcedriverClassName: com.mysql.jdbc.DriverjdbcUrl: jdbc:mysql://127.0.0.1:3301/db_user?allowPublicKeyRetrieval=true&useSSL=falseusername: rootpassword: 123456
    
  • 解决方案:

        datasource:names: server_user,server_order0,server_order1server_user:type: com.zaxxer.hikari.HikariDataSourcedriverClassName: com.mysql.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3301/db_user?allowPublicKeyRetrieval=true&useSSL=falseusername: rootpassword: 123456
    
    • dataSourceClassName替换为type
    • jdbcUrl替换为url

6.4 could not determine a constructor for the tag !SHARDING:

  • 报错内容
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.yaml.snakeyaml.constructor.ConstructorException: 
could not determine a constructor for the tag !SHARDING:in 'reader', line 28, column 7:- !SHARDING:

我的shardingsphere 版本5.1.1 按照官网sharding-jdbc yaml配置会报上述错误,不识别- !SHARDING

  • 解决方案

    - !SHARDING替换为sharding
    

    如下图所示:

    在这里插入图片描述

6.5 Data sources cannot be empty

  • 报错内容

    Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'shardingSphereDataSource' threw exception; nested exception is java.lang.IllegalArgumentException: Data sources cannot be empty.
    Caused by: java.lang.IllegalArgumentException: Data sources cannot be empty.
    
  • 出错原因

    # 按照官网文档配置dataSources:server_user:dataSourceClassName: com.zaxxer.hikari.HikariDataSourcedriverClassName: com.mysql.jdbc.DriverjdbcUrl: jdbc:mysql://127.0.0.1:3301/db_user?allowPublicKeyRetrieval=true&useSSL=falseusername: rootpassword: 123456
    
  • 解决方案

        datasource:names: server_user,server_order0,server_order1server_user:type: com.zaxxer.hikari.HikariDataSourcedriverClassName: com.mysql.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3301/db_user?allowPublicKeyRetrieval=true&useSSL=falseusername: rootpassword: 123456
    
    • dataSources替换为datasource
    • 添加names属性,值为逻辑属性源

6.6 Insert statement does not support sharding table routing to multiple data nodes

  • 报错内容

    org.mybatis.spring.MyBatisSystemException: 
    nested exception is org.apache.ibatis.exceptions.PersistenceException: 
    ### Error updating database.  Cause: java.lang.IllegalStateException: Insert statement does not support sharding table routing to multiple data nodes.
    ### The error may exist in com/gaogzhen/shardingjdbcdemo/mapper/OrderMapper.java (best guess)
    ### The error may involve com.gaogzhen.shardingjdbcdemo.mapper.OrderMapper.insert-Inline
    ### The error occurred while setting parameters
    ### SQL: INSERT INTO t_order  ( order_no, user_id )  VALUES  ( ?, ? )
    ### Cause: java.lang.IllegalStateException: Insert statement does not support sharding table routing to multiple data nodes.at com.gaogzhen.shardingjdbcdemo.HorizontalShardingTest.testInsertOrderAndOrderItem(HorizontalShardingTest.java:94)
    Caused by: org.apache.ibatis.exceptions.PersistenceException: 
    
  • 报错原因

        rules:sharding:tables:t_order_item:actualDataNodes: server-order$->{0..1}.t_order_item$->{0..1}databaseStrategy:standard:shardingColumn: user_idshardingAlgorithmName: alg-modtableStrategy:standard:shardingColumn: order_idshardingAlgorithmName: alg-hash-modkeyGenerateStrategy:column: idkeyGeneratorName: alg-snowflakekeyGenerators:alg-snowflake:type: SNOWFLAKEshardingAlgorithms:alg-inline-userid:type: INLINEprops:algorithm-expression: server-order$->{user_id % 2}alg-mod:type: MODprops:sharding-count: 2alg-hash-mod:type: HASH_MODprops:sharding-count: 2
    
    • 分库或者分表算法名称不能使用“_"下划线分割 ,用“-”代替

    6.7 Inline sharding algorithm expression cannot be null or empty

    • 报错原因

              shardingAlgorithms:alg-inline-userid:type: INLINEprops:algorithmExpression: server-order$->{user_id % 2}
      
      • algorithmExpression不能为驼峰命名
    • 解决方案

      algorithmExpression改为algorithm-expression
      

结语

如果小伙伴什么问题或者指教,欢迎交流。

QQ:806797785

仓库源代码地址:https://gitee.com/gaogzhen/shardingsphere-jdbc-demo.git

参考链接:

[1]ShardingSphere5实战教程[CP/OL].2022-09-14.p18-23.

[2]0101读写分离测试-jdbc-shardingsphere-中间件[CP/OL].

[3]0102垂直分片-jdbc-shardingsphere[CP/OL].

相关文章:

0103水平分片-jdbc-shardingsphere-中间件

文章目录 1 准备服务器1.1 创建server-order0容器1.2 创建server-order1容器 2、基本水平分片2.1、基本配置2.2、数据源配置2.3、标椎分片表配置2.4、行表达式2.5、分片算法配置2.6、分布式序列算法 3、多表关联3.1、创建关联表3.2、创建实体类3.3、创建Mapper3.4、配置关联表3…...

Vue2.0+webpack 引入字体文件(eot,ttf,woff)

webpack.base.config.js 需要配置 {test:/\/(woff2?|eot|ttf|otf)(\?.*)?$/,loader: url-loader,options: {limit: 10000,name: utils.assetsPath(fonts/[name].[hash:7].[ext])}} 如果 Vue2.0webpack3.6引入字体文件&#xff08;eot&#xff0c;ttf&#xff0c;woff&…...

Eureka:CAP原则及对比Zookeeper

...

WPF入门到精通:3.MVVM简单应用及全局异常处理

MVVM简介 在WPF应用程序开发中&#xff0c;MVVM&#xff08;Model-View-ViewModel&#xff09;是一种非常流行的架构模式。它为应用程序的设计提供了良好的分层结构和可扩展性。 结构分为下列三部分 Model&#xff1a;定义了应用程序的数据模型 就是系统中的对象&#xff0c;…...

Springboot+mybatis-plus+dynamic-datasource+Druid 多数据源 分布式事务

Springbootmybatis-plusdynamic-datasourceDruid 多数据源事务&#xff0c;分布式事务 文章目录 Springbootmybatis-plusdynamic-datasourceDruid 多数据源事务&#xff0c;分布式事务0.前言1. 基础介绍ConnectionFactoryAbstractRoutingDataSource 动态路由数据源的抽象类 Dyn…...

673. 最长递增子序列的个数

673. 最长递增子序列的个数 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;方法一&#xff1a;动态规划方法二&#xff1a;贪心 前缀和 二分查找 参考代码&#xff1a;__673最长递增子序列的个数__动态规划__673最长递增子序列的个数__贪心_前缀和_二分查找…...

Android12之ABuffer数据处理(三十四)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药. 更多原创,欢迎关注:Android…...

whisper 语音识别项目部署

1.安装anaconda软件 在如下网盘免费获取软件&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1zOZCQOeiDhx6ebHh5zNasA 提取码&#xff1a;hfnd 2.使用conda命令创建python3.8环境 conda create -n whisper python3.83.进入whisper虚拟环境 conda activate whisper4.…...

实例044 在关闭窗口前加入确认对话框

实例说明 用户对程序进行操作时&#xff0c;难免会有错误操作的情况&#xff0c;例如不小心关闭程序&#xff0c;如果尚有许多资料没有保存&#xff0c;那么损失将非常严重&#xff0c;所以最好使程序具有灵活的交互性。人机交互过程一般都是通过对话框来实现的&#xff0c;对话…...

子查询和事务隔离以及用户管理

一、子查询 子查询是另一个语句中的select语句嵌套在另一个select中。注意子查询语法上必须使用()包起来。 嵌套的那个语句返回的结果有可能是&#xff1a; 一个字段&#xff0c;一行记录&#xff0c;一个列或一个表。嵌套的位置 where / having语句里面作为条件使用在from语…...

uniapp 滚动到指定元素的位置(锚点)

需求&#xff1a;在页面中&#xff0c;不管位于何处&#xff0c;点击按钮页面滚动到对应的标题位置。 最简单有效的方式&#xff08;直接复制改数据就行&#xff09; 使用 scroll-view 标签的属性&#xff1a;scroll-top(距离值 num) 或 scroll-into-view(子元素的id,不能以…...

Spring AOP 的 afterReturing 返回值是否能修改问题

文章目录 结论举例子原因外传 结论 最近要搞脱敏信息&#xff0c;所以&#xff0c;想了几种方案&#xff0c;最后使用全局的接口拦截&#xff0c;但是&#xff0c;又不能用注解的方式&#xff0c;毕竟是几年的老产品&#xff0c;有很多限制。 中间尝试过使用Spring AOP 的 aft…...

MyBatis分页插件PageHelper的使用及特殊字符的处理

目录 一、PageHelper简介 1.什么是分页 2.PageHelper是什么 3.使用PageHelper的优点 二、PageHelper插件的使用 原生limit查询 1. 导入pom依赖 2. Mybatis.cfg.xml 配置拦截器 3. 使用PageHelper进行分页 三、特殊字符的处理 1.SQL注入&#xff1a; 2.XML转义&#…...

[语音识别] 基于Python构建简易的音频录制与语音识别应用

语音识别技术的快速发展为实现更多智能化应用提供了无限可能。本文旨在介绍一个基于Python实现的简易音频录制与语音识别应用。文章简要介绍相关技术的应用&#xff0c;重点放在音频录制方面&#xff0c;而语音识别则关注于调用相关的语音识别库。本文将首先概述一些音频基础概…...

Matlab彩色图像转索引图像

索引图像 索引图像是一种把像素值直接作为RGB调色板下标的图像。索引图像包括一个数据矩阵X&#xff0c;一个调色板矩阵map&#xff0c;也称为颜色映像矩阵。其中&#xff0c;数据矩阵X可以是8位无符号整型、16位无符号整型或双精度类型。调色板矩阵map是一个m3的数据阵列&…...

测试框架pytest教程(11)-pytestAPI

常量 pytest.__version__ #输出pytest版本 pytest.version_tuple #输出版本的元组形式 功能 pytest.approx pytest.approx 是一个用于进行数值近似比较的 pytest 断言工具。 在测试中&#xff0c;有时候需要对浮点数或其他具有小数部分的数值进行比较。然而&#xff0c;由于…...

Docker自学:利用FastAPI建立一个简单的web app

环境配置&#xff1a;下载Docker Desktop 文件一&#xff1a;main.py from typing import Unionfrom fastapi import FastAPIimport uvicornapp FastAPI()app.get("/") def read_root():return {"Hello": "World"}app.get("/items/{item…...

微调bert做学术论文分类(以科大讯飞学术论文分类挑战赛为例)

代码 12-How to Fine-Tune BERT for Text Classification&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1EKggbyC4ZW-ufnDW45eKzA 提取码&#xff1a;k3b2 baseline 链接&#xff1a;https://pan.baidu.com/s/12hkZNJjQ__FGAHiF3fifvQ 提取码&#xff1a;88tb 数据…...

Springboot中sharding-jdbc的API模式并使用自定义算法

Springboot中sharding-jdbc的API模式并使用自定义算法 可配合AbstractRoutingData使用切换数据源 程序用到了AbstractRoutingData来切换数据源&#xff08;数据源是自定义的格式编写并没有用springboot的自动装配的格式写&#xff09;&#xff0c;但是又用到sharding-jdbc进行…...

MySQL回表是什么?哪些情况下会回表

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌&#xff0c;CSDN博客专家&#xff0c;阿里云社区专家博主&#xff0c;2023年6月CSDN上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责…...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好&#xff0c;欢迎来到《云原生核心技术》系列的第七篇&#xff01; 在上一篇&#xff0c;我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在&#xff0c;我们就像一个拥有了一块崭新数字土地的农场主&#xff0c;是时…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

vulnyx Blogger writeup

信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面&#xff0c;gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress&#xff0c;说明目标所使用的cms是wordpress&#xff0c;访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分&#xff1a; 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...