Java最新太牛逼了,ShardingJdbc基于Zookeeper实现分布式治理(1),聊聊Java开发的现状和思考

面试题总结

其它面试题(springboot、mybatis、并发、java中高级面试总结等)

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

spring.shardingsphere.rules.sharding.tables.t_order.actual-data-nodes=ds-KaTeX parse error: Expected group after '_' at position 17: …>{0..1}.t_order_̲->{0…1}

spring.shardingsphere.rules.sharding.tables.t_order.table-strategy.standard.sharding-column=order_id

spring.shardingsphere.rules.sharding.tables.t_order.table-strategy.standard.sharding-algorithm-name=t-order-inline

spring.shardingsphere.rules.sharding.tables.t_order.key-generate-strategy.column=order_id

spring.shardingsphere.rules.sharding.tables.t_order.key-generate-strategy.key-generator-name=snowflake

spring.shardingsphere.rules.sharding.sharding-algorithms.database-inline.type=INLINE

spring.shardingsphere.rules.sharding.sharding-algorithms.database-inline.props.algorithm-expression=ds-$->{user_id % 2}

spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.type=INLINE

spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.props.algorithm-expression=t_order_$->{order_id % 2}

spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-item-inline.type=INLINE

spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-item-inline.props.algorithm-expression=t_order_item_$->{order_id % 2}

spring.shardingsphere.rules.sharding.key-generators.snowflake.type=SNOWFLAKE

spring.shardingsphere.rules.sharding.key-generators.snowflake.props.worker-id=123

增加Zookeeper配置

=============

治理名称(在zookeeper上的节点名称)

spring.shardingsphere.governance.name=sharding-jdbc-split-zookeeper

本地配置是否覆盖配置中心配置。如果可覆盖,每次启动都以本地配置为准.

spring.shardingsphere.governance.overwrite=true

Zookeeper/etcd

spring.shardingsphere.governance.registry-center.type=ZooKeeper

spring.shardingsphere.governance.registry-center.server-lists=192.168.221.131:2181

之所以加下面两个参数,是因为默认的链接超时时间是1500毫秒,由于时间较短导致启动时很容易超时,导致连接失败

重试次数

spring.shardingsphere.governance.registry-center.props.maxRetries=4

重试间隔时间

spring.shardingsphere.governance.registry-center.props.retryIntervalMilliseconds=6000

启动项目进行测试

========

启动过程中看到如下日志,表示配置zookeeper成功,启动的时候会先把本地配置保存到zookeeper中,后续我们可以在zookeeper中修改相关配置,然后同步通知给到相关的应用节点。

2021-07-29 21:31:25.007 INFO 112916 — [ main] org.apache.zookeeper.ZooKeeper : Client environment:java.io.tmpdir=C:\Users\mayn\AppData\Local\Temp\

2021-07-29 21:31:25.007 INFO 112916 — [ main] org.apache.zookeeper.ZooKeeper : Client environment:java.compiler=

2021-07-29 21:31:25.007 INFO 112916 — [ main] org.apache.zookeeper.ZooKeeper : Client environment:os.name=Windows 10

2021-07-29 21:31:25.007 INFO 112916 — [ main] org.apache.zookeeper.ZooKeeper : Client environment:os.arch=amd64

2021-07-29 21:31:25.007 INFO 112916 — [ main] org.apache.zookeeper.ZooKeeper : Client environment:os.version=10.0

2021-07-29 21:31:25.007 INFO 112916 — [ main] org.apache.zookeeper.ZooKeeper : Client environment:user.name=mayn

2021-07-29 21:31:25.007 INFO 112916 — [ main] org.apache.zookeeper.ZooKeeper : Client environment:user.home=C:\Users\mayn

2021-07-29 21:31:25.007 INFO 112916 — [ main] org.apache.zookeeper.ZooKeeper : Client environment:user.dir=E:\教研-课件\vip课程\第五轮\03 高并发组件\09 ShardingSphere基于Zookeeper实现分布式治理\sharding-jdbc-readwrite-zookeeper

2021-07-29 21:31:25.007 INFO 112916 — [ main] org.apache.zookeeper.ZooKeeper : Client environment:os.memory.free=482MB

2021-07-29 21:31:25.007 INFO 112916 — [ main] org.apache.zookeeper.ZooKeeper : Client environment:os.memory.max=7264MB

2021-07-29 21:31:25.007 INFO 112916 — [ main] org.apache.zookeeper.ZooKeeper : Client environment:os.memory.total=501MB

2021-07-29 21:31:25.009 INFO 112916 — [ main] org.apache.zookeeper.ZooKeeper : Initiating client connection, connectString=192.168.221.131:2181 sessionTimeout=60000 watcher=org.apache.curator.ConnectionState@68e2d03e

2021-07-29 21:31:25.012 INFO 112916 — [ main] org.apache.zookeeper.common.X509Util : Setting -D jdk.tls.rejectClientInitiatedRenegotiation=true to disable client-initiated TLS renegotiation

2021-07-29 21:31:25.020 INFO 112916 — [ main] org.apache.zookeeper.ClientCnxnSocket : jute.maxbuffer value is 1048575 Bytes

2021-07-29 21:31:25.023 INFO 112916 — [ main] org.apache.zookeeper.ClientCnxn : zookeeper.request.timeout value is 0. feature enabled=false

2021-07-29 21:31:25.030 INFO 112916 — [ main] o.a.c.f.imps.CuratorFrameworkImpl : Default schema

接着访问如下接口进行测试。

@RestController

@RequestMapping(“/t-order”)

public class TOrderController {

@Autowired

ITOrderService orderService;

@GetMapping

public void init() throws SQLException {

orderService.initEnvironment();

orderService.processSuccess();

}

}

配置中心的数据结构说明

===========

注册中心的数据结构如下

namespace: 就是spring.shardingsphere.governance.name

namespace

├──users # 权限配置

├──props # 属性配置

├──schemas # Schema 配置

├ ├──${schema_1} # Schema 名称1

├ ├ ├──datasource # 数据源配置

├ ├ ├──rule # 规则配置

├ ├ ├──table # 表结构配置

├ ├──${schema_2} # Schema 名称2

├ ├ ├──datasource # 数据源配置

├ ├ ├──rule # 规则配置

├ ├ ├──table # 表结构配置

rules全局配置规则

===========

可包括访问 ShardingSphere-Proxy 用户名和密码的权限配置

  • !AUTHORITYusers: - root@%:root - sharding@127.0.0.1:shardingprovider: type: NATIVE

props属性配置

=========

ShardingSphere相关属性配置

executor-size: 20sql-show: true

/schemas/${schemeName}/dataSources

==================================

多个数据库连接池的集合,不同数据库连接池属性自适配(例如:DBCP,C3P0,Druid, HikariCP)。

ds_0: dataSourceClassName: com.zaxxer.hikari.HikariDataSource props: url: jdbc:mysql://127.0.0.1:3306/demo_ds_0?serverTimezone=UTC&useSSL=false password: null maxPoolSize: 50 connectionTimeoutMilliseconds: 30000 idleTimeoutMilliseconds: 60000 minPoolSize: 1 username: root maxLifetimeMilliseconds: 1800000ds_1: dataSourceClassName: com.zaxxer.hikari.HikariDataSource props: url: jdbc:mysql://127.0.0.1:3306/demo_ds_1?serverTimezone=UTC&useSSL=false password: null maxPoolSize: 50 connectionTimeoutMilliseconds: 30000 idleTimeoutMilliseconds: 60000 minPoolSize: 1 username: root maxLifetimeMilliseconds: 1800000

/schemas/${schemeName}/rule

===========================

规则配置,可包括数据分片、读写分离等配置规则

rules:- !SHARDING defaultDatabaseStrategy: standard: shardingAlgorithmName: database-inline shardingColumn: user_id keyGenerators: snowflake: props: worker-id: ‘123’ type: SNOWFLAKE shardingAlgorithms: t-order-inline: props: algorithm-expression: t_order_KaTeX parse error: Expected '}', got 'EOF' at end of input: …expression: ds-->{user_id % 2} type: INLINE t-order-item-inline: props: algorithm-expression: t_order_item_KaTeX parse error: Expected '}', got 'EOF' at end of input: …lDataNodes: ds-->{0…1}.t_order_$->{0…1} keyGenerateStrategy: column: order_id keyGeneratorName: snowflake logicTable: t_order tableStrategy: standard: shardingAlgorithmName: t-order-inline shardingColumn: order_id

/schemas/${schemeName}/table

============================

表结构配置,暂时不支持动态修改

configuredSchemaMetaData: tables: t_order: columns: order_id: caseSensitive: false dataType: 0 generated: true name: order_id primaryKey: true user_id: caseSensitive: false dataType: 0 generated: false name: user_id primaryKey: false address_id: caseSensitive: false dataType: 0 generated: false name: address_id primaryKey: false status: caseSensitive: false dataType: 0 generated: false name: status primaryKey: falseunconfiguredSchemaMetaDataMap: ds-0: - t_order_complex - t_order_interval - t_order_item_complex

动态生效

====

除了table相关的配置无法动态更改之外,其他配置在zookeeper上修改之后,在不重启应用节点时,都会同步到相关服务节点。

比如,我们修改图9-2所示的红色部分的位置,把t_order_ − > 0..1 修改成 t _ o r d e r _ ->{0..1}修改成t\_order\_ >0..1修改成t_order_->{0…4},这样就会生成4个分片,并且取模规则也做相应更改。

然后点击保存后,在不重启应用节点时,重新发起接口测试请求,就可以看到修改成功后的结果。

http://localhost:8080/swagger-ui.html

太牛逼了!ShardingJdbc基于Zookeeper实现分布式治理

图9-2 zookeeper配置中心

注册中心节点

======

在zookeeper服务器上,还存在以下节点信息。

namespace ├──states ├ ├──proxynodes ├ ├ ├── y o u r i n s t a n c e i p a @ {your_instance_ip_a}@ yourinstanceipa@{your_instance_pid_x}@ U U I D ├├├── {UUID} ├ ├ ├── UUID├├├──{your_instance_ip_b}@ y o u r i n s t a n c e p i d y @ {your_instance_pid_y}@ yourinstancepidy@{UUID} ├ ├ ├──… ├ ├──datanodes ├ ├ ├── s c h e m a 1 ├├├├── {schema_1} ├ ├ ├ ├── schema1├├├├──{ds_0} ├ ├ ├ ├── d s 1 ├├├── {ds_1} ├ ├ ├── ds1├├├──{schema_2} ├ ├ ├ ├── d s 0 ├├├├── {ds_0} ├ ├ ├ ├── ds0├├├├──{ds_1} ├ ├ ├──…

这个是注册中心节点,用来保存shardingsphere-proxy中间件的服务器实例信息、以及实例运行情况。

运行实例标识由运行服务器的 IP 地址和 PID 构成。

运行实例标识均为临时节点,当实例上线时注册,下线时自动清理。 注册中心监控这些节点的变化来治理运行中实例对数据库的访问等。

由于注册中心会在后续的内容中讲,所以这里暂时不展开。

分布式治理总结

=======

引入zookeeper这样一个角色,可以协助ShardingJDBC完成以下功能

架构学习资料

准备两个月,面试五分钟,Java中高级岗面试为何越来越难?

准备两个月,面试五分钟,Java中高级岗面试为何越来越难?

准备两个月,面试五分钟,Java中高级岗面试为何越来越难?

准备两个月,面试五分钟,Java中高级岗面试为何越来越难?

准备两个月,面试五分钟,Java中高级岗面试为何越来越难?

由于篇幅限制小编,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

存中…(img-Kt31Hz8x-1715430458874)]

[外链图片转存中…(img-EdcKqYSY-1715430458875)]

[外链图片转存中…(img-9NbN8tld-1715430458875)]

由于篇幅限制小编,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 16
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 使用 ZooKeeper 实现分布式锁最常见的方法是使用公平锁(Fair Lock)。在这种情况下,在 ZooKeeper 集群中创建一个特殊的临时节点,并使用它来保持锁定状态。当一个客户端尝试获取锁时,它会尝试创建这个临时节点,如果节点创建成功,则说明该客户端已经获得了锁。 使用 ZooKeeper 进行分布式锁的实现需要使用 ZooKeeper 的原子操作,例如创建节点和监视节点,以保证锁的正确性。 代码示例如下: ```java public class DistributedLock { private ZooKeeper zk; private String lockNode; private String lockPath; public DistributedLock(ZooKeeper zk, String lockNode) { this.zk = zk; this.lockNode = lockNode; this.lockPath = "/locks/" + lockNode; } public void lock() throws Exception { while (true) { try { zk.create(lockPath, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL); return; } catch (KeeperException.NodeExistsException e) { waitForLock(); } } } public void unlock() throws Exception { zk.delete(lockPath, -1); } private void waitForLock() throws Exception { CountDownLatch latch = new CountDownLatch(1); Watcher lockWatcher = new Watcher() { @Override public void process(WatchedEvent event) { if (event.getType() == EventType.NodeDeleted) { latch.countDown(); } } }; zk.exists(lockPath, lockWatcher); latch.await(); } } ``` 该代码示例提供了一个简单的实现,可以作为创建自己的分布式锁的基 ### 回答2: 在基于 ZooKeeper 实现 Java 分布式锁的过程中,可以按照以下步骤进行: 1. 创建一个基于 ZooKeeper 的客户端对象。 2. 在 ZooKeeper 上创建一个持久化的节点,作为锁的根节点。 3. 当需要进行锁操作时,创建一个临时有序节点作为当前请求的锁节点。 4. 调用 `getChildren` 方法获取锁根节点下的所有节点,并根据节点的序号进行排序。 5. 检查当前节点是否是锁根节点下序号最小的节点,如果是则获取到锁,执行业务逻辑。 6. 如果当前节点不是锁根节点下序号最小的节点,则注册监听锁根节点下序号比自己小一的节点。 7. 当监听到序号比自己小一的节点删除时,重复步骤 4-6 直到获取到锁。 8. 业务逻辑执行完成后,可以删除当前节点,释放锁资源。 此外,还需要特别注意以下几个问题: 1. 分布式锁的超时机制:在创建临时节点时,可以指定一个超时时间,当超过该时间后,如果还未获取到锁,可以删除当前节点,避免死锁。 2. 锁的释放:在业务逻辑执行完成后,需要手动删除当前节点。如果由于某些原因未能正常删除,则需要提供一种机制,在锁节点创建时设置一个 TTL(time-to-live),让 ZooKeeper 在锁节点过期后自动删除。 3. 锁节点的竞争:在并发较高的情况下,可能会出现多个客户端同时创建临时节点的情况。这时可以使用 `CyclicBarrier` 或者 `CountDownLatch` 进行同步,确保每次只有一个客户端创建锁节点。 4. 异常情况的处理:在进行锁操作时,需要处理各种异常情况,比如连接断开、网络超时等,保证系统的稳定性和可靠性。 综上所述,基于 ZooKeeper 可以实现 Java 分布式锁,通过创建临时有序节点和监听上一个节点的删除来实现锁的竞争和获取。 ### 回答3: 实现基于 ZooKeeperJava 分布式锁可以遵循以下步骤: 1. 连接 ZooKeeper:首先,通过 Java API 连接到 ZooKeeper 服务器,可以使用 zookeeper API 提供的 ZooKeeper 类来创建一个连接对象。 2. 创建锁节点:在 ZooKeeper 上创建一个父节点作为锁的根节点,该节点的所有子节点都作为锁节点。可以使用 zookeeper API 的 create() 方法创建临时顺序节点。 3. 获取锁:每个需要获取锁的进程都要通过创建一个临时顺序节点来竞争锁。通过 zookeeper API 的 getChildren() 方法获取锁根节点的所有子节点,如果创建的节点序号是当前所有节点中最小的,则表示获取到了锁。 4. 监听锁节点变化:如果未能获取到锁,应该在创建节点后,使用 zookeeper API 的 exists() 方法注册一个监听器来监听创建的子节点。当监听到创建的子节点发生变化时,判断自己的节点是否变成了最小的节点,如果是则表示获取到了锁。 5. 释放锁:对于已经获取到锁的进程,执行完任务后,需要通过 zookeeper API 的 delete() 方法将自己创建的锁节点删除,这样其他进程就能获取到该锁了。 需要注意的是,在分布式环境下,网络通信可能会出现延迟或故障,因此需要考虑到这些情况来保证分布式锁的正确性和可靠性。此外,还需考虑到异常情况处理、死锁检测和容错等问题,以确保分布式锁的高可用性和可靠性。 以上是使用 ZooKeeper 实现 Java 分布式锁的基本步骤,通过合理地使用 ZooKeeper 的 API,可以轻松实现分布式环境下的锁机制。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值