国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

dubbo泛化調(diào)用之消費(fèi)者傳遞JavaBean

這篇具有很好參考價(jià)值的文章主要介紹了dubbo泛化調(diào)用之消費(fèi)者傳遞JavaBean。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

一、泛化調(diào)用概念

泛化調(diào)用是指在調(diào)用方?jīng)]有服務(wù)方提供的 API(SDK)的情況下,對(duì)服務(wù)方進(jìn)行調(diào)用,并且可以正常拿到調(diào)用結(jié)果。

二、使用場(chǎng)景

泛化調(diào)用主要用于實(shí)現(xiàn)一個(gè)通用的遠(yuǎn)程服務(wù) Mock 框架,可通過(guò)實(shí)現(xiàn) GenericService 接口處理所有服務(wù)請(qǐng)求。比如如下場(chǎng)景:

  1. 網(wǎng)關(guān)服務(wù):如果要搭建一個(gè)網(wǎng)關(guān)服務(wù),那么服務(wù)網(wǎng)關(guān)要作為所有 RPC 服務(wù)的調(diào)用端。但是網(wǎng)關(guān)本身不應(yīng)該依賴于服務(wù)提供方的接口 API(這樣會(huì)導(dǎo)致每有一個(gè)新的服務(wù)發(fā)布,就需要修改網(wǎng)關(guān)的代碼以及重新部署),所以需要泛化調(diào)用的支持。

  2. 測(cè)試平臺(tái):如果要搭建一個(gè)可以測(cè)試 RPC 調(diào)用的平臺(tái),用戶輸入分組名、接口、方法名等信息,就可以測(cè)試對(duì)應(yīng)的 RPC 服務(wù)。那么由于同樣的原因(即會(huì)導(dǎo)致每有一個(gè)新的服務(wù)發(fā)布,就需要修改網(wǎng)關(guān)的代碼以及重新部署),所以平臺(tái)本身不應(yīng)該依賴于服務(wù)提供方的接口 API。所以需要泛化調(diào)用的支持。

三、使用方式

demo 可見(jiàn)?dubbo 項(xiàng)目中的示例代碼

API 部分以此 demo 為例講解使用方式。

1. 服務(wù)接口
public interface HelloService {

    String sayHello(String name);

    CompletableFuture<String> sayHelloAsync(String name);

    CompletableFuture<Person> sayHelloAsyncComplex(String name);

    CompletableFuture<GenericType<Person>> sayHelloAsyncGenericComplex(String name);
}
2. 服務(wù)實(shí)現(xiàn)類
public class HelloServiceImpl implements HelloService {

    @Override
    public String sayHello(String name) {
        return "sayHello: " + name;
    }

    @Override
    public CompletableFuture<String> sayHelloAsync(String name) {
        CompletableFuture<String> future = new CompletableFuture<>();
        new Thread(() -> {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            future.complete("sayHelloAsync: " + name);
        }).start();

        return future;
    }

    @Override
    public CompletableFuture<Person> sayHelloAsyncComplex(String name) {
        Person person = new Person(1, "sayHelloAsyncComplex: " + name);
        CompletableFuture<Person> future = new CompletableFuture<>();
        new Thread(() -> {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            future.complete(person);
        }).start();

        return future;
    }

    @Override
    public CompletableFuture<GenericType<Person>> sayHelloAsyncGenericComplex(String name) {
        Person person = new Person(1, "sayHelloAsyncGenericComplex: " + name);
        GenericType<Person> genericType = new GenericType<>(person);
        CompletableFuture<GenericType<Person>> future = new CompletableFuture<>();
        new Thread(() -> {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            future.complete(genericType);
        }).start();

        return future;
    }
}
3. 通過(guò)API使用泛化調(diào)用
服務(wù)啟動(dòng)方
  1. 在設(shè)置?ServiceConfig?時(shí),使用setGeneric("true")來(lái)開(kāi)啟泛化調(diào)用

  2. 在設(shè)置?ServiceConfig?時(shí),使用 setRef 指定實(shí)現(xiàn)類時(shí),要設(shè)置一個(gè)?GenericService?的對(duì)象。而不是真正的服務(wù)實(shí)現(xiàn)類對(duì)象

  3. 其他設(shè)置與正常 Api 服務(wù)啟動(dòng)一致即可

private static String zookeeperAddress = "zookeeper://" + System.getProperty("zookeeper.address", "127.0.0.1") + ":2181";

    public static void main(String[] args) throws Exception {
        new EmbeddedZooKeeper(2181, false).start();

        //創(chuàng)建ApplicationConfig
        ApplicationConfig applicationConfig = new ApplicationConfig();
        applicationConfig.setName("generic-impl-provider");
        //創(chuàng)建注冊(cè)中心配置
        RegistryConfig registryConfig = new RegistryConfig();
        registryConfig.setAddress(zookeeperAddress);
        
        //新建服務(wù)實(shí)現(xiàn)類,注意要使用GenericService接收
        GenericService helloService = new GenericImplOfHelloService();

        //創(chuàng)建服務(wù)相關(guān)配置
        ServiceConfig<GenericService> service = new ServiceConfig<>();
        service.setApplication(applicationConfig);
        service.setRegistry(registryConfig);
        service.setInterface("org.apache.dubbo.samples.generic.call.api.HelloService");
        service.setRef(helloService);
        //重點(diǎn):設(shè)置為泛化調(diào)用
        //注:不再推薦使用參數(shù)為布爾值的setGeneric函數(shù)
        //應(yīng)該使用referenceConfig.setGeneric("true")代替
        service.setGeneric("true");
        service.export();

        System.out.println("dubbo service started");
        
        new CountDownLatch(1).await();
    }
}
泛化調(diào)用方

步驟:

  1. 在設(shè)置?ReferenceConfig?時(shí),使用?setGeneric("true")?來(lái)開(kāi)啟泛化調(diào)用

  2. 配置完?ReferenceConfig?后,使用?referenceConfig.get()?獲取到?GenericService?類的實(shí)例

  3. 使用其?$invoke?方法獲取結(jié)果

  4. 其他設(shè)置與正常 Api 服務(wù)啟動(dòng)一致即可

    private static GenericService genericService;
    public static void main(String[] args) throws Exception {
        //創(chuàng)建ApplicationConfig
        ApplicationConfig applicationConfig = new ApplicationConfig();
        applicationConfig.setName("generic-call-consumer");
        //創(chuàng)建注冊(cè)中心配置
        RegistryConfig registryConfig = new RegistryConfig();
        registryConfig.setAddress("zookeeper://127.0.0.1:2181");
        //創(chuàng)建服務(wù)引用配置
        ReferenceConfig<GenericService> referenceConfig = new ReferenceConfig<>();
        //設(shè)置接口
        referenceConfig.setInterface("org.apache.dubbo.samples.generic.call.api.HelloService");
        applicationConfig.setRegistry(registryConfig);
        referenceConfig.setApplication(applicationConfig);
        //重點(diǎn):設(shè)置為泛化調(diào)用
        //注:不再推薦使用參數(shù)為布爾值的setGeneric函數(shù)
        //應(yīng)該使用referenceConfig.setGeneric("true")代替
        referenceConfig.setGeneric(true);
        //設(shè)置異步,不必須,根據(jù)業(yè)務(wù)而定。
        referenceConfig.setAsync(true);
        //設(shè)置超時(shí)時(shí)間
        referenceConfig.setTimeout(7000);
        
        //獲取服務(wù),由于是泛化調(diào)用,所以獲取的一定是GenericService類型
        genericService = referenceConfig.get();
        
        //使用GenericService類對(duì)象的$invoke方法可以代替原方法使用
        //第一個(gè)參數(shù)是需要調(diào)用的方法名
        //第二個(gè)參數(shù)是需要調(diào)用的方法的參數(shù)類型數(shù)組,為String數(shù)組,里面存入?yún)?shù)的全類名。
        //第三個(gè)參數(shù)是需要調(diào)用的方法的參數(shù)數(shù)組,為Object數(shù)組,里面存入需要的參數(shù)。
        Object result = genericService.$invoke("sayHello", new String[]{"java.lang.String"}, new Object[]{"world"});
        //使用CountDownLatch,如果使用同步調(diào)用則不需要這么做。
        CountDownLatch latch = new CountDownLatch(1);
        //獲取結(jié)果
        CompletableFuture<String> future = RpcContext.getContext().getCompletableFuture();
        future.whenComplete((value, t) -> {
            System.err.println("invokeSayHello(whenComplete): " + value);
            latch.countDown();
        });
        //打印結(jié)果
        System.err.println("invokeSayHello(return): " + result);
        latch.await();
    }

四、消費(fèi)者如何傳遞JavaBean

在Dubbo中,泛化調(diào)用可以實(shí)現(xiàn)對(duì)任何類型的服務(wù)方法的調(diào)用,包括復(fù)雜的參數(shù)類型。具體實(shí)現(xiàn)方式如下:

1.?首先需要使用泛化調(diào)用的客戶端對(duì)象(GenericService)來(lái)調(diào)用服務(wù)方法,并傳入方法名和參數(shù)列表。參數(shù)列表可以使用Object數(shù)組來(lái)表示,如下所示

GenericService genericService = referenceConfig.get();
Object[] params = new Object[]{arg1, arg2, ...};
Object result = genericService.$invoke(methodName, parameterTypes, params);

2.?對(duì)于復(fù)雜參數(shù)類型,需要先生成對(duì)應(yīng)的JavaBean類,并將參數(shù)封裝到該類中。然后將該JavaBean對(duì)象作為參數(shù)列表中的一個(gè)元素傳入泛化調(diào)用方法中,如下所示:

@Data
public class ComplexRequest implements Serializable {

    private Map<String, Object> content;

    private String key;

    private String value;

    private List<User> users;
}


@Data
public class User implements Serializable {

    private String name;

    private String age;
}

?3. 消費(fèi)者調(diào)用代碼完整如下

    @Test
    public void testDubbo() {
        ApplicationConfig applicationConfig = new ApplicationConfig();
        applicationConfig.setName("generic-call-consumer");
        //創(chuàng)建注冊(cè)中心配置
        RegistryConfig registryConfig = new RegistryConfig();
        registryConfig.setAddress("zookeeper://127.0.0.1:2181");
        //創(chuàng)建服務(wù)引用配置
        ReferenceConfig<GenericService> referenceConfig = new ReferenceConfig<>();
        //設(shè)置接口, 提供者的接口名
        referenceConfig.setInterface("com.test.api.provideFacade");
        applicationConfig.setRegistry(registryConfig);
        referenceConfig.setApplication(applicationConfig);
        //重點(diǎn):設(shè)置為泛化調(diào)用
        //注:不再推薦使用參數(shù)為布爾值的setGeneric函數(shù)
        //應(yīng)該使用referenceConfig.setGeneric("true")代替
        referenceConfig.setGeneric(true);
        //設(shè)置異步,不必須,根據(jù)業(yè)務(wù)而定。
        referenceConfig.setAsync(false);
        //設(shè)置超時(shí)時(shí)間
        referenceConfig.setTimeout(7000);
        //獲取服務(wù),由于是泛化調(diào)用,所以獲取的一定是GenericService類型
        GenericService genericService = referenceConfig.get();
        //使用GenericService類對(duì)象的$invoke方法可以代替原方法使用
        //第一個(gè)參數(shù)是需要調(diào)用的方法名
        //第二個(gè)參數(shù)是需要調(diào)用的方法的參數(shù)類型數(shù)組,為String數(shù)組,里面存入?yún)?shù)的全類名。
        //第三個(gè)參數(shù)是需要調(diào)用的方法的參數(shù)數(shù)組,為Object數(shù)組,里面存入需要的參數(shù)。
        ComplexRequest entity = new ComplexRequest();
        Map<String, Object> map = new HashMap<>();
        map.put("key", "key");
        map.put("value", "value");
        entity.setContent(map);
        entity.setKey("key");
        entity.setValue("value");

        List<User> users = new ArrayList<>();
        User user = new User();
        user.setName("name");
        user.setAge("18");
        users.add(user);
        entity.setUsers(user);

        // 構(gòu)造泛化調(diào)用參數(shù)
        //消費(fèi)者調(diào)用方的實(shí)體類
        String[] paramTypes = new String[]{"com.test.api.request.ComplexRequest"};
        Object[] params = new Object[]{entity};

        Object result = genericService.$invoke("method", paramTypes, params);
        System.out.println(result);
    }

4. 提供者代碼如下

public interface ProvideFacade {

    PlainResult<Response> method(ComplexRequest req);
}


public class testFacadeImpl implements testFacade {

    @Override
    public PlainResult<Response> method(ComplexRequest req) {}

}

5. 執(zhí)行單元測(cè)試

運(yùn)行消費(fèi)者單元測(cè)試代碼,請(qǐng)求提供者的dubbo泛化接口,進(jìn)入到提供者機(jī)器,發(fā)現(xiàn)請(qǐng)求體已經(jīng)傳遞過(guò)來(lái),當(dāng)提供者有多臺(tái)機(jī)器時(shí),請(qǐng)求會(huì)負(fù)載均衡,輪詢到不同的機(jī)器上。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-707403.html

到了這里,關(guān)于dubbo泛化調(diào)用之消費(fèi)者傳遞JavaBean的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • RabbitMQ多消費(fèi)者實(shí)例時(shí),保證只有一個(gè)消費(fèi)者進(jìn)行消費(fèi)(單活消費(fèi)者模式)

    RabbitMQ多消費(fèi)者實(shí)例時(shí),保證只有一個(gè)消費(fèi)者進(jìn)行消費(fèi)(單活消費(fèi)者模式)

    有一種業(yè)務(wù)場(chǎng)景,當(dāng)人員組織結(jié)構(gòu)變更時(shí),會(huì)有大量數(shù)據(jù)進(jìn)行推送。這些數(shù)據(jù)類型有的是add,有的是update,并且必須先add,才能進(jìn)行update。 這時(shí),為了保證消費(fèi)順序,需要 只有一個(gè)實(shí)例進(jìn)行按順序消費(fèi),其他實(shí)例僅提供日常對(duì)外服務(wù) ,不進(jìn)行消息消費(fèi)。當(dāng)唯一消費(fèi)實(shí)例無(wú)法

    2024年02月11日
    瀏覽(23)
  • Kafka3.0.0版本——消費(fèi)者(消費(fèi)者組詳細(xì)消費(fèi)流程圖解及消費(fèi)者重要參數(shù))

    Kafka3.0.0版本——消費(fèi)者(消費(fèi)者組詳細(xì)消費(fèi)流程圖解及消費(fèi)者重要參數(shù))

    創(chuàng)建一個(gè)消費(fèi)者網(wǎng)絡(luò)連接客戶端,主要用于與kafka集群進(jìn)行交互,如下圖所示: 調(diào)用sendFetches發(fā)送消費(fèi)請(qǐng)求,如下圖所示: (1)、Fetch.min.bytes每批次最小抓取大小,默認(rèn)1字節(jié) (2)、fetch.max.wait.ms一批數(shù)據(jù)最小值未達(dá)到的超時(shí)時(shí)間,默認(rèn)500ms (3)、Fetch.max.bytes每批次最大抓取大小,默

    2024年02月09日
    瀏覽(21)
  • 10、Kafka ------ 消費(fèi)者組 和 消費(fèi)者實(shí)例,分區(qū) 和 消費(fèi)者實(shí)例 之間的分配策略

    10、Kafka ------ 消費(fèi)者組 和 消費(fèi)者實(shí)例,分區(qū) 和 消費(fèi)者實(shí)例 之間的分配策略

    形象來(lái)說(shuō):你可以把主題內(nèi)的多個(gè)分區(qū)當(dāng)成多個(gè)子任務(wù)、多個(gè)子任務(wù)組成項(xiàng)目,每個(gè)消費(fèi)者實(shí)例就相當(dāng)于一個(gè)員工,假如你們 team 包含2個(gè)員工。 同理: 同一主題下,每個(gè)分區(qū)最多只會(huì)分給同一個(gè)組內(nèi)的一個(gè)消費(fèi)者實(shí)例 消費(fèi)者以組的名義來(lái)訂閱主題,前面的 kafka-console-consu

    2024年01月19日
    瀏覽(19)
  • 13、Kafka ------ kafka 消費(fèi)者API用法(消費(fèi)者消費(fèi)消息代碼演示)

    13、Kafka ------ kafka 消費(fèi)者API用法(消費(fèi)者消費(fèi)消息代碼演示)

    消費(fèi)者API的核心類是 KafkaConsumer,它提供了如下常用方法: 下面這些方法都體現(xiàn)了Kafka是一個(gè)數(shù)據(jù)流平臺(tái),消費(fèi)者通過(guò)這些方法可以從分區(qū)的任意位置、重新開(kāi)始讀取數(shù)據(jù)。 根據(jù)KafkaConsumer不難看出,使用消費(fèi)者API拉取消息很簡(jiǎn)單,基本只要幾步: 1、創(chuàng)建KafkaConsumer對(duì)象,創(chuàng)建

    2024年04月11日
    瀏覽(30)
  • Kafka3.0.0版本——消費(fèi)者(消費(fèi)者組原理)

    Kafka3.0.0版本——消費(fèi)者(消費(fèi)者組原理)

    1.1、消費(fèi)者組概述 Consumer Group(CG):消費(fèi)者組,由多個(gè)consumer組成。形成一個(gè)消費(fèi)者組的條件,是所有消費(fèi)者的groupid相同。 注意: (1)、消費(fèi)者組內(nèi)每個(gè)消費(fèi)者負(fù)責(zé)消費(fèi)不同分區(qū)的數(shù)據(jù),一個(gè)分區(qū)只能由一個(gè)組內(nèi)消費(fèi)者消費(fèi)。 (2)、消費(fèi)者組之間互不影響。所有的消費(fèi)者

    2024年02月09日
    瀏覽(28)
  • kafka復(fù)習(xí):(22)一個(gè)分區(qū)只能被消費(fèi)者組中的一個(gè)消費(fèi)者消費(fèi)嗎?

    kafka復(fù)習(xí):(22)一個(gè)分區(qū)只能被消費(fèi)者組中的一個(gè)消費(fèi)者消費(fèi)嗎?

    默認(rèn)情況下,一個(gè)分區(qū)只能被消費(fèi)者組中的一個(gè)消費(fèi)者消費(fèi)。但可以自定義PartitionAssignor來(lái)打破這個(gè)限制。 一、自定義PartitionAssignor. 二、定義兩個(gè)消費(fèi)者,給其配置上述PartitionAssignor. 在kafka創(chuàng)建只有一個(gè)分區(qū)的topic : study2023 創(chuàng)建一個(gè)生產(chǎn)者往study2023這個(gè) topic發(fā)送消息: 分別

    2024年02月10日
    瀏覽(25)
  • 分布式 - 消息隊(duì)列Kafka:Kafka消費(fèi)者和消費(fèi)者組

    分布式 - 消息隊(duì)列Kafka:Kafka消費(fèi)者和消費(fèi)者組

    1. Kafka 消費(fèi)者是什么? 消費(fèi)者負(fù)責(zé)訂閱Kafka中的主題,并且從訂閱的主題上拉取消息。與其他一些消息中間件不同的是:在Kafka的消費(fèi)理念中還有一層消費(fèi)組的概念,每個(gè)消費(fèi)者都有一個(gè)對(duì)應(yīng)的消費(fèi)組。當(dāng)消息發(fā)布到主題后,只會(huì)被投遞給訂閱它的每個(gè)消費(fèi)組中的一個(gè)消費(fèi)者

    2024年02月13日
    瀏覽(29)
  • 【Kafka】【十七】消費(fèi)者poll消息的細(xì)節(jié)與消費(fèi)者心跳配置

    默認(rèn)情況下,消費(fèi)者?次會(huì)poll500條消息。 代碼中設(shè)置了?輪詢的時(shí)間是1000毫秒 意味著: 如果?次poll到500條,就直接執(zhí)?for循環(huán) 如果這?次沒(méi)有poll到500條。且時(shí)間在1秒內(nèi),那么?輪詢繼續(xù)poll,要么到500條,要么到1s 如果多次poll都沒(méi)達(dá)到500條,且1秒時(shí)間到了,那么直接執(zhí)

    2024年02月09日
    瀏覽(30)
  • kafka配置多個(gè)消費(fèi)者groupid kafka多個(gè)消費(fèi)者消費(fèi)同一個(gè)partition(java)

    kafka配置多個(gè)消費(fèi)者groupid kafka多個(gè)消費(fèi)者消費(fèi)同一個(gè)partition(java)

    kafka是由Apache軟件基金會(huì)開(kāi)發(fā)的一個(gè)開(kāi)源流處理平臺(tái)。kafka是一種高吞吐量的分布式發(fā)布訂閱消息系統(tǒng),它可以處理消費(fèi)者在網(wǎng)站中的所有動(dòng)作流數(shù)據(jù)。 kafka中partition類似數(shù)據(jù)庫(kù)中的分表數(shù)據(jù),可以起到水平擴(kuò)展數(shù)據(jù)的目的,比如有a,b,c,d,e,f 6個(gè)數(shù)據(jù),某個(gè)topic有兩個(gè)partition,一

    2024年01月22日
    瀏覽(161)
  • Kafka3.0.0版本——消費(fèi)者(消費(fèi)者總體工作流程圖解)

    Kafka3.0.0版本——消費(fèi)者(消費(fèi)者總體工作流程圖解)

    角色劃分:生產(chǎn)者、zookeeper、kafka集群、消費(fèi)者、消費(fèi)者組。如下圖所示: 生產(chǎn)者發(fā)送消息給leader,followerr主動(dòng)從leader同步數(shù)據(jù),一個(gè)消費(fèi)者可以消費(fèi)某一個(gè)分區(qū)數(shù)據(jù)或者一個(gè)消費(fèi)者可以消費(fèi)多個(gè)分區(qū)數(shù)據(jù)。如下圖所示: 每個(gè)分區(qū)的數(shù)據(jù)只能由消費(fèi)者組中一個(gè)消費(fèi)者消費(fèi)。如下

    2024年02月09日
    瀏覽(37)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包