简介
头一次接触ShardingSphere-Proxy,先扫一遍官方介绍
看完后,尝试用自己的话来解释proxy:
- 从开发者的角度看,proxy基本做到了用户无感知,对代码的侵入也很少,使用起来就像使用普通数据库一样简单方便
- 从工作原理的角度看,相比于ShardingSphere-JDBC,proxy是在ORM层发挥作用,本质是个代理服务:用户->proxy->数据库
暂时了解了这么多,接下来是踩坑之旅...
启动ShardingSphere-Proxy
基于上一篇文章里准备的开发环境(ShardingSphere代码clone到本地),博主选择了直接修改本地配置文件后,启动Bootstrap方式,来开启本地的proxy服务。
具体步骤
1. 改配置文件
工程:shardingsphere-proxy-bootstrap
路径:src\main\resources\conf\server.yaml、config-sharding.yaml、config-readwrite-splitting.yaml、config-encrypt.yaml
示例:
放开server.yaml中的注释配置,并修改sql-show,便于后期调试
rules:
- !AUTHORITY
users:
- root@:root
- sharding@:sharding
provider:
type: NATIVE
props:
max-connections-size-per-query: 1
executor-size: 16 # Infinite by default.
proxy-frontend-flush-threshold: 128 # The default value is 128.
# LOCAL: Proxy will run with LOCAL transaction.
# XA: Proxy will run with XA transaction.
# BASE: Proxy will run with B.A.S.E transaction.
proxy-transaction-type: LOCAL
proxy-opentracing-enabled: false
proxy-hint-enabled: false
sql-show: true
check-table-metadata-enabled: false
放开config-sharding.yaml中的注释配置
schemaName: sharding_db
dataSources:
ds_0:
url: jdbc:mysql://127.0.0.1:3306/demo_ds_0?serverTimezone=UTC&useSSL=false
username: root
password:
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
minPoolSize: 1
ds_1:
url: jdbc:mysql://127.0.0.1:3306/demo_ds_1?serverTimezone=UTC&useSSL=false
username: root
password:
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
minPoolSize: 1
注意
config-shardingyaml文件中,有一处配置schemaName:sharding_db,此为分片策略的逻辑库名称,在后续启动示例工程,验证策略时会用到。
config-readwrite-splitting.yaml、config-encrypt.yaml也如上处理,不再赘述
2. 启动Bootstrap
3. Navicat测试连接
在proxy服务启动前:
proxy服务启动后:
由此可见,对于使用者而言,proxy生效后,相当于一个数据库服务!
运行示例
数据分片
1. 数据库初始化
CREATE SCHEMA IF NOT EXISTS demo_ds_0;
CREATE SCHEMA IF NOT EXISTS demo_ds_1;
2. 改工程配置文件
工程:shardingsphere-proxy-boot-mybatis-example
文件路径:src\main\resources\application.properties
修改如下:
mybatis.config-location=classpath:META-INF/mybatis-config.xml
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3307/sharding_db?useServerPrepStmts=true&cachePrepStmts=true
spring.datasource.username=root
spring.datasource.password=root
注意,数据库ip、端口都是本地的proxy代理服务,数据库用的是逻辑数据库sharding_db,对应数据分片
3. 执行用例
为了更好的查看效果,先注释掉代码中的delete、drop操作:
运行ProxySpringBootStarterExample
4. 观察结果
示例工程的控制台日志打印正常:
到数据库里查看,订单数据确实实现了分表:
proxy服务的控制台日志,可以看出执行了分片策略:
读写分离
1. 数据库初始化
CREATE SCHEMA IF NOT EXISTS demo_write_ds;
CREATE SCHEMA IF NOT EXISTS demo_read_ds_0;
CREATE SCHEMA IF NOT EXISTS demo_read_ds_1;
CREATE TABLE IF NOT EXISTS demo_read_ds_0.t_order (order_id BIGINT NOT NULL AUTO_INCREMENT, user_id INT NOT NULL, status VARCHAR(50), PRIMARY KEY (order_id));
CREATE TABLE IF NOT EXISTS demo_read_ds_1.t_order (order_id BIGINT NOT NULL AUTO_INCREMENT, user_id INT NOT NULL, status VARCHAR(50), PRIMARY KEY (order_id));
CREATE TABLE IF NOT EXISTS demo_read_ds_0.t_order_item (order_item_id BIGINT NOT NULL AUTO_INCREMENT, order_id BIGINT NOT NULL, user_id INT NOT NULL, status VARCHAR(50), PRIMARY KEY (order_item_id));
CREATE TABLE IF NOT EXISTS demo_read_ds_1.t_order_item (order_item_id BIGINT NOT NULL AUTO_INCREMENT, order_id BIGINT NOT NULL, user_id INT NOT NULL, status VARCHAR(50), PRIMARY KEY (order_item_id));
2. 改工程配置文件
同上,需要注意的是,修改逻辑库为:readwrite-splitting_db
mybatis.config-location=classpath:META-INF/mybatis-config.xml
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3307/readwrite-splitting_db?useServerPrepStmts=true&cachePrepStmts=true
spring.datasource.username=root
spring.datasource.password=root
3. 执行用例
同上
4. 观察结果
重点看proxy服务的控制台日志,可以看到读写分别走了不同的库
加密
1. 数据库初始化
CREATE SCHEMA IF NOT EXISTS demo_ds_0;
CREATE SCHEMA IF NOT EXISTS demo_ds_1;
2. 改工程配置文件
同上,需要注意的是,修改逻辑库为:encrypt_db
mybatis.config-location=classpath:META-INF/mybatis-config.xml
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3307/encrypt_db?useServerPrepStmts=true&cachePrepStmts=true
spring.datasource.username=root
spring.datasource.password=root
3. 执行用例
同上
4. 观察结果
从proxy服务的控制台日志,可以看到项目正常执行,但是数据并未加密???
加密未生效的坑,还需填上(今天搞太晚了,后面找时间再测试一把。。)
(更新于2021.08.25,来填坑了)
查看了项目里config-encrypt.yaml的配置,以及官方文档对加密配置项的介绍,发现数据未加密的原因是没有填对配置项。。o(╯□╰)o
赶紧改了一把(注意加密字段的数据类型,跟加密后的数据类型是否一致,这一步得选择合适的算法)
最终效果:
总结
相比第一天的jdbc,proxy的调试顺利多了,后面还得再接再厉!!!
踩坑的过程也暴露出自己身上很多问题:
- 事先准备不够,既没有完整地浏览一遍文档,也没有认真地思考文档内容,只看了个大概,就急着动手,导致后续犯了太多低级错误(很多错误只要足够细心就能避免)
- 过程里只求调通,没有进一步沉下心去琢磨实现原理