日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

命令界面:使用Java中的动态API处理Redis

發布時間:2023/12/3 java 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 命令界面:使用Java中的动态API处理Redis 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Redis是一個數據存儲,支持190多個已記錄命令和450多個命令排列。 社區積極支持Redis開發; 每個主要的Redis版本都附帶新命令。 今年,Redis向第三方供應商開放,以開發可擴展Redis功能的模塊。 對于客戶端開發人員和Redis用戶而言,命令的增長和對即將發布的模塊的跟蹤是一項挑戰。

命令增長

對于客戶端庫,Redis中的命令增長是一項具有挑戰性的業務。 多個客戶端公開一個類型化的API,該API為每個Redis API調用聲明一個方法(函數)簽名。 靜態聲明對使用很有幫助,但是大量的Redis命令使用大量方法簽名污染了客戶端。 某些命令可能以不同的方式執行,從而影響需要附加簽名的響應類型( ZREVRANGE , ZREVRANGE … WITHSCORES )。 讓我們仔細看看一些方法簽名:

重新發行

# Get the values of all the given hash fields. # # @example # redis.hmget("hash", "f1", "f2")def hmget(key, *fields, &blk)

杰迪斯

public List<String> hmget(final String key, final String... fields)

生菜

List<V> public List<K> hmget(K key, K... fields)

聲明的方法可為開發人員提供類型安全性和文檔,但它們同時是靜態的。 Redis引入新命令后,客戶端供應商必須更改API,否則新命令將不可用。 大多數Redis客戶端公開客戶端調用API來執行自定義命令來解決此問題:

重新發行

client.call([:hmget, key] + fields)

杰迪斯

final byte[][] params = …; jedis.sendCommand(HMGET, params);

生菜

lettuce.dispatch(CommandType.HMGET, new ValueListOutput<>(codec), new CommandArgs<>(codec).addKey(key).addKey(field));

吉迪普斯

rce.accept(client -> client.sendCmd(Cmds.HMGET, "hash", "field1", "field2", …));

其他客戶端(例如node_redis基于Redis命令創建函數原型。 這是對靜態API的改進,因為它使API具有一定的靈活性。

構造Redis命令需要有關其請求和響應結構的知識。 這些知識被記錄在調用代碼內部的某個位置。 這很方便,因為您將其放在需要代碼的地方,但是它也有一些缺點。 由于自定義命令是從方法內部運行的,因此自定義命令需要額外的精力才能重用。 不需要在許多客戶端上找到的典型方法簽名。 如果不遵循API組件方法,這種方法會使自省更具挑戰性。 這是因為所有自定義命令僅使用不同的參數來調用同一方法。

具有固定參數列表的靜態方法聲明的性質僅限于接受所提供的參數。 方法調用的上下文控件不能通過該方法應用。 例如,Lettuce提供了一個同步API,該API可以控制所有命令的命令超時,但不能控制命令調用級別。

讓我們通過動態API處理Redis。

動態API

動態API是編程接口,因為它們遵循約定,因此具有一定的靈活性。 從Resteasy客戶端代理或Spring Data的查詢派生中可以知道動態API。 兩者都是生活在用戶區代碼中的接口。 Resteasy / Spring Data檢查接口并通過提供Java代理來實現這些接口。 這些接口(代理)上的方法調用將被攔截,檢查并轉換為相應的調用。 讓我們看一下這對于Java和Redis如何工作:

一個簡單的命令界面

public interface MyRedisCommands {List<String> hmget(String key, String... values);}

上面的接口聲明了一個方法: List<String > hmget(String key, String... fields) 。 我們可以從該聲明中得出某些信息:

  • 它應該同步執行-結果類型中沒有聲明異步或反應性包裝器
  • Redis命令方法返回一個String List -告訴我們有關命令結果的期望,因此我們期望使用Redis數組并將每個項目轉換為字符串
  • 該方法名為hmget 。 因為這是唯一可用的詳細信息,所以我們假設命令名為hmget 。
  • 定義了兩個參數: String key和String... values 。 這告訴我們參數的順序及其類型。 盡管Redis除了批量字符串外不接受任何其他參數類型,我們仍然可以對參數進行轉換-我們可以從聲明的類型中推斷出它們的序列化。

從上面調用的命令如下所示:

commands.hmget("key", "field1", "field2");

并轉換為Redis命令:

HMGET key field1 field2

接口上的聲明帶有兩個有趣的屬性:

  • 有一個方法簽名。 盡管這是一個顯而易見的事實,但這是一個常見的可執行文件。 它允許通過搜索此方法的引用來快速分析呼叫者。
  • 在方法簽名上方有一個空格,理想用于文檔目的。
  • 多種執行模型

    public interface MyRedisCommands {List<String> hmget(Timeout timeout, String key, String... values);RedisFuture<List<String>> mget(String... keys);Flux<String> smembers(String key);}

    動態API允許返回類型的差異。 讓我們看看這如何影響我們可以從其返回類型派生的事物。

    • 您已經知道hmget以阻塞方式執行。 但是,等等,那Timeout參數是什么? 這是一個自己的參數類型,可以在調用級別上聲明超時。 基礎執行將從參數應用超時,而不再是在連接級別設置的默認值。
    • mget聲明一個RedisFuture返回類型,該返回類型包裝String的List 。 RedisFuture是用于異步執行的包裝器類型,它返回一個句柄以在稍后階段執行同步或方法鏈接。 該方法可以異步執行。
    • smembers使用String Flux 。 基于返回類型,我們可以期待兩個屬性: Flux是一個反應式執行包裝器,它將延遲執行直到訂閱者訂閱Flux為止。 List類型消失了,因為Flux可以發出0..N項目,因此我們可以決定進行流式響應執行。

    命令結構

    public interface MyRedisCommands {List<String> mget(String... keys);@Command("MGET")RedisFuture<List<String>> mgetAsync(String... keys);@CommandNaming(strategy = DOT)double nrRun(String key, int... indexes)@Command("NR.OBSERVE ?0 ?1 -> ?2 TRAIN")List<Integer> nrObserve(String key, int[] in, int... out) }

    Java要求方法的名稱或參數類型有所不同。 字節碼級別僅支持返回類型的差異,但在代碼中編寫方法時則不支持。 如果要聲明一個同步執行的方法和一個采用相同參數異步執行的方法,該怎么辦? 您需要指定其他名稱。 但是,這是否與先前解釋的名稱派生沖突? 是的

    • 仔細看看mget和mgetAsync 。 兩種方法均旨在同步和異步執行MGET命令。 mgetAsync帶有@Command注釋,該命令為命令提供命令名稱,并覆蓋該方法否則將被命名為MGETASYNC的假設。
    • Redis對模塊開放。 每個模塊都可以通過提供新命令來擴展Redis,其中命令模式遵循<PREFIX>。<COMMAND>準則。 但是,Java方法名稱中不允許使用點。 讓我們使用@CommandNaming(strategy = DOT)將不同的命名策略應用于nrRun 。 駱駝駝峰(字母大小寫的變化)通過在各個命令段之間放置一個點來表示,我們很NR.RUN從Neural Redis運行NR.RUN 。
    • 某些命令帶有更復雜的語法,該語法不允許僅串聯參數。 看一下NR.OBSERVE 。 它由三個靜態部分組成,中間部分之間有參數。 該命令結構以類似命令的語言表示。 NR.OBSERVE ?0 ?1 -> ?2 TRAIN將命令描述為字符串,并為參數添加索引引用。 命令中的所有字符串部分都是常量,參數引用將替換為實際參數。

    結論

    將動態API應用于Redis可以將視圖轉移到新的視角。 它可以為用戶提供簡化的自定義命令方法,而不會犧牲可重用性。 方法聲明的性質為調用者的文檔記錄和自省創造了條件。

    動態API也對使用RESP的其他應用程序(例如Disque或Tile38)也有利 。

    可從Sonatype的OSS Snapshot存儲庫https://oss.sonatype.org/content/repositories/snapshots/通過生菜獲得實驗性實現:

    <dependency><groupId>biz.paluch.redis</groupId><artifactId>lettuce</artifactId><version>5.0.0-dynamic-api-SNAPSHOT</version> </dependency>

    使用RedisCommandFactory

    RedisCommandFactory factory = new RedisCommandFactory(connection);TestInterface api = factory.getCommands(TestInterface.class); String value = api.get("key");public interface TestInterface {String get(String key);@Command("GET")byte[] getAsBytes(String key); }

    參考

    • @Command :命令注釋通過使用類似命令的語言來指定命令名稱或整個命令結構。
    • @CommandNaming :用于指定命令命名策略的注釋。
    • Timeout :包含超時的值對象。
    • RedisFuture :未來結果句柄。
    • Flux : Project Reactor發布者,用于執行0..N項目的反應式執行。

    翻譯自: https://www.javacodegeeks.com/2016/10/command-interfaces-approaching-redis-dynamic-apis-java.html

    總結

    以上是生活随笔為你收集整理的命令界面:使用Java中的动态API处理Redis的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。