上手Dubbo之 环境搭建
和传统ssm整合--写XML配置文件
搭建服务的提供者和服务的消费者,实现服务消费者跨应用远程调用服务提供者
公共模块抽取
- 公共模块的抽取
服务的消费者远程调用服务的提供者, 最起码他自己要得到在服务提供者提供服务的那个类的引用, 那消费者和服务的一人一份,如果是集群就会翻倍,故抽取公共模块,存放公共使用的类和接口
服务提供者
- 依赖
// 自定义的公共模块
<dependency>
<groupId>com.changwu</groupId>
<artifactId>commom</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.3</version>
</dependency>
- 编写提供服务的业务Service, 对接口进行具体的实现
public class UserServiceImpl implements UserService {
public List<UserAddress> getUserAddressList() {
UserAddress a1= new UserAddress(1,"张三","北京市朝阳区");
UserAddress a2= new UserAddress(2,"李四","山东济南");
return Arrays.asList(a1,a2);
}
}
- 编写配置文件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://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<!-- 暴露服务提供者, name=服务名(不能和其他服务名重复) -->
<dubbo:application name="user-service-provider" />
<!-- z指定zookeeper的地址 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181" />
<!-- 指定通信规则,通信协议, 通信端口. 服务消费者和dubbo之间的通信-->
<dubbo:protocol name="dubbo" port="20880" />
<!-- 声明需要暴露的服务接口 ref=服务的真正实现, 下面使用<bean>调用-->
<dubbo:service interface="com.changwu.service.UserService" ref="userService" />
<!-- 接口的实现 -->
<bean id="userService" class="com.changwu.service.impl.UserServiceImpl" />
<dubbo:monitor protocol="registry"></dubbo:monitor>
</beans>
schema配置参考手册, 点击查看全部标签,及详细解释
补充: 属性配置的重写覆盖优先级
- 优先级最高 JVM 启动时 使用-D设置参数
- 次之,dubbo.xml
- 再次之 dubbo.properties
如下,是一个典型的dubbo.properties配置样例。
dubbo.application.name=foo
dubbo.application.owner=bar
dubbo.registry.address=10.20.153.10:9090
- idea设置虚拟机启动参数
- log4j配置文件,(不添加的话会有警告)
###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
服务的消费者
- 依赖
// 自定义的公共模块
<dependency>
<groupId>com.changwu</groupId>
<artifactId>commom</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
// zk的客户端依赖 curator
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.13.0</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.13</version>
</dependency>
- 编写consumer.xml
编写配置文件自己的服务名,配置注册中心的地址,进而向注册中心拉取服务的列表,配置当前的消费者中使用的哪些接口是通过远程RPC调用实现的, 还可以配置监控中心查看服务的健康情况,彼此的调用情况,别忘了使用Spring注解还得配置包扫描
<?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://dubbo.apache.org/schema/dubbo" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
<dubbo:application name="order-service" />
<!--注册中心地址 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181" />
<!-- 生成远程服务代理,可以和本地bean一样使用 userService -->
<dubbo:reference id="userService" interface="com.changwu.service.UserService" />
<!--添加包扫描-->
<context:component-scan base-package="com.changwu"></context:component-scan>
<!--配置监控中心,有下面两种方式 1. 去注册中心自动发现, 2. 直连模式-->
<dubbo:monitor protocol="registry"></dubbo:monitor>
<!-- <dubbo:monitor address="127.0.0.1:7070"></dubbo:monitor>-->
</beans>
- 消费者调用服务提供者的实现
下面的@Service注解使用的Spring原生的
@Service // 没有用dubbo的service注解
public class OrderServiceImpl implements OrderService {
@Autowired
UserService userService;
public List initOrder(String userId) {
// 查询用户的地址
System.out.println("userId == "+userId);
List<UserAddress> userAddressList = userService.getUserAddressList("1");
for (UserAddress userAddress : userAddressList) {
System.out.println(userAddress.getAdress());
}
return userAddressList;
}
}
- 启动测试
public class MainApp {
public static void main(String[] args) {
ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("consumer.xml");
OrderService orderService = ioc.getBean(OrderService.class);
orderService.initOrder("1");
try {
System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
}
}
整合Springboot
公共模块
同样重复使用类,接口放到中,然后在其它模块引用
服务提供者
- 依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.changwu</groupId>
<artifactId>common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--
dubbo整合进springboot
zookeeper,curate它都已经导入进来了
-->
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
- 将provider.xml配置文件替换成application.properties
可以将xml的tag名和属性名组合起来,用‘.’分隔。每行一个属性
# 指定当前的服务, 一般为了防止重复,设置成当前module的名字
dubbo.application.name=provider
# 指定注册中心的地址
dubbo.registry.address=127.0.0.1:2181
dubbo.registry.protocol=zookeeper
# dubbo 使用的协议
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
# 原配置文件中暴露服务的名字,使用类似下面的方式,但是在SpringBoot中使用 @Service注解(dubbo的)
# dubbo.service.interface=com.changwu.service.UserService
# 监控中心
dubbo.monitor.protocol=registry
server.port=8082
- 服务提供者对接口进行实现
@Service使用的dubbo的接口
@Component
@Service //使用dubbo的Service 对外保留服务
public class UserServiceImpl implements UserService {
public List<UserAddress> getUserAddressList(String userId) {
UserAddress a1= new UserAddress(1,"张三","北京市朝阳区");
UserAddress a2= new UserAddress(2,"李四","山东济南");
return Arrays.asList(a1,a2);
}
}
- 启动类,开启dubbo配置
@EnableDubbo
@SpringBootApplication
public class ProviderApp {
public static void main(String[] args) {
SpringApplication.run(ProviderApp.class);
}
}
服务的消费者
- 依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.changwu</groupId>
<artifactId>common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
- 使用application.properties配置文件替换consumer.xml
# 告诉注册中心自己的名字
dubbo.application.name=consumer
# 注册中心的地址
dubbo.registry.address=zookeeper://127.0.0.1:2181
# 配置监控中心
dubbo.monitor.protocol=registry
# 原来在配置文件中使用 dubbo:reference 配置远程调用的接口,现在用注解
server.port=8081
- 远程调用@Reference dubbo注解
@Service
public class OrderServiceImpl implements OrderService{
//@Autowired
@Reference // dubbo的注解
UserService userService;
public List<UserAddress> initOrder(String userId) {
return userService.getUserAddressList("1");
}
}
- 编写Controller
- 启动类, 开启dubbo配置
@EnableDubbo
@SpringBootApplication
public class MainApp {
public static void main(String[] args) {
SpringApplication.run(MainApp.class);
}
}
其他常用配置
示例, dubbo常用的配置示例
启动时检查
服务的消费者在启动是会去检查自己需要远程调用的服务是否已经注册到了 注册中心中, 一旦检查到注册中心没有检查到即使没有调用这个方法也会自动报错而阻止Spring启动,在开发时,可以选择手动关掉这个配置
- 通过配置文件
配置某个服务启动时检查
在服务消费者中,关闭某个服务的启动时检查 (没有提供者时报错):
<dubbo:reference interface="com.foo.BarService" check="false" />
统一配置全部服务启动时不检查
关闭所有服务的启动时检查 (没有提供者时报错):
<dubbo:consumer check="false" />
默认是true. 表示注册中心不存在时报错
关闭注册中心启动时检查 (注册订阅失败时报错):
<dubbo:registry check="false" />
- 通过dubbo.properties
dubbo.reference.com.foo.BarService.check=false
dubbo.reference.check=false
dubbo.consumer.check=false
dubbo.registry.check=false
- 通过JVM参数
java -Ddubbo.reference.com.foo.BarService.check=false
java -Ddubbo.reference.check=false
java -Ddubbo.consumer.check=false
java -Ddubbo.registry.check=false
超时设置
消费者远程调用服务提供者, 服务提供者的实现逻辑可能存在大量的耗时操作,这是就可能存在大量的线程阻塞在这个方法上, 超时设置解决了这个问题,一旦在指定的时间内,依然没有返回任何数据,同样会立即返回,保证系统的可用
缺省使用dubbo:consumer的timeout, 而dubbo:cosumer中默认的超时时间是 1000ms
如下,设置超时时间为3秒
<!-- 生成远程服务代理,可以和本地bean一样使用 userService -->
<dubbo:reference id="userService" interface="com.changwu.service.UserService" timeout="3000"/>
从上图中,我标记了他们的作用,最优先的就是方法级别, 接口次之 , 全局级别最低 , -- 相同级别的消费者设置优先,提供者设置次之
重试次数
一般超时配置timeout 和 重试次数retries 配合使用
调用失败后,会根据重试的次数再次尝试远程调用, 重试次数不包含第一次,如果我们配置的3, 算上第一次,最多尝试调用四次
如果服务提供者存在集群, 消费者就会轮询集群进行重试
- 幂等次数
- 查询,删除,修改(特点是,同样的请求,同样的参数无论执行多少次,产生的结果都是一样的), 设置重试次数
- 非幂等
- 新增,不设置幂等次数, retries=0
<!-- 生成远程服务代理,可以和本地bean一样使用 userService -->
<dubbo:reference id="userService" interface="com.changwu.service.UserService" retries="3" timeout="3000"/>
多版本
我们给系统的某些功能进行了升级,但是不能一下把升级后的代码一次性全部适用到集群中的全部机器上,使用多版本控制,先把集群中的一小部分机器进行升级,没有出现不可用现象再逐步拓展规模,最终完成全部替换
新旧版本的服务提供者全部继承同一个接口com.foo.BarService , 通过ref指向不同的实现Bean
老版本服务提供者配置:
<dubbo:service interface="com.foo.BarService" version="1.0.0" ref="userService1" />
<bean id="userService1" class="xxx">
新版本服务提供者配置:
<dubbo:service interface="com.foo.BarService" version="2.0.0" ref="userService2"/>
<bean id="userService2" class="yyy">
老版本服务消费者配置:
<dubbo:reference id="barService" interface="com.foo.BarService" version="1.0.0" />
新版本服务消费者配置:
<dubbo:reference id="barService" interface="com.foo.BarService" version="2.0.0" />
如果不需要区分版本,可以按照以下的方式配置 [1]:
<dubbo:reference id="barService" interface="com.foo.BarService" version="*" />
本地存根
如果想在服务的消费者发送远程过程调用其他方法之前进行,进行参数的验证,如,判空处理, 可以选择使用本地存根
如, UserService 是某个服务提供者实现的, 消费者远程调用这个服务,进行如下配置消费者在本地提供自己的实现,并判断参数的合法性
public class UserServiceImpl implements UserService{
// 注入这个被服务提供者支持的接口
private final UserService userService;
// 提供构造函数
public UserServiceImpl(UserService userService) {
this.userService = userService;
}
@Override
public List<UserAddress> getUserAddressList(String userId) {
// 判空
if (!StringUtils.isEmpty(userId)){
return userService.getUserAddressList(userId);
}
return null;
}
}
- 配置文件
在 spring 配置文件中按以下方式配置:
# 是消费者在本地自己的实现 com.changwu.service.UserServiceImpl
<dubbo:service interface="com.changwu.service.UserServiceImpl" stub="true" />
或
<dubbo:service interface="com.foo.BarService" stub="com.changwu.service.UserServiceImpl" />
Dubbo和SpringBoot整合的三种方式
方法1
- 引入dubbo-starter
- 在主配置类上使用@EnableDubbo (指定 包扫描规则)
- 在application.properties配置属性
- 服务提供者: 使用 @Service 暴露服务
- 服务消费者: 使用 @Reference 引用服务
方法2
如果还想添加诸如方法级别的配置,则保留dubboxml的配置文件
- 在启动类上去掉@EnableDubbo注解
- 在启动类上添加@ImportResource(localtion="classpath:provider/consumer.xml")
- 去掉 application.properties 中的有关dubbo配置
- 服务提供者使用 provider.xml 配置文件
- 服务消费者是有 consumer.xml 配置文件
方法3 注解配置
要求使用dubbo为2.6.3
上手Dubbo之 环境搭建的更多相关文章
- 【转载】Maven+druid+MyBatis+Spring+Oracle+Dubbo开发环境搭建
原地址:http://blog.csdn.net/wp1603710463/article/details/48247817#t16 Maven+druid+MyBatis+spring+Oracle ...
- Dubbo简单环境搭建
Dubbo服务的发展和作用: 首先,看下一般网站架构随着业务的发展,逻辑越来越复杂,数据量越来越大,交互越来越多之后的常规方案演进历程. 其次,当服务越来越多之后,我们需要做哪些服务治理? 最后,是d ...
- Dubbo系列(二)dubbo的环境搭建
dubbo是一个分布式服务框架,提供一个SOA的解决方案.简单的说,dubbo就像在生产者和消费者中间架起了一座桥梁,使之能透明交互.本文旨在搭建一个可供使用和测试的dubbo环境,使用了spring ...
- 【2020-03-21】Dubbo本地环境搭建-实现服务注册和消费
前言 本周主题:加班工作.本周内忙于CRUD不能自拔,基本每天都是九点半下班,下周上线,明天还要加班推进进度.今天是休息日,于是重拾起了dubbo,打算近期深入了解一下其使用和原理.之所以说是重拾,是 ...
- 构建第一个Spring Boot2.0应用之集成dubbo上---环境搭建(九)
一.环境: Windows: IDE:IntelliJ IDEA 2017.1.1 JDK:1.8.0_161 Maven:3.3.9 springboot:2.0.2.RELEASE Linux(C ...
- Maven+druid+MyBatis+Spring+Oracle+Dubbo开发环境搭建
1.开发工具使用: MyEclipse或Eclipse,数据库使用Oracle.需要用到的软件有Zookeeper(注册中心),Tomcat(Web容器)和Maven(包管理). 2.初始环境配置: ...
- 初学者易上手的SSH-hibernate01环境搭建
这里我们继续学习SSH框架中的另一框架-hibernate.那么hibernate是什么?Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序 ...
- dubbo + zookeeper 环境搭建
一.zookeeper windows部署 1.下载安装 到官网下载解压版后解压至F:\server\zookeeper-3.4.8,剩下为文件配置工作: 2.本地伪集群 1) 在F:\server\ ...
- Zookeeper+Dubbo+SpringMVC环境搭建
项目码云GIT地址:https://gitee.com/xshuai/dubbo/ 开发工具 MyEclipse 10.7 JDK 1.7 容器 Tomcat 8(运行dubbo) zookeeper ...
随机推荐
- python匿名函数的介绍及用途
匿名函数 用lambda能够创建一个匿名函数,这中函数得名于省略了用def声明函数的标准步骤. 语法 lambda [arg1 [,arg2,.....argn]]:expression 如何使用 我 ...
- TinyMCE使用
1.文本&文本字体颜色 与word类似不赘述 2.字体加粗&划线 与word类似不赘述 选中后 ctrl + B 加粗快捷键 选中后 ctrl + I 斜体快捷键 选中后 c ...
- 敏捷开发--必备工具Jira&Confluence学习视频
敏捷开发必备工具:Jira+confluence,完美组合. 入门培训视频,内含Jira, Confluence, BigGantt, Zephyr, Tempo, Question, ScriptR ...
- 使用MTA HTML5统计API来分析数据
使用MTA HTML5统计API来分析数据 在开发个人博客的时候,用到了腾讯移动分析(MTA),相比其他数据统计平台来说我喜欢她的简洁高效,易上手,同时文档也比较全面,提供了数据接口供用户调用. 在看 ...
- vim基础命令,查找和替换
vim 基本命令查找和替换 vim简单的命令用着还好.比如插入,删除,查询.但替换就用的比较少.所以,还是需要用的时候拿出来对照者看. 使用vim编辑文件: vim xxx 进入之后的界面叫做命令模式 ...
- 剑指Offer(二十一):栈的压入、弹出序列
剑指Offer(二十一):栈的压入.弹出序列 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/b ...
- python学习——文件操作
打开文件 f = open(文件名, 文件打开模式,文件编码) ‘w’:只写模式,它是只能写,而不能读的.如果用’w’模式打开一个不存在的文件,则会创建新的文件开始写入:如果用’w’模式打开一个已存在 ...
- Centos安装和配置Mysql5.7
[root@localhost ~]# wget https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm -bash ...
- emlog博客的安装教程
简介 emlog 是一款基于PHP和MySQL的功能强大的博客及CMS建站系统.致力于为您提供快速.稳定,且在使用上又极其简单.舒适的内容创作及站点搭建服务. 安装步骤 1.将src文件夹下的所有文件 ...
- 使用docker快速搭建Permeate渗透测试系统实践
一.背景 笔者最近在做一场Web安全培训,其中需要搭建一套安全测试环境:在挑选渗透测试系统的时候发现permeate渗透测试系统比较满足需求,便选择了此系统:为了简化这个步骤,笔者将系统直接封装到了d ...