主要内容
1.Dubbo简介
2.Dubbo架构讲解
3.Dubbo支持的协议
4.Dubbo支持的注册中心
5.第一个Dubbo的Provider
6.Admin管理界面搭建
7.完成Dubbo的Consumer
8.负载均衡
9.完整Dubbo项目演示
一.Dubbo简介
1.官方说明
Apache Dubbo是一个高可用的,基于Java的开源RPC框架
Dubbo框架不仅仅是具备RPC访问功能,还包含服务治理功能
2发展历史
Dubbo最开始是阿里巴巴内部使用的RPC框架
2011年对外提供
2012年停止更新
2017年开始继续更新
2019年捐献给Apache,由Apaceh维护2.7以上版本
二.Dubbo框架讲解
1.架构图
2.架构说明
2.1虚线
虚线表示异步,实现表示同步.异步不阻塞线程性能高,同步阻塞线程必须等待响应结果才能继续执行,相对性能低
2.2Provider
提供者.编写持久层,业务层和事务代码
2.3Container
容器(Spring容器),Dubbo完全基于Spring实现的
2.4Registry
注册中心.放置所有Provider对外提供的信息.包含Provider的IP,访问端口,访问遵守的协议,对外提供的接口,接口中有哪些方法等相关信息
2.5Consumer
消费者(RPC调用者,SOA调用服务的项目)开发中也是一个项目,编写service和controller(还可以包括页面等).调用远程服务实现(XXXServiceImpl)中的方法
2.6Monitor
监控中心.监控Provider的压力情况等.每个2分钟Consumer和Provider会把调用次数发送给Monitor,由Monitor进行统计
3.执行流程
0.start:启动Spring容器时会把Provider启动
1.register:把Provider相关信息注册到Registry里
2.subscribe:Consumer从Registry中订阅Provider的信息
3.notify:通知给Consumer
4.invoke:Consumer根据Registry通知的信息进行调用Provider中方法
5.count:Consumer和Provider把调用次数信息异步发送给Monitor进行统计
三.Dubbo支持的协议
1.Dubbo协议(官方推荐协议)
优点:
采用NIO复用单一长链接,并使用线程池并发处理请求,减少握手和加大并发效率,性能较好(推荐使用)协议的默认端口是:20880.(端口是服务端Provider占用的)
缺点:
大文件上传时,可能出现问题(不使用Dubbo实现文件传输)
2.RMI(Remote Method Invocation)协议
优点:
jdk自带的能力
缺点:
偶尔连接失败
3.Hessian协议
优点:
可与原生Hession互操作,基于HTTP协议
缺点:
需hession.jar支持,http短连接的开销大
四.Dubbo支持的注册中心
1.Zookeeper(官方推荐)
1)优点:
支持分布式,很多周边产品
2)缺点:
受限于Zookeeper软件的稳定性.Zookeeper专门分布式辅助软件,稳定性较优
2.Multicast
1)优点
去中心化,不需要单独安装软件
2)缺点:
2.2.1Provider,Consumer和Registry不能跨机房(路由)
3.Redis
1)优点:
支持集群,性能高
2)缺点:要求服务器时间同步,否则可能出现集群失败问题
4.Simple
1)优点:
标准RPC服务,没有兼容问题
2)缺点:
不支持集群
五.第一个Dubbo的Provider
新建父项目Parent1.最终结构如下:
编写pom.xml继承SpringBoot父项目
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
</parent>
1.新建api项目
1.1创建接口
创建com.bjsxt.dubbo.service.DemoDubboService接口
public interface DemoDubboService{
String demo();
}
2.新建propvider项目
2.1编写pom.xml
注意:不需要依赖web,如果依赖spring-boot-start-web还需要考虑端口问题
<dependencies>
<dependency>
<artifactId>api</artifactId>
<groupId>com.bjsxt</groupId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.3</version>
<dependency>
<dependency>
<groupId>prg.apache.curator</groupId>
<artifactId>curator-recipes<a/rtifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.2.0</version>
</dependency>
</dependencies>
2.2编写配置文件
新建application.yml
dubbo:
application:
name: dubbo-provider
registry:
address: zookeeper://192.168.232.132:2181
2.3先进实现类
先进com.bjsxt.dubbo.service.impl.DemoDubboServiceImpl
注意:
注解是apache的注解
import com.bjsxt.dubbo.service.DemoDubboService;
import org.apache.dubbo.config.annotation.Service;
@Service
public class DemoDubboServiceImpl implements DemoDubboService{
@Override
public String demo(){
System.out.println("demo方法");
return "123";
}
}
2.4新建启动类
新建com.bjext.ProviderApplication
必须要有@EnableDubbo注解,否则Dubbo不生效
@SpringBootApplication
@EnableDubbo
public class ProviderApplication{
public static void main(String[] args){ SpringApplication.run(ProviderApplication.class,args);
}
}
六.Admin管理界面搭建
01资料中把dubbo-admin-server-0.2.0.jar\BOOT-INF\classes中application.properties里面注册中心的ip设置正确
使用java -jar dubbo-admin-server-0.2.0.jar运行即可.访问http://localhost:8080可以进入Dubbo Admin管理控制台
注意:占用8080端口,不要冲突了.如果需要修改端口,增加配置server.port=新端口号
七.完成Dubbo的Consumer
创建consumer项目
1.编写pom.xml
<dependencies>
<dependency>
<artifactId>api</artifactId>
<groupId>com.bjsxt</groupId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>spring-boot-starter-web</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.2.0</version>
</dependency>
</dependencies>
2.新建配置文件
新建application.yml
dubbo:
application:
name: dubbo-consumer
registry:
address: zookeeper://192.168.232.132:2181
3.新建service及实现类
新建com.bjsxt.service.DemoService
新建com.bjsxt.service.impl.DemoServiceImpl
调用服务使用@Reference注解,不要导错包了,有两个
public interface DemoService{
String comsumerDemo();
}
import com.bjsxt.dubbo.service.DemoDubboService;
import com.bjsxt.service.DemoService;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Service;
@Service
public class DemoServiceImpl implements DemoService{
@Reference
private DemoDubboService demoDubboService;
@override
public String consumerDemo(){
return demoDubboService.demo();
}
}
4.新建控制器
新建控制器com.bjsxt.controller.DemoController
@Controller
publci class DemoController{
@Autowired
private DemoService demoService;
@RequestMapping("/demo")
@ResponseBody
public String demo(){
return demoService.consumerDemo();
}
}
5.新建启动器
先进com.bjsxt.ConsumerApplication
@SpringBootApplication
@EnableDubbo
public class ConsumerApplication{
public static void main(String[] args){
SpringApplication.run(ConsumerApplication.class,args);
}
}
八.负载均衡
集群:一个内容,部署多次,形成的整体称为集群.集群中每个个体应该部署到不同的服务器上.
伪集群:集群中内部部署到同一台服务器上,通过不同端口区分不同个体
负载均衡是在集群前提下,当访问整个集群时,集群中每个节点被访问次数或频率的规则
Dubbo内置了四个负载均衡策略.默认为Random
负载均衡策略的决定规则:
1.Provider方默认负载均衡策略是Random,随机策略
2.Consumer方默认负载均衡策略不设定,使用Provider提供的负载均衡策略
3.如果双方都设置了负载均衡策略,使用Consumer的负载均衡策略,因为局部优先,Provider是给所有的Consumer提供服务的,负载均衡策略也是给所有的Consumer提供的默认策略.Consumer的负载均衡策略只局限在当前消费端,是一个局部策略
1.内置策略
1.1Random
随机.随机访问集群中节点.访问概率和权重有关
1.2RoundRobin
轮训.访问评率和权重有关
权重(weight):占有比例.集群中,每个项目部署的服务器的性能可能是不同,性能好的服务器权重应该高一些
1.3LeastActive
活页数相同的随机,不同的活跃数高的放前面
1.4ConsistentHash
一致性Hash.相同参数请求总是发到一个提供者
2.Provider集群
新建四个启动类
每次启动启动类修改配置文件dubbo.protocal.port.默认20880
3.设置负载均衡
3.1@Reference
调用的服务采用的负载均衡
@Reference(loadbalance="roundrobin")
private DemoDubboService demoDubboService;
3.2@Service
当前服务采用的负载均衡算法
@Service(loadbalance="random")
public class DemoDubboServiceImpl implements DemoDubboService{
设置权重
@Service(weight=4)
}
3.3配置文件
全局设置所有provider和consumer的负载均衡效果
dubbo:
application:
name: dubbo-provider
registry:
address: zookeeper://192.168.232.132:2181
protocol:
port: 20884
provider;
loadbalance: random
consumer:
loadbalance: random
九.注解常用属性详解
1.group分组
为服务人为划分组别.Provider可以在不同的组中注册类似的服务.Consumer可以指定获取远程服务所在分组,获取徐亚ode远程服务.通过分组属性,可以更清晰的管理服务.
Provider注册服务到userGroup分组,注解如下:
@Service(group="userGroup")
Consumer获取userGroup分组下的指定服务,注解如下:
@Reference(group="userGroup")
2.version版本
为服务定制版本.Provider可以为同一个服务发布多个版本的实现.Consumer可以根据具体情况,获取指定版本的服务代理对象.通过版本属性,可以让服务的应用更加细致.
Provider注册服务版本,注解如下:
@Service(group="userGroup",version="1.0")
Consumer获取指定版本的服务,注解如下:
@Service(group="userGroup",version="1.0")
3.payload限制
在Dubbo中,默认限制请求和应答最大容量为8M(8388608).当请求或应答数据容量超标时,会抛出异常.需要通过配置文件设置更大的限制,具体如下:
dubbo:
registry:
address: zookeeper://192.168.232.132:2181
application:
name:dubbo-first-consumer
provider:
payload:83886080 # 设置请求和应答容量限制为8M
十.完整Dubbo项目演示
1.原型
1.1部门显示
显示全部部门信息
1.2员工新增
1.3查看部门员工
2.按照分布式架构进行设计项目
设定员工管理和部门不在同一个模块,需要有一个员工管理项目和一个部门管理项目.
为了方便,不去每个项目使用一个窗口,而是使用聚合项目
3.创建数据库表
create table dept(
id int(11) primary key auto_increment,
name varchar(20)
);
insert into dept values(default,'开发部');
insert into dept values(default,'产品部');
create table emp(
id int(11) primary key auto_increment,
name varchar(20),
photo varchar(200),
did int(11),
CONSTRAINT fk_emp_dept FOREIGN key (did) REFERENCES dept(id)
);
4.使用逆向工程
略
5.创建父项目
5.1创建项目parent
5.2编写pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</depenency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.apaceh.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
</depenencies>
</depenencyManagement>
6.创建pojo项目
把逆向工程代码粘贴进来
7.创建mapper项目
71.编写pom.xml
<dependencies>
<dependency>
<artifactId>pojo</artifactId>
<groupId>com.bjsxt</groupId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</depenency>
</dependencies>
7.2新建配置文件
先进application-mybatis.yml
spring:
datasource:
driver-class-name:com.mysql.cj.jdbc.Driver
url:jdbc:mysql://localhost:3306/maven?serverTimezone=GMT%2B8
username:root
password:root
mybatis:
mapper-location:classpath:mybatis/*.xml
type-aliases-package:com.bjsxt.pojo
从逆向工程中把mapper接口和mapper.xml粘贴进行
8.先进api项目
8.1编写pom.xml
<dependencies>
<dependency>pojo</dependency>
<groupId>com.bjsxt</groupId>
<version>1.0-SNAPSHOT</version>
</dependencies>
9.先进provider
9.1编写pom.xml
<dependencies>
<dependency>
<artifactId>mapper</artifactId>
<groupId>com.bjsxt</groupId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<artifactId>api</artifactId>
<groupId>com.bjsxt</groupId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
</dependency>
</dependencies>
9.2先进配置文件
新建application.yml
dubbo:
application:
name:dubbo-provider
registry:
address: zookeeper://192.168.232.132:2181
#加载其他配置文件,加载其他application-*.yml文件,多个名称之间使用逗号分隔
spring:
profiles:
active:mybatis
9.3新建启动类
先进com.bjsxt.ProviderApplication
@SpringBootApplication
@EnableDubbo
@MapperScan("com.bjsxt.mapper")
public class ProviderApplication{
public static void main(String[] args){
SpringApplication.run(ProviderApplication.class,args);
}
}
10.完成Dept查询功能
10.1在api中先进接口
com.bjsxt.dubbo.servcie.DeptDubboService
public interfacr DeptDubboService{
List<Dept>selectAll();
}
10.2在provider中先进实现类
com.bsjxt.dubbo.service.DeptDubboServiceImpl
@Service
public class DeptDubboServiceImpl implements DeptDubboService{
@Autowired
private DeptMapper deptMapper;
@Override
public List<Dept>selectAll(){
return deptMapper.selectByExample(null);
}
}
10.3新建项目dept
10.3.1添加依赖
<dependencies>
<dependency>
<artifactId>api</artifactId>
<groupId>com.bjsxt</groupId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
</dependency>
<dependency>
<groupId>oeg.apache.curator</groupId>
<artifactId>curator-framework</artifatId>
</dependency>
</dependencies>
10.3.2编写配置文件
新建application.yml
dubbo:
application:
name:dubo-dept-consumer
registry:
address: zookeeper://192.168.232.132:2181
10.3.3新建启动类
com.bjsxt.DeptApplication
@SrpingBootApplication
@EnableDubbo
public class DeptApplication{
publci static void main(String[] args){
SpringApplication.run(DeptApplication.class,args);
}
}
10.4新建接口及实现类
接口:com.bjsxt.service.DeptService
实现类:com.bjsxt.service.impl.DeptServiceImpl
public interface DeptService{
List<Dept>showAll();
}
@Servcie
public class DeptServcieImpl implements DeptService{
@Reference
private DeptDubboService deptDubboServcie;
@Override
public List<Dept>showAll(){
return deptDubboService.selectAll();
};
}
10.3.5新建控制器
com.bjsxt.controller.DeptController
@Controller
public class DeptController{
@Autowired
private DeptServcie deptService;
@GetMapping("/dept")
public String showDept(Model model){
model.addAttribute("list",deptService.showAll());
return "dept";
}
}
10.3.6新建页面
在resources/templates新建dept.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<table border="1" width="500">
<tr>
<th>编号</th>
<th>部门名称</th>
<th>查看</th>
</tr>
<tr th:each="dept:${list}">
<td th:text="${dept.id}"></td>w
<td th:text="${dept.name}"></td>
<td><a th:href="@{/showEmp(did=${dept.id})}">查看</a></td>.
</tr>
</table>
</body>
</html>