JRaft高版本jdk上手踩坑實錄(新年快樂)
在分布式系統(tǒng)中,保持數(shù)據(jù)的一致性是一項非常重要的任務。然而,實現(xiàn)一個高效、可靠且易于使用的一致性系統(tǒng)并不容易。幸運的是,有一些優(yōu)秀的框架和算法可以幫助我們解決這個問題。其中,螞蟻金服開源的jraft框架是其中的代表之一。

jraft是一個基于Raft一致性算法的Java框架,為構建分布式一致性系統(tǒng)提供了便利。
什么是Raft算法?在介紹jraft之前,讓我們先了解一下Raft算法。Raft是一種共識算法,用于解決分布式系統(tǒng)中的一致性問題。它類似于Paxos算法,但更易理解和實現(xiàn)。Raft算法通過選舉、日志復制和安全性機制來確保分布式系統(tǒng)中的數(shù)據(jù)一致性。它將系統(tǒng)中的節(jié)點分為領導者、跟隨者和候選者,并通過選舉機制選擇領導者,進而實現(xiàn)數(shù)據(jù)的一致性。
jraft框架概述
jraft框架是基于Raft算法實現(xiàn)的一個Java框架,旨在簡化構建分布式一致性系統(tǒng)的過程。它提供了一組核心組件和API,可以幫助開發(fā)者快速構建高性能、可靠的分布式一致性系統(tǒng)。
核心組件
jraft框架包含以下核心組件:
-
Raft協(xié)議:jraft框架實現(xiàn)了Raft算法的核心邏輯,包括領導者選舉、日志復制和安全性機制等。
-
日志模塊:jraft框架提供了日志模塊,用于管理和復制日志條目。它確保日志在整個集群中的一致性。
-
狀態(tài)機:jraft框架支持自定義狀態(tài)機,開發(fā)者可以根據(jù)自己的需求實現(xiàn)狀態(tài)機邏輯,框架會保證狀態(tài)機在集群中的一致性。
-
網(wǎng)絡通信:jraft框架使用基于TCP的網(wǎng)絡通信機制,在節(jié)點之間進行消息傳遞和數(shù)據(jù)同步。
使用jraft框架構建一個基于Raft算法的分布式一致性系統(tǒng)非常簡單。開發(fā)者只需要引入jraft框架的依賴,然后按照框架提供的API進行開發(fā)即可。開發(fā)者可以定義自己的狀態(tài)機邏輯,并通過框架提供的API與集群中的其他節(jié)點進行通信。
當前最新版本為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的優(yōu)勢和適用場景
jraft框架具有以下優(yōu)勢:
- 易于使用:jraft框架提供了簡單易用的API,開發(fā)者可以快速上手并構建分布式一致性系統(tǒng)。
- 高性能:jraft框架經(jīng)過優(yōu)化,具有出色的性能和吞吐量。
- 可靠性:jraft框架實現(xiàn)了Raft算法的核心邏輯,并提供了高可靠性的數(shù)據(jù)復制和一致性保證。
jraft框架適用于構建需要保持數(shù)據(jù)一致性的分布式系統(tǒng),例如分布式數(shù)據(jù)庫、分布式緩存和分布式文件系統(tǒng)等。
嘗試jraftjraft官方提供了一個counter計數(shù)器的復制狀態(tài)機實現(xiàn),我們就嘗試通過這個demo來對jraft的使用有一個初步的直觀認識。
項目信息
項目github地址:https://github.com/sofastack/sofa-jraft
counter項目在下圖所示位置,路徑為
jraft-example/
|-src
|-main
|-java
|-com/alipay/sofa/jraft/example/counter

編譯代碼
筆者公司已經(jīng)全面升級到jdk17,因此平時學習寫一些自己的demo的時候也傾向于使用jdk17作為運行時環(huán)境。
jraft當前只支持jdk1.8,因此使用高版本的jdk如jdk11,jdk17等在運行時就會報錯。 主要報錯內(nèi)容為:
module java.base does not "opens sun.misc" to unnamed module
這個錯誤信息是由于在Java 9及更高版本中引入的模塊化系統(tǒng)所導致的。在這個錯誤中,它表示未命名模塊(unnamed module)試圖訪問 sun.misc 模塊,但 java.base 模塊沒有對 sun.misc 模塊進行打開(opens)操作。
解決方法
解決方法就是繞過模塊化的限制,在編譯時期增加以下參數(shù):
--add-modules=jdk.unsupported

運行服務端
服務端直接運行會報
module java.base does not "opens java.lang" to unnamed module
因此需要在服務端的運行參數(shù)中增加對相關模塊的支持
--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

客戶端運行過程中也會報相關的錯誤,因此在客戶端的運行參數(shù)中也需要增加如下命令:
--add-modules=jdk.unsupported
--add-opens=java.base/java.lang=ALL-UNNAMED
--add-opens=java.base/java.lang.reflect=ALL-UNNAMED

啟動服務端
服務端我們構建一個三階段的raft集群,依次啟動。
重點設置四個參數(shù):
- dataPath:表示當前節(jié)點的數(shù)據(jù)存儲的路徑,這里為D:\jraft\example\counter\node1
- groupId:表示該raft集群的唯一標識(組名),這里為jraft-counter
- serverIdStr:表示當前節(jié)點的地址和端口號,這里為127.0.0.1:8081
- initConfStr:表示該raft集群中所有節(jié)點的地址和端口號,這里為127.0.0.1:8081,127.0.0.1:8082,127.0.0.1:8083
節(jié)點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";
節(jié)點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";
節(jié)點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";
啟動完成之后,節(jié)點日志如下:
從節(jié)點日志
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
主要就是加載了當前節(jié)點的log到內(nèi)存,加入到raft集群中,當前節(jié)點是follower
主節(jié)點日志
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.
可以看到主節(jié)點維護了集群的節(jié)點列表,并接受投票,更新任期。
2024-02-04 13:17:23 [JRaft-FSMCaller-Disruptor-0] INFO StateMachineAdapter:62 - onLeaderStart: term=3.
這行日志就代表了任期已經(jīng)更新。
運行客戶端
客戶端代碼:
// 初始化 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);
// 執(zhí)行增量操作
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的節(jié)點信息
- 選擇 leader,并構造請求發(fā)送給leader節(jié)點
leader節(jié)點收到請求之后會執(zhí)行操作,并記錄log并同步給follower。
看一下incrementAndGet的代碼邏輯
// 創(chuàng)建一個增量請求對象
IncrementAndGetRequest request = IncrementAndGetRequest.newBuilder().setDelta(delta).build();
// 異步調(diào)用leader的endpoint,并傳入請求對象和回調(diào)函數(shù)
cliClientService.getRpcClient().invokeAsync(leader.getEndpoint(), request, new InvokeCallback() {
@Override
public void complete(Object result, Throwable err) {
if (err == null) {
// 如果沒有異常,減少latch的計數(shù)器,并打印結果
latch.countDown();
System.out.println("incrementAndGet result:" + result);
} else {
// 如果有異常,減少latch的計數(shù)器,并打印異常信息
err.printStackTrace();
latch.countDown();
}
}
@Override
public Executor executor() {
return null;
}
}, 5000);
客戶端運行結果
發(fā)送一個循環(huán)累加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次請求均執(zhí)行成功
服務端運行結果
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
服務端執(zhí)行成功
小結
- 由于jdk1.8之后增加了模塊特性,因此對于某些包需要顯式配置訪問權限。
- jraft框架是一個基于Raft算法的Java框架,為構建分布式一致性系統(tǒng)提供了便利。通過使用jraft框架,開發(fā)者可以輕松構建高性能、可靠的分布式一致性系統(tǒng)。無論是構建分布式數(shù)據(jù)庫還是分布式緩存,jraft都是一個值得考慮的選擇。
- 進一步的運用我們后續(xù)會繼續(xù)展開講解
希望本文對有興趣對在高版本jdk下使用jraft的同學有所參考。
祝大家新年快樂。
