分布式
什么是分布式?
最早期的web项目都是单一架构,如果用户访问量过大,我们只能将项目部署在多台服务器上来提高并发量。但是这种模型有一些问题,后来演变成了垂直架构
垂直架构:将项目拆分成多个不同的模块,各个模块之间互不关联(没有交互)。
垂直架构中模块拆分过多的时候,各个模块之间避免不了交互,但是垂直结构并不支持交互,此时就出现了SOA(面向服务架构)
SOA:SOA(面向服务架构)是一个架构思想,它的宗旨就是根据项目的服务完成架构的设计以及搭建,以服务为基础完成组件化和模块化。提供服务是项目的基本内容,而其他的controller层与view只是体现服务的一种方式(controller层使用服务层)。在一个项目中如果需要多个模块进行交互,可以用Dubbo来进行交互。
Maven的打包方式
1.jar
2.war
3.pom:专门为分布式服务的
maven项目的继承以及聚合
为什么要使用maven继承?
让多个模块的依赖版本号一致,对项目的依赖进行维护。maven的继承就是指子模块(子项目)可以自动继承父模块(父项目)的插件、依赖、属性等。假设我们有多个项目,则此时我们可以定义一个父项目,将所有的依赖写入到父项目中,子项目继承父项目即可。
继承流程
- 创建maven项目,将src目录删除,因为父项目中不用写代码,在pom文件中写入需要的依赖
- 在该项目中添加maven模块,此时会自动继承
maven的聚合
maven的聚合经常和继承一起使用,maven通过聚合将所有的子模块整合成一个整体,所有的子模块之间没有关系。maven的聚合是依靠modules标签完成的,父项目通过该标签可以整合所有的子项目,然后一起打包,我们使用maven命令对父项目进行操作的时候,所有module中的项目也会执行统一的操作。
<modules>
<module>子项目1</module>
<module>子项目2</module>
<module>子项目3</module>
</modules>
Dubbo
Dubbo是一个分布式服务器框架(RPC),Dubbo可以让我们实现多个项目之间进行数据的交互(可以让web项目相互调用)。
RPC:是指远程过程调用,简单来说它是一种进程之间的通讯方式,是一种技术思想,不是规范。
RPC有两个大模块:
- 通讯模块
- 序列化
dubbo是一款高性能,轻量级的开源javaRPC框架,它提供了三大核心功能:1.面向接口的远程方法调用 2.智能的容错和负载均衡 3.服务的自动和发现
dubbo中的核心角色
- 注册中心(registry):注册中心返回服务器提供方的地址列表给消费方,如果地址有变更,注册中心将基于长链接推送变更数据给消费者
- 监控中心(monitor):服务消费者和提供者在内存中积累调用次数和调用时间等都会定时每分钟发送一次统计数据到监控中心。
- 服务提供者(provider):暴露服务的服务提供方,服务提供在启动的时候会向注册中心注册自己提供的服务
- 服务消费者(consumer):调用远程服务的服务消费方,服务消费者在启动时,会向注册中心订阅自己需要的服务。服务消费者从提供者的地址列表中,基于软负载均衡算法选择一台提供者进行调用。如果调用失败,则在选其他的进行调用
0:服务提供者启动容器,加载运行服务提供者,根据服务提供者的配置文件将服务按照指定的协议发布,完成服务初始化工作。
1:服务初始化完成之后,根据配置的注册中心地址链接注册中心,将提供者的信息发布到注册中心上,向注册中心注册自己的服务。
2:服务消费者启动后,消费者根据配置文件的服务引用信息连接注册中心,向注册中心订阅自己需要的服务。
3:服务注册中心根据服务订阅的关系,返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送最新的服务地址信息给消费者。
4:服务消费者调用远程服务时,根据路由策略,从本地缓存的服务提供者地址列表中选择选一台提供者进行,然后根据协议类型建立链路,跨进程调用服务提供者,如果调用失败,再选另一台调用。
5:服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
zookeeper(ZK)
dubbo使用ZK作为自己的注册中心。zookeeper主要服务于分布式领域以及大数据领域,可以对集群信息进行统一的管理、统一的管理、统一命名等。
添加dubbo依赖
<!--dubbo依赖-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.8</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.13</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.13.0</version>
</dependency>
服务提供者:
编写需要暴露的接口
package com.zhiyou.service;
/**
* @author zhangruiyan
*/
public interface UserService {
public String getMsg();
}
------------------------------------------------
package com.zhiyou.service.impl;
import com.zhiyou.service.UserService;
import org.apache.dubbo.config.annotation.DubboService;
/**
* @author zhangruiyan
*/
@DubboService
public class UserServiceImpl implements UserService {
@Override
public String getMsg() {
return null;
}
}
修改配置
server:
port: 8888
dubbo:
application:
#服务名称,不能和别的服务提供者重复
name: provider
registry:
#指定注册中心
protocol: zookeeper
#注册中心的地址
address: 192.168.8.102:2181
#协议固定dubbo,服务暴露的接口
protocol:
name: dubbo
port: 20800
#dubbo扫描那个路径下的包
scan:
base-packages: com.zhiyou.service.impl
服务消费者:
controller
package com.zhiyou.controller;
import com.zhiyou.service.UserService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author zhangruiyan
*/
@RestController
public class UserController {
@DubboReference
UserService userService;
@GetMapping
public String hello(){
System.out.println("成功获取");
return userService.getMsg();
}
}
接口需要与服务提供者一致
package com.zhiyou.service;
/**
* @author zhangruiyan
*/
public interface UserService {
public String getMsg();
}
可以不用扫描包,需要修改端口号和服务名称
server:
port: 8081
dubbo:
application:
#服务名称,不能和别的服务提供者重复
name: consumer
registry:
#指定注册中心
protocol: zookeeper
#注册中心的地址
address: 192.168.8.102:2181
#协议固定dubbo,服务暴露的接口
protocol:
name: dubbo
port: 20800
需要在启动类上添加@EnableDubbo
开启dubbo注解