目前分布式开发应用中,使用较多的一个RPC框架。
基础知识
分布式基础理论
分布式系统
分布式系统是若干独立计算机的集合,这些计算机对于用户来说就单个系统。
架构发展演变
单一应用架构
当网站流量很小的时候,只需要一个应用,将所有的功能部署在一起,以减少部署节点和成本。此时,用于简化增删改查工作量的数据访问框架(ORM)是关键。
- 优点
- 可以将整个应用打包部署在一台服务器中,开发、部署简单
- 可以部署多台,分担流量压力
- 缺点
- 不易扩展,添加一个功能,需要重新打包整个应用,重新部署到多台服务器
- 协作开发不容易
- 单台服务器跑很大的程序时,压力会比较大,已经不能带来性能上的提升了
垂直应用架构
可以将单体应用独立拆分为单个小的应用,并独立部署到不同的服务器上
- 优点
- 分工合作容易,每个人开发单独的应用,互不干扰
- 易扩展,可以单独部署某个小的应用集群,之前是带着一整个完整的应用扩展
- 缺点
- 市场上对页面需要经常改动,改动页面就需要重新部署这个应用
- 应用不可能完全独立,也需要应用之间相互交互
分布式应用架构
随着吹着应用越来越多,应用之间还需要交互,可以将核心功能抽取
A服务器调B服务器,代码之间调用为RPC(远程过程调用)
难点:
- 如何进行远程过程调用
- 如何拆分业务,提升复用性
流动计算架构
调度中心负责维护调度之间的复杂关系,以及实施管理服务集群。
基于访问压力,实时管理集群容量,提高集群利用率。
RPC简介
RPC基本原理
网络之间传递数据,都需要进行序列化。
影响RPC框架:
- 通信效率:能否快速建立连接
- 序列化效率:序列化与反序列化的速度
Dubbo核心概念
Dubbo架构
注册中心
官方推荐Zookeeper。
Zookeeper注册中心官网地址
Zookeeper(注册中心)
下载
官网
下载列表地址
下载了3.4.11版本
3.4.11下载链接
安装
tar -zxvf zookeeper-3.4.11.tar.gz
启动服务端
进入bin目录
cd bin
启动(Linux)
./zkServer.sh start
报错:
原因:
zoo.cfg文件在conf目录下没有
复制zoo_sample.cfg目录复制一份,并修改名称为zoo.cfg
cp zoo_sample.cfg zoo.cfg
创建data文件夹,并在zoo.cfg配置中指定目录用来存储文件
mkdir data
再次启动即可。
./zkServer.sh start
使用zookeeper的客户端来连接
启动客户端
./zkCli.sh
常用命令
zookeeper是个树形目录结构
查看根节点数据
get /
查看根节点下的节点
ls /
创建临时节点
#创建一个临时节点 test001 值为abc
create -e /test001 abc
搭建测试完成!
Monitor(监控中心)
可选,不影响操作, 帮助用户通过可视化界面管理服务,查看情况。
下载
生产者工程环境搭建
pom
<modelVersion>4.0.0</modelVersion>
<groupId>com.xiu.gmall</groupId>
<artifactId>user-service-provider</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
</dependency>
</dependencies>
实体类:
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @author zhangzengxiu
* @date 2023/3/18
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserAddress implements Serializable {
private static final long serialVersionUID = -5242080009018461173L;
private Integer id;
/**
* 用户地址
*/
private String userAddress;
/**
* 用户id
*/
private String userId;
/**
* 收货人
*/
private String consignee;
/**
* 电话号码
*/
private String phoneNum;
/**
* 是否默认地址
*/
private String isDefault;
}
接口:
import com.xiu.bean.UserAddress;
import java.util.List;
/**
* @author zhangzengxiu
* @date 2023/3/18
*/
public interface UserService {
/**
* 获取用户地址列表
*
* @param userId 用户id
* @return
*/
public List<UserAddress> getUserAddressList(String userId);
}
接口实现类:
import com.xiu.bean.UserAddress;
import com.xiu.service.UserService;
import java.util.Arrays;
import java.util.List;
/**
* @author zhangzengxiu
* @date 2023/3/18
*/
public class UserServiceImpl implements UserService {
public List<UserAddress> getUserAddressList(String userId) {
UserAddress userAddress1 = new UserAddress(1, "北京市xxxxx", "1", "张三", "12345678902", "Y");
UserAddress userAddress2 = new UserAddress(2, "杭州市xxxxx", "1", "张三", "12345678902", "N");
return Arrays.asList(userAddress1, userAddress2);
}
}
消费者工程环境搭建
pom
接口:
此时需要调用user-service中的接口,但是该服务部署在其他服务器上,所以并不能通过本地jar包的形式进行引用,需要调用需要如下操作:
将provider中的bean及其接口复制一份到consumer中:
此时会出现的问题:
- 本次调用会失败,因为接口的真正实现类在provider中;
- 如果多个服务都调用了UserService接口,需要在多个项目中都要维护该接口,十分繁琐
我们可以将通用的bean和接口抽取到一个工程中:
dubbo官方也建议我们将服务模型,接口,服务异常等均放在我们的api包下。
其他需要用到的服务进行依赖api包。
公共模块抽取
将接口和bean放在公共模块中,其他服务依赖该服务。
坐标:
<dependency>
<groupId>com.xiu.gmall</groupId>
<artifactId>gmall-interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
因为我们依赖的接口的真正实现是在其他的服务中,到时候甚至会部署到不同的服务器上,此时就需要进行远程调用才行。
Dubbo进行改造
步骤:
- 将服务提供者注册到注册中心(暴露服务)
- 消费者去注册中心订阅服务提供者的地址
将服务注册到注册中心,需要导入dubbo的依赖。
导入dubbo和zookeeper的依赖
2.6dubbo及以后版本的zookeeper用的是
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.12.0</version>
</dependency>
2.6之前用的是
<dependency>
<groupId>com.101tec