分布式服务dubbo
时间:2023-05-06 20:07:00
第九章 Dubbo
1. Dubbo的发展背景
随着互联网的发展,网站应用的规模不断扩大,传统的垂直应用架构无法应对。分布式服务架构和移动计算架构势在必行,需要一个管理系统来确保架构的有序发展。
[外链图片存储失败,源站可能有防盗链机制,建议保存图片直接上传(img-fExrWkHq-1602494371674)(https://ae01.alicdn.com/kf/H8d8556092f7b4d59921529a161412470O.png)]
1.1 单一应用架构
当网站流量非常小时时只需要一个应用程序来部署所有功能,以降低部署节点和成本。 此时,用于简化数据访问框架访问框架(ORM)是关键。用一个web容器(如tomcat),然后使用Servlet/JSP最后,选择合适的数据库管理系统存储数据(MySQL、Oracle)。
1.2 垂直应用架构
当访问量逐渐增加时,单个应用程序增加机器的加速度越来越小。提高效率的方法之一是将应用程序拆分为几个不相关的应用
,以提高效率。
此时,用于加快前端页面的开发Web框架(MVC)是关键。
用户系统、权限系统、商品系统、订单系统、物流系统…
特点:独立部署系统,每个系统都有完整的前后端;
问题:各个系统无法做到完全独立,公共模块无法复用,系统之间通信比较麻烦;
1.3 分布式服务架构
独立服务
,逐步形成稳定的服务中心,使前端应用能够更快地响应多变的市场需求。此时,分布式服务框架用于改善业务再利用和集成(RPC)是关键。
分布式架构的难点:
- 如何远程调用每个系统?
- 如何拆分业务?
1.4 流动计算架构
当越来越多的服务、容量评估、小型服务资源的浪费等问题逐渐出现时,需要根据访问压力增加调度中心,实时管理集群容量,提高集群利用率。此时,用于提高机器利用率的资源调度和管理中心(SOA)是关键。
2.RPC
RPC(Remote Procedure Call)- 远程过程调用是一种网络技术协议,通过网络从远程计算机程序中要求服务,无需了解底层。RPC假设存在某种传输协议(如TCP),为通信程序携带数据;一般来说,RPC远程计算机提供的服务可以像调用本地方法一样调用;
2.1 RPC简单原理
[外链图片存储失败,源站可能有防盗链机制,建议保存图片直接上传(img-MiZ7OC2C-1602494371684)(https://ae01.alicdn.com/kf/Hf87aef8fc1314dd696b626b9d9a99551s.png)]
- 客户端以本地调用的方式调用远程服务
- client stub接到调用后,将方法、参数等组装成网络传输信息;
- client stub找到服务地址后,将消息发送到服务端;
- server stub收到消息后,解码收到的消息;
- server stub根据解码结果,通过反射调用本地服务;
- 服务端执行完成后,返回结果Server stub;
- server stub将返回结果打包成消息并发送给客户端;
- client stub收到消息后,解码结果;
3. Dubbo
Apache Dubbo高性能 Java RPC框架
。
Apache Dubbo |?d?b??| 高性能、轻量级开源Java RPC它提供了三个核心能力:调用面向接口的远程方法,智能容错和负载平衡, 自动注册和发现服务。
3.1 Dubbo架构
1. 构建中的角色
- Provider :服务提供者
- Consumer :服务消费者
- Registry :中心的服务注册和发现
- Monitor :统计服务调用监控中心
- Container : Dubbo的容器
[外链图片存储失败,源站可能有防盗链机制,建议保存图片直接上传(img-V6RtSRDw-1602494371688)(https://ae02.alicdn.com/kf/Ha1e1718a05e545e5bcec9f268fa807adK.png)]
2. 调用关系
- 负责启动、加载和运行服务提供商
- 启动时,服务提供商应向注册中心注册自己提供的服务
- 当服务消费者开始时,他们订阅注册中心所需的服务
- 注册中心将服务提供商的地址列表返回给消费者。如果有服务变更(在线和离线服务),注册中心将通过长连接向消费者推送变更
- 基于地址列表的服务**软件负载聚恒算法**,如果调用失败,可以选择服务提供商进行调用。
- 为消费者和提供者服务,在内存中累计调用时间和次数,每分钟向监控中心发送统计数据。
4. 安装单机Zookeeper
4.1 windows 版本
-
解压zookeeper-3.4.12.tar.gz 到当前目录
-
在 zookeeper-3.4.12 目录下创建
data
目录[外链图片存储失败,源站可能有防盗链机制,建议保存图片直接上传(img-xySseaGU-1602494371693)(https://ae01.alicdn.com/kf/H2265729af51e43498cd2b848e6bc545d0.png)]
-
将
zookeeper-3.4.12/conf
目录下的zoo_sample.cfg
重命名文件zoo.cfg
[外链图片存储失败,源站可能有防盗链机制,建议保存图片直接上传(img-jqI0pNVm-1602494371696)(https://ae03.alicdn.com/kf/Hebfa5db0720a4650805653e83f2a2049v.png)] -
修改
zoo.cfg
文件中的dataDir
选项[外链图片存储失败,源站可能有防盗链机制,建议保存图片直接上传(img-3pC4AbTc-1602494371698)(https://ae01.alicdn.com/kf/H2b2484131b324d4caf53959d68115e53U.png)]
-
双击 zookeeper-3.4.12/bin/zkServer.cmd ,启动服务端
[外链图片存储失败,源站可能有防盗链机制,建议保存图片直接上传(img-3yFXrDCS-1602494371699)(https://ae01.alicdn.com/kf/He0fb1d817ff34bb28eefb34ca85879b5C.png)]
- 双击 zookeeper-3.4.12/bin/zkCli.cmd ,启动客户端
[外链图片存储失败,源站可能有防盗链机制,建议保存图片直接上传(img-hy4IYze9-1602494371701)(https://ae04.alicdn.com/kf/H23c84676e2e8495f83ebc63f731e9b002.png)]
4.2 Linux / Mac 版本
- 将 zookeeper-3.4.12.tar.gz 上传到
/opt
目录
#在压缩包目录中 运行git bash scp zookeeper-3.4.12.tar.gz root@ip:/opt #解压 压缩包 tar -zxvf zookeeper-3.4.12.tar.gz -C /opt
#创建软连接
ln -s zookeeper-3.4.12.tar.gz zookeeper
- 进入zookeeper 创建data 目录
cd zookeeper
mkdir data
- 进入zookeeper-3.4.12.tar.gz/conf目录下,将zoo_sample.cfg修改为zoo.cfg
cd conf
mv zoo_sample.cfg zoo.cfg
- 编辑zoo.cfg
vim zoo.cfg
# 输入12GA 将dataDir修改为 ../data
- 启动zookeeper服务
cd ../bin
./zkServer.sh start
- 启动ZK客户端
./zkCli.sh
5. Dubbo控制台安装
-
dubbo主要用于服务治理
-
可以通过控制台查看所有服务
-
可以设置负载均衡、权重调节、服务降级策略等
#控制台默认访问地址 http://localhost:7001 #默认的用户名和密码 root / root
-
在dubbo-admin.jar 所在的目录运行 cmd
java -jar dubbo-admin.jar 即可
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-71B7loOM-1602494371703)(https://ae02.alicdn.com/kf/H8098147f09e64c52bf8b0ce501b16a0cJ.png)]
6. dubbo普通工程
6.1创建maven父工程 dubbo-hello
- 引入maven依赖
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>dubboartifactId>
<version>2.6.5version>
<exclusions>
<exclusion>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.2.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.apache.curatorgroupId>
<artifactId>curator-frameworkartifactId>
<version>2.13.0version>
dependency>
dependencies>
dependencyManagement>
6.2 创建子工程服务接口 dubbo-hello-interface
- 创建服务接口
/** * 服务接口 * * 服务提供者实现这个接口 提供服务 * 消费者引用这个接口 消费服务 */
public interface HelloService {
String sayHello(String name);
}
- 创建本地存根,[暂时这个工程不需要]
/* *使用本地存根需要在服务接口的包下创建 [接口名字]Stub类 *继承自[接口名字]类 */
package com.etoak.service;
public class HelloServiceStub implements HelloService{
HelloService helloService;
public HelloServiceStub(HelloService helloService) {
this.helloService = helloService;
}
@Override
public String sayHello(String name) {
if(name != null && !"".equals(name) ){
return helloService.sayHello(name);
}
return "参数异常";
}
}
6.3 创建消息提供者 [dubbo-hello-provider]
- 引入maven依赖
<dependencies>
<dependency>
<artifactId>dubbo-hello-interfaceartifactId>
<groupId>com.etoak.et1912.dubbogroupId>
<version>1.0-SNAPSHOTversion>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>dubboartifactId>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
dependency>
<dependency>
<groupId>org.apache.curatorgroupId>
<artifactId>curator-frameworkartifactId>
dependency>
dependencies>
- 配置provider.xml
<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">
<dubbo:application name="hello-provider" >dubbo:application>
<dubbo:registry address="zookeeper://127.0.0.1:2181" >dubbo:registry>
<dubbo:protocol name="dubbo" port="20880" />
<dubbo:service interface="com.etoak.service.HelloService" ref="helloService" stub="true"/>
<bean id="helloService" class="com.etoak.service.HelloServiceImpl" >bean>
beans>
- 书写服务提供类
package com.etoak.service;
public class HelloServiceImpl implements HelloService{
@Override
public String sayHello(String name) {
return String.format("Hello %s",name);
}
}
- 书写测试类
package com.etoak.test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
public class ProviderMain {
public static void main(String[] args) throws IOException {
new ClassPathXmlApplicationContext("provider.xml");
System.in.read();
}
}
-
运行测试类即可在测试端或者网页管理器中查看到注册的服务
- 在客户端查看已经注册的服务
ls /dubbo ls /dubbo/[service name] ls /dubbo/[service name]/provider
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NMkZohIW-1602494371705)(https://ae02.alicdn.com/kf/Hb8b621867fa145b3b3fc9b112c71b8ecY.png)]
- 在浏览器查看消息提供者
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NxbkRqXP-1602494371706)(https://ae02.alicdn.com/kf/He5fd4a7a4e054e88b5ee1507fffcab2fG.png)]
6.4 创建消息消费者 [dubbo-hello-consumer]
- 引入maven依赖
<dependencies>
<dependency>
<artifactId>dubbo-hello-interfaceartifactId>
<groupId>com.etoak.et1912.dubbogroupId>
<version>1.0-SNAPSHOTversion>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>dubboartifactId>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
dependency>
<dependency>
<groupId>org.apache.curatorgroupId>
<artifactId>curator-frameworkartifactId>
dependency>
dependencies>
- 配置consumer.xml
<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">
<dubbo:application name="hello-consumer" />
<dubbo:registry address="zookeeper://127.0.0.1:2181" />
<dubbo:reference id="helloService" interface="com.etoak.service.HelloService">dubbo:reference>
beans>
- 创建消费者
package com.etoak.test;
import com.etoak.service.HelloService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
public class ConsumerMain {
public static void main(String[] args) throws IOException {
ApplicationContext ioc = new ClassPathXmlApplicationContext("consumer.xml");
//获取远程服务的代理对象
HelloService helloService = ioc.getBean(HelloService.class);
String result = helloService.sayHello("");
System.out.println(result);
System.in.read();
}
}
- 在控制端和网页端查看消费者
-
在控制端查看
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aLI99lem-1602494371708)(https://ae04.alicdn.com/kf/H3213ad17eb8a4e3e94d527ee35823a7aG.png)]
-
在网页端查看
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XuZ1SEvW-1602494371710)(https://ae04.alicdn.com/kf/H372640990885404a8d64a2170a9fabf7g.png)]
7. dubbo 整合 springmvc
7.1 创建父工程[dubbo-mvc]
- 创建maven工程 dubbo-mvc,并引入maven依赖
<dependencyManagement>
<dependencies>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
<version>3.1.0version>
<scope>providedscope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webartifactId>
<version>5.2.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.2.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-context-supportartifactId>
<version>5.2.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>5.2.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-txartifactId>
<version>5.2.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.thymeleafgroupId>
<artifactId>thymeleafartifactId>
<version>3.0.11.RELEASEversion>
dependency>
<dependency>
<groupId>org.thymeleafgroupId>
<artifactId>thymeleaf-spring5artifactId>
<version>3.0.11.RELEASEversion>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.9.5version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.46version>
dependency>
<dependency