Dubbo
Dubbo
java分布式框架
服务框架
分布式系统中相关概念
大型互联网项目架构的目标
- 传统项目和互联网项目
传统项目:OA,HR等企业员工使用
互联网项目:微信等网民使用
注重用户体验:美观,功能,速度,稳定性
互联网项目特点:用户多、流量大,并发高、海量数据、易受攻击、功能繁琐、变更快
- 衡量网站的性能指标
响应时间: 指执行一个请求从开始到最后收到响应数据所花费的总体时间。
并发数:指系统同时能处理的请求数量
并发连接数:指的是客户端向服务器发起请求,并建立了TCP连接。每秒钟服务器连接的总TCP数量请求数:也称为QPS(Query Per Second)指每秒多少请求
并发用户数:单位时间内有多少用户
吞吐量:指单位时间内系统能处理的请求数量
QPS:QueryPer Second 每秒查询数
TPS:Transactions Per Secdd 每秒事务数。
一个事务是指一个客户机向服务器发送请求然后服务器做出反应的过程。客户机在发送请求时开始计时,收到服务器响应后结束计时,以此来计算使用的时间和完成的事务个数。
一个页面的一次访问,只会形成一个TPS,但一次页面请求,可能产生多次对服务器的请求,就会有多个QPS
QPS >= 并发连接数>= TPS
- 大型互联网项目架构目标
高性能:提供快速的访问体验
高可用:网站服务一直可以正常访问
可伸缩:通过硬件增加/减少,提高/降低处理能力。
高可扩展:系统间羯合低,方便的通过新增/移除方式,增加/减少新的功能/模块
安全性:提供网站安全访问和数据加密,安全存储等策略敏捷性:随需应变,快速响应。
集群和分布式
集群:很多机器做同一件事
分布式:很多机器做不同的事,很多事能组成一件更大的事
高性能,高可用
可伸缩:某个模块性能比较低,就在模块添加机器
高可扩展:去掉不好的模块替换好的模块
集群:一个业务模块,部署在多态服务器上
分布式:一个大的业务系统,拆分为小的业务模块,分别部署在不同的机器上
架构演进
单体架构(多机的单体架构)--->垂直架构--->分布式架构--->SOA架构--->微服务架构
单体架构:项目启动慢,里面模块过多,可靠性差,某一个模块挂了整个项目就挂了,可伸缩性差:想扩展某一个模块要把所有模块全部重新部署一次,扩展性和可维护性差,性能低
垂直架构是指将单体架构中的多个模块拆分为多个独立的项目。形成多个独立的单体架构。模块拆分成独立的几个项目,项目之间不进行交互(独立的单体架构),重复功能多,改一个重复的都要改。
分布式架构是在垂直架构的基础上,将公共业务模块抽取出来,作为独立的服务,同其他调用者消费,实现服务的共享和重用。但是服务提供者一旦发生变化,所有消费者都需要变化
RPC: Remote Procedure Call 远程过程调用。有非常多的协议和技术来都实现了RPC的过程。比如:HTTP REST风格,Java RMI规范、WebService SOAP协议、Hession等等
服务消费者和服务提供者通过RPC实现信息的传输
Dubbo自动进行RPC的过程
SOA架构:模块之间不相互调用了,通过ESB组件通信(企业服务总线),模块每次变化都跟ESB说一下
SOA:(Service-OrientedArchitecture,面向服务的架构)是一个组件模型,它将应用程序的不同功能单元(称为服务)进行拆分,并通过这些服务之间定义良好的接口和契约联系起来。
ESB:(EnterpariseServce Bus) 企业服务总线,服务中介。主要是提供了一个服务于服务之间的交互。ESB包含的功能如:负载均衡,流量控制,加密处理,服务的监控,异常处理,监控告急等等。
微服务架构是在SOA上做的升华,微服务架构强调的一个重点是“业务需要彻底的组件化和服务化”原有的单个业务系统会拆分为多个可以独立开发、设计、运行的小应用。这些小应用之间通过服务完成交互和集成。微服务架构=80%的SOA服务架构思想 +100%的组件化架构思想+80%的领域建模思想。
服务实现组件化:开发者可以自由选择开发技术。也不需要协调其他团队
服务之间交互一般使用RESTAP去中心化:每个微服务有自己私有的数据库持久化业务数据
自动化部署:把应用拆分成为一个一个独立的单个服务,方便自动化部署、测试、运维
Dubbo
Dubbo是阿里巴巴公司开源的一个高性能、轻量级的Java RPC框架
致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案
架构
- Provider:暴露服务的服务提供方
- Container:服务运行容器
- Consumer:调用远程服务的服务消费方
- Registry:服务注册与发现的注册中心
- Monitor:统计服务的调用次数和调用时间的监控中心
Dubo使用Zookeeper作为注册中心
安装jdk
查询版本号
#查询版本号
yum search java|grep jdk
#安装jdk
yum install -y java-1.8.0-openjdk
#查看jdk默认安装路径
find / -name 'java'
配置jdk环境变量
vim /etc/profile
#添加
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.382.b05-1.el7_9.x86_64
export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin
更新环境变量
source /etc/profile
Zookeeper安装
windows cmd
scp D:\apache-zookeeper-3.5.6-bin.tar.gz root@192.168.88.130:/
FInalShell
#打开 opt目录
cd /opt
#创建zooKeeper目录
mkdir zooKeeper
#将zookeeper安装包移动到 /opt/zooKeeper
mv apache-zookeeper-3.5.6-bin.tar.gz /opt/zookeeper/
cd /opt/zookeeper/
tar -zxvf apache-zookeeper-3.5.6-bin.tar.gz
配置
#进入到conf目录
cd /opt/zookeeper/apache-zookeeper-3.5.6-bin/conf/
#拷贝
cp zoo_sample.cfg zoo.cfg
#修改zoo.cfg
vim zoo.cfg
#打开目录
cd /opt/zookeeper/
#创建zooKeeper存储目录
mkdir zkdata
#打印目录
cd zkdata
pwd
#修改zoo.cfg
vim /opt/zooKeeper/apache-zooKeeper-3.5.6-bin/conf/zoo.cfg
cd bin/
./zkServer.sh start
案例
dubboDEMO
解除web模块与Service的耦合,让这两个模块分别连接dubbo
- Spring和SpringMVC整合
- 服务提供者,服务消费者
- 改进:提供一个公共接口模块,里面写接口,web和Service分别依赖,这样web模块和Service模块就不用都写Service接口了
dubbo-admin管理平台
一个图形化的服务管理页面
从注册中心获取到所有的提供者/消费者进行配置管理
路由规则、动态配置、服务降级、访问控制、权重调整、负载均衡等管理功能
环境准备
dubbo-admin 是一个前后端分离的项目。前端使用vue,后端使用springboot,安装 dubbo-admin 其实就是部署该项目。我们将dubbo-admin安装到开发环境上。要保证开发环境有jdk,maven,nodejs
安装node下载地址:https://nodejs.org/en/
因为前端工程是用vue开发的,所以需要安装node.js,node.js中自带了npm,后面我们会通过npm启动
下载 Dubbo-Admin
进入github,搜索dubbo-admin下载:https://github.com/apache/dubbo-admin
把下载的zip包解压到指定文件夹(解压到那个文件夹随意)
修改配置文件
解压后我们进入…\dubbo-admin-develop\dubbo-admin-server\src\main\resources目录,找到 application.properties 配置文件 进行配置修改
修改zookeeper地址
# centers in dubbo2.7
admin.registry.address=zookeeper://192.168.149.135:2181
admin.config-center=zookeeper://192.168.149.135:2181
admin.metadata-report.address=zookeeper://192.168.149.135:2181
admin.registry.address注册中心
admin.config-center 配置中心
admin.metadata-report.address元数据中心
打包项目
在 dubbo-admin-develop 目录执行打包命令
mvn clean package
打包失败的,单独去server里面打包一次,再出来打包
mvn clean install -DskipTests
启动后端
切换到目录dubbo-Admin-develop\dubbo-admin-distribution\target>
执行下面的命令启动 dubbo-admin,dubbo-admin后台由SpringBoot构建。
java -jar .\dubbo-admin-0.1.jar
前台后端
dubbo-admin-ui 目录下执行命令
npm run dev
要解决这个问题,你可以尝试以下步骤:
- 确保你的项目依赖项是最新的:运行
npm update
或yarn upgrade
来更新你的项目依赖项,看看是否有相关的修复。 - 检查 Node.js 版本:确保你使用的 Node.js 版本是稳定和兼容的版本。升级到最新的 LTS 版本可能有助于解决一些问题。
- 检查你的项目配置:查看你的项目配置文件,特别是与加密、哈希或安全相关的配置,确保没有不兼容或错误的设置。
- 检查依赖项:检查你的项目依赖项中是否有不兼容的包或版本冲突。可能需要升级、降级或替换某些依赖项。
- 查看相关文档:查看你正在使用的库或框架的文档,看看是否有与此错误相关的已知问题和解决方案。
如果以上步骤都无法解决问题,你可能需要进一步调查 OpenSSL 相关的配置和设置,以找出导致错误的具体原因。还可以尝试在开发者社区或论坛中寻求帮助,可能会有其他开发者遇到了类似的问题并提供了解决方案。
访问
浏览器输入http://localhost:8081/
用户名密码都是root
使用
修改Dubbo端口
- applicationContext.xml
<dubbo:protocol port="20880" />
元数据信息需要打开我们的生产者配置文件加入下面配置才能看见
- applicationContext.xml
<!-- 元数据配置 -->
<dubbo:metadata-report address="zookeeper://192.168.149.135:2181" />
高级
序列化
两个机器传输数据,如何传输java对象?
Dubbo内部已经将序列化和反序列化的过程内部封装了,我们只需要定义pojo类实现Serializable接口即可
把实体类单独做成一个模块
被依赖的java工程需要重新install才能用
地址缓存
注册中心挂了,服务是否可以正常访问
可以,因为Dubbo服务消费者在第一次调用时会将服务提供者的地址缓存到本地,以后在调用的时候不会访问注册中心。
当服务提供者的地址发生变化时,注册中心会通知服务消费者
超时
服务消费者在调用服务提供者的时候发生了阻塞,等待的情形,此时服务消费者会一直等待下去
在摸个峰值时刻,大量的请求同时请求服务消费者,会造成大量线程堆积,造成雪崩
Dubbo利用超时机制解决这个问题,设置一个超时时间,在这个时间段内无发完成服务则自动断开连接
使用timeout属性配置超时时间。默认1000ms
@Service(timeout = 3000,retries = 0)
服务提供者;
@Reference(timeout = 3000,retries = 0)
服务消费者;
两方都可以生效,建议定义在服务提供者上
重试
如果出现了网络抖动,则这一次的请求就会失败
Dubbo通过提供重试机制避免类似的问题发生
通过retries属性设置重试次数,默认为2次(一共三次)
多版本
服务提供者升级,将新服务部署在另一个机器上,此时一般让其中一个服务消费者先试用一下新服务,其余的服务还是使用原来的服务提供者,等新服务没有问题了,其余的服务消费者再使用新服务提供者提供的服务
灰度发布:当出现新功能时,会让一部分用户先使用新功能,用户反馈没问题时再将所有用户迁移到新功能
Dubbo使用version属性设置和调用同一个接口的不同版本
@Service(version = "v1.0")
public class UserServiceImpl implements UserService{}
@Service(version = "v2.0")
public class UserServiceImpl implements UserService{}
controller:
@Reference(version="v1.0")
private UserService uservice;
负载均衡
多个服务提供者,当一个消费者需要服务时,由负载均衡决定调用哪个服务提供者
负载均衡策略:
-
Random:按权重随机,默认值,按权重设置随机概率
- 每个服务设置一个权重
-
RoundRobin:按权重轮询
- 100,200,100:1.2.3.2
-
LeastActive:最少活跃调用数,相同活跃数的随机
- 看每一个服务处理请求花的时间,消费者找一个最快的机器
-
ConsistentHash:一致性hash,相同参数的请求总是发送到统一提供者
第一个服务:
@Service(weight=100)
public class UserServiceImpl implements UserService{}
增加服务:
@Service(weight=200)
public class UserServiceImpl implements UserService{}
tomcat插件改端口:
<port>9003</port>
改applicationContext.xml配置:
<dubbo:protocol port="20883” />
<!--dubbo的配署-->
<!--1.配需项目的名称,唯一-->
<dubbo:application name="dubbo-service">
<dubbo:parameter key="qos.port” value="55555"/>
</dubbo:application>
<!--2.配置注册中心的地址-->
<dubbo:registry address="zookeeper://192.168.149.135:2181"/>
<!--3.配胃dubbo包扫描-->
<dubbo:annotation package="com.itheima.service,impl”/>
配置负载均衡策略
controller:
@Reference(loadbalance = "random")
private UserService uservice;
集群容错
dubbo.apache.org
消费者调用某一个提供者出错了,使用容错机制处理
集群容错模式:
- FailoverCluster:失败重试,默认值。当出现失败,重试其他服务器,默认重试2次,使用retries配置,一般用于读操作
- 写的话可能是往数据库写的请求,有可能延时,可能写成功了当时是超时了,可能就会同时写多条数据。
- Failfast Cluster:快速失败,只发起一次调用,失败立即报错;通常用于写操作
- Failsafe Cluster: 失败安全,出现异常时,直接忽略。返回一个空结果。
- FailbackCluster: 失败自动恢复,后台记录失败请求,定时重发。
- Forking Cluster: 并行调用多个服务器,只要一个成功即返回
- Broadcast Cluster:广播调用所有提供者,逐个调用,任意一台报错则报错。
- 一些同步更新使用
controller:
@Reference(cluster="failover")//重试
private UserService uservice;
服务降级
某一个服务(机器)性能达到应用最大化,消费者调用服务时,把一些不太重要的服务关掉释放资源,保证核心的业务服务(广告,支付)能正常运行
服务降级方式:
- mock=force:return null:表示消费方对该服务的方法调用都直接返回null值,不发起远程调用。用来屏蔽不重要服务不可用时对调用方的影响
- mock=fail:return null:表示消费方对该服务的方法调用在失败后,再返回null 值,不抛异常。用来容忍不重要服务不稳定时对调用方的影响
controller:
@Reference(mock="force:return null")//不再调用userService的服务
private UserService uservice;
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术