Dubbo学习 —— Dubbo常用配置

Posted JohnnyLin00

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Dubbo学习 —— Dubbo常用配置相关的知识,希望对你有一定的参考价值。

@TOC

Dubbo配置

配置原则

首先,从Dubbo支持的配置来源说起,默认有四种配置来源:

JVM System Properties,-D 参数
Externalized Configuration,外部化配置(如application.yml)
ServiceConfig、ReferenceConfig 等编程接口采集的配置(通过编码形式,如写个配置类标注为@Component)
本地配置文件 dubbo.properties

覆盖关系

优先级顺序:

  • JVM 启动-D参数优先,这样可以使用户在部署和启动时进行参数的重写,比如在启动时需要改变协议的端口时。
  • XML次之。如果中有配置项,则dubbo.properties中相应配置项无效。
  • Properties。 相当于缺省值,只有XML没有配置时,dubbo.properties的相应配置项才会生效。

参见Dubbo 官网 配置加载流程

重试次数 retries

retries 属性表示远程服务调用重试次数,不包括第一次调用,不需要重试请设为0。默认为2.
如果该服务名下有多台服务器,当出现失败时,会轮询自动切换尝试其他服务器。

注解形式配置

@DubboService 和@DubboReference都有重试次数属性。@DubboService标注在对应接口的实现类上,@DubboReference标注在要注入的远程调用对象上。

@Service  // 放进springboot容器中
//服务提供者接口实现类需要被@DubboService 驱动
@DubboService(retries = 3)  //默认重试次数是2次
public class UserServiceImpl implements UserService 



    public List<UserAddress> getUserAddressList(String userId) 
        System.out.println("UserServiceImpl..1.....");
        UserAddress address1 = new UserAddress(1, "北京市朝阳区麦肯锡", "1", "李老师", "010-56253825", "Y");
        UserAddress address2 = new UserAddress(2, "深圳市宝安区珠江工厂)", "1", "王老师", "010-56253825", "N");
        try  TimeUnit.SECONDS.sleep(3);  catch (InterruptedException e)  e.printStackTrace(); 
        return Arrays.asList(address1,address2);
    



控制请求超时,打印结果:

UserServiceImpl..1.....
UserServiceImpl..1.....
UserServiceImpl..1.....
UserServiceImpl..1.....

使用注解形式无法实现方法级别的属性设置

Spring XML 配置

<dubbo:service retries="2" /><dubbo:reference retries="2" /><dubbo:reference>
    <dubbo:method name="findFoo" retries="2" />
</dubbo:reference>

超时等待时间 timeout

由于网络或服务端不可靠,会导致出现一种不确定的中间状态(超时)。为了避免超时导致客户端资源挂起耗尽,必须设置超时时间。timeout该属性远程服务调用超时时间(毫秒),默认时间为1000ms。

配置的覆盖规则:

  1. 方法级配置别优于接口级别,即小Scope优先
  2. Consumer端配置 优于 Provider配置 优于 全局配置,
  3. 最后是Dubbo Hard Code的配置值(见配置文档)

配置的覆盖规则:
1、 方法级别的优于接口级别,接口级别的优于全局配置。
2、 Consumer端配置优于Provider

Spring XML 形式

consumer.xml

服务提供者
项目结构

主启动类
由于是使用xml暴露服务的,所以不用使用@EnableDubbo

DubboProviderMain20881.java

//@EnableDubbo  //使用xml暴露服务时候不用@EnableDubbo注解
@SpringBootApplication
public class DubboProviderMain20881 
    public static void main(String[] args) 
        SpringApplication.run(DubboProviderMain20881.class,args);
    


服务接口实现类之一UserServiceImpl

package com.johnny.dubbo.service.impl;

import com.johnny.dubbo.entity.UserAddress;
import com.johnny.dubbo.service.UserService;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author Johnny Lin
 * @date 2021/7/8 17:42
 */
@Service  // 放进springboot容器中
//服务提供者接口实现类需要被@DubboService 驱动
@DubboService  // 一定一定要加上@DubboService注解暴露远程服务给消费者  一开始就是就没有加上
public class UserServiceImpl implements UserService 



    public List<UserAddress> getUserAddressList(String userId) 
        System.out.println("UserServiceImpl..v1.....");
        UserAddress address1 = new UserAddress(1, "北京市朝阳区麦肯锡", "1", "李老师", "010-56253825", "Y");
        UserAddress address2 = new UserAddress(2, "深圳市宝安区珠江工厂)", "1", "王老师", "010-56253825", "N");
//        try  TimeUnit.SECONDS.sleep(2);  catch (InterruptedException e)  e.printStackTrace(); 

        System.out.println(address1.getId()+"\\t"+address1.getUserAddress());
        System.out.println(address2.getId()+"\\t"+address2.getUserAddress());

        return Arrays.asList(address1,address2);
    


服务接口实现类之一UserServiceImpl2.java

package com.johnny.dubbo.service.impl;

import com.johnny.dubbo.entity.UserAddress;
import com.johnny.dubbo.service.UserService;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author Johnny Lin
 * @date 2021/7/8 17:42
 */
@Service  // 放进springboot容器中
//服务提供者接口实现类需要被@DubboService 驱动
@DubboService  // 一定一定要加上@DubboService注解暴露远程服务给消费者  一开始就是就没有加上
public class UserServiceImpl2 implements UserService 



    public List<UserAddress> getUserAddressList(String userId) 
        System.out.println("UserServiceImpl..v2.....");
        UserAddress address1 = new UserAddress(3, "北京市朝阳区麦肯锡", "1", "李老师", "010-56253825", "Y");
        UserAddress address2 = new UserAddress(4, "深圳市宝安区珠江工厂)", "1", "王老师", "010-56253825", "N");
//        try  TimeUnit.SECONDS.sleep(2);  catch (InterruptedException e)  e.printStackTrace(); 

        System.out.println(address1.getId()+"\\t"+address1.getUserAddress());
        System.out.println(address2.getId()+"\\t"+address2.getUserAddress());

        return Arrays.asList(address1,address2);
    


服务提供者配置文件provider.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd
		http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- 1、指定当前服务/应用的名字(同样的服务名字相同,不要和别的服务同名) -->
    <dubbo:application name="user-service-dubbo-provider"></dubbo:application>

    <!-- 2、指定注册中心的位置 -->
    <!-- <dubbo:registry address="zookeeper://192.168.59.123:2181"></dubbo:registry> -->
    <dubbo:registry protocol="zookeeper" address="192.168.59.123:2181"></dubbo:registry>

    <!-- 3、指定通信规则(通信协议?通信端口) -->
    <dubbo:protocol name="dubbo" port="20882"></dubbo:protocol>

    <!-- 4、暴露服务 interface:面向的接口  ref:指向服务的真正的实现对象
            version: 版本,通过指定版本可以实现灰度发布
     -->
    <dubbo:service interface="com.johnny.dubbo.service.UserService"
                   ref="userServiceImpl" timeout="1000" version="1.0.0">
        <dubbo:method name="getUserAddressList" timeout="1000"></dubbo:method>
    </dubbo:service>

    <!--统一设置服务提供方的规则  -->
    <dubbo:provider timeout="1000"></dubbo:provider>


    <!-- 服务的实现 -->
    <bean id="userServiceImpl" class="com.johnny.dubbo.service.impl.UserServiceImpl"></bean>

    <dubbo:service interface="com.johnny.dubbo.service.UserService"
                   ref="userServiceImpl2" timeout="1000" version="2.0.0">
        <dubbo:method name="getUserAddressList" timeout="1000"></dubbo:method>
    </dubbo:service>

    <bean id="userServiceImpl2" class="com.johnny.dubbo.service.impl.UserServiceImpl2"></bean>

    <!-- 连接监控中心 -->
    <dubbo:monitor protocol="registry"></dubbo:monitor>

</beans>

消费者
项目结构

注意application
yaml 和 consumer0.xml 都没有用到

**主启动类 ConsumerMain8081 **

@SpringBootApplication
//@EnableDubbo开启Dubbo注解 该注解中有@DubboComponentScan 作用是扫描dubbo注解所在包
//由于使用xml文件暴露服务 所以不需要该注解
//@EnableDubbo 
public class ConsumerMain8081 
    public static void main(String[] args) 
        SpringApplication.run(ConsumerMain8081.class,args);
    

服务实现类 OrderServiceImpl

package com.johnny.dubbo.service.impl;

import com.johnny.dubbo.entity.UserAddress;
import com.johnny.dubbo.service.OrderService;
import com.johnny.dubbo.service.UserService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author Johnny Lin
 * @date 2021/7/8 0:18
 */

@Service
public class OrderServiceImpl implements OrderService 

    //Reference注解引用服务远程调用
//    @DubboReference
//    UserService userService;
    //通过xml配置文件暴露接口时,接口的调用使用@Autowired注解,不用 @DubboReference
    // 相当于通过spring将这个接口对象注入了

    @Resource
    private UserService userService;

    public List<UserAddress> initOrder(String userId) 
        System.out.println("OrderService 1……");
        return userService.getUserAddressList(userId);
    


**服务控制类 OrderController **

package com.johnny.dubbo.controller;

import com.johnny.dubbo.entity.UserAddress;
import com.johnny.dubbo.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * @author Johnny Lin
 * @date 2021/7/8 23:50
 */

@RestController
public class OrderController 

    @Autowired
    private OrderService orderService;

    @GetMapping("/initOrder/id")
    public List<UserAddress> initOrder(@PathVariable("id")String userId) 
        return orderService.initOrder(userId);
    


配置文件consumer.xml

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">


    <dubbo:application name="order-service-dubbo-consumer"></dubbo:application>

    <dubbo:registry id="register" protocol="zookeeper" address="192.168.59.123:2181" timeout="25000"></dubbo:registry>
    <!-- retries 重试次数: 不包含第一次调用 0代表不重试
    幂等操作(如查询、删除、修改)需要设置重试次数
    非幂等操作(如新增) 不能设置重试次数
    -->
    <!-- timeout 超时等待时间: 为0 表示默认是1000ms-->
    <!-- 配置当前消费者的统一规则  设置全局超时时间  check=false表示所有服务启动时都不检查是否有提供者-->
    <dubbo:consumer timeout="5000" check="false" ></dubbo:consumer>
    <!-- 指定接口以及特定方法超时配置 -->
    <!-- 通过dubbo:reference 的timeout属性设置接口级的超时时间-->
    <!-- 通过dubbo:reference 标签生成一个id为userService的远程代理对象 该对象的timeout属性 -->
    <!-- register 属性从指定注册中心注册获取服务列表,在多个注册中心时使用,值为<dubbo:registry>的id属性,多个注册中心ID用逗号分隔  缺省向所有registry注册 -->
    <!-- 通过dubbo:reference的version属性指定使用消费端的版本实现灰度发布,* 表示所有版本,也可以指定版本  -->
    <dubbo:reference interface="com.johnny.dubbo.service.UserService" id="userService"
                     registry="register" timeout="6000"
                    version = "*">
        <!-- 通过dubbo:method 的timeout属性设置方法级的超时时间   方法级别的起作用-->
        <dubbo:method name="getUserAddressList" timeout="1000" ></dubbo:method>
    </dubbo:reference>

    <!-- 指定监控中心协议 会在注册中心寻找监控中心地址 否则直连监控中心 因此无需再填写详细地址-->
    <dubbo:monitor protocol="registry"  ></dubbo:monitor>
    <!-- <dubbo:monitor address="127.0.0.1:7001"></dubbo:monitor> -->


</beans>
非幂等操作(如新增) 不能设置重试次数
    -->
    <!-- timeout 超时等待时间: 为0 表示默认是1000ms-->
    <!-- 配置当前消费者的统一规则  设置全局超时时间 所有服务都不检查-->
    <dubbo:consumer timeout="5000" check="false" ></dubbo:consumer>
    <!-- 指定接口以及特定方法超时配置 -->
    <!-- 设置接口级的超时时间-->
    <!-- 通过dubbo:reference 标签生成一个id为userService的远程代理对象 该对象的timeout属性 -->
    <dubbo:reference interface="com.johnny.dubbo.service.UserService" id="userService"
     

以上是关于Dubbo学习 —— Dubbo常用配置的主要内容,如果未能解决你的问题,请参考以下文章

Dubbo学习 —— Dubbo常用配置

Dubbo学习 —— Dubbo常用配置

dubbo的本地存根(Stub)

Dubbo本地存根是什么,Dubbo本地伪装又是什么?

dubbo源码阅读-ProxyFactory之StubProxyFactoryWrapper本地存根

Dubbo 系列(07-5)集群容错 - Mock