原文链接: 作者四月天五月雨^_^,转载请注明出处,谢谢

声明

本文参考dubbo官网:http://dubbo.apache.org/en-us/docs/user/preface/architecture.html

基础架构,理论篇可参考:dubbo使用小全 分析 理解 附GitHub 源码 ( 一 ) 其他重要功能可参考:dubbo使用小全 分析 理解 附GitHub 源码 ( 三 )

1.搭建简单工程:

在springboot大行其道的今天,本文用纯注解方式使用dubbo,注册中心可用zookeeper,redis等需要单独搭建,本文采用multicast广播方式,可用于测试,生产上建议zookeeper

1.依赖

<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.6.4</version>
        </dependency>
        <!--补充dubbo依赖的netty包-->
        <dependency>
            <groupId>com.datastax.cassandra</groupId>
            <artifactId>cassandra-driver-core</artifactId>
            <version>3.1.2</version>
        </dependency>

2.provider

2.1 服务提供方配置信息,以后的各种使用,基本都在此处

/**
 * @author peichanglei
 * @date 2018/11/02 12:16
 */
@Configuration
public class DubboProviderConfig {
    @Bean
    public ApplicationConfig applicationConfig() {
        ApplicationConfig applicationConfig = new ApplicationConfig();
        applicationConfig.setName("provider-test");
        return applicationConfig;
    }

    @Bean
    public RegistryConfig registryConfig() {
        RegistryConfig registryConfig = new RegistryConfig();
        registryConfig.setAddress("multicast://224.5.6.7:1234");
        registryConfig.setClient("curator");
        return registryConfig;
    }

    @Bean
    public ProviderConfig providerConfig() {
        ProviderConfig providerConfig = new ProviderConfig();

        /**
         * 集群容错模式,设置重试次数(不含第一次)
         */
        providerConfig.setRetries(2);
        return providerConfig;
    }
}

2.2.具体提供的服务,真实的项目中需单独打包此接口,让提供,消费双方方使用

dubbo框架转化为单体_dubbo框架转化为单体


2.3 application启动类上加暴露服务扫描

@SpringBootApplication
@DubboComponentScan(basePackages = "com.lei.record.service.impl")
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

2.4实现服务,对外暴露

import com.alibaba.dubbo.config.annotation.Service;
import com.lei.record.service.UserService;

/**
 * @author peichanglei
 * @date 2018/11/02 2:00
 */
@Service(timeout = 3000)
public class UserServiceImpl implements UserService {
    @Override
    public String getUser(Long id) {
        return "provider user " + id;
    }
}

注意:此处使用dubbo的Service注解暴露,不能是spring的

3.consumer

3.1服务提供方配置信息,以后的各种使用,基本都在此处

@Configuration
public class DubboConfiguration {
    @Bean
    public ApplicationConfig applicationConfig() {
        ApplicationConfig applicationConfig = new ApplicationConfig();
        applicationConfig.setName("consumer-test1");
        //经典错误导致:dubbo的qos默认端口为22222,区别于应用端口和dubbo服务端口,如果在一台机器上启动超过1个dubbo服务,就会冲突,不管是provider还是consumer
        applicationConfig.setQosPort(22223);
        return applicationConfig;
    }

    @Bean
    public ConsumerConfig consumerConfig() {
        ConsumerConfig consumerConfig = new ConsumerConfig();
        consumerConfig.setTimeout(3000);
        //启动时检查,默认为true,当服务不可用或多个应用存在循环依赖,需关闭检测,以防启动失败,若后面时间中,服务恢复,dubbo的心跳检查会自动连上
        consumerConfig.setCheck(false);
        return consumerConfig;
    }

    @Bean
    public RegistryConfig registryConfig() {
        RegistryConfig registryConfig = new RegistryConfig();
        registryConfig.setAddress("multicast://224.5.6.7:1234");
        registryConfig.setClient("curator");
        return registryConfig;
    }
}

3.2 引入定义好的接口jar包,不在赘述
3.3 application启动类上加引用服务包的扫描

@SpringBootApplication
@DubboComponentScan(basePackages = "com.lei.record.service")
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

3.4服务消费

@Controller
public class User {
    @Reference
    private UserService userService;

    @RequestMapping(value = "getName", method = {RequestMethod.GET}, produces = "application/json")
    @ResponseBody
    public String getName() {
        String result;
        if (userService != null) {
            String user = userService.getUser(12L);
            System.out.println("调用成功------" + user);
            result = "调用成功------" + user;
        } else {
            System.out.println("调用失败------");
            result = "调用失败------";
        }
        return result;
    }
}

import com.alibaba.dubbo.config.annotation.Reference注解可注入可使用的服务

4,至此,一个基于dubbo的生产消费架构搭建完成

页面访问显示调用成功

dubbo框架转化为单体_java_02


以上为简单调用,更多的配置信息科参考下篇.

5.遇到的问题

1.provider正常启动了,当consumer启动时,端口被占用:错误复现如下:

2018-11-02 17:09:50.253  INFO 68880 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2018-11-02 17:09:50.253  INFO 68880 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
2018-11-02 17:09:50.795 ERROR 68880 --- [           main] com.alibaba.dubbo.qos.server.Server      :  [DUBBO] qos-server can not bind localhost:22222, dubbo version: 2.6.2, current host: 192.168.244.1

java.net.BindException: Address already in use: bind
	at sun.nio.ch.Net.bind0(Native Method) ~[na:1.8.0_171]
	at sun.nio.ch.Net.bind(Net.java:433) ~[na:1.8.0_171]
	at sun.nio.ch.Net.bind(Net.java:425) ~[na:1.8.0_171]
	at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223) ~[na:1.8.0_171]
	at io.netty.channel.socket.nio.NioServerSocketChannel.doBind(NioServerSocketChannel.java:130) ~[netty-transport-4.1.29.Final.jar:4.1.29.Final]
	at io.netty.channel.AbstractChannel$AbstractUnsafe.bind(AbstractChannel.java:558) ~[netty-transport-4.1.29.Final.jar:4.1.29.Final]
	at io.netty.channel.DefaultChannelPipeline$HeadContext.bind(DefaultChannelPipeline.java:1358) ~[netty-transport-4.1.29.Final.jar:4.1.29.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeBind(AbstractChannelHandlerContext.java:501) ~[netty-transport-4.1.29.Final.jar:4.1.29.Final]
	at io.netty.channel.AbstractChannelHandlerContext.bind(AbstractChannelHandlerContext.java:486) ~[netty-transport-4.1.29.Final.jar:4.1.29.Final]
	at io.netty.channel.DefaultChannelPipeline.bind(DefaultChannelPipeline.java:1019) ~[netty-transport-4.1.29.Final.jar:4.1.29.Final]
	at io.netty.channel.AbstractChannel.bind(AbstractChannel.java:254) ~[netty-transport-4.1.29.Final.jar:4.1.29.Final]
	at io.netty.bootstrap.AbstractBootstrap$2.run(AbstractBootstrap.java:366) ~[netty-transport-4.1.29.Final.jar:4.1.29.Final]
	at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163) ~[netty-common-4.1.29.Final.jar:4.1.29.Final]
	at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404) ~[netty-common-4.1.29.Final.jar:4.1.29.Final]
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:446) ~[netty-transport-4.1.29.Final.jar:4.1.29.Final]
	at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884) ~[netty-common-4.1.29.Final.jar:4.1.29.Final]
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.29.Final.jar:4.1.29.Final]
	at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_171]

乍一看错误为端口被占,条件反射就工程的接口和dubbo服务的接口,更改后发现问题依旧,花了好一会才发现是dubbo的qos端口被占

dubbo框架转化为单体_dubbo_03


,这也是个人的思维死角,只看到了明显的现象,以为就是原因,没有继续向上翻,耗费了点时间,这里算是给自己的成长,以后再排除问题就的先仔细阅读堆栈信息,定位真实有用的信息后,再解决.

去配置中心,改掉即可

dubbo框架转化为单体_分布式_04