1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        JRaft高版本jdk上手踩坑實錄(新年快樂)

        共 30366字,需瀏覽 61分鐘

         ·

        2024-04-11 06:20

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

        b39d54ddf421be495c04ca654daa08c1.webp

        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)等。

        嘗試jraft

        jraft官方提供了一個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

        9b2b8e7a3f18850c3cbe4febfebf301a.webp

        編譯代碼

        筆者公司已經(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 

        95885991d5c81e17e5a61b92dccdbb19.webp

        運行服務端

        服務端直接運行會報

              
              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

        43a60f96f32fafa204af9ddbbb953725.webp

        客戶端運行過程中也會報相關的錯誤,因此在客戶端的運行參數(shù)中也需要增加如下命令:

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

        b62adce05be6ea5570908f06c9e395bf.webp

        啟動服務端

        服務端我們構建一個三階段的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的同學有所參考。

        祝大家新年快樂。


        瀏覽 55
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            工地被农民工强我好爽 | 淫色网址 | 最好看的日本字幕MV视频 | 色戒免费观看电影全集高清版 | a一级毛片直接观看 | 色网址在线 | 欧美日产国产精品 | 午夜成人精品一区二三区免费看 | 亚洲成人无码原创 | 别把冰块放进去…高h |