栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

Dubbo生产者消费者

Dubbo生产者消费者

生产者消费者在注册中心的注册

我今天了解一下dubbo的用法,虽然多,但是我只想了解注解的用法(毕竟之前都主要是注解)。

然后再dubbo-samples下面有个dubbo-samples-annotation目录。给的示例是使用zookeeper作为注册中心,要实现的就是架构图而已,主要是先了解registry,provider,和consumer的用法:

 看示例是使用zookeeper作为注册中心。所以下了一个zookeeper。

思路流程

1、首先肯定是启动zookeeper,然后看下初始有什么目录。

2、再启动provider,启动完毕后观察zookeeper多了什么东西,然后根据内容猜测含义。

3、再启动consumer,再观察zookeeper有什么变化。

刚开始的zookeeper肯定是这样的:

 然后启动org.apache.dubbo.samples.annotation.AnnotationProviderBootstrap,多了两个目录:

dubbo和service。

猜测

字面意思dubbo就存放于dubbo相关的信息,service就存放于服务相关的信息。

验证

首先看dubbo

 依次有config, mapping, metadata, org.apache.dubbo.samples.annotation.api.GreetingService, org.apache.dubbo.samples.annotation.api.HelloService。

config, mapping, metadata根据字面意思就是配置信息,映射信息和元数据信息。

后面两个应该就是暴露的服务api。

大概找了一找前三个重复度相对高一点,主要是还是对外暴露的api(猜测可能是api可以取别名之类的,默认一致),应该是用的时候需要拿值。所以前三个先不管。

还是看看后面两个。因为做事情是一致的 所以就用其中一个就行了。

这个基本应该都猜得到 configurators应该是保存配置信息的。providers就是服务提供方(微服务下可能服务有多个)。

configurators没有值。看providers。

dubbo%3A%2F%2F192.168.2.49%3A20880%2Forg.apache.dubbo.samples.annotation.api.HelloService%3Fanyhost%3Dtrue%26application%3Dsamples-annotation-provider%26deprecated%3Dfalse%26dubbo%3D2.0.2%26dynamic%3Dtrue%26generic%3Dfalse%26interface%3Dorg.apache.dubbo.samples.annotation.api.HelloService%26metadata-type%3Dremote%26methods%3DsayHello%2CsayGoodbye%26pid%3D12444%26release%3D3.0.2.1%26revision%3D1.0.0_annotation%26sayGoodbye.retries%3D0%26sayGoodbye.return%3Dtrue%26sayGoodbye.sent%3Dtrue%26sayGoodbye.timeout%3D250%26service-name-mapping%3Dtrue%26side%3Dprovider%26timeout%3D1000%26timestamp%3D1640077451474%26token%3D27c2a162-5a0e-4150-a1ad-b4806548e250%26version%3D1.0.0_annotation 

这个应该就是所谓的dubbo协议。

 比如首先出现的dubbo表示是dubbo协议,后面的ip是我网卡的地址,在后面是api调用路径等等等。

再看一下services节点

感觉像是dubbo应用名。然后我就改了一下这个重启

 所以应该是这个控制了。

 再看看节点下的东西。

就是暴露服务的ip和端口。

接下来就是consumer了。理论上应该类似:

 原本我以为/services应该会有个consumer的服务,但是没有。应该是调用就结束了,所以没有必要单独存个服务名。

主要是这个地方有变化:

看看之前的:

 多了router,consumer两个。

字面意思router就是路由的,consumer就是消费方。

不知为何没有数据,先就这样,整体很乱,我整理一张图出来试试。

应用例子

其实看了一看,也没有什么好说的。

provider:简单带过就是借助spring的容器配置好bean,然后根据配置文件配置服务提供的一些信息。扫描对应的类将接口调用注册到zookeeper中。

实际流程:

1、AnnotationProviderBootstrap:启动spring容器加载并配置ProviderConfiguration类。

2、ProviderConfiguration:通过加载dubbo-provider.properties配置属性,加载对应的接口实现类调用实际的方法。然后生产一个ProviderConfig类并对外提供api。

public class AnnotationProviderBootstrap {
    public static void main(String[] args) throws Exception {
        new EmbeddedZooKeeper(2181, false).start();
        //使用spring环境,在ProviderConfiguration类中申明并注册接口和相关配置
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ProviderConfiguration.class);
        //容器环境启动
        context.start();
        System.out.println("dubbo service started.");
        new CountDownLatch(1).await();
    }
}
@Configuration
@EnableDubbo(scanbasePackages = "org.apache.dubbo.samples.annotation.impl")
@PropertySource("classpath:/spring/dubbo-provider.properties")
public class ProviderConfiguration {
    @Bean
    public ProviderConfig providerConfig() {
        ProviderConfig providerConfig = new ProviderConfig();
        providerConfig.setTimeout(1000);
        return providerConfig;
    }
}
@DubboService(version = AnnotationConstants.VERSION, methods = {@Method(name = "sayGoodbye", timeout = 250, retries = 0)})
public class AnnotationHelloServiceImpl implements HelloService {

    @Override
    public String sayHello(String name) {
        System.out.println("provider received invoke of sayHello: " + name);
        sleepWhile();
        return "Annotation, hello " + name;
    }

    public String sayGoodbye(String name) {
        System.out.println("provider received invoke of sayGoodbye: " + name);
        sleepWhile();
        return "Goodbye, " + name;
    }

    private void sleepWhile() {
        try {
            Thread.sleep(300);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}
dubbo.application.name=samples-annotation-provider
dubbo.registry.address=zookeeper://${zookeeper.address:127.0.0.1}:2181
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
dubbo.provider.token=true

consumer:与provider类似,都是要指定一些信息和属性,但不同的是作为调用方。需要知道调用provider的哪个接口的哪个方法。

实际流程:

1、AnnotationConsumerBootstrap:启动spring容器加载并配置ConsumerConfiguration类,然后从spring容器中拿到bean,再调用对应的方法。

2、ConsumerConfiguration:通过加载dubbo-consumer.properties配置属性,加载对应的接口实现类调用实际的方法。

3、AnnotationAction:通过@DubboReference绑定接口,并配置属性(如版本、超时时间等),方便使用接口调用provider提供的方法。

public class AnnotationConsumerBootstrap {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConsumerConfiguration.class);
        context.start();
        final AnnotationAction annotationAction = (AnnotationAction) context.getBean("annotationAction");

        System.out.println("hello : " + annotationAction.doSayHello("world"));
        System.out.println("goodbye : " + annotationAction.doSayGoodbye("world"));
        System.out.println("greeting : " + annotationAction.doGreeting("world"));
        System.out.println("reply : " + annotationAction.replyGreeting("world"));
    }


}
@Configuration
@EnableDubbo(scanbasePackages = "org.apache.dubbo.samples.annotation.action")
@PropertySource("classpath:/spring/dubbo-consumer.properties")
@ComponentScan(value = {"org.apache.dubbo.samples.annotation.action"})
public class ConsumerConfiguration {

}
dubbo.application.name=samples-annotation-consumer
dubbo.registry.address=zookeeper://${zookeeper.address:127.0.0.1}:2181
@Component("annotationAction")
public class AnnotationAction {

    @DubboReference(interfaceClass = HelloService.class, version = AnnotationConstants.VERSION 
    )
    private HelloService helloService;

    @DubboReference(interfaceClass = GreetingService.class,
            version = AnnotationConstants.VERSION,
            timeout = 1000,
            methods = {@Method(name = "greeting", timeout = 3000, retries = 1)})
    private GreetingService greetingService;

    public String doSayHello(String name) {
        try {
            return helloService.sayHello(name);
        } catch (Exception e) {
            e.printStackTrace();
            return "Throw Exception";
        }
    }

    public String doSayGoodbye(String name) {
        try {
            return helloService.sayGoodbye(name);
        } catch (Exception e) {
            e.printStackTrace();
            return "Throw Exception";
        }

    }

    public String doGreeting(String name) {
        try {
            return greetingService.greeting(name);
        } catch (Exception e) {
            e.printStackTrace();
            return "Throw Exception";
        }

    }

    public String replyGreeting(String name) {
        try {
            return greetingService.replyGreeting(name);
        } catch (Exception e) {
            e.printStackTrace();
            return "Throw Exception";
        }
    }
}

总结:从上面可以看出来。要实现调用,要统一好接口。即不管是provider还是consumer,api的接口应该都一致,所以一般来说微服务的接口调用都会在父项目上写一个公共的api接口,这样就避免了接口不一致出现问题。总体过程感觉好像完全理解了调用,但是让我叙述一遍似乎又没什么好说的,可能还是没有实际运用过吧

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/677014.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号