分布式
分布式系统理论
分布式Dubbo+Zookeeper+SpringBoot
什么是分布式系统
分布式系统是由一组通过网络进行通信,为了完成共同的任务而协调工作的计算机节点组成的系统。分布式系统的出现是为了用廉价的、普通的机器完成单个计算机无法完成的计算、存储任务。其目的是利用更多的机器,处理更多的数据
分布式系统(distributed system)是建立在网络之上的软件系统
RPC
RPC【Remote Procedure Call】是指远程过程调用,是一种进程间通信方式,他是一种技术的思想,而不是规范,他允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,而不是程序员显示编码这个远程远程调用的细节。即程序员无论是调用本地的还是远程的函数,本质上编写的调用代码基本相同
也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据
为什么要用RPC呢,就是无法在一个进程内,甚至一个计算机内通过本地调用的方式完成的需求,比如不同的系统间的通讯,甚至不同的组织间的通讯,由于计算能力需要横向扩展,需要在多台机器组成的集群上部署应用
RPC就是要像调用本地的函数一样去调用远程函数
RPC两个核心模块:通讯,序列化:数据传输需要转换
Dubbo及Zookeeper安装
什么是dubbo
Apache Dubbo 是一款高性能、轻量级的开源Java RPC框架,他提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现
服务提供者(Provider):暴露服务的服务提供放,服务提供者在启动时,向注册中心注册自己提供的服务
服务消费者(Consumer):调用远程服务的服务消费方,服务消费者在启动时,向注册中心订阅自己所需的服务,服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用
注册中心(Registry):注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者
监控中心(Monitor):服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心
安装zookeeper
下载zookeeper apache-zookeeper-3.6.2-bin.tar.gz
https://downloads.apache.org/zookeeper/zookeeper-3.6.2/
运行/bin/zkServer.md
配置CLASSPATH环境变量
变量名为CLASSPATH,变量值为 .;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;
/conf/ 复制zoo_sample.cfg 重命名为zoo.cfg
运行/bin/zkServer.md
运行/bin/zkCli.md 连接
安装dubbo-admin
用jdk1.8版本,不要用新的
dubbo本身并不是一个服务软件,其实就是一个jar包,能够帮你的java程序连接到zookeeper,并利用zookeeper消费,提供服务
但是为了让用户更好的管理监控众多的dubbo服务,官方提供了一个可视化的监控程序dubb-admin,不过这个监控即使不装也不影响使用
下载dubbo-admin
https://github.com/apache/dubbo-admin/tree/master
解压进入目录
修改dubbo-admin\src\main\resources\application.properties 指定zookeeper地址
在项目目录下打包dubbo-admin
mvn clean package -Dmaven.test.skip=true
直接在命令行下执行,而不是powershell
PowerShell 窗口下,执行带参数的需要’单引号’包起来才可以
执行dubbo-admin\target下的dubbo-admin-0.0.1-SNAPSHOT.jar(zookeeper的服务一定要打开)
java -jar dubbo-admin-0.0.1-SNAPSHOT.jar
访问http://localhost:7001/ 这时候需要输入登录账户和密码,我们都是默认的root-root
dubbo-admin 是一个监控管理后台~可以查看注册了哪些服务,哪些服务被消费了
Dubbo:jar包
服务注册发现实战
pom文件不生效,解决办法
- 右击pom文件 add as maven project
- 或者 project structure Module import module 导入pom文件
新建一个空工程
- 新建一个spring initializer 命名为 provider-server 勾选web
- 新建一个spring initializer 命名为 consumer-server 勾选web
provider-service 导入依赖 Dubbo+zookeeper
<!-- https://mvnrepository.com/artifact/org.apache.dubbo/dubbo-spring-boot-starter -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.8</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.sgroschupf/zkclient -->
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>
<!--日志会冲突-->
<!-- https://mvnrepository.com/artifact/org.apache.curator/curator-framework -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>5.1.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.curator/curator-recipes -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>5.1.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.6.2</version>
<!--排除这个slf4j-log4j12-->
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
provider-server
配置
server.port=8001
#服务应用名字
dubbo.application.name=provicer-server
#注册中心地址
dubbo.registry.address=zookeeper:/127.0.0.1:2181
#哪些服务要被注册
dubbo.scan.base-packages=com.company.service
package com.company.service;
public interface TicketService {
String getTicket();
}
package com.company.service;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.stereotype.Component;
//zookeeper:服务注册与发现
@Service //可以被扫描到,在项目以启动就自动注册到注册中心
@Component//使用了Dubbo后尽量不要用service注解
public class TicketServiceImpl implements TicketService{
@Override
public String getTicket() {
return "明";
}
}
启动出错:解决
-
配置文件配置超时时间
-
dubbo.config-center.timeout=10
-
windows 查看端口被占用情况
-
netstat -aon|findstr "8080"
-
强制终止
-
taskkill /f /pid 进程号
启动成功后,
运行java -jar dubbo-xx.jar
访问localhost:7001/ 在服务治理下/服务 可以看到TicketService
注意Dubbo注解不要导错了
服务端
导入依赖
<!-- https://mvnrepository.com/artifact/org.apache.dubbo/dubbo-spring-boot-starter -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.8</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.sgroschupf/zkclient -->
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>
<!--日志会冲突-->
<!-- https://mvnrepository.com/artifact/org.apache.curator/curator-framework -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>5.1.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.curator/curator-recipes -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>5.1.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.6.2</version>
<!--排除这个slf4j-log4j12-->
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
配置
server.port=8002
#消费者去哪里拿服务需要暴露自己的名字
dubbo.application.name=consumer-server
#注册中心地址
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.config-center.timeout=10
消费
package com.company.service;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Service;
@Service //放到容器中
public class UserService {
//想拿到provider提供的票
@Reference //引用,pom坐标,可以定义路径相同的接口名
TicketService ticketService;
public void buyTicket(){
String ticket = ticketService.getTicket();
System.out.println("在注册中心拿到=》"+ticket);
}
}
总结
前提:zookeeper服务已开启
服务者提供服务
- 导入依赖
- 配置注册中心的地址,以及服务发现名,和要扫描的包
- 在想要被注册的服务上面,增加一个注解@service (不是Spring的注解)(新版的是@DubboService)
消费者消费
- 导入依赖
- 配置注册中心的地址,配置自己的服务名
- 从远程注入服务~@Reference
微服务架构问题
分布式架构遇到的四个核心问题
- 这么多服务,客户端如何去访问
- 这么多服务,服务之间如何通信
- 这么多服务,如何治理
- 服务挂了,怎么办
解决方案
-
SpringCloud,是一套生态,就是来解决以上分布式架构的4个问题
SpringCloud是基于SpringBoot
1.SpringCloud NetFlix
Api网关 zuul组件
Feign -》HttpClient-》Http的通信方式,同步并阻塞
服务注册与发现,Eureka
熔断机制,Hystrix
2.Apache Dubbo zookeeper
Api:没有,要么找第三方组件,要么自己实现
Dubbo是一个高性能的基于Java实现的RPC通信框架
服务注册与发现,zookeeper:动物园管理者(Hadoop,Hive)
3.SpringCloud Alibaba 一站式解决方案
目前,又提出一种方案:
- 服务网格:下一代微服务标准 Server Mesh
- 代表解决方案:istio(未来可能需要掌握)
一通百通:
- API网关,服务路由
- HTTP,RPC框架,异步调用
- 服务注册与发现,高可用
- 熔断机制,服务降级
不要停止学习的脚步,程序员学无止境