欢迎访问我的GitHub
github.com/zq2599/blog_demos
内容:所有原创文章分类汇总及配套源码,涉及Java、Docker、Kubernetes、DevOPS等;
关于dubbo
- Apache Dubbo (发音ˈdʌbəʊ) 是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现;
- 以下是来自官方的架构图:
版本简介和选定
- 截止写此文时,Dubbo 社区主力维护的有 2.6.x 和 2.7.x 两大版本;
- 2.6.x 主要以 bugfix 和少量 enhancements 为主,因此能完全保证稳定性;
- 2.7.x 作为社区的主要开发版本,得到持续更新并增加了大量新 feature 和优化,同时也带来了一些稳定性挑战;
- 综上所述,《dubbo实战》系列选择了社区推荐的2.7.6版本,这是2.7系列的稳定版;
环境信息
我这边用来编码的环境如下:
- 操作系统:macOS Catalina 10.15.5
- JDK:1.8.0_121
- Maven:33.3.9
- 开发工具:IntelliJ IDEA 2019.3.2 (Ultimate Edition)
注意事项
如果您是在windows环境运行代码,并且安装了VMWare,请您关闭对应的虚拟网卡,否则在广播模式(Multicast)时,consumer可能无法找到自己所需的服务;
本篇概览
- 作为《dubbo实战》系列的开篇,本文的主要内容如下:
- 创建整个《dubbo实战》系列的父工程;
- 创建整个《dubbo实战》系列的公共二方库;
- 初步体验dubbo框架,为了简单,本篇的实战暂不使用注册中心,而是服务提供方启动时广播自己的地址,再由消费方启动时订阅,并随时远程调用,调用逻辑如下图所示:
4. 先创建一个提供远程服务的子工程,名为helloxmldirectprovider,并运行起来;
5. 再创建名为helloxmldirectconsumer的子工程,运行起来后,会调用helloxmldirectprovider提供的远程服务,将远端返回的内容打印出来;
- 接下来开始编码
源码下载
- 如果您不想编码,可以在GitHub下载所有源码,地址和链接信息如下表所示:
名称 | 链接 | 备注 |
---|---|---|
项目主页 | github.com/zq2599/blog_demos | 该项目在GitHub上的主页 |
git仓库地址(https) | github.com/zq2599/blog_demos.git | 该项目源码的仓库地址,https协议 |
git仓库地址(ssh) | git@github.com:zq2599/blog_demos.git | 该项目源码的仓库地址,ssh协议 |
- 这个git项目中有多个文件夹,本章的应用在dubbopractice文件夹下,如下图红框所示:
3. dubbopractice是父子结构的工程,本篇的代码在helloxmldirectprovider和helloxmldirectconsumer这两个子工程中,如下图:
《dubbo实战》系列的父工程
- 为了方便管理《dubbo实战》系列的代码和依赖库版本的管理,这里创建名为dubbopractice的父maven工程,整个系列的后续源码都会作为它的子工程;
- dubbopractice的pom.xml内容如下:
<?xml version="1.0" encoding="UTF-8"?>
practiceinterfacehelloxmldirectproviderhelloxmldirectconsumerspringbootzkproviderspringbootzkconsumerspringbootmulticastproviderspringbootmulticastconsumerUTF-81.81.81.82.7.62.3.3.RELEASE4.0.0com.bolingcavalrydubbopractice1.0-SNAPSHOTpomorg.apache.dubbodubbo-dependencies-bom${dubbo.version}pomimportio.nettynetty-all4.1.25.Finalorg.apache.dubbodubbo${dubbo.version}org.apache.dubbodubbo-dependencies-zookeeper${dubbo.version}pomorg.apache.dubbodubbo-spring-boot-starter${dubbo.version}org.apache.dubbodubbo-registry-multicast${dubbo.version}org.apache.zookeeperzookeeper3.4.7com.github.sgroschupfzkclient0.1org.projectlomboklombok1.16.16com.fasterxml.jackson.corejackson-databind2.11.0compilecom.fasterxml.jackson.datatypejackson-datatype-jdk82.11.0compileorg.slf4jslf4j-log4j121.7.25compilecommons-iocommons-io2.7compileorg.apache.commonscommons-lang33.10compileio.springfoxspringfox-swagger22.5.0io.springfoxspringfox-swagger-ui2.5.0
《dubbo实战》系列的二方库
- 涉及到多个工程之间的服务调用,因此要有个工程保存公用的数据结构、接口定义等,因此新建名为practiceinterface的子工程;
- practiceinterface工程的pom.xml内容如下,非常简单:
<?xml version="1.0" encoding="UTF-8"?>
dubbopracticecom.bolingcavalry1.0-SNAPSHOT../pom.xml4.0.0com.bolingcavalrypracticeinterface1.0-SNAPSHOTpracticeinterfaceBeans of all app
- 此工程目前只有一个接口定义,后面多个子工程都会用到:
package com.bolingcavalry.dubbopractice.service;
public interface DemoService {
String sayHello(String name);
}
编码(服务提供方)
- 先创建提供服务的工程helloxmldirectprovider,一共要创建6个文件,创建顺序和功能如下表:
创建顺序 | 文件名 | 作用 |
---|---|---|
1 | pom.xml | 工程的pom文件 |
2 | src/main/java/com/bolingcavalry/helloxmldirectprovider/ProviderApplication.java | 启动类 |
3 | src/main/java/com/bolingcavalry/helloxmldirectprovider/service/impl/DemoServiceImpl.java | 提供具体的服务 |
4 | src/main/resources/log4j.properties | 日志配置文件 |
5 | src/main/resources/dubbo.properties | dubbo配置文件 |
6 | src/main/resources/spring/dubbo-provider.xml | spring的bean配置 |
- 完整的文件位置如下图:
- 接下来逐个创建上述内容;
- 创建名为helloxmldirectprovider的子工程,pom.xml内容如下,可见刚才新建的二方库practiceinterface也被依赖了:
<?xml version="1.0" encoding="UTF-8"?>
dubbopracticecom.bolingcavalry1.0-SNAPSHOT4.0.0com.bolingcavalryhelloxmldirectprovider1.0-SNAPSHOTcom.bolingcavalrypracticeinterface${project.version}org.apache.dubbodubboorg.projectlomboklombokorg.slf4jslf4j-log4j12
- 编写启动类ProviderApplication.java,可见就是个普通的后台程序,加载spring配置做初始化:
package com.bolingcavalry.helloxmldirectprovider;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ProviderApplication {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/dubbo-provider.xml");
context.start();
System.in.read();
}
}
- 编写提供具体服务的业务实现类DemoServiceImpl.java,只是个简单的接口实现类而已:
package com.bolingcavalry.helloxmldirectprovider.service.impl;
import com.bolingcavalry.dubbopractice.service.DemoService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.rpc.RpcContext;
@Slf4j
public class DemoServiceImpl implements DemoService {
@Override
public String sayHello(String name) {
log.info("Hello " + name + ", request from consumer: " + RpcContext.getContext().getRemoteAddress());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Hello " + name + ", response from provider: " + RpcContext.getContext().getLocalAddress();
}
}
- 日志配置文件log4j.properties,内容如下:
###set log levels###
log4j.rootLogger=info, stdout
###output to the console###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%d{dd/MM/yy HH:mm:ss:SSS z}] %t %5p %c{2}: %m%n
- 在同样位置创建dubbo配置文件dubbo.properties,内容很简单只有qos的端口设置,用于支持telnet命令:
dubbo.application.qos.port=22222
- 在resources目录下新建文件夹spring,在此文件夹下创建文件dubbo-provider.xml,要重点关注的是dubbo:registry的配置,其address属性值为multicast://224.5.6.7:1234,代表当前服务通过广播让消费者获得自身信息:
<?xml version="1.0" encoding="UTF-8"?>
- 至此,服务提供方编码完成,直接在IDEA上运行ProviderApplication类即可启动服务,启动成功后的日志输出如下图:
编码(服务消费方)
- 现在网络上已经有了服务,接下来创建一个消费该服务的工程helloxmldirectconsumer,一共要创建5个文件,创建顺序和功能如下表:
创建顺序 | 文件名 | 作用 |
---|---|---|
1 | pom.xml | 工程的pom文件 |
2 | src/main/java/com/bolingcavalry/helloxmldirectconsumer/ConsumerApplication.java | 启动、调用远端服务、再结束自身进程 |
3 | src/main/resources/log4j.properties | 日志配置文件 |
4 | src/main/resources/dubbo.properties | dubbo配置文件 |
5 | src/main/resources/spring/dubbo-consumer.xml | spring的bean配置 |
- 完整的文件位置如下图:
- 接下来逐个创建上述文件;
- 创建名为helloxmldirectconsumer的子工程,pom.xml内容如下,可见刚才新建的二方库practiceinterface也被依赖了:
<?xml version="1.0" encoding="UTF-8"?>
dubbopracticecom.bolingcavalry1.0-SNAPSHOT4.0.0com.bolingcavalryhelloxmldirectconsumer1.0-SNAPSHOTcom.bolingcavalrypracticeinterface${project.version}org.apache.dubbodubboorg.projectlomboklombokorg.slf4jslf4j-log4j12
- 编写唯一的java文件ConsumerApplication.java,里面用了最简单的方法初始化spring环境,然后取得服务实例,执行过方法后结束进程:
package com.bolingcavalry.helloxmldirectconsumer;
import com.bolingcavalry.dubbopractice.service.DemoService;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ConsumerApplication {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/dubbo-consumer.xml");
context.start();
DemoService demoService = context.getBean("demoService", DemoService.class);
String hello = demoService.sayHello("world1");
System.out.println("result: " + hello);
}
}
- 日志配置文件log4j.properties,内容如下:
###set log levels###
log4j.rootLogger=info, stdout
###output to console###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%d{dd/MM/yy HH:mm:ss:SSS z}] %t %5p %c{2}: %m%n
- 在同样位置创建dubbo配置文件dubbo.properties,内容很简单只有qos的端口设置,用于支持telnet命令,本例中是用不上的,因为远程调用后进程就会结束:
dubbo.application.qos.port=33333
- 在resources目录下新建文件夹spring,在此文件夹下创建文件dubbo-consumer.xml,要重点关注的是dubbo:registry的配置,其address属性值为multicast://224.5.6.7:1234?unicast=false,代表当前服务通过广播让消费者获得自身信息,unicast=false表示多个消费者都能收到广播:
<?xml version="1.0" encoding="UTF-8"?>
- 上面的dubbo-consumer.xml中还有一处要注意,就是dubbo:reference的timeout属性,这是远程调用的超时时间,此处设置为2秒,要注意的是前面helloxmldirectprovider提供的服务延时了1秒才返回,所以这里设置不能低于1秒;
- 至此,服务消费方编码完成,直接在IDEA上运行ConsumerApplication类即可启动,如下图,红框中就是远程调用helloxmldirectprovider服务返回的内容:
- 至此,《dubbo实战》系列的准备和初体验都完成了,接下来的章节,咱们会通过更多实战来学习这个优秀的框架;
我是欣宸,期待与您一同畅游Java世界…