SpringBoot>20 - 集成Dubbo构建分布式架构(二)

简介:

Dubbo默认的远程调用超时时间为 1 秒,超时重试次数为2次(加上原本的一次总共3次),而在实际项目中不允许超时的场景很多, 例如,添加数据的业务中重试会避免重复数据、发送短信的业务可能重复发送等。

本章在【上一章】的基础上参看官网引入dubbo的几种配置方式、引入超时重试的配置。推荐xml配置方式。

官网地址(重要):
http://dubbo.apache.org/en-us/docs/user/quick-start.html

一、Dubbo的配置方式:

总结三种:
1、注解配置: 上一章,使用@Service、@Reference,有些版本的dubbo还需要开启dubbo的注解,此种最简单,但是没有提供控制到方法级别的注解。此种方式使用retries属性指定超时重试有很多坑,容易出错。

2、Dubbo xml 配置: 此种方式很直观,可直接参考官网schema配置参考手册,本章使用超时重试机制也是在此种方式上验证。推荐使用。

3、使用API的方式: 将每一个组件手动创建到容器中,使用@Service、@Reference。

二、项目构建

此处只有部分代码,完整代码请【下载源码】

1、pom依赖:
上一章使用的 springboot 的 starter,点进去可以看到它包含了 dubbo、zk 的相关依赖,我们这章不使用封装好的starter,直接引入dubbo 和 zk 的相关依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>dubbo</artifactId>
    <version>2.5.7</version>
    <exclusions>
        <exclusion>
            <artifactId>spring</artifactId>
            <groupId>org.springframework</groupId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.4.6</version>
    <exclusions>
        <exclusion>
            <artifactId>slf4j-log4j12</artifactId>
            <groupId>org.slf4j</groupId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>com.github.sgroschupf</groupId>
    <artifactId>zkclient</artifactId>
    <version>0.1</version>
</dependency>

三、Dubbo xml 方式配置:

新建springboot-dubbo-service-xml 模块
1、在resources 下新建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">

	<!-- 当前服务的名字(同样的服务名字相同,不要和别的服务同名) -->
	<!--<dubbo:application name="user-service-provider-xml"></dubbo:application>-->
	<!-- 注册中心的位置 -->
	<dubbo:registry address="zookeeper://127.0.0.1:2181"></dubbo:registry>
	<!--<dubbo:registry protocol="zookeeper" address="127.0.0.1:2181"></dubbo:registry>-->
	<!-- 3通信规则 -->
	<dubbo:protocol name="dubbo" port="20882"></dubbo:protocol>

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

	<!-- 用户服务   ref:指向服务实现对象 spring 容器中的名字 -->
	<!-- 控制到类 -->
	<dubbo:service interface="com.coolron.service.user.UserService" ref="userService" timeout="1000" version="1.0.0" >
		<!-- 方法级别的控制 retries 默认是2 指定为0 表示禁止 超时重试 -->
		<dubbo:method name="getAllUser" timeout="1000" retries="0"></dubbo:method>
	</dubbo:service>
	<!-- 权限服务 -->
	<dubbo:service interface="com.coolron.service.permission.PermissionService" ref="permissionService" version="1.0.0" >
	</dubbo:service>
	<!-- 角色服务 -->
	<dubbo:service interface="com.coolron.service.permission.RoleService" ref="roleService" version="1.0.0" >
	</dubbo:service>

	<!-- 服务的实现类   也可在 实现类上加上 @Service(Spring 的注解 不要与 dubbo的 service 注解混淆 ) -->
	<!--<bean id="userService" class="com.coolron.service.impl.user.UserServiceImpl"></bean>-->
	<!-- 连接监控中心 -->
	<!--<dubbo:monitor protocol="registry"></dubbo:monitor>-->
 	<!--<dubbo:monitor address="127.0.0.1:7001"></dubbo:monitor>-->

</beans>

相关标签的使用请参看官网,写的非常详细。

2、属性配置:
第一步provider 的配置已经可以完成dubbo服务的暴露了,但是如果有很多配置,又不想写冗余代码,可以使用属性配置作为缺省值。
在这里插入图片描述
2.1、在resources下新建dubbo.properties配置文件:

扫描二维码关注公众号,回复: 4979848 查看本文章
1###  此处的配置只作为缺省 #####
2### JVM 启动 -D 参数优先 > XML > Properties #####
3# 应用名
4dubbo.application.name=properties-provider
5# 注册中心地址
6dubbo.registry.address=zookeeper://127.0.0.0:2181
7# 调用协议地址
8dubbo.protocol.name=dubbo
9dubbo.protocol.port=38080

2.2、问题:若xml中和properties中有相同配置,怎么选择?
看官网
优先级:JVM -D参数 > XML > properties

3、@ImportResource导入服务配置

/**
 * @Auther: xf
 * @Date: 2018/12/01 22:55
 * @Description:
 */
@ImportResource(locations = {"classpath:provider.xml"})
@SpringBootApplication
@MapperScan("com.coolron.dao.*")
public class XmlServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(XmlServiceApplication.class, args);
    }
}

4、启动:dubbo admin 监控、springboot-dubbo-service-xml服务

超时重试机制:

1、超时: 在约定的时间内服务提供方没有返回结果,则认为调用失败。
2、重试: 超时后,会再次调用,如果重试次数达到约定次数则抛出异常。默认2次。
3、示例:(类、方法上都可以指定)

1<!-- 方法级别的控制 超时时间一秒  禁止重试 -->
2<dubbo:method name="getAllUser" timeout="1000" retries="0"></dubbo:method>

4、测试:
4.1、服务消费者使用上一章的服务,启动

4.2、注释超时重试配置

    <dubbo:service interface="com.coolron.service.user.UserService" ref="userService" timeout="1000" version="1.0.0" >
        <!-- 方法级别的控制 retries 默认是2 指定为0 表示禁止 超时重试 -->
        <!--<dubbo:method name="getAllUser" timeout="1000" retries="0"></dubbo:method>-->
    </dubbo:service>

4.3、请求接口:http://localhost:8070/user/getUserList 请求正常。
将服务提供方的方法打上断点后控制台日志:超时时间1秒,重试3次。

4.4、将超时重试的注释去掉,加上断点结果如下:
在这里插入图片描述
5、建议:

  • 业务复杂可适当设置大一点的超时时间,超时并不代表异常,所以超时重试可能带来重复执行代码,容易出现多余的数据。需根据业务设置。
  • 超时重试建议设置到服务提供方,因为服务消费方只需要交互数据,服务提供方注重的是业务逻辑,所以,业务的复杂度,允不允许超时重试业务提供方最清楚。

四、注解API 方式配置:

1、新建springboot-dubbo-service-api模块
2、新建配置类:

/**
 * @Auther: xf
 * @Date: 2018/12/01 23:58
 * @Description: dubbo api 配置类
 */
@Configuration
public class ServiceDubboConfig {
	@Bean
	public ApplicationConfig applicationConfig() {
		ApplicationConfig applicationConfig = new ApplicationConfig();
		applicationConfig.setName("service-provider-api");
		return applicationConfig;
	}
	@Bean
	public RegistryConfig registryConfig() {
		RegistryConfig registryConfig = new RegistryConfig();
		registryConfig.setProtocol("zookeeper");
		registryConfig.setAddress("127.0.0.1:2181");
		return registryConfig;
	}
	//<dubbo:protocol name="dubbo" port="20882"></dubbo:protocol>
	@Bean
	public ProtocolConfig protocolConfig() {
		ProtocolConfig protocolConfig = new ProtocolConfig();
		protocolConfig.setName("dubbo");
		protocolConfig.setPort(20880);
		return protocolConfig;
	}
	/**
	 *<dubbo:service interface="com.atguigu.gmall.service.UserService" 
		ref="userService" timeout="1000" version="1.0.0">
		<dubbo:method name="getUserAddressList" timeout="1000"></dubbo:method>
	</dubbo:service>
	 */
	@Bean
	public ServiceConfig<UserService> serviceConfig(){
		ServiceConfig<UserService> serviceConfig = new ServiceConfig<UserService>();
		serviceConfig.setApplication(applicationConfig());
		serviceConfig.setRegistry(registryConfig()); // 多个注册中心可以用setRegistries()
		serviceConfig.setProtocol(protocolConfig()); // 多个协议可以用setProtocols()
		serviceConfig.setInterface(UserService.class);
		serviceConfig.setRef(new UserServiceImpl());
		serviceConfig.setVersion("1.0.0");
		return serviceConfig;
	}
//	<dubbo:provider timeout="1000"></dubbo:provider>
	@Bean
	public ProviderConfig providerConfig() {
		ProviderConfig providerConfig = new ProviderConfig();
		providerConfig.setTimeout(5000);
		return providerConfig;
	}
//	<dubbo:monitor address="127.0.0.1:7070"></dubbo:monitor>
//	@Bean
//	public MonitorConfig monitorConfig() {
//		MonitorConfig monitorConfig = new MonitorConfig();
//		monitorConfig.setAddress("127.0.0.1:7070");
//		monitorConfig.setProtocol("registry");
//		return monitorConfig;
//	}
}

3、配置扫描

@DubboComponentScan(basePackages = "com.coolron.service.impl")
@SpringBootApplication
@MapperScan("com.coolron.dao.*")
public class ApiServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(ApiServiceApplication.class, args);
    }
}

注解api 配置完成,详细请参看官网。

总结:

  1. dubbo提供了三种配置方式,dubbo xml为重点配置方式,也是官网资料相对其他几种较多的,可结合属性配置减少冗余代码。
  2. 超时并不代表代码有异常,默认超时会重连2次,避免重复数据等问题,业务中慎重考虑使用。且超时重连机制建议在服务提供方配置,其他地方不配置。
  3. 本章中xml的配置只在服务提供方有设计,服务消费方类似,使用dubbo:reference 标签接口,请参看官网。

代码地址:
https://gitee.com/cpla026/dubbo/tree/master/springboot-dubbo-parent

个人学习分享
更多 springboot、springcloud、docker 文章关注微信公众号吧:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/cp026la/article/details/86512112