【Dubbo】
主要内容
- Dubbo简介
- Dubbo架构讲解
- Dubbo支持的协议
- Dubbo支持的注册中心
- Dubbo应用
- Admin管理界面搭建
- 完成Dubbo的Consumer
- 负载均衡
- 完整Dubbo项目演示
学习目标
知识点 要求
Dubbo简介 掌握
Dubbo架构讲解 精通
Dubbo支持的协议 掌握
Dubbo支持的注册中心 掌握
第一个Dubbo的Provider 掌握
Admin管理界面搭建 掌握
完成Dubbo的Consumer 掌握
负载均衡 掌握
完整Dubbo项目演示 掌握
一、 Dubbo简介
1 官方说明
Apache Dubbo 是一个高可用的,基于Java的开源RPC框架。
Dubbo框架不仅仅是具备RPC访问功能,还包含服务治理功能。
2 发展历史
Dubbo是最开始是阿里巴巴内部使用的RPC框架。
2011年对外提供。
2012年停止更新。
2017年开始继续更新。
2019年捐献给Apache,由Apache维护2.7以上版本。
二、 Dubbo架构讲解
1 架构图
2 架构说明
2.1 虚线
虚线表示异步,实线表示同步。异步不阻塞线程性能高,同步阻塞线程必须等待响应结果才能继续执行,相对性能低。
2.2 Provider
提供者。编写持久层和事务代码。
2.3 Container
容器(Spring容器),Dubbo完全基于Spring实现的。
2.4 Registry
注册中心。放置所有Provider对外提供的信息。包含Provider的IP,访问端口,访问遵守的协议,对外提供的接口,接口中有哪些方法等相关信息。
2.5 Consumer
消费者(RPC调用者,SOA调用服务的项目)开发中也是一个项目,编写service和controller(还可以包含页面等)。调用XXXXServiceImpl中的方法。
2.6 Monitor
监控中心。监控Provider的压力情况等。每隔2分钟Consumer和Provider会把调用次数发送给Monitor,由Monitor进行统计。
3 执行流程
0. start:启动Spring容器时会把Provider启动。
- register:把Provider相关信息注册到Registry里
- subscribe:Consumer从Registry中订阅Provider的信息
- notify:通知给Consumer
- invoke:Consumer根据Registry通知的信息进行调用Provider中方法。
- count:Consumer和Provider把调用次数信息异步发送给Monitor进行统计。
三、 Dubbo支持的协议
1 Dubbo协议(官方推荐协议)
优点:
采用NIO复用单一长连接,并使用线程池并发处理请求,减少握手和加大并发效率,性能较好(推荐使用)
缺点:
大文件上传时,可能出现问题(不使用Dubbo文件上传)
2 RMI(Remote Method Invocation)协议
优点:
JDK自带的能力。
缺点:
偶尔连接失败.
3 Hessian协议
优点:
可与原生Hessian互操作,基于HTTP协议
缺点:
需hessian.jar支持,http短连接的开销大
四、 Dubbo支持的注册中心
1 Zookeeper(官方推荐)
- 优点:
支持分布式.很多周边产品. - 缺点:
受限于Zookeeper软件的稳定性.Zookeeper专门分布式辅助软件,稳定较优
2 Multicast - 优点:
去中心化,不需要单独安装软件. - 缺点:
2.2.1 Provider和Consumer和Registry不能跨机房(路由)
3 Redis - 优点:
支持集群,性能高 - 缺点:
要求服务器时间同步.否则可能出现集群失败问题.
4 Simple - 优点:
标准RPC服务.没有兼容问题 - 缺点:
不支持集群.
五、 Dubbo应用
1 创建父工程
1.1 新建父项目double
1.2 修改POM文件
<?xml version="1.0" encoding="UTF-8"?>
4.0.0
<groupId>com.bjsxt</groupId>
<artifactId>dubbo_parent</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>api</module>
<module>consumer</module>
<module>provider</module>
</modules>
<properties>
<spring.version>5.1.11.RELEASE</spring.version>
<mybatis.version>3.5.1</mybatis.version>
<mybatis.spring>2.0.1</mybatis.spring>
<servlet.version>3.1.0</servlet.version>
<jsp.version>2.0</jsp.version>
<jstl.version>1.2</jstl.version>
<log4j.version>1.2.17</log4j.version>
<slf4j-api.version>1.7.12</slf4j-api.version>
<mysqlconnection.version>5.1.38</mysqlconnection.version>
<aspectjweaver.version>1.9.4</aspectjweaver.version>
<dubbo.version>2.7.3</dubbo.version>
<curator.version>4.2.0</curator.version>
</properties>
<dependencyManagement>
<dependencies>
<!--Spring-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<!--Log4j-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<!--MysqlDriver-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysqlconnection.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectjweaver.version}</version>
</dependency>
<!--Mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis.spring}</version>
</dependency>
<!-- Servlet And JSP-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>${jsp.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>${curator.version}</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>${curator.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
2 新建api项目
2.1 创建接口
创建com.bjsxt.dubbo.service.DemoDubboService接口
public interface DemoDubboService {
String showMsg(String str);
}
3 新建provider项目
3.1 修改pom.xml
注意:不需要依赖web
com.bjsxt
api
1.0-SNAPSHOT
org.apache.dubbo
dubbo
org.apache.curator
curator-recipes
org.apache.curator
curator-framework
3.2 创建DemoDubboServiceImpl接口实现类
import com.bjsxt.dubbo.service.DemoDubboService;
public class DemoDubboServiceImpl implements DemoDubboService {
@Override
public String showMsg(String str) {
return "Hello "+str;
}
}
3.3 编写配置文件
3.3.1 配置文件位置
配置文件必须放到resources/META-INF/spring/*.xml
3.3.2 配置文件内容
<dubbo:application name=“myprovider”/>
<dubbo:registry address=“192.168.40.138:2181” protocol=“zookeeper”/>
<dubbot:protocol name=“dubbo” port=“20880”/>
<dubbo:service interface=“com.bjsxt.dubbo.service.DemoDubboService” ref=“service”/>
基于注解
接口实现类
import com.bjsxt.api.DemoDubboService;
import org.apache.dubbo.config.annotation.Service;
@Service
public class DemoDubboServiceImpl implements DemoDubboService {
@Override
public String showMsg(String str) {
return str+" Hello";
}
}
配置文件
<!--配置服务名称-->
<dubbo:application name="myProvider"/>
<!--配置注册中心地址以及访问协议-->
<dubbo:registry address="192.168.40.150:2181" protocol="zookeeper"/>
<!--服务访问协议-->
<dubbo:protocol name="dubbo" port="20880"/>
<!--dubbo扫描自己@Service注解-->
<dubbo:annotation package="com.bjsxt.provider.impl"/>
3.4 创建Dubbo的启动类
import org.apache.dubbo.container.Main;
public class Start {
public static void main(String[] args) {
Main.main(args);
}
}
3.5 使用Zookeeper客户端工具查看注册信息
ls /dubbo/服务接口名称/providers
3.5.1 解码前
dubbo%3A%2F%2F192.168.153.1%3A20880%2Fcom.bjsxt.dubbo.service.DemoDubboService%3Fanyhost%3Dtrue%26application%3Dmyprovider%26bean.name%3Dcom.bjsxt.dubbo.service.DemoDubboService%26deprecated%3Dfalse%26dubbo%3D2.0.2%26dynamic%3Dtrue%26generic%3Dfalse%26interface%3Dcom.bjsxt.dubbo.service.DemoDubboService%26methods%3DshowMsg%26pid%3D16920%26register%3Dtrue%26release%3D2.7.3%26side%3Dprovider%26timestamp%3D1577027345488
3.5.2 解码后
dubbo://192.168.153.1:20880/com.bjsxt.dubbo.service.DemoDubboService?anyhost=true&application=myprovider&bean.name=com.bjsxt.dubbo.service.DemoDubboService&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&interface=com.bjsxt.dubbo.service.DemoDubboService&methods=showMsg&pid=16920®ister=true&release=2.7.3&side=provider×tamp=1577027345488
六、 Admin管理界面搭建
01资料中把dubbo-admin-server-0.2.0.jar\BOOT-INF\classes 中application.properties里面注册中心的ip设置正确
使用java -jar dubbo-admin-server-0.2.0.jar运行即可。
注意:占用8080端口,不要冲突了。
七、 完成Dubbo的Consumer
创建consumer项目web工程
1 编写pom.xml
dubbo_parent
com.bjsxt
1.0-SNAPSHOT
war
4.0.0
consumer
com.bjsxt
api
1.0-SNAPSHOT
org.springframework
spring-context
org.apache.dubbo
dubbo
org.apache.curator
curator-recipes
org.apache.curator
curator-framework
org.springframework
spring-web
org.springframework
spring-webmvc
org.apache.tomcat.maven
tomcat7-maven-plugin
2.2
8081
2 创建业务层
2.1 接口
public interface DemoDubboConsumerService {
String find(String str);
}
2.2 接口实现类
import com.bjsxt.dubbo.service.DemoDubboService;
import com.bjsxt.consumer.service.DemoDubboConsumerService;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Service;
@Service
public class DemoDubboConsumerServiceImpl implements DemoDubboConsumerService {
@Reference
private DemoDubboService demoDubboService;
@Override
public String find(String str) {
return this.demoDubboService.showMsg(str);
}
}
3 新建dubbo配置文件
配置文件位置正常放在resources目录下。
<dubbo:application name=“myconsumer”/>
<dubbo:registry address=“192.168.40.138:2181” protocol=“zookeeper”/>
<dubbo:annotation package=“com.bjsxt.consumer.service”/>
4 添加web.xml、springmvc、spring配置文件
5 创建Controller
@Controller
public class DemoController {
@Autowired
private DemoDubboService demoDubboService;
@RequestMapping("/find")
public String find(String str, Model model){
String msg = this.demoDubboService.showMsg(str);
model.addAttribute("msg",msg);
return "showMsg";
}
}
6 创建JSP页面
<%@ page contentType=“text/html;charset=UTF-8” language=“java” %>
${msg}
7 测试
八、 负载均衡
集群:一个内容,部署多次,形成的整体称为集群。集群中每个个体应该部署到不同的服务器上。
伪集群:集群中内容部署到同一台服务器上,通过不同端口区分不同个体。
负载均衡是在集群前提下,当访问整个集群时,集群中每个节点被访问次数或频率的规则。
Dubbo 内置了四个负载均衡策略。默认为Random
1 内置策略
1.1 Random
随机。随机访问集群中节点。访问概率和权重有关。
1.2 RoundRobin
轮询。访问频率和权重有关。
权重(weight):占有比例。集群中每个项目部署的服务器的性能可能是不同,性能好的服务器权重应该高一些。
1.3 LeastActive
活跃数相同的随机,不同的活跃数高的放前面。
1.4 ConsistentHash
一致性Hash。相同参数请求总是发到一个提供者。
2 Provider集群
新建四个启动类。
每次启动启动类修改配置文件dubbo.protocal.port
3 设置负载均衡
3.1 @Reference
调用的服务采用的负载均衡
@Reference(loadbalance = “roundrobin”)
private DemoDubboService demoDubboService;
3.2 @Service
当前服务采用的负载均衡算法
@Service(loadbalance = “random”)
public class DemoDubboServiceImpl implements DemoDubboService {
设置权重
@Service(weight = 4)
九、 MyBatis逆向工程
十、 完整Dubbo项目演示