• Dubbo-入门到精通(一)


    为了个人的技术提升,所以今天开始自学dubbo(当然,肯定要参考官方文档和其他各位大神的文章,,标题中的入门到精通,现在才是入门的开始),以此来记录遇到的问题和大家分享,在这里我参考了(https://segmentfault.com/a/1190000019896723)他的文章,在他的文章里讲了几种开发方式,xml, api和基于注解。既然如今 springboot 盛行,大家都倾向于 java config的方式,所以我这里只写一下 java config方式的启动。

    一、首先引入maven(可能导致 log4j 冲突,所以我把它给移除了),这里引用了 dubbo git上的推荐 (dubbo 官方地址:http://dubbo.apache.org/en-us/ ,dubbo git地址:https://github.com/apache/dubbo)。 

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.yqn.herman</groupId>
        <artifactId>study.dubbo</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <properties>
            <dubbo.version>2.7.5</dubbo.version>
            <java.compiler.version>1.8</java.compiler.version>
        </properties>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.4.RELEASE</version>
        </parent>
    
        <dependencies>
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo</artifactId>
                <version>${dubbo.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-dependencies-zookeeper</artifactId>
                <exclusions>
                    <exclusion>
                        <artifactId>slf4j-log4j12</artifactId>
                        <groupId>org.slf4j</groupId>
                    </exclusion>
                </exclusions>
                <version>${dubbo.version}</version>
                <type>pom</type>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </dependency>
        </dependencies>
    
    </project>
    View Code

    二、本地搭一套 zookeeper 环境

    从步骤一中的引入我们可以知道,dubbo是需要zk共同协作的,至于为什么需要zk,这里依然引用 dubbo git的图,从图中可以看到dubbo需要有一个东西作为服务注册和发现的中间件,作用和 spring cloud里的 Eureka等同,那么dubbo优先选择的就是zk。

    由于我是在windows写项目,因此如果是windonws的同学,可以直接去 zk 官网下载(https://www.apache.org/dyn/closer.cgi/zookeeper/ ,注意,windows一定要下载 bin.tar.gz 结尾的镜像文件,然后参考 https://www.cnblogs.com/xiohao/p/9717364.html 启动

    一个单机节点就可以使用了)

    三、编写服务,这里我们简单的进行示例,接收服务调用方的参数并打印,然后返回服务调用方(注意,代码里边有些包名是我自己的,需要你根据你自己的项目改写):

      定义一个接口:

    public interface ServiceProvider {
        String getMyName(String name);
    }

      实现接口,这里接口的实现需要加入 @Service 注解(注意,这个注解不要引 spring的,而是需要引 dubbo的):

    @Service
    public class ServiceProviderImpl implements ServiceProvider {
        
        @Override
        public String getMyName(String name) {
            System.out.println("接收到服务调用者的名字:" + name);
            return "hello, " + name;
        }
    }

      java config形式注入dubbo启动需要的环境(此处有一个大坑,在设置 RegistryConfig 的时候我也写在了注释里边,就是虽然在代码里设置了port,但是没有生效,导致我一致连不上zk, 原因是 dubbo在启动过程中会检测你是否有自定义的 RegistryConfig,从而

           帮你把这个类给转化成 ConfigCenterConfig, 但是在转化的过程中,只赋值了 protocol, address等,port却被拿去用来 设置id了,参考类 DubboBootstrap.useRegistryAsConfigCenterIfNecessary()):

    package com.yqn.herman.demo;
    
    import org.apache.dubbo.config.ApplicationConfig;
    import org.apache.dubbo.config.ProtocolConfig;
    import org.apache.dubbo.config.ProviderConfig;
    import org.apache.dubbo.config.RegistryConfig;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * @author Lu, Hui
     * @since 2020/1/11
     **/
    @Configuration
    public class ServiceCustomerConfig {
        @Bean // #1 服务提供者信息配置,这里我们直接采用默认的
        public ProviderConfig providerConfig() {
            ProviderConfig providerConfig = new ProviderConfig();
            providerConfig.setTimeout(1000);
            return providerConfig;
        }
    
        @Bean // #2 分布式应用信息配置
        public ApplicationConfig applicationConfig() {
            ApplicationConfig applicationConfig = new ApplicationConfig();
            applicationConfig.setName("dubbo-annotation-provider"); //设置服务的名字,分布式环境下必须保证唯一性,和spring cloud下的 application name一样
            return applicationConfig;
        }
    
        @Bean // #3 注册中心信息配置
        public RegistryConfig registryConfig() {
            RegistryConfig registryConfig = new RegistryConfig();
            registryConfig.setProtocol("zookeeper");
            registryConfig.setAddress("localhost:2181"); // zk server 地址,一定要在这里把port加上
            //registryConfig.setPort(2181); // zk client 监听端口, 设置了也没有任何效果
            return registryConfig;
        }
    
        @Bean // #4 使用协议配置,这里使用 dubbo
        public ProtocolConfig protocolConfig() {
            ProtocolConfig protocolConfig = new ProtocolConfig();
            protocolConfig.setName("dubbo");
            protocolConfig.setPort(20880);
            return protocolConfig;
        }
    }
    View Code

    启动并发布我们的服务(注意,这个时候需要我们先启动 zk, 不然会报错,我的zk是下载下来后的默认端口):

    package com.yqn.herman.demo;
    
    
    import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    
    import java.util.concurrent.CountDownLatch;
    
    /**
     * @author Lu, Hui
     * @since 2020/1/11
     **/
    @SpringBootApplication
    @EnableDubbo(scanBasePackages = "com.yqn.herman.demo") //参考其注释可以知道,这里是所有 @Service 注解标注的服务的包,也就是我们要对外发布的所有服务
    public class ServiceStarter {
    
        public static void main(String[] args) throws Exception {
            SpringApplication.run(ServiceStarter.class);
            new CountDownLatch(1).await(); //
        }
    
    }
    View Code

    到这里基本没有意外了,启动成功:

    接下来,我们需要写服务消费者了:

    首先定义我们的消费者:

    package com.yqn.herman.demo.com.yqn.herman.client;
    
    import com.yqn.herman.demo.provider.ServiceProvider;
    import org.apache.dubbo.config.annotation.Reference;
    import org.springframework.stereotype.Component;
    
    /**
     * @author Lu, Hui
     * @since 2020/1/11
     **/
    @Component // 在这里,我的消费者和服务提供者在同一个项目,所以我直接引用了,如果你分开写了,需要在你的客户端引入服务者的jar包
    public class ServiceConsumer {
    
        @Reference //该注解类似于 spring cloud 的 feign, 通过对这个注解的处理来找到需要的服务
        private ServiceProvider serviceProvider;
    
        public void call(String name) {
            serviceProvider.getMyName(name);
        }
    }
    View Code

    接着,和服务端一样,我们需要配置dubbo客户端的环境:

    package com.yqn.herman.demo.com.yqn.herman.client;
    
    import org.apache.dubbo.config.ApplicationConfig;
    import org.apache.dubbo.config.ConsumerConfig;
    import org.apache.dubbo.config.RegistryConfig;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * @author Lu, Hui
     * @since 2020/1/11
     **/
    @Configuration
    public class ClientConfig {
        @Bean // 应用配置
        public ApplicationConfig applicationConfig() {
            ApplicationConfig applicationConfig = new ApplicationConfig();
            applicationConfig.setName("dubbo-annotation-consumer");
            Map<String, String> stringStringMap = new HashMap<String, String>();
            stringStringMap.put("qos.enable","true");
            stringStringMap.put("qos.accept.foreign.ip","false");
            stringStringMap.put("qos.port","33333");
            applicationConfig.setParameters(stringStringMap);
            return applicationConfig;
        }
    
        @Bean // 服务消费者配置
        public ConsumerConfig consumerConfig() {
            ConsumerConfig consumerConfig = new ConsumerConfig();
            consumerConfig.setTimeout(3000);
            return consumerConfig;
        }
    
        @Bean // 配置注册中心
        public RegistryConfig registryConfig() {
            RegistryConfig registryConfig = new RegistryConfig();
            registryConfig.setProtocol("zookeeper");
            registryConfig.setAddress("localhost:2181");
            return registryConfig;
        }
    }
    View Code

    最后,启动客户端,调用一次服务:

    package com.yqn.herman.demo.com.yqn.herman.client;
    
    import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    /**
     * @author Lu, Hui
     * @since 2020/1/11
     **/
    @SpringBootApplication
    @EnableDubbo(scanBasePackages = "com.yqn.herman.demo.com.yqn.herman.client") //需要服务注入的包,也就是consumer在的包
    public class ClientStarter implements CommandLineRunner {
    
        private ServiceConsumer serviceConsumer;
    
        public static void main(String[] args) {
            SpringApplication.run(ClientStarter.class);
        }
    
        public ClientStarter(ServiceConsumer serviceConsumer) {
            this.serviceConsumer = serviceConsumer;
        }
    
        @Override //这里我实现了 CommandLineRunner 接口,用于在程序启动结束执行一次该方法
        public void run(String... args) throws Exception {
            serviceConsumer.call("小甜甜");
        }
    }
    View Code

    可以看到,服务端接收到了请求:

    到这里,我们就算是入门了,可以自己写一个 Hello Word 级别的dubbo例子了。如果有任何问题,写在评论区,我们一起讨论。

  • 相关阅读:
    SpringCloud之初入江湖
    消息中间件RabbitMQ
    分布式搜索引擎ElasticSearch
    MongoDB简介
    SpringBoot和SpringCloud版本对应
    终于有人把Elasticsearch原理讲透了!
    nginx不停服,重新加载配置
    小程序自定义头部标题栏并且自适应各种手机屏幕(滚动头部渐隐渐现)
    Navicat链接数据库报错1130解决方案
    传统的小程序登录 和 云开发小程序登录
  • 原文地址:https://www.cnblogs.com/hermanlife/p/12180344.html
Copyright © 2020-2023  润新知