目录
首先我们要知道什么是互联网项目,聊互联网项目,就不得不需要了解一下它的另外一个兄弟,传统项目。
互联网项目就是我们经常用的像淘宝,微信,百度等,这些是面向广大网民使用的。
传统项目就是公司内部的项目,比如像OA( 办公自动化 ),HR(人力资源),CRM( 客户关系 )等,这些是面向企业内部的。
它们的区别就是,用户的群体不一样,传统项目就是企业员工,而互联网就是广大的网民了,而网民是肯定比企业员工多的,而且是非常多!
然后就是一个忍耐力,像传统项目是给企业员工用的,虽然可能会有BUG,但是你还是得用啊,你不用你就辞职,但是网民不一样,你这个软件不好用,我就换一个软件。
我们制作一个软件肯定是注重几点:
1、用户体验:美观、功能、速度、稳定性; 2、响应是否快:打开一个新页面一瞬间完成;页面内跳转,一刹那间完成。
互联网项目是传统项目复杂很多的,让我门来看看互联网项目有什么特点。
知道了互联网项目的特点后,我们就要知道设计互联网项的时候要达到什么样的目标:
我们主要需要知道衡量网站的性能指标:
QPS >= 并发连接数 >= TPS
集群:就是很多“人”一起干一样的事情。这里人代指机器 分布式:分布式:很多“人”一起,干不一样的事。这些不一样的事,合起来是一件大事。
它们的好处是什么呢?
高性能 高可用 可伸缩 高可扩展
集群就像是两个厨师,他们要洗菜,切菜,炒菜,两个人干一样的事,这就是集群。
分布式就是只让厨师炒菜,洗菜和切菜重新找人,虽然他们干的事情都不一样,但是合起来就是做饭这一件事。
而且我们中间,比如如果觉得这个洗菜的速度太慢了,我们还可以再加一个人进来洗菜。
了解了基本的概念后呢,我们就来看看它们在互联网中长什么样。
早期的互联网项目就像上图那样,是一种单机的架构,那么这种架构有很多问题,我们要给它搭建集群,来提高它的性能,来提高它的可用性。所以就会变成这样。
我们搞了三个web服务器,然后每个web服务器都部署一份这样的项目,然后这个项目对外提供访问服务,我们就往里加入一个负载均衡的软件或者硬件。这样就提高了性能和可用性,过了一段时间后,我们觉得这样可伸缩和可扩展性不够,我们可以对这个服务进行一个拆分,那就会变成这样。
这样拆完之后,这app就分成了很多个项目,这里面又有集群又有分布式,这样做的好处就显而易见了,如果我们觉得其中一台机器性能不够,我们可以选择换一台机器,或增加一台机器。
Dubbo 是 SOA时代的产物,SpringCloud 是微服务时代的产物
Dubbo是阿里巴巴公司开源的一个高性能、轻量级的 Java RPC 框架。 致力于提供高性能和透明化的 RPC 远程服务调用方案,以及 SOA 服务治理方案。 官网:http://dubbo.apache.org
节点角色说明:
Zookeeper是注册中心,为什么要使用Zookeeper作为注册中心?
因为官方推荐。
(2条消息) Linux版ZooKeeper安装_一切总会归于平淡的博客-CSDN博客
实现步骤:
主要用作父模块管理pom依赖,下面是它的pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jie.demo</groupId>
<artifactId>dubbo-demo</artifactId>
<version>1.0</version>
<modules>
<module>dubbo-web</module>
<module>dubbo-service</module>
</modules>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.5</version>
<relativePath/>
</parent>
<properties>
<java.version>1.8</java.version>
<dubbo.version>2.7.3</dubbo.version>
</properties>
<dependencyManagement>
<dependencies>
</dependencies>
</dependencyManagement>
<dependencies>
<!--dubbo-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>${dubbo.version}</version>
</dependency>
<!--ZooKeeper-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<version>${dubbo.version}</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
这里比较主要的就是service层的IUserServiceImpl里的@Service注解了,它是Dubbo下的哦,不要导错了。
然后就是yml文件了。
server:
port: 8081
dubbo:
application:
name: dubbo-service #应用名称
registry:
address: zookeeper://192.168.58.149:2181 #zookeeper地址
# 注册服务采用的协议 端口号
protocol:
name: dubbo
port: 20880
#配置服务实现类所在包
scan:
base-packages: com.jie.dubboserice.service.impl
消费者主要就是Controller层。
然后就是要在pom文件导入服务提供者的模块,正常业务下,我们是要把它导成jar包然后导入的,这里就直接调接口了。
这里启动项目一定要先启动服务提供者。
也许会有其他遗漏的细节,代码仓库地址就放在文章最后了下面了。
dubbo-admin 管理平台,是图形化的服务管理页面,它可以使我们可以通过肉眼就可以看到有几个生产者,有几个消费者在注册中心注册了。
它的主要功能就是从注册中心中获取所有的提供者/消费者进行配置管理。
路由规则、动态配置、服务降级、访问控制、权重调整、负载均衡等管理功能
dubbo-admin 是一个前后端分离的项目。前端使用vue,后端使用springboot, 安装 dubbo-admin 其实就是部署该项目。
教程,大家看这篇dubbo-admin安装_一切总会归于平淡的博客-CSDN博客博客应该就够了。
两个机器传输数据,如何传输JAVA对象?
现在消费者要去调用生产者的提供的后一个查询服务,那生产者去查数据库,就可以查出来一些数据,再将数据封装成一个对象,再把对象返回给消费者。
但是,这个消费者和生产者未来是要部署在两台机器上的两个项目,如何将生产者的这个对象,传输导消费者的电脑上去,答案就是序列化。
我们可以将这个对象序列化,序列化流的数据,将来消费者和生产者它们要进行通讯就会建立一个流的通道,我们将对象序列化流的数据,通过流发过去就可以了。
然后消费者拿到数据之后,再将其反序列化转换成对象。
不管是序列化还是反序列化,我们都会用到同一个类,我们一般的做法就是将这个类定义到一个独立的模块,消费者和生产者都通过Maven来依赖这个模块。
一套操作下来呢,可能比较麻烦的就是序列化和反序列化了,但是dubbo 内部已经将序列化和反序列化的过程内部封装了,我们只需要在定义pojo类时实现Serializable接口即可 一般会定义一个公共的pojo模块,让生产者和消费者都依赖该模块。
代码演示:
首先我们再创建一个dubbo-pojo模块用来存放对象。
然后就是在dubbo-api模块声明一个方法使用该对象,记得在api模块的pom文件继承poj模块。
接下来就是service模块实现该方法。
web模块controller调用该方法,现在我们的对象是没有序列化的,启动项目访问一下我们看看效果。
不错所料报错了。
那我们现在就去实体类实现Serializable接口。
重启项目,再访问一次。
问题:注册中心挂了,服务是否可以正常访问?
答案:可以。
原因:dubbo服务消费者在第一次调用时,会将服务提供方地址缓存到本地,以后在调用则不会访问注册中心。 当服务提供者地址发生变化时,注册中心会通知服务消费者。
大家可以去尝试一下,注册中心挂了了之后,老服务是可以使用的,但是新服务就要去重启注册中心了。
服务消费者在调用服务提供者的时候发生了阻塞、等待的情形,这个时候,服务消费者会一直等待下去。 在某个峰值时刻,大量的请求都在同时请求服务消费者,会造成线程的大量堆积,势必会造成雪崩。
遇到以上情况,Dubbo会怎么做呢?
dubbo 利用超时机制来解决这个问题,设置一个超时时间,在这个时间段内,无法完成服务访问,则自动断开连接。 使用timeout属性配置超时时间,默认值1000,单位毫秒。
代码演示:
这个属性可以配大@Service注解上,也可以配置到@Reference注解上。
我们先来看看@Service注解。
然后再访问一下,看控制台。
接下来我们看看@Reference
这里,我们只设置1秒,那边设置3秒,来看看是1秒生效,还是3秒生效。
答案是1秒生效。
这里推荐这个超时重试设置在服务的提供方。
说完超时,我们说一下重试这个机制,如果只设置了超时,其实也会引发一些问题。
如果出现网络抖动,则这一次请求就会失败。
那么Dubbo为了预防这个问题,就做了个重试的机制。
通过 retries 属性来设置重试次数。默认为 2 次。
我们之前写过,大家有兴趣可以自己去试试。
这个就像是,游戏正式服和体验服,当游戏有重大更新,游戏厂家一般不会直接更新到正式服,而是更新到体验服,让一部分玩家去体验服体验,如果没有重大BUG,再更到正式服,让所有玩家体验,一般像体验服这个版本我们叫做:
灰度发布:当出现新功能时,会让一部分用户先使用新功能,用户反馈没问题时,再将所有用户迁移到新功能。
那Dubbo是如何做的呢?
dubbo 中使用version 属性来设置和调用同一个接口的不同版本
在Dubbo中提供4中负载均衡的策略。
具体如何使用:
首先可以在@Service注解上设置权重
然后在@Reference
如果大家不知道在里面填啥可以,如果你用的是IDEA,可以CTRL+N,查找AbstractLoadBalance,这个抽象类里面有4个不同的实现类,就是我们所说的4种不同的策略。
挑一个点进去。
现在大家如果不知道或者不记得,可以通过这种方法。
对于集群容错,Dubbo提供了蛮多策略。
怎么设置呢?
属性是cluster,那剩下的策略是什么呢?我们可以用老办法。
CTRL+N,搜索Cluster。
它这里有很多的实现类。
大家就选择自己要使用 的策略点进去看就好了。
服务降级就像是,一台机器里面有A,B,C三个服务,然后机器的CPU和内存都要爆满,快要崩了,这个时候运维人员就要看看是否可以舍弃掉一些服务,只留下重要的服务。
Dubbo服务降级的方式有哪些。
如何使用,就是在@Reference注解上使用,例如:
@Reference(mock = "force:return null")
这个就代表 不在调用某个service 服务。
Demo地址:dubbo-demo: 初学dubbo