上手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 ...
随机推荐
- 如何在GitHub上上传自己本地的项目?(很适合新手使用哦!)
这是我看了一些大佬们的博客后,尝试了几次,终于成功了上传项目,所以想做一下总结,以便以后查看,同时想分享给才接触GitHub的新手们,希望能够有所帮助~ 条条大路通罗马,上传的方法肯定不止一种,等我学 ...
- 基于sparksql collect_list的udf定义踩坑
多条collect_list,然后将collect_list的结果concat起来,最初使用的是concat_ws(),但是发现超过4个collect_list就会报错, select concat_ ...
- C++的精度控制
#include <iostream> #include <iomanip> using namespace std; int main( void ) { const dou ...
- python实例:利用jieba库,分析统计金庸名著《倚天屠龙记》中人物名出现次数并排序
本实例主要用到python的jieba库 首先当然是安装pip install jieba 这里比较关键的是如下几个步骤: 加载文本,分析文本 txt=open("C:\\Users\\Be ...
- 体验RxJava
RxJava是 ReactiveX在 Java上的开源的实现,简单概括,它就是一个实现异步操作的库,使用时最直观的感受就是在使用一个观察者模式的框架来完成我们的业务需求: 其实java已经有了现成的观 ...
- unity_实用小技巧(空指针错误)
在游戏开发中,空指针错误是我们最常见也是最容易出现的错误.下面介绍一下博主近期遇见的空指针错误 如上图,有两个类,如果此时我们在图2中调用图1的单例模式可能会出现空指针错误. 原因在于:编译器可能先执 ...
- HDU 6053(莫比乌斯反演)
题意略. 思路:首先想到暴力去扫,这样的复杂度是n * min(ai),对于gcd = p,对答案的贡献应该是 (a1 / p) * (a2 / p) * .... * (an / p),得出这个贡献 ...
- Keras(一)Sequential与Model模型、Keras基本结构功能
keras介绍与基本的模型保存 思维导图 1.keras网络结构 2.keras网络配置 3.keras预处理功能 模型的节点信息提取 config = model.get_config() 把mod ...
- DB2 根据id查表
SELECT * FROM SYSCAT.TABLES WHERE TBSPACEID = 2 AND TABLEID = 50 SELECT * FROM SYSCAT.COLUMNS WHERE ...
- SDU暑期集训排位(3)
B. Mysterious LCM 做法 保留 \(a_i|x\) 的元素,其它元素解体. \(a_i\) 的某个质因子的指数,要和 \(x\) 的这个质因子一样多,才有贡献,否则这个质因子它在划水啊 ...