JRaft高版本jdk上手踩坑实录(新年快乐)

分布式朝闻道

共 30366字,需浏览 61分钟

 ·

2024-04-11 06:20

在分布式系统中,保持数据的一致性是一项非常重要的任务。然而,实现一个高效、可靠且易于使用的一致性系统并不容易。幸运的是,有一些优秀的框架和算法可以帮助我们解决这个问题。其中,蚂蚁金服开源的jraft框架是其中的代表之一。

b39d54ddf421be495c04ca654daa08c1.webp

jraft是一个基于Raft一致性算法的Java框架,为构建分布式一致性系统提供了便利。

什么是Raft算法?

在介绍jraft之前,让我们先了解一下Raft算法。Raft是一种共识算法,用于解决分布式系统中的一致性问题。它类似于Paxos算法,但更易理解和实现。Raft算法通过选举、日志复制和安全性机制来确保分布式系统中的数据一致性。它将系统中的节点分为领导者、跟随者和候选者,并通过选举机制选择领导者,进而实现数据的一致性。

jraft框架概述

jraft框架是基于Raft算法实现的一个Java框架,旨在简化构建分布式一致性系统的过程。它提供了一组核心组件和API,可以帮助开发者快速构建高性能、可靠的分布式一致性系统。

核心组件

jraft框架包含以下核心组件:

  • Raft协议:jraft框架实现了Raft算法的核心逻辑,包括领导者选举、日志复制和安全性机制等。

  • 日志模块:jraft框架提供了日志模块,用于管理和复制日志条目。它确保日志在整个集群中的一致性。

  • 状态机:jraft框架支持自定义状态机,开发者可以根据自己的需求实现状态机逻辑,框架会保证状态机在集群中的一致性。

  • 网络通信:jraft框架使用基于TCP的网络通信机制,在节点之间进行消息传递和数据同步。

使用jraft框架构建一个基于Raft算法的分布式一致性系统非常简单。开发者只需要引入jraft框架的依赖,然后按照框架提供的API进行开发即可。开发者可以定义自己的状态机逻辑,并通过框架提供的API与集群中的其他节点进行通信。

当前最新版本为1.3.14,maven坐标为:

      
      <!-- https://mvnrepository.com/artifact/com.alipay.sofa/jraft-core -->
<dependency>
    <groupId>com.alipay.sofa</groupId>
    <artifactId>jraft-core</artifactId>
    <version>1.3.14</version>
</dependency>

jraft的优势和适用场景

jraft框架具有以下优势:

  • 易于使用:jraft框架提供了简单易用的API,开发者可以快速上手并构建分布式一致性系统。
  • 高性能:jraft框架经过优化,具有出色的性能和吞吐量。
  • 可靠性:jraft框架实现了Raft算法的核心逻辑,并提供了高可靠性的数据复制和一致性保证。

jraft框架适用于构建需要保持数据一致性的分布式系统,例如分布式数据库、分布式缓存和分布式文件系统等。

尝试jraft

jraft官方提供了一个counter计数器的复制状态机实现,我们就尝试通过这个demo来对jraft的使用有一个初步的直观认识。

项目信息

项目github地址:https://github.com/sofastack/sofa-jraft

counter项目在下图所示位置,路径为

      
      jraft-example/
  |-src
   |-main
    |-java
     |-com/alipay/sofa/jraft/example/counter

9b2b8e7a3f18850c3cbe4febfebf301a.webp

编译代码

笔者公司已经全面升级到jdk17,因此平时学习写一些自己的demo的时候也倾向于使用jdk17作为运行时环境。

jraft当前只支持jdk1.8,因此使用高版本的jdk如jdk11,jdk17等在运行时就会报错。 主要报错内容为:

      
      module java.base does not "opens sun.misc" to unnamed module

这个错误信息是由于在Java 9及更高版本中引入的模块化系统所导致的。在这个错误中,它表示未命名模块(unnamed module)试图访问 sun.misc 模块,但 java.base 模块没有对 sun.misc 模块进行打开(opens)操作。

解决方法

解决方法就是绕过模块化的限制,在编译时期增加以下参数:

      
      --add-modules=jdk.unsupported 

95885991d5c81e17e5a61b92dccdbb19.webp

运行服务端

服务端直接运行会报

      
      module java.base does not "opens java.lang" to unnamed module

因此需要在服务端的运行参数中增加对相关模块的支持

      
      --add-modules=jdk.unsupported
--add-opens=java.base/sun.nio.ch=ALL-UNNAMED
--add-opens=java.base/java.lang=ALL-UNNAMED
--add-opens=java.base/java.lang.reflect=ALL-UNNAMED

43a60f96f32fafa204af9ddbbb953725.webp

客户端运行过程中也会报相关的错误,因此在客户端的运行参数中也需要增加如下命令:

      
      --add-modules=jdk.unsupported
--add-opens=java.base/java.lang=ALL-UNNAMED
--add-opens=java.base/java.lang.reflect=ALL-UNNAMED

b62adce05be6ea5570908f06c9e395bf.webp

启动服务端

服务端我们构建一个三阶段的raft集群,依次启动。

重点设置四个参数:

  • dataPath:表示当前节点的数据存储的路径,这里为D:\jraft\example\counter\node1
  • groupId:表示该raft集群的唯一标识(组名),这里为jraft-counter
  • serverIdStr:表示当前节点的地址和端口号,这里为127.0.0.1:8081
  • initConfStr:表示该raft集群中所有节点的地址和端口号,这里为127.0.0.1:8081,127.0.0.1:8082,127.0.0.1:8083

节点1

      
              final String dataPath = "D:\\jraft\\example\\counter\\node1";
        final String groupId = "jraft-counter";
        final String serverIdStr = "127.0.0.1:8081";
        final String initConfStr = "127.0.0.1:8081,127.0.0.1:8082,127.0.0.1:8083";

节点2

      
              final String dataPath = "D:\\jraft\\example\\counter\\node2";
        final String groupId = "jraft-counter";
        final String serverIdStr = "127.0.0.1:8082";
        final String initConfStr = "127.0.0.1:8081,127.0.0.1:8082,127.0.0.1:8083";

节点3

      
              final String dataPath = "D:\\jraft\\example\\counter\\node3";
        final String groupId = "jraft-counter";
        final String serverIdStr = "127.0.0.1:8083";
        final String initConfStr = "127.0.0.1:8081,127.0.0.1:8082,127.0.0.1:8083";

启动完成之后,节点日志如下:

从节点日志

      
      2024-02-04 13:17:37 [main] INFO  JRaftServiceLoader:275 - SPI service [com.alipay.sofa.jraft.JRaftServiceFactory - com.alipay.sofa.jraft.core.DefaultJRaftServiceFactory] loading.
2024-02-04 13:17:38 [main] INFO  JRaftServiceLoader:275 - SPI service [com.alipay.sofa.jraft.rpc.RaftRpcFactory - com.alipay.sofa.jraft.rpc.impl.BoltRaftRpcFactory] loading.
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j2 ]
2024-02-04 13:17:38 [main] INFO  log:30 - Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j2 ]
2024-02-04 13:17:38 [main] INFO  JRaftServiceLoader:275 - SPI service [com.alipay.sofa.jraft.util.timer.RaftTimerFactory - com.alipay.sofa.jraft.util.timer.DefaultRaftTimerFactory] loading.
2024-02-04 13:17:38 [main] INFO  NodeImpl:556 - The number of active nodes increment to 1.
2024-02-04 13:17:38 [JRaft-Group-Default-Executor-0] INFO  RocksDBLogStorage:613 - Truncated prefix logs in data path: D:\jraft\example\counter\node3\log from log index 0 to 13013, cost 1 ms.
2024-02-04 13:17:38 [main] INFO  FSMCallerImpl:215 - Starts FSMCaller successfully.
2024-02-04 13:17:38 [main] INFO  SnapshotExecutorImpl:268 - Loading snapshot, meta=last_included_index: 13012
last_included_term: 2
peers: "127.0.0.1:8081"
peers: "127.0.0.1:8082"
peers: "127.0.0.1:8083"
.
2024-02-04 13:17:38 [JRaft-FSMCaller-Disruptor-0] INFO  StateMachineAdapter:79 - onConfigurationCommitted: 127.0.0.1:8081,127.0.0.1:8082,127.0.0.1:8083.
2024-02-04 13:17:38 [JRaft-FSMCaller-Disruptor-0] INFO  SnapshotExecutorImpl:487 - Node <jraft-counter/127.0.0.1:8083> onSnapshotLoadDone, last_included_index: 13012
last_included_term: 2
peers: "127.0.0.1:8081"
peers: "127.0.0.1:8082"
peers: "127.0.0.1:8083"

2024-02-04 13:17:38 [main] INFO  NodeImpl:725 - Node <jraft-counter/127.0.0.1:8083> target priority value has changed from: 0, to: -1.
2024-02-04 13:17:38 [JRaft-Group-Default-Executor-1] INFO  RocksDBLogStorage:613 - Truncated prefix logs in data path: D:\jraft\example\counter\node3\log from log index 13013 to 13013, cost 0 ms.
2024-02-04 13:17:38 [main] INFO  NodeImpl:1091 - Node <jraft-counter/127.0.0.1:8083> init, term=2, lastLogId=LogId [index=13012, term=2], conf=127.0.0.1:8081,127.0.0.1:8082,127.0.0.1:8083, oldConf=.
2024-02-04 13:17:38 [main] INFO  RaftGroupService:136 - Start the RaftGroupService successfully.
Started counter server at port:8083

主要就是加载了当前节点的log到内存,加入到raft集群中,当前节点是follower

主节点日志

      
      2024-02-04 13:17:13 [main] INFO  JRaftServiceLoader:275 - SPI service [com.alipay.sofa.jraft.JRaftServiceFactory - com.alipay.sofa.jraft.core.DefaultJRaftServiceFactory] loading.
2024-02-04 13:17:13 [main] INFO  JRaftServiceLoader:275 - SPI service [com.alipay.sofa.jraft.rpc.RaftRpcFactory - com.alipay.sofa.jraft.rpc.impl.BoltRaftRpcFactory] loading.
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j2 ]
2024-02-04 13:17:13 [main] INFO  log:30 - Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j2 ]
2024-02-04 13:17:13 [main] INFO  JRaftServiceLoader:275 - SPI service [com.alipay.sofa.jraft.util.timer.RaftTimerFactory - com.alipay.sofa.jraft.util.timer.DefaultRaftTimerFactory] loading.
2024-02-04 13:17:13 [main] INFO  NodeImpl:556 - The number of active nodes increment to 1.
2024-02-04 13:17:13 [JRaft-Group-Default-Executor-0] INFO  RocksDBLogStorage:613 - Truncated prefix logs in data path: D:\jraft\example\counter\node1\log from log index 0 to 13013, cost 0 ms.
2024-02-04 13:17:13 [main] INFO  FSMCallerImpl:215 - Starts FSMCaller successfully.
2024-02-04 13:17:13 [main] INFO  SnapshotExecutorImpl:268 - Loading snapshot, meta=last_included_index: 13012
last_included_term: 2
peers: "127.0.0.1:8081"
peers: "127.0.0.1:8082"
peers: "127.0.0.1:8083"
.
2024-02-04 13:17:13 [JRaft-FSMCaller-Disruptor-0] INFO  StateMachineAdapter:79 - onConfigurationCommitted: 127.0.0.1:8081,127.0.0.1:8082,127.0.0.1:8083.
2024-02-04 13:17:13 [JRaft-FSMCaller-Disruptor-0] INFO  SnapshotExecutorImpl:487 - Node <jraft-counter/127.0.0.1:8081> onSnapshotLoadDone, last_included_index: 13012
last_included_term: 2
peers: "127.0.0.1:8081"
peers: "127.0.0.1:8082"
peers: "127.0.0.1:8083"

2024-02-04 13:17:13 [main] INFO  NodeImpl:725 - Node <jraft-counter/127.0.0.1:8081> target priority value has changed from: 0, to: -1.
2024-02-04 13:17:13 [JRaft-Group-Default-Executor-1] INFO  RocksDBLogStorage:613 - Truncated prefix logs in data path: D:\jraft\example\counter\node1\log from log index 13013 to 13013, cost 0 ms.
2024-02-04 13:17:13 [main] INFO  NodeImpl:1091 - Node <jraft-counter/127.0.0.1:8081> init, term=2, lastLogId=LogId [index=13012, term=2], conf=127.0.0.1:8081,127.0.0.1:8082,127.0.0.1:8083, oldConf=.
2024-02-04 13:17:13 [main] INFO  RaftGroupService:136 - Start the RaftGroupService successfully.
Started counter server at port:8081
2024-02-04 13:17:15 [JRaft-ElectionTimer-<jraft-counter/127.0.0.1:8081>0] INFO  NodeImpl:2668 - Node <jraft-counter/127.0.0.1:8081> term 2 start preVote.
2024-02-04 13:17:15 [JRaft-ElectionTimer-<jraft-counter/127.0.0.1:8081>0] ERROR AbstractClientService:156 - Fail to connect 127.0.0.1:8083, remoting exception: com.alipay.remoting.exception.RemotingException: Create connection failed. The address is 127.0.0.1:8083.
2024-02-04 13:17:15 [JRaft-ElectionTimer-<jraft-counter/127.0.0.1:8081>0] WARN  NodeImpl:2700 - Node <jraft-counter/127.0.0.1:8081> channel init failed, address=127.0.0.1:8083.
2024-02-04 13:17:15 [JRaft-ElectionTimer-<jraft-counter/127.0.0.1:8081>0] ERROR AbstractClientService:156 - Fail to connect 127.0.0.1:8082, remoting exception: com.alipay.remoting.exception.RemotingException: Create connection failed. The address is 127.0.0.1:8082.
2024-02-04 13:17:15 [JRaft-ElectionTimer-<jraft-counter/127.0.0.1:8081>0] WARN  NodeImpl:2700 - Node <jraft-counter/127.0.0.1:8081> channel init failed, address=127.0.0.1:8082.
2024-02-04 13:17:16 [JRaft-ElectionTimer-<jraft-counter/127.0.0.1:8081>0] INFO  NodeImpl:2668 - Node <jraft-counter/127.0.0.1:8081> term 2 start preVote.
2024-02-04 13:17:16 [JRaft-ElectionTimer-<jraft-counter/127.0.0.1:8081>0] ERROR AbstractClientService:156 - Fail to connect 127.0.0.1:8083, remoting exception: com.alipay.remoting.exception.RemotingException: Create connection failed. The address is 127.0.0.1:8083.
2024-02-04 13:17:16 [JRaft-ElectionTimer-<jraft-counter/127.0.0.1:8081>0] WARN  NodeImpl:2700 - Node <jraft-counter/127.0.0.1:8081> channel init failed, address=127.0.0.1:8083.
2024-02-04 13:17:16 [JRaft-ElectionTimer-<jraft-counter/127.0.0.1:8081>0] ERROR AbstractClientService:156 - Fail to connect 127.0.0.1:8082, remoting exception: com.alipay.remoting.exception.RemotingException: Create connection failed. The address is 127.0.0.1:8082.
2024-02-04 13:17:16 [JRaft-ElectionTimer-<jraft-counter/127.0.0.1:8081>0] WARN  NodeImpl:2700 - Node <jraft-counter/127.0.0.1:8081> channel init failed, address=127.0.0.1:8082.
2024-02-04 13:17:18 [JRaft-ElectionTimer-<jraft-counter/127.0.0.1:8081>0] INFO  NodeImpl:2668 - Node <jraft-counter/127.0.0.1:8081> term 2 start preVote.
2024-02-04 13:17:18 [JRaft-ElectionTimer-<jraft-counter/127.0.0.1:8081>0] ERROR AbstractClientService:156 - Fail to connect 127.0.0.1:8083, remoting exception: com.alipay.remoting.exception.RemotingException: Create connection failed. The address is 127.0.0.1:8083.
2024-02-04 13:17:18 [JRaft-ElectionTimer-<jraft-counter/127.0.0.1:8081>0] WARN  NodeImpl:2700 - Node <jraft-counter/127.0.0.1:8081> channel init failed, address=127.0.0.1:8083.
2024-02-04 13:17:18 [JRaft-ElectionTimer-<jraft-counter/127.0.0.1:8081>0] ERROR AbstractClientService:156 - Fail to connect 127.0.0.1:8082, remoting exception: com.alipay.remoting.exception.RemotingException: Create connection failed. The address is 127.0.0.1:8082.
2024-02-04 13:17:18 [JRaft-ElectionTimer-<jraft-counter/127.0.0.1:8081>0] WARN  NodeImpl:2700 - Node <jraft-counter/127.0.0.1:8081> channel init failed, address=127.0.0.1:8082.
2024-02-04 13:17:19 [JRaft-ElectionTimer-<jraft-counter/127.0.0.1:8081>0] INFO  NodeImpl:2668 - Node <jraft-counter/127.0.0.1:8081> term 2 start preVote.
2024-02-04 13:17:19 [JRaft-ElectionTimer-<jraft-counter/127.0.0.1:8081>0] ERROR AbstractClientService:156 - Fail to connect 127.0.0.1:8083, remoting exception: com.alipay.remoting.exception.RemotingException: Create connection failed. The address is 127.0.0.1:8083.
2024-02-04 13:17:19 [JRaft-ElectionTimer-<jraft-counter/127.0.0.1:8081>0] WARN  NodeImpl:2700 - Node <jraft-counter/127.0.0.1:8081> channel init failed, address=127.0.0.1:8083.
2024-02-04 13:17:19 [JRaft-ElectionTimer-<jraft-counter/127.0.0.1:8081>0] ERROR AbstractClientService:156 - Fail to connect 127.0.0.1:8082, remoting exception: com.alipay.remoting.exception.RemotingException: Create connection failed. The address is 127.0.0.1:8082.
2024-02-04 13:17:19 [JRaft-ElectionTimer-<jraft-counter/127.0.0.1:8081>0] WARN  NodeImpl:2700 - Node <jraft-counter/127.0.0.1:8081> channel init failed, address=127.0.0.1:8082.
2024-02-04 13:17:21 [JRaft-ElectionTimer-<jraft-counter/127.0.0.1:8081>0] INFO  NodeImpl:2668 - Node <jraft-counter/127.0.0.1:8081> term 2 start preVote.
2024-02-04 13:17:21 [JRaft-ElectionTimer-<jraft-counter/127.0.0.1:8081>0] ERROR AbstractClientService:156 - Fail to connect 127.0.0.1:8083, remoting exception: com.alipay.remoting.exception.RemotingException: Create connection failed. The address is 127.0.0.1:8083.
2024-02-04 13:17:21 [JRaft-ElectionTimer-<jraft-counter/127.0.0.1:8081>0] WARN  NodeImpl:2700 - Node <jraft-counter/127.0.0.1:8081> channel init failed, address=127.0.0.1:8083.

2024-02-04 13:17:23 [Bolt-conn-event-executor-5-thread-1] INFO  ClientServiceConnectionEventProcessor:50 - Peer 127.0.0.1:8082 is connected
2024-02-04 13:17:23 [JRaft-RPC-Processor-0] INFO  NodeImpl:2622 - Node <jraft-counter/127.0.0.1:8081> received PreVoteResponse from 127.0.0.1:8082, term=2, granted=true.
2024-02-04 13:17:23 [JRaft-RPC-Processor-0] INFO  NodeImpl:1134 - Node <jraft-counter/127.0.0.1:8081> start vote and grant vote self, term=2.

2024-02-04 13:17:23 [JRaft-RPC-Processor-0] WARN  NodeImpl:1170 - Node <jraft-counter/127.0.0.1:8081> channel init failed, address=127.0.0.1:8083.
2024-02-04 13:17:23 [JRaft-RPC-Processor-0] WARN  Utils:424 - Unable to fsync directory D:\jraft\example\counter\node1\raft_meta on windows.
2024-02-04 13:17:23 [JRaft-RPC-Processor-0] INFO  LocalRaftMetaStorage:132 - Save raft meta, path=D:\jraft\example\counter\node1\raft_meta, term=3, votedFor=127.0.0.1:8081, cost time=3 ms
2024-02-04 13:17:23 [JRaft-RPC-Processor-1] INFO  NodeImpl:1231 - Node <jraft-counter/127.0.0.1:8081> become leader of group, term=3, conf=127.0.0.1:8081,127.0.0.1:8082,127.0.0.1:8083, oldConf=.

2024-02-04 13:17:23 [JRaft-RPC-Processor-1] INFO  Replicator:917 - Replicator [group: jraft-counter, peer: 127.0.0.1:8082, type: Follower] is started
2024-02-04 13:17:23 [JRaft-RPC-Processor-1] INFO  Recyclers:52 - -Djraft.recyclers.maxCapacityPerThread: 4096.
2024-02-04 13:17:23 [JRaft-FSMCaller-Disruptor-0] INFO  StateMachineAdapter:62 - onLeaderStart: term=3.

可以看到主节点维护了集群的节点列表,并接受投票,更新任期。

      
      2024-02-04 13:17:23 [JRaft-FSMCaller-Disruptor-0] INFO  StateMachineAdapter:62 - onLeaderStart: term=3.

这行日志就代表了任期已经更新。

运行客户端

客户端代码:

      
              // 初始化 gRPC
        final String groupId = "jraft-counter";
        final String confStr = "127.0.0.1:8081,127.0.0.1:8082,127.0.0.1:8083";
        CounterGrpcHelper.initGRpc();

        // 解析配置文件
        final Configuration conf = new Configuration();
        if (!conf.parse(confStr)) {
            throw new IllegalArgumentException("Fail to parse conf:" + confStr);
        }

        // 更新路由表配置
        RouteTable.getInstance().updateConfiguration(groupId, conf);

        // 初始化 CLI 客户端服务
        final CliClientServiceImpl cliClientService = new CliClientServiceImpl();
        cliClientService.init(new CliOptions());

        // 刷新 leader
        if (!RouteTable.getInstance().refreshLeader(cliClientService, groupId, 1000).isOk()) {
            throw new IllegalStateException("Refresh leader failed");
        }

        // 选择 leader
        final PeerId leader = RouteTable.getInstance().selectLeader(groupId);
        System.out.println("Leader is " + leader);

        // 执行增量操作
        final int n = 10;
        final CountDownLatch latch = new CountDownLatch(n);
        final long start = System.currentTimeMillis();
        for (int i = 0; i < n; i++) {
            incrementAndGet(cliClientService, leader, i, latch);
        }
        latch.await();
        System.out.println(n + " ops, cost : " + (System.currentTimeMillis() - start) + " ms.");
        System.exit(0);

可以看到主要做了如下几件事情:

  • 初始化 gRPC
  • 解析配置文件,更新路由表配置
  • 初始化 CLI 客户端服务
  • 刷新 leader,获取leader的节点信息
  • 选择 leader,并构造请求发送给leader节点

leader节点收到请求之后会执行操作,并记录log并同步给follower。

看一下incrementAndGet的代码逻辑

      
              // 创建一个增量请求对象
        IncrementAndGetRequest request = IncrementAndGetRequest.newBuilder().setDelta(delta).build();
        
        // 异步调用leader的endpoint,并传入请求对象和回调函数
        cliClientService.getRpcClient().invokeAsync(leader.getEndpoint(), request, new InvokeCallback() {
            
            @Override
            public void complete(Object result, Throwable err) {
                if (err == null) {
                    // 如果没有异常,减少latch的计数器,并打印结果
                    latch.countDown();
                    System.out.println("incrementAndGet result:" + result);
                } else {
                    // 如果有异常,减少latch的计数器,并打印异常信息
                    err.printStackTrace();
                    latch.countDown();
                }
            }
            
            @Override
            public Executor executor() {
                return null;
            }
        }, 5000);

客户端运行结果

发送一个循环累加10的请求到raft服务端,客户端日志:

      
      2024-02-04 13:17:45 [main] INFO  JRaftServiceLoader:275 - SPI service [com.alipay.sofa.jraft.rpc.RaftRpcFactory - com.alipay.sofa.jraft.rpc.impl.BoltRaftRpcFactory] loading.
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j2 ]
2024-02-04 13:17:45 [main] INFO  log:30 - Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j2 ]
Leader is 127.0.0.1:8081
10 ops, cost : 48 ms.
incrementAndGet result:value: 6493563
success: true

incrementAndGet result:value: 6493570
success: true

incrementAndGet result:value: 6493578
success: true

incrementAndGet result:value: 6493572
success: true

incrementAndGet result:value: 6493554
success: true

incrementAndGet result:value: 6493578
success: true

incrementAndGet result:value: 6493586
success: true

incrementAndGet result:value: 6493590
success: true

incrementAndGet result:value: 6493583
success: true

incrementAndGet result:value: 6493546
success: true

可以看到,10次请求均执行成功

服务端运行结果

      
      2024-02-04 13:17:46 [JRaft-FSMCaller-Disruptor-0] INFO  CounterStateMachine:120 - Added value=6493545 by delta=1 at logIndex=13014
2024-02-04 13:17:46 [JRaft-FSMCaller-Disruptor-0] INFO  CounterStateMachine:120 - Added value=6493546 by delta=8 at logIndex=13015
2024-02-04 13:17:46 [JRaft-FSMCaller-Disruptor-0] INFO  CounterStateMachine:120 - Added value=6493554 by delta=9 at logIndex=13016
2024-02-04 13:17:46 [JRaft-FSMCaller-Disruptor-0] INFO  CounterStateMachine:120 - Added value=6493563 by delta=7 at logIndex=13017
2024-02-04 13:17:46 [JRaft-FSMCaller-Disruptor-0] INFO  CounterStateMachine:120 - Added value=6493570 by delta=2 at logIndex=13018
2024-02-04 13:17:46 [JRaft-FSMCaller-Disruptor-0] INFO  CounterStateMachine:120 - Added value=6493572 by delta=6 at logIndex=13019
2024-02-04 13:17:46 [JRaft-FSMCaller-Disruptor-0] INFO  CounterStateMachine:120 - Added value=6493578 by delta=0 at logIndex=13020
2024-02-04 13:17:46 [JRaft-FSMCaller-Disruptor-0] INFO  CounterStateMachine:120 - Added value=6493578 by delta=5 at logIndex=13021
2024-02-04 13:17:46 [JRaft-FSMCaller-Disruptor-0] INFO  CounterStateMachine:120 - Added value=6493583 by delta=3 at logIndex=13022
2024-02-04 13:17:46 [JRaft-FSMCaller-Disruptor-0] INFO  CounterStateMachine:120 - Added value=6493586 by delta=4 at logIndex=13023

服务端执行成功

小结

  • 由于jdk1.8之后增加了模块特性,因此对于某些包需要显式配置访问权限。
  • jraft框架是一个基于Raft算法的Java框架,为构建分布式一致性系统提供了便利。通过使用jraft框架,开发者可以轻松构建高性能、可靠的分布式一致性系统。无论是构建分布式数据库还是分布式缓存,jraft都是一个值得考虑的选择。
  • 进一步的运用我们后续会继续展开讲解

希望本文对有兴趣对在高版本jdk下使用jraft的同学有所参考。

祝大家新年快乐。


浏览 22
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报