SpringCloud Alibaba系列——4Dubbo简介与应用(二)

老老老JR老北
发布于 2022-8-24 16:37
浏览
0收藏

作者 | 一起撸Java
来源 |今日头条

第2章 Dubbo使用

官方案例:
https://github.com/apache/dubbo/tree/3.0/dubbo-demo

2.1 Dubbo初使用

在maven中查看匹配版本
https://mvnrepository.com/artifact/org.apache.dubbo/dubbo

zookeeper集群搭建教程见zookeeper集群部署讲义

  • 构建maven-empty项目dubbo-eclipse2019-demo目录
  • 构建三个maven-archetype-quickstart子项目
  • dubbo-api
  • dubbo-providerrovider
  • dubbo-consumer
    2.1.1 dubbo-api
    1.配置pom
<!-- 增加下面的依赖,后面高级使用会用到参数验证 --><dependency>    <groupId>javax.validation</groupId>    <artifactId>validation-api</artifactId>    <version>1.0.0.GA</version></dependency>

2.dubbo-api提供服务的公共契约,里面提供了对外的服务。

public interface FirstService {    //获取返回值    String getFristStr(String str);}

2.1.2 dubbo-provider
1.配置pom

<properties>    <maven.compiler.source>1.8</maven.compiler.source>    <maven.compiler.target>1.8</maven.compiler.target>    <source.level>1.8</source.level>    <target.level>1.8</target.level>    <!-- 3.0.2.1版本跟spring5.2.8.release匹配 -->    <dubbo.version>3.0.2.1</dubbo.version><!-- spring用这个版本因为有源码注释 -->    <spring.version>5.2.8.RELEASE</spring.version>    <junit.version>4.13</junit.version>    <maven-compiler-plugin.version>3.7.0</maven-compiler-plugin.version>    <skip_maven_deploy>true</skip_maven_deploy>    <dubbo.compiler.version>0.0.2</dubbo.compiler.version></properties><dependencyManagement>    <dependencies>        <dependency>            <groupId>org.springframework</groupId>            <artifactId>spring-framework-bom</artifactId>            <version>${spring.version}</version>            <type>pom</type>            <scope>import</scope>        </dependency>        <dependency>            <groupId>org.apache.dubbo</groupId>            <artifactId>dubbo-bom</artifactId>            <version>${dubbo.version}</version>            <type>pom</type>            <scope>import</scope>        </dependency>        <dependency>            <groupId>org.apache.dubbo</groupId>            <artifactId>dubbo-dependencies-zookeeper</artifactId>            <version>${dubbo.version}</version>            <type>pom</type>        </dependency>    </dependencies></dependencyManagement><dependencies>    <!-- 引入dubbo和zookeeper依赖包 -->    <dependency>        <groupId>org.apache.dubbo</groupId>        <artifactId>dubbo</artifactId>    </dependency>    <dependency>        <groupId>junit</groupId>        <artifactId>junit</artifactId>        <version>${junit.version}</version>    </dependency>    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-test</artifactId>    </dependency>    <dependency>        <groupId>org.apache.dubbo</groupId>        <artifactId>dubbo-dependencies-zookeeper</artifactId>        <type>pom</type>    </dependency>    <dependency>        <groupId>org.apache.dubbo</groupId>        <artifactId>dubbo-metadata-report-zookeeper</artifactId>    </dependency>    <dependency>        <groupId>junit</groupId>        <artifactId>junit</artifactId>        <version>${junit.version}</version>    </dependency>    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-test</artifactId>    </dependency>    <dependency>        <groupId>com.example</groupId>        <artifactId>dubbo-api</artifactId>        <version>1.0-SNAPSHOT</version>    </dependency>    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-web</artifactId>    </dependency>    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-webmvc</artifactId>    </dependency>    <dependency>        <groupId>org.apache.tomcat.embed</groupId>        <artifactId>tomcat-embed-core</artifactId>        <version>8.5.23</version>    </dependency>    <dependency>        <groupId>org.apache.tomcat</groupId>        <artifactId>tomcat-jasper</artifactId>        <version>8.5.16</version>    </dependency>    <dependency>        <groupId>ch.qos.logback</groupId>        <artifactId>logback-classic</artifactId>        <version>1.1.2</version>    </dependency>    <dependency>        <groupId>ch.qos.logback</groupId>        <artifactId>logback-core</artifactId>        <version>1.1.2</version>    </dependency>    <dependency>        <groupId>javax.validation</groupId>        <artifactId>validation-api</artifactId>        <version>1.0.0.GA</version>    </dependency>    <dependency>        <groupId>org.hibernate</groupId>        <artifactId>hibernate-validator</artifactId>        <version>4.2.0.Final</version>    </dependency></dependencies>

2.在dubbo-provider服务中提供ContactService的实现

@DubboService //@DubboService注解就是服务暴露的注解,想要暴露什么服务就在类上加上该注解public class FirstServiceImpl implements FirstService {    @Override    public String getContact(String name) {        System.out.println("===服务端接收到获取联系方式的请求==="+name);        return name+"的联系方式是:111";    }}

3.增加配置类,且加入@EnableDubbo注解即可完成对@DubboService的扫描,如下:

@Configuration//作用 扫描 @DubboService注解  @DubboReference@EnableDubbo(scanBasePackages = "com.example")@PropertySource("classpath:/dubbo-provider.properties")public class ProviderConfiguration {}

4.在resource目录下配置dubbo-provider.properties

dubbo.application.name=dubbo_providerdubbo.registry.address=zookeeper://${zookeeper.address:127.0.0.1}:2181dubbo.protocol.name=dubbodubbo.protocol.port=20880dubbo.config-center.address=zookeeper://${zookeeper.address:127.0.0.1}:2181

5.在resource目录下增加日志配置log4j.properties(消费端也要增加)

#优先级从高到低依次为:OFF FATAL ERROR WARN INFO DEBUG TRACE ALLlog4j.rootLogger=info, stdout###output to the console###log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.Target=System.outlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=[%d{dd/MM/yy hh:mm:ss:sss z}] %t %5p %c{2}: %m%n

6.因为注册中心用的是zookeeper,所以还得在本地启动zookeeper服务(如何启动参照zookeeper文章)

7.然后启动服务端服务,将接口注册到zookeeper上去

public class AnnotationProvider {    public static void main(String[] args) throws InterruptedException {        new AnnotationConfigApplicationContext(ProviderConfiguration.class);        System.out.println("---dubbo服务端启动---");        new CountDownLatch(1).await();    }}

2.1.3 dubbo-consumer
1.配置pom

<properties>    <maven.compiler.source>1.8</maven.compiler.source>    <maven.compiler.target>1.8</maven.compiler.target>    <source.level>1.8</source.level>    <target.level>1.8</target.level>    <dubbo.version>3.0.2.1</dubbo.version>    <spring.version>5.2.8.RELEASE</spring.version>    <junit.version>4.12</junit.version>    <maven-compiler-plugin.version>3.7.0</maven-compiler-plugin.version></properties><dependencyManagement>    <dependencies>        <dependency>            <groupId>org.springframework</groupId>            <artifactId>spring-framework-bom</artifactId>            <version>${spring.version}</version>            <type>pom</type>            <scope>import</scope>        </dependency>        <dependency>            <groupId>org.apache.dubbo</groupId>            <artifactId>dubbo-bom</artifactId>            <version>${dubbo.version}</version>            <type>pom</type>            <scope>import</scope>        </dependency>        <dependency>            <groupId>org.apache.dubbo</groupId>            <artifactId>dubbo-dependencies-zookeeper</artifactId>            <version>${dubbo.version}</version>            <type>pom</type>        </dependency>    </dependencies></dependencyManagement><dependencies>    <dependency>        <groupId>org.apache.dubbo</groupId>        <artifactId>dubbo</artifactId>    </dependency>    <dependency>        <groupId>org.apache.dubbo</groupId>        <artifactId>dubbo-dependencies-zookeeper</artifactId>        <type>pom</type>    </dependency>    <dependency>        <groupId>junit</groupId>        <artifactId>junit</artifactId>        <version>${junit.version}</version>    </dependency>    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-test</artifactId>    </dependency>    <dependency>        <groupId>com.example</groupId>        <artifactId>dubbo-api</artifactId>        <version>1.0-SNAPSHOT</version>    </dependency>    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-web</artifactId>    </dependency>    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-webmvc</artifactId>    </dependency>    <dependency>        <groupId>org.apache.tomcat.embed</groupId>        <artifactId>tomcat-embed-core</artifactId>        <version>8.5.23</version>    </dependency>    <dependency>        <groupId>org.apache.tomcat</groupId>        <artifactId>tomcat-jasper</artifactId>        <version>8.5.16</version>    </dependency>    <!-- 日志相关依赖 -->    <dependency>        <groupId>org.slf4j</groupId>        <artifactId>slf4j-api</artifactId>        <version>1.7.10</version>    </dependency>    <dependency>        <groupId>ch.qos.logback</groupId>        <artifactId>logback-classic</artifactId>        <version>1.1.2</version>    </dependency>    <dependency>        <groupId>ch.qos.logback</groupId>        <artifactId>logback-core</artifactId>        <version>1.1.2</version>    </dependency>    <dependency>        <groupId>javax.validation</groupId>        <artifactId>validation-api</artifactId>        <version>1.0.0.GA</version>    </dependency>    <dependency>        <groupId>org.hibernate</groupId>        <artifactId>hibernate-validator</artifactId>        <version>4.2.0.Final</version>    </dependency></dependencies>

2.增加配置类

@Configuration//@EnableDubbo(scanBasePackages = "com.example")就会扫描@DubboReference注解的属性并且进行属性的依赖注入。@EnableDubbo(scanBasePackages = "com.example")@PropertySource("classpath:/dubbo-consumer.properties")public class ConsumerConfiguration {}

3.在resource目录下配置dubbo-consumer.properties

dubbo.application.name=dubbo_consumerdubbo.registry.address=zookeeper://${zookeeper.address:127.0.0.1}:2181dubbo.protocol.port=29015dubbo.config-center.address=zookeeper://${zookeeper.address:127.0.0.1}:2181

4.启动消费

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(classes = ConsumerConfiguration.class)public class TestFirstService {    @DubboReference    private ContactService contactService;    @Test    public void test(){        System.out.println(contactService.getContact("eclipse2019"));    }}

2.1.4 总结
简单总结一下上面的整个过程,其实不难发现,Dubbo这个中间件为我们提供了服务远程通信的解决方案。通过dubbo这个框架,可以开发者快速高效的构建微服务架构下的远程通信实现。

不知道大家是否发现,我们在使用dubbo发布服务,或者消费服务的时候,全程都是采用spring的配置来完成的,这样的好处是我们在学习或者使用dubbo时,如果你用过spring这个框架,那么对于它的学习难度会大大的降低。而且我们也可以看到,dubbo是完全集成Spring 的,因此后续我们去分析dubbo的源码时,还是会有一些和spring有关的内容。

2.2 集成注册中心
Dubbo并不仅仅只是一个RPC框架,他还是一个服务治理框架,它提供了对服务的统一管理、以及服务的路由等功能。

在上面的案例中,我们只是掩饰了Dubbo作为RPC通信的点对点服务,但是就像咱们前面在学习spring cloud的内容一样,服务多了以后,如何管理和维护,以及动态发现呢?

而且,从Dubbo的架构图中可以看到,Dubbo天然就支持服务注册与发现,官方最早推荐的服务注册中心是zookeeper,当然,目前dubbo能够支持的注册中心已经非常多了,比如consul、etcd、nacos、sofa、zookeeper、eureka、redis等等,很显然,Dubbo已经在往一个独立微服务解决方案的生态在发展。

2.2.1 集成zookeeper
集成Zookeeper作为服务注册中心
添加zookeeper的jar包依赖

<dependency>    <groupId>org.apache.dubbo</groupId>    <artifactId>dubbo-dependencies-zookeeper</artifactId>    <version>${dubbo.version}</version>    <type>pom</type></dependency>

添加注册中心配置,创建dubbo-providerrovider.properties文件用于取代xml中的配置属性,然后用@PropertySource加载该properties配置文件即可 。 dubbo-providerrovider.properties文件内容如下:

<dependency>    <groupId>org.apache.dubbo</groupId>    <artifactId>dubbo-dependencies-zookeeper</artifactId>    <version>${dubbo.version}</version>    <type>pom</type></dependency>

2.2.2 配置管理
1.配置组件 Dubbo框架的配置项比较繁多,为了更好地管理各种配置,将其按照用途划分为不同的组件,最终所有配置项都会汇聚到URL中,传递给后续处理模块。 常用配置组件如下:

  • application: Dubbo应用配置
  • registry: 注册中心
  • protocol: 服务提供者RPC协议
  • config-center: 配置中心
  • metadata-report: 元数据中心
  • service: 服务提供者配置
  • reference: 远程服务引用配置
  • provider: service的默认配置或分组配置
  • consumer: reference的默认配置或分组配置
  • module: 模块配置
  • monitor: 监控配置
  • metrics: 指标配置
  • ssl: SSL/TLS配置
    2.配置来源 从Dubbo支持的配置来源说起,默认有6种配置来源:
  • JVM System Properties,JVM -D 参数
  • System environment,JVM进程的环境变量
  • Externalized Configuration,外部化配置,从配置中心读取
  • Application Configuration,应用的属性配置,从Spring应用的Environment中提取"dubbo"打头的属性集
  • API / XML /注解等编程接口采集的配置可以被理解成配置来源的一种,是直接面向用户编程的配置采集方式
  • 从classpath读取配置文件 dubbo.properties
    3.覆盖关系 下图展示了配置覆盖关系的优先级,从上到下优先级依次降低: 

SpringCloud Alibaba系列——4Dubbo简介与应用(二)-鸿蒙开发者社区2.3 API的使用

https://dubbo.apache.org/zh/docs/references/configuration/api/

以API 配置的方式来配置你的 Dubbo 应用

通过API编码方式组装配置,启动Dubbo,发布及订阅服务。此方式可以支持动态创建
ReferenceConfig/ServiceConfig,结合泛化调用可以满足API Gateway或测试平台的需要。

  • api
public interface ApiService {    String getApiServiceStr(String str);}
  • 服务提供者
    通过ServiceConfig暴露服务接口,发布服务接口到注册中心。
public class ApiServiceImpl implements ApiService {    @Override    public String getApiServiceStr(String str) {        return "api方式调用返回:"+str;    }    public static void main(String[] args) throws IOException {        ApiServiceImpl apiService = new ApiServiceImpl();        //1、应用信息        ApplicationConfig applicationConfig = new ApplicationConfig();        applicationConfig.setName("dubbo-provider-api");        //2、注册信息        RegistryConfig registryConfig = new RegistryConfig();        registryConfig.setAddress("zookeeper://127.0.0.1:2181");        //3、协议信息        ProtocolConfig protocolConfig = new ProtocolConfig();        protocolConfig.setName("dubbo");        protocolConfig.setPort(20881);        protocolConfig.setThreads(200);        //服务发布        ServiceConfig<ApiService> serviceConfig = new ServiceConfig<>();        serviceConfig.setApplication(applicationConfig);        serviceConfig.setRegistry(registryConfig);// 多个注册中心可以用setRegistries()        serviceConfig.setProtocol(protocolConfig);// 多个协议可以用setProtocols()        serviceConfig.setInterface(ApiService.class);        serviceConfig.setRef(apiService);//        serviceConfig.setVersion("1.0.0");        serviceConfig.setTimeout(1000000);        //暴露及注册服务        serviceConfig.export();        //挂起等待(防止进程退出)        System.in.read();    }}
  • 服务消费者 通过ReferenceConfig引用远程服务,从注册中心订阅服务接口。
public class ApiTest {    @Test    public void api(){        // 1、应用信息        ApplicationConfig applicationConfig = new ApplicationConfig();        applicationConfig.setName("dubbo_consumer-api");        //2、注册信息        RegistryConfig registry = new RegistryConfig();        registry.setAddress("zookeeper://127.0.0.1:2181");        //引用API        ReferenceConfig<ApiService> referenceConfig = new ReferenceConfig<>();        referenceConfig.setApplication(applicationConfig);        referenceConfig.setRegistry(registry);        referenceConfig.setInterface(ApiService.class);        //服务引用  。这个引用过程非常重,如果想用api方式去引用服务,这个对象需要缓存        ApiService apiService = referenceConfig.get();        System.out.println(apiService.getApiServiceStr("eclipse2019"));    }}
  • bootstrap 服务发布
public class BootstrapApi {    public static void main(String[] args) {        new EmbeddedZooKeeper(2181, false).start();        ConfigCenterConfig configCenter = new ConfigCenterConfig();        configCenter.setAddress("zookeeper://127.0.0.1:2181");        // 服务提供者协议配置        ProtocolConfig protocol = new ProtocolConfig();        protocol.setName("dubbo");        protocol.setPort(12345);        protocol.setThreads(200);        // 注意:ServiceConfig为重对象,内部封装了与注册中心的连接,以及开启服务端口        // 服务提供者暴露服务配置        ServiceConfig<UserService> demoServiceConfig = new ServiceConfig<>();        demoServiceConfig.setInterface(UserService.class);        demoServiceConfig.setRef(new UserServiceImpl());        demoServiceConfig.setVersion("1.0.0");        // 第二个服务配置        ServiceConfig<MockService> fooServiceConfig = new ServiceConfig<>();        fooServiceConfig.setInterface(MockService.class);        fooServiceConfig.setRef(new MockServiceImpl());        fooServiceConfig.setVersion("1.0.0");        // 通过DubboBootstrap简化配置组装,控制启动过程        DubboBootstrap.getInstance()            .application("demo-provider") // 应用配置            .registry(new RegistryConfig("zookeeper://127.0.0.1:2181")) // 注册中心配置            .protocol(protocol) // 全局默认协议配置            .service(demoServiceConfig) // 添加ServiceConfig            .service(fooServiceConfig)            .start() // 启动Dubbo            .await(); // 挂起等待(防止进程退出)    }}

bootstrap 服务发现

public class BootstrapApi {    public static void main(String[] args) {        // 引用远程服务        ReferenceConfig<UserService> demoServiceReference = new            ReferenceConfig<UserService>();        demoServiceReference.setInterface(UserService.class);        demoServiceReference.setVersion("1.0.0");        ReferenceConfig<MockService> fooServiceReference = new            ReferenceConfig<MockService>();        fooServiceReference.setInterface(MockService.class);        fooServiceReference.setVersion("1.0.0");        // 通过DubboBootstrap简化配置组装,控制启动过程        DubboBootstrap bootstrap = DubboBootstrap.getInstance();        bootstrap.application("demo-consumer") // 应用配置            .registry(new RegistryConfig("zookeeper://127.0.0.1:2181")) // 注册中心配置            .reference(demoServiceReference) // 添加ReferenceConfig            .reference(fooServiceReference)            .start(); // 启动Dubbo        // 和本地bean一样使用demoService        // 通过Interface获取远程服务接口代理,不需要依赖ReferenceConfig对象        UserService demoService =            DubboBootstrap.getInstance().getCache().get(UserService.class);        System.out.println(demoService.queryUser("jack"));        MockService fooService =            DubboBootstrap.getInstance().getCache().get(MockService.class);        System.out.println(fooService.queryArea("1"));    }}

分类
已于2022-8-24 16:37:10修改
收藏
回复
举报
回复
    相关推荐