dubbo安装及使用
(新手笔记,存在错误还请指正)
尚硅谷dubbo
dubbo的github地址
dubbo官方文档
dubbo使用
dubbo和zookeeper的关系
dubbo和zookeeper的关系
zookeeper安装
zookpper安装
dubbo快速入门
概念
Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。(rpc的两个核心模块即:通讯,序列化。)
设计架构:
环境搭建
一、打开zookeeper
二、安装dubbo-admin管理控制台
dubbo本身并不是一个服务软件。它其实就是一个jar包能够帮你的java程序连接到zookeeper,并利用zookeeper消费、提供服务。所以不用在Linux上启动什么dubbo服务。
但是为了让用户更好的管理监控众多的dubbo服务,官方提供了一个可视化的监控程序,不过这个监控即使不装也不影响使用。
下载地址:
dubbo-admin
进入目录,修改dubbo-admin配置:
修改 src\main\resources\application.properties 指定zookeeper地址
打包dubbo-admin,cmd中运行:
mvn clean package -Dmaven.test.skip=true
运行dubbo-admin
java -jar dubbo-admin-0.0.1-SNAPSHOT.jar
在浏览器中访问localhost:7001即可访问管理页面(用户名密码均为root)
三、创建工程
需求:
某个电商系统,订单服务需要调用用户服务获取某个用户的所有地址;我们现在需要创建两个服务模块。
订单服务web模块:创建订单等
用户服务web模块:查询用户地址等
实现:两个模块在不同的服务器并且A可以远程调用B的功能。
1、服务提供者
定义一个实体bean,和一个服务提供service
public class UserAddress implements Serializable {
private Integer id;
private String userAddress;
private String userId;
private String consignee;
private String phoneNum;
private String isDefault;
public UserAddress() {
super();
}
public UserAddress(Integer id, String userAddress, String userId, String consignee, String phoneNum, String isDefault) {
this.id = id;
this.userAddress = userAddress;
this.userId = userId;
this.consignee = consignee;
this.phoneNum = phoneNum;
this.isDefault = isDefault;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserAddress() {
return userAddress;
}
public void setUserAddress(String userAddress) {
this.userAddress = userAddress;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getConsignee() {
return consignee;
}
public void setConsignee(String consignee) {
this.consignee = consignee;
}
public String getPhoneNum() {
return phoneNum;
}
public void setPhoneNum(String phoneNum) {
this.phoneNum = phoneNum;
}
public String getIsDefault() {
return isDefault;
}
public void setIsDefault(String isDefault) {
this.isDefault = isDefault;
}
@Override
public String toString() {
return "UserAddress{" +
"id=" + id +
", userAddress='" + userAddress + '\'' +
", userId='" + userId + '\'' +
", consignee='" + consignee + '\'' +
", phoneNum='" + phoneNum + '\'' +
", isDefault='" + isDefault + '\'' +
'}';
}
}
public class UserServiceImpl implements UserService {
@Override
public List<UserAddress> getUserAddressList(String userId) {
System.out.println("UserServiceImpl.....old...");
// TODO Auto-generated method stub
UserAddress address1 = new UserAddress(1, "北京市昌平区宏福科技园综合楼3层", "1", "李老师", "010-56253825", "Y");
UserAddress address2 = new UserAddress(2, "深圳市宝安区西部硅谷大厦B座3层(深圳分校)", "1", "王老师", "010-56253825", "N");
return Arrays.asList(address1,address2);
}
}
2、服务消费者
加入同样的bean实体和一个订单service
public class OrderServiceImpl implements OrderService {
UserService userService;
@Override
public List<UserAddress> initOrder(String userId) {
// TODO Auto-generated method stub
System.out.println("用户id:"+userId);
//1、查询用户的收货地址
List<UserAddress> addressList = userService.getUserAddressList(userId);
for (UserAddress userAddress : addressList) {
System.out.println(userAddress.getUserAddress());
}
return addressList;
}
}
但userservice和订单service在不同的工程中,这时就需要用到dubbo.
工程架构
1、分包
建议将服务接口,服务模型,服务异常等均放在 API 包中,因为服务模型及异常也是 API 的一部分,同时,这样做也符合分包原则:重用发布等价原则(REP),共同重用原则(CRP)。
如果需要,也可以考虑在 API 包中放置一份 spring 的引用配置,这样使用方便,只需在 spring 加载过程中引用此配置即可,配置建议放在模块的包目录下,以免冲突,如:com/alibaba/china/xxx/dubbo-reference.xml。
2、粒度
服务接口尽可能大粒度,每个服务方法应代表一个功能,而不是某功能的一个步骤,否则将面临分布式事务问题,Dubbo 暂未提供分布式事务支持。
服务接口建议以业务场景为单位划分,并对相近业务做抽象,防止接口数量爆炸。
不建议使用过于抽象的通用接口,如:Map query(Map),这样的接口没有明确语义,会给后期维护带来不便。
创建公共接口工程
创建公共接口工程,将上述bean和功能接口复制进去,将服务者和消费者的bean和service接口删掉:
在consumer和provider中引入公共接口依赖:
<dependency>
<groupId>org.example</groupId>
<artifactId>gmall-interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
引入dubbo
为了使订单service可以成功实现远程调用用户service,需要使用dubbo进行改造。
步骤:
1、将服务提供者注册到注册中心(暴露服务)
1)、导入dubbo依赖(2.6.2)\操作zookeeper的客户端(curator)
2)、配置服务提供者
2、让服务消费者去注册中心订阅服务提供者的服务地址
首先在服务和消费模块引入依赖:
<!--Dubbo的起步依赖,版本2.7之后统一为rg.apache.dubb -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.2</version>
</dependency>
<!--ZooKeeper客户端实现 -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.12.0</version>
</dependency>
服务端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://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
">
<!-- 配置提供者-->
<!--当前应用/服务的名字(同样的服务名字相同,不要和别的服务同名) -->
<dubbo:application name="user-service-provider"></dubbo:application>
<!--指定注册中心的地址 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181" />
<!--使用dubbo协议,将服务暴露在20880端口 -->
<dubbo:protocol name="dubbo" port="20880" />
<!-- 指定需要暴露的服务 ref:指向服务的真正实现对象-->
<dubbo:service interface="com.atguigu.gmall.service.UserService" ref="userServiceImpl" />
<bean id="userServiceImpl" class="com.atguigu.gmail.service.impl.UserServiceImpl"></bean>
</beans>
服务端consumer.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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.atguigu.gmall.service.impl"></context:component-scan>
<!-- 应用名 -->
<dubbo:application name="order-service-consumer"></dubbo:application>
<!-- 指定注册中心地址 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181" ></dubbo:registry>
<!-- 声明需要调用的远程服务的接口:生成远程服务代理,可以和本地bean一样使用demoService -->
<dubbo:reference id="userService" interface="com.atguigu.gmall.service.UserService"></dubbo:reference>
</beans>
在orderServiceImpl中给其加上@Service注解,将给userservice上加@Autowired注解注入容器。
启动服务
//服务端
public class MainApplication {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("classpath:provider.xml");
context.start();
System.in.read();
}
}
//消费端
public class MainApplication {
@SuppressWarnings("resource")
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("classpath:consumer.xml");
OrderService order = context.getBean(OrderService.class);
order.initOrder("1");
System.in.read();
}
}
两个应用启动成功后在dubbo admin管理页面就可以看到相应的信息。
访问initOrder请求,会调用UserService获取用户地址;
调用成功。说明我们order已经可以调用远程的UserService了;
监控中心安装
前面安装过的dubbo-admin是图形化的服务管理页面;安装时需要指定注册中心地址,即可从注册中心中获取到所有的提供者/消费者进行配置管理。
dubbo-monitor-simple是一个简单的监控中心;
安装步骤:
安装
1、下载 dubbo-ops
ops
2、修改配置指定注册中心地址
进入 dubbo-monitor-simple\src\main\resources\conf
修改 dubbo.properties文件
3、打包dubbo-monitor-simple
mvn clean package -Dmaven.test.skip=true
4、解压 tar.gz 文件,并运行dubbo-monitor-simple-2.0.0中bin目录下的start.bat
如果缺少servlet-api,自行导入servlet-api再访问监控中心
访问8080端口:
在consumer.xml和provider.xml中配置监控中心
<!-- 所有服务配置连接监控中心,进行监控统计-->
<!-- 监控中心协议,如果为protocol="registry",表示从注册中心发现监控中心地址,否则直连监控中心 -->
<dubbo:monitor protocol="registry"></dubbo:monitor>
与springboot整合
新建springboot的provider和consumer项目,将service实现复制进去,同样的将gmall-interface通用接口的依赖导入两个应用中。
引入dubbo和curator的依赖
在两个应用中引入依赖,注意springboot和dubbo的版本要适配。
<!-- 我的是springboot2.6.7-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.8</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.9</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
properties文件配置:
提供者配置:
dubbo.application.name=boot-user-service-provider
dubbo.registry.protocol=zookeeper
dubbo.registry.address=127.0.0.1:2181
dubbo.scan.base-package=com.atguigu.gmall #配置包扫描规则,开启了的话基于不用配置@EnableDubbo了
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
dubbo.monitor.protocol=registry
#application.name就是服务名,不能跟别的dubbo提供端重复
#registry.protocol 是指定注册中心协议
#registry.address 是注册中心的地址加端口号
#protocol.name 是分布式固定是dubbo,不要改。
#base-package 注解方式要扫描的包
消费者配置:
server.port=8081 #和监控中心端口号重叠,改一下
dubbo.application.name=boot-order-service-consumer
dubbo.registry.protocol=zookeeper
dubbo.registry.address=127.0.0.1:2181
dubbo.scan.base-package=com.atguigu.gmall
dubbo.protocol.name=dubbo
dubbo.monitor.protocol=registry
在要暴露的提供者服务上加上dubbo的@service注解
import org.apache.dubbo.config.annotation.DubboService;
@DubboService //暴露服务
@Component
public class UserServiceImpl implements UserService {
@Override
public List<UserAddress> getUserAddressList(String userId) {
......
}
在消费者服务中引入远程调用service注解
@Service
public class OrderServiceImpl implements OrderService {
//@Autowired
@DubboReference
UserService userService;
......
}
在两个应用中要开启dubbo功能
@EnableDubbo //开启基于注解的dubbo功能
@SpringBootApplication
public class BootOrderServiceConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(BootOrderServiceConsumerApplication.class, args);
}
}
在消费者服务中增加controller层
@Controller
public class OrderController {
@Autowired
OrderService orderService;
@ResponseBody
@RequestMapping("/initOrder")
public List<UserAddress> initOrder(@RequestParam("uid")String userId) {
return orderService.initOrder(userId);
}
}
访问如下地址
//随便带上一个uid
http://localhost:8081/initOrder?uid=1
访问成功:
dubbo配置
可以看我整理的另一篇文章:
dubbo配置
dubbo高可用
文章地址:
dubbo高可用
版权归原作者 sashaSloan 所有, 如有侵权,请联系我们删除。