redis 分佈式鎖幫上忙了?

需求:CS 架構的客戶端批量打印功能要做到控制單個客戶端操作,不可多客戶端同時操作批量打印,因爲批量打印調的後臺接口流水碼生成是續流的,任何一個Client調用都續流,多客戶端同時調用批量打印,一次批量打印出的流水碼就可能跳碼。接口服務是分佈式的,如果單服務接口,可以用同步鎖來實現。

思路:利用 redis 緩存標識是否有 Client 正在使用批量打印功能,操作批量打印功能時都查詢(查詢服務接口分佈式的)一次這個緩存標識,沒 Client 操作中就可操作批量打印功能,同時標識有客戶端正在操作中,不讓別的客戶端操作,批量打印操作完成之後釋放操作權限(批量打印異常也要釋放),標識沒有客戶端正在操作。

每個Client 操作批量打印功能前查詢這個標識時利用分佈式鎖技術,可參考博文1 和 博文2,誰先操作誰先搶到查詢標識的權限,按查詢標識結果提示是否等待一段時間再操作批量打印。

 

這個思路設計待測試,理論上應該是行得通的。

 

猿友們若有好的思路建議,歡迎留言。

 

測試結果出來了:

2020-04-04 14:13:58 Thread[客戶端窗口10,5,main]有客戶端正在批量打印中,請稍後再試!
2020-04-04 14:13:58 Thread[客戶端窗口18,5,main] 批量打印中
2020-04-04 14:13:58 Thread[客戶端窗口2,5,main]有客戶端正在批量打印中,請稍後再試!
2020-04-04 14:13:58 Thread[客戶端窗口13,5,main]有客戶端正在批量打印中,請稍後再試!
2020-04-04 14:13:58 Thread[客戶端窗口11,5,main]有客戶端正在批量打印中,請稍後再試!
2020-04-04 14:13:58 Thread[客戶端窗口5,5,main]有客戶端正在批量打印中,請稍後再試!
2020-04-04 14:13:58 Thread[客戶端窗口3,5,main]有客戶端正在批量打印中,請稍後再試!
2020-04-04 14:13:58 Thread[客戶端窗口15,5,main]有客戶端正在批量打印中,請稍後再試!
2020-04-04 14:13:58 Thread[客戶端窗口18,5,main] 批量打印完成
2020-04-04 14:13:59 Thread[客戶端窗口17,5,main] 批量打印中
2020-04-04 14:13:59 Thread[客戶端窗口19,5,main]有客戶端正在批量打印中,請稍後再試!
2020-04-04 14:13:59 Thread[客戶端窗口14,5,main]有客戶端正在批量打印中,請稍後再試!
2020-04-04 14:13:59 Thread[客戶端窗口7,5,main]有客戶端正在批量打印中,請稍後再試!
2020-04-04 14:13:59 Thread[客戶端窗口9,5,main]有客戶端正在批量打印中,請稍後再試!
2020-04-04 14:13:59 Thread[客戶端窗口12,5,main]有客戶端正在批量打印中,請稍後再試!
2020-04-04 14:13:59 Thread[客戶端窗口16,5,main]有客戶端正在批量打印中,請稍後再試!
2020-04-04 14:13:59 Thread[客戶端窗口17,5,main] 批量打印完成
2020-04-04 14:14:00 Thread[客戶端窗口6,5,main] 批量打印中
2020-04-04 14:14:00 Thread[客戶端窗口20,5,main]有客戶端正在批量打印中,請稍後再試!
2020-04-04 14:14:00 Thread[客戶端窗口6,5,main] 批量打印完成
2020-04-04 14:14:01 Thread[客戶端窗口8,5,main] 批量打印中
2020-04-04 14:14:01 Thread[客戶端窗口4,5,main]有客戶端正在批量打印中,請稍後再試!
2020-04-04 14:14:01 Thread[客戶端窗口8,5,main] 批量打印完成
2020-04-04 14:14:02 Thread[客戶端窗口1,5,main] 批量打印中
2020-04-04 14:14:02 Thread[客戶端窗口1,5,main] 批量打印完成

 


import jodd.datetime.JDateTime;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;

public class MyThreed implements Runnable {

    private final String URL = "http://……/get-batchlabelflag";

    @Override
    public void run() {

        try {
            HttpClient   httpClient = HttpClientBuilder.create().build();
            HttpGet      httpGet    = new HttpGet(URL);
            HttpResponse resultRep  = httpClient.execute(httpGet);
            String       msg        = EntityUtils.toString(resultRep.getEntity());
            if ("true".equals(msg)) {
                JDateTime jdt = new JDateTime();
                System.out.println(jdt.toString("YYYY-MM-DD hh:mm:ss")+" "+Thread.currentThread().toString().replaceFirst(",5,main","") +" 有客戶端正在批量打印中,請稍後再試!");
            } else {
                // 有權限執行批量打印功能
                // 模擬批量打印時間
                JDateTime jdt = new JDateTime();
                System.out.println(jdt.toString("YYYY-MM-DD hh:mm:ss") +" "+Thread.currentThread().toString().replaceFirst(",5,main","") + " 批量打印中");
                Thread.sleep(3000);
                HttpPut put = new HttpPut(URL);
                httpClient.execute(put);
                jdt = new JDateTime();
                System.out.println(jdt.toString("YYYY-MM-DD hh:mm:ss") +" "+Thread.currentThread().toString().replaceFirst(",5,main","") + " 批量打印完成");

            }
        } catch (Exception e) {
        }

    }
}

 



public class ThreedTest {
    public static void main(String[] args) {
        //得到對象
        MyThreed mtd = new MyThreed();
        //把對象放入線程中
        Thread t1  = new Thread(mtd, "客戶端01");
        Thread t2  = new Thread(mtd, "客戶端02");
        Thread t3  = new Thread(mtd, "客戶端03");
        Thread t4  = new Thread(mtd, "客戶端04");
        Thread t5  = new Thread(mtd, "客戶端05");
        Thread t6  = new Thread(mtd, "客戶端06");
        Thread t7  = new Thread(mtd, "客戶端07");
        Thread t8  = new Thread(mtd, "客戶端08");
        Thread t9  = new Thread(mtd, "客戶端09");
        Thread t10 = new Thread(mtd, "客戶端10");
        Thread t11 = new Thread(mtd, "客戶端11");
        Thread t12 = new Thread(mtd, "客戶端12");
        Thread t13 = new Thread(mtd, "客戶端13");
        Thread t14 = new Thread(mtd, "客戶端14");
        Thread t15 = new Thread(mtd, "客戶端15");
        Thread t16 = new Thread(mtd, "客戶端16");
        Thread t17 = new Thread(mtd, "客戶端17");
        Thread t18 = new Thread(mtd, "客戶端18");
        Thread t19 = new Thread(mtd, "客戶端19");
        Thread t20 = new Thread(mtd, "客戶端20");

        t1.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();
        t6.start();
        t7.start();
        t8.start();
        t9.start();
        t10.start();
        t11.start();
        t12.start();
        t13.start();
        t14.start();
        t15.start();
        t16.start();
        t17.start();
        t18.start();
        t19.start();
        t20.start();
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章