1、微服务架构
微服务架构是一种设计复杂应用步伐的方法,它提倡将单一应用步伐开发为一组小型、独立的服务,每个服务运行在其自己的进程中,并通过轻量级通信(通常是HTTP协议)进行交互。每个服务都是围绕业务功能构建的,能够独立摆设、扩展和维护。
上述说常用的服务间通信的协议是HTTP协议,但是现在很多公司里也会利用Dubbo作为RPC调用框架。
HTTP协议是存在于ISO模子中的应用层,应用层实现具体的应用功能,为应用步伐提供服务。
Dubbo则是基于TCP协议的RPC架构,而TCP协议处于ISO模子的传输层,传输层只是建立、管理和维护端到端的连接。
所以在哀求的过程中,TCP协议会比HTTP协议封装更少的内容,速度也比HTTP会快一些。
微服务焦点特点:
- 模块化:微服务架构夸大高内聚低耦合,每个服务专注于执行单一业务功能,这使得系统更易于理解和维护。
- 独立摆设:每个微服务都可以独立于其他服务进行构建、测试、摆设和扩展,减少了摆设时的相互影响。
- 技能栈灵活:不同的微服务可以根据具体需求选择最适合的技能栈,不必受限于整个系统的统一技能选择。
- 弹性伸缩:微服务架构允许按需扩展特定的服务实例,以应对高负载环境,而无需扩展整个应用步伐。
- 故障隔离:假如某个微服务出现故障,不会立刻影响整个系统,由于其他服务仍然可以正常运行。
- 一连交付:由于微服务的独立性和自动化测试,团队可以更频仍地进行代码提交和摆设,加快产品迭代速度。
- 数据管理:每个微服务通常拥有自己的数据库,遵循“数据全部权”原则,避免了全局数据模式的复杂性。
1.1、Dubbo在微服务架构中的脚色
Dubbo在微服务架构中不仅提供了高效的服务间通信机制,还通过其全面的服务治理能力,极大地降低了构建、管理和维护复杂微服务架构的难度
- 服务治理:Dubbo是一个高性能、轻量级的开源服务框架,它提供了全面的服务治理办理方案,包罗服务注册、服务发现、负载均衡、容错、限流、动态配置等功能,帮助构建稳固可靠的微服务架构。
- RPC通信:Dubbo采用高性能的RPC(Remote Procedure Call)通信机制,允许服务消耗者远程调用服务提供者的接口,就像调用当地方法一样简朴,极大地简化了分布式系统间的交互。
- 服务注册与发现:Dubbo支持多种注册中心,如Zookeeper、Nacos、Consul等,用于服务的自动注册与发现,使得服务提供者和消耗者之间能够动态地找到相互,而无需硬编码服务地址。
- 智能路由:Dubbo提供了丰富的路由计谋,如随机、轮询、最少活跃数、一致性哈希等,可以根据不同的场景和需求,智能地选择服务实例进行调用,进步服务调用效率和系统的团体性能。
- 容错与重试:Dubbo内置了多种容错计谋,如失败重试、失败回调、降级、熔断等,能够在服务不可用或网络异常时,提供优雅的降级方案,保证系统的稳固性和用户体验。
- 监控与统计:Dubbo集成了强盛的监控统计功能,可以及时监控服务调用的耽误、吞吐量、异常率等关键指标,帮助开发者快速定位和办理题目。
- 灵活的配置管理:Dubbo支持动态配置更新,可以在不重启服务的环境下调整服务参数,进步了运维的灵活性和效率。
1.2、Zookeeper和Nacos作为服务注册与发现中心的作用。
(1)Zookeeper
Zookeeper主要用于和谐分布式应用,提供了一套完整的分布式和谐服务办理方案。它能够为分布式应用提供命名服务、配置管理、集群管理、分布式锁、队列管理等服务。
在微服务架构中,Zookeeper可以作为一个服务注册中心,各个微服务启动后会向Zookeeper注册自己的信息(如IP地址、端口号等),而其他必要调用这些服务的应用则可以从Zookeeper上查询到服务的信息,实现服务的自动发现。
Zookeeper的焦点是其数据模子和Watcher机制,通过维护一个条理化的命名空间来存储数据,而且提供了及时的数据变动关照机制。但是,Zookeeper的性能并不适合高并发场景,且其API相对复杂,必要一定的学习本钱。
(2)Nacos
Nacos是阿里巴巴开源的一款易于构建云原生应用的动态服务发现、配置管理和服务管理平台。它结合了服务发现与配置管理的功能,旨在简化微服务和DevOps的运维工作。
Nacos提供了一个强盛的服务注册与发现功能,微服务可以在启动时向Nacos注册,同时Nacos也支持健康查抄,确保只返回可用的服务实例。服务消耗者可以通过Nacos发现并调用服务。
Nacos具有高可用性、高性能和易用性,支持动态配置更新,无需重启服务即可生效。此外,Nacos还提供了丰富的可视化界面,方便用户管理和监控服务。
2、环境准备
1、IDEA编码工具。
2、Maven依赖管理工具
2.1、安装和配置Zookeeper和Nacos。
2.1.1、Zookeeper
(1)下载
Zookeeper是Apache旗下的产品,下载地址:Apache Zookeeper
(2)解压并启动
将Zookeeper压缩包下载好后进行解压。
解压好后还不能直接启动,还必要修改配置文件,一个很简朴的修改操作。将conf目次下的zoo_sample.cfg文件改为zoo.cfg文件即可。
修改前:
修改后:
进入bin目次,在windows系统中直接双击zkServer.cmd文件启动Zookeeper,而在Linux系统下则必要运行zkServer.sh文件。
2.1.2、Nacos
(1)下载
Nacos 是阿里的产品,如今是 SpringCloud 中的一个组件。它的功能要比 Eureka、Zookeeper 更加丰富,在国内比较受欢迎。
下载地址:Nacos GitHub下载地址
(2)下载后解压
(3)修改数据库配置
进入conf目次下,打开application.properties文件,必要在这里面修改数据库的配置。
在修改数据库配置之前必要走一个必不可少的流程,就是将conf目次下的mysql-schema.sql在指定的数据库中执行一次,让数据库中有所必要的表。
数据库的配置信息从33行开始。
- #*************** Config Module Related Configurations ***************#
- ### If use MySQL as datasource:
- ### Deprecated configuration property, it is recommended to use `spring.sql.init.platform` replaced.
- spring.datasource.platform=mysql
- spring.sql.init.platform=mysql
- db.num=1
- db.url=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
- db.user=root
- db.password=123456
复制代码 (4)启动Nacos
在bin目次下执行指定的命令:
1、单机模式:startup.cmd -m standalone
2、集群模式:startup.cmd -m cluster,必要开启集群模式。
看到上述环境则表示Nacos启动乐成,可以访问:http://localhost:8848/nacos,用户名和密码假如没有设置的话都是:nacos/nacos。
2.2、依赖版本选择
- SpringBoot依赖版本:2.7.17
- JDK版本:JDK 17
- Dobbu依赖版本:2.7.17(nacos)、3.2.12(zookeeper)
- Nacos依赖版本:2021.0.5.0
2.2.1、Zookeeper版本下父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>
- <parent>
- <groupId>com.tt</groupId>
- <artifactId>dubbo-demo</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- </parent>
- <packaging>pom</packaging>
- <artifactId>zookeeper-registry</artifactId>
- <modules>
- <module>provider</module>
- <module>interface-api</module>
- <module>Consumer</module>
- </modules>
- <properties>
- <maven.compiler.source>17</maven.compiler.source>
- <maven.compiler.target>17</maven.compiler.target>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- </properties>
- <dependencyManagement>
- <dependencies>
- <dependency>
- <groupId>org.apache.dubbo</groupId>
- <artifactId>dubbo-spring-boot-starter</artifactId>
- <version>3.2.12</version>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter</artifactId>
- <version>3.2.5</version>
- </dependency>
- <dependency>
- <groupId>org.apache.dubbo</groupId>
- <artifactId>dubbo-registry-zookeeper</artifactId>
- <version>3.2.12</version>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- <version>3.2.5</version>
- </dependency>
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- <version>1.18.32</version>
- <scope>provided</scope>
- </dependency>
- </dependencies>
- </dependencyManagement>
- </project>
复制代码 2.2.2、Nacos模式下父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>
- <parent>
- <groupId>com.tt</groupId>
- <artifactId>dubbo-demo</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- </parent>
- <packaging>pom</packaging>
- <artifactId>nacos-registry</artifactId>
- <modules>
- <module>nacos-interface-api</module>
- <module>nacos-provider</module>
- <module>nacos-consumer</module>
- </modules>
- <properties>
- <maven.compiler.source>17</maven.compiler.source>
- <maven.compiler.target>17</maven.compiler.target>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <spring.version>2.7.17</spring.version>
- </properties>
- <dependencyManagement>
- <dependencies>
- <dependency>
- <groupId>org.apache.dubbo</groupId>
- <artifactId>dubbo-spring-boot-starter</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- <version>1.18.32</version>
- </dependency>
- <dependency>
- <groupId>org.apache.dubbo</groupId>
- <artifactId>dubbo-registry-nacos</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>com.alibaba.cloud</groupId>
- <artifactId>spring-cloud-alibaba-dependencies</artifactId>
- <version>2021.0.5.0</version>
- <type>pom</type>
- <scope>import</scope>
- </dependency>
- </dependencies>
- </dependencyManagement>
- </project>
复制代码 3、Dubbo与SpringBoot集成
将阿里巴巴开源的高性能、轻量级的微服务框架Dubbo,与盛行的Spring Boot框架结合利用,以构建分布式服务应用。这种集成可以充实利用Dubbo的RPC(远程过程调用)功能和Spring Boot的快速开发特性,实现服务的自动注册、发现、负载均衡、容错、降级等功能。
3.1、团体项目结构
3.2、公共模块
公共模块主要是提供接口和公共的对象。
3.2.1、Nacos模式下的公共模块
- // 提供公共的接口,具体业务由实现类完成。
- public interface UserService {
- public String userLogin(String username, String password);
- }
复制代码 3.2.2、Zookeeper模式下的公共模块
- public interface UserService {
- String userLogin(String username, String password);
- }
复制代码 3.2、构建服务提供者
服务提供者,先导入公共模块的依赖同时实现相应的接口,并将实现类的信息上传到注册中心。
3.2.1、Nacos模式服务提供者
(1)导入API公共模块依赖
在服务提供者的pom文件中导入API模块的依赖
- <dependency>
- <groupId>com.tt</groupId>
- <artifactId>nacos-interface-api</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- </dependency>
复制代码 (2)实现接口,完成业务逻辑
- @DubboService
- public class UserServiceImpl implements UserService {
- @Override
- public String userLogin(String username, String password) {
- // 省略具体的业务逻辑
- return username + "登录成功";
- }
- }
复制代码 @DubboService是Dubbo Spring Boot Starter提供的一个注解,用于标记一个接口的实现类为Dubbo的服务提供者。
(3)开启Dubbo服务并设置配置中心
- @SpringBootApplication
- @EnableDubbo // 在启动类上开启Dubbo服务
- public class NacosProviderApplication {
- public static void main(String[] args) {
- SpringApplication.run(NacosProviderApplication.class, args);
- }
- }
复制代码- server:
- port: 8081
- spring:
- application:
- name: nacos-provider
- cloud:
- nacos:
- config:
- server-addr: 127.0.0.1:8848
- namespace: 2cb71f92-6787-40bd-b9df-ccc2be92e0ec
- file-extension: yaml
- discovery:
- server-addr: 127.0.0.1:8848
- namespace: 2cb71f92-6787-40bd-b9df-ccc2be92e0ec
- dubbo:
- registry:
- address: nacos://${spring.cloud.nacos.config.server-addr}
- protocol:
- port: 20880 # dubbo服务端口
- name: dubbo # 协议
- # monitor:
- # protocol: registry
- scan:
- base-packages: com.tt.service
复制代码 3.2.2、Zookeeper模式服务提供者
Zookeeper模式下的服务提供者除了配置文件与Nacos模式的服务提供者不同,其他基本一致。
- spring:
- application:
- name: tt-provider
- dubbo:
- protocol:
- name: dubbo
- port: -1
- # serialization: kryo
- registry:
- address: zookeeper://127.0.0.1:2181
- application:
- qos-port: 2222
- provider:
- timeout: 5000
- scan:
- base-packages: com.tt.service
复制代码 3.3、构建服务消耗者
在Dubbo模式下,服务消耗者调用服务提供者的路径是一个涉及多个组件和步骤的过程。下面是一个典型的调用流程概述:
- 服务注册
服务提供者启动时,它会向注册中心(如Zookeeper)注册其提供的服务,包罗服务的接口名、版本、所在主机、端口等信息。
- 服务发现
当服务消耗者启动时,它会向注册中心订阅所需服务的接口信息。
注册中心返回服务提供者列表给消耗者。
- 署理创建
消耗者根据服务接口生成动态署理对象(Proxy),这个署理对象对用户透明,看起来就像在当地调用一样。
- 调用路由
当消耗者通过署理对象调用服务时,调用会被转发到Invoker。
Invoker利用集群路由计谋(如轮询、最少活跃数、一致性哈希等)选择一个服务提供者。
- 远程调用
选定提供者后,调用哀求通过网络传输到提供者,通常利用Netty等高性能网络框架。
提供者吸收到哀求后,执行当地调用并返回结果。
- 结果处理
结果被编码并通过网络返回给消耗者。
消耗者吸收到结果,完成整个调用链路。
3.3.1、Nacos模式下消耗者
(1)开启Dubbo服务并配置注册中心
- @SpringBootApplication
- @EnableDubbo
- public class NacosConsumerApplication {
- public static void main(String[] args) {
- SpringApplication.run(NacosConsumerApplication.class, args);
- }
- }
复制代码- server:
- port: 8082
- spring:
- application:
- name: nacos-consumer
- cloud:
- nacos:
- config:
- server-addr: 127.0.0.1:8848
- namespace: 2cb71f92-6787-40bd-b9df-ccc2be92e0ec
- file-extension: yaml
- discovery:
- server-addr: 127.0.0.1:8848
- namespace: 2cb71f92-6787-40bd-b9df-ccc2be92e0ec
- dubbo:
- registry:
- address: nacos://${spring.cloud.nacos.config.server-addr}
- protocol:
- port: 20880 # dubbo服务端口
- name: dubbo # 协议
- # monitor:
- # protocol: registry
- # scan:
- # base-packages: com.tt.service
复制代码 (2)进行Dubbo调用
- @RestController
- public class UserController {
- @DubboReference // 通过接口进行代理对象的注入,然后进行RPC调用
- private UserService userService;
- @GetMapping(value = "/login/{username}/{password}")
- public String userLogin(@PathVariable("username") String username, @PathVariable("password") String password){
- return userService.userLogin(username, password);
- }
- }
复制代码 3.3.2、Zookeeper模式下消耗者
同Nacos模式下的消耗者类似。
4、Dubbo特性
4.1、Dubbo的负载均衡计谋
Dubbo是一个高性能、轻量级的开源微服务框架,它支持多种负载均衡计谋来优化服务调用的分布,从而进步系统的团体性能和稳固性。以下是Dubbo支持的主要负载均衡计谋:
- 随机(Random)
这是Dubbo默认的负载均衡计谋,它随机选择一个可用的服务实例进行调用。假如配置了权重,那么权重较大的服务实例被选中的概率也更大。
- 轮询(RoundRobin)
也称为循环调理,按序次逐一分配哀求到不同的服务实例,保证每个实例都能公平地吸收哀求。当配置了权重时,权重高的实例会有更高的机会被选中。
- 最少活跃数(LeastActive)
选择活跃数最少的服务实例,即正在处理哀求最少的谁人实例,这样可以避免某些服务实例过载。
- 一致性哈希(ConsistentHash)
基于哀求参数的哈希值进行路由,将哀求分配给距离当前哈希值近来的下一个服务实例。这种计谋可以减少服务实例变革带来的重新分配本钱。
- 加权轮询(WeightedRoundRobin)
这是轮询计谋的一种扩展,根据服务实例的权重进行轮询,权重大的实例被选中的频率更高。
- 加权随机(WeightedRandom)
类似于随机计谋,但是根据服务实例的权重来随机选择,权重越高的实例被选中的概率越大。
在实际应用中,你可以根据服务的具体需求和场景选择符合的负载均衡计谋,也可以自界说实现以满意更复杂的需求。这些计谋可以通过Dubbo的配置文件或者注解来指定,比方在@Reference注解中利用loadbalance属性来指定负载均衡计谋。
- @RestController
- public class UserController {
- @DubboReference(loadbalance = "random") // 声明使用的负载均衡策略
- private UserService userService;
- @GetMapping(value = "/login/{username}/{password}")
- public String userLogin(@PathVariable("username") String username, @PathVariable("password") String password){
- return userService.userLogin(username, password);
- }
- }
复制代码 负载均衡是分布式系统中一个关键的部分,它有助于提升系统的可用性、伸缩性和性能。
4.2、容错机制和重试计谋。
Dubbo提供了多种容错机制和重试计谋,用于处理服务调用时可能遇到的故障和异常环境。这些机制可以帮助服务保持高可用性和稳固性,尤其是在分布式系统中。下面是几种主要的容错和重试计谋:
- Failover(失败自动切换)
当调用失败时,Dubbo会自动切换到其他可用的服务提供者进行重试。
这种计谋通常用于读操作,由于重试可能会带来额外的耽误。
可以通过retries参数来设置重试次数(不包罗首次调用)。
- Failfast(快速失败):
只发起一次调用,假如调用失败,则立刻抛出异常并停止后续调用。
适用于非幂等性的写操作,比方新增记载。
- Failsafe(失败安全):
出现异常时,直接忽略并返回一个默认结果或空结果。
通常用于写入审计日志等操作,即使失败也不影响系统的主要功能。
- Failback(失败自动规复):
哀求失败后,会自动记载在失败队列中,并由一个定时线程在后台重试。
这种计谋适用于那些可以延后处理且不会造成严峻结果的操作。
- Forking(并行调用):
同时调用多个服务提供者,只要其中一个乐成即返回。
适用于及时性要求较高的读操作,但必要消耗更多的服务资源。
- Broadcast(广播调用):
广播调用全部服务提供者,逐个调用,恣意一台报错则报错。
通常用于关照全部提供者更新缓存或日志等当地资源信息。
在实际应用中,可以根据服务的特性和业务需求选择符合的容错计谋。比方,对于查询语句,保举利用默认的Failover计谋,而对于增编削操作,建议利用Failfast计谋,或者利用Failover计谋但将retries设为0,以防止数据重复添加。
这些计谋可以通过Dubbo的配置文件或代码中的注解来指定,比方在@DubboReference或@DubboService注解中利用cluster属性来设置容错计谋。
- @RestController
- public class UserController {
- // 随机的负载均衡策略,失败自动切换的容错机制,5次的重试机制
- @DubboReference(loadbalance = "random", cluster = "failover", retries = 5)
- private UserService userService;
- @GetMapping(value = "/login/{username}/{password}")
- public String userLogin(@PathVariable("username") String username, @PathVariable("password") String password){
- return userService.userLogin(username, password);
- }
- }
复制代码 假如项目中利用的是XML,可以利用以下写法:
- <dubbo:reference id="demoService" interface="com.example.DemoService" cluster="failover" retries="2"/>
复制代码 4.3、服务降级和熔断
Dubbo的服务降级和服务熔断是微服务架构中用于增强系统稳固性和防止雪崩效应的关键机制。它们通过限制或改变服务调用行为,来保护系统免受异常服务实例的影响。
4.3.1、服务降级
服务降级是指在服务调用遇到题目时,自动降低服务的功能或性能,返回一个默认或简化的响应,而不是等候服务响应或重试。这有助于避免服务调用方因等候无响应的服务而导致的资源耗尽。
在Dubbo中,服务降级可以通过多种方式实现:
- Mock机制:Dubbo允许你配置一个Mock对象,当服务调用失败时,Mock对象会返回一个预界说的响应,而不是抛出异常。这可以通过在@DubboReference注解中设置mock属性,或者在XML配置中利用mock标签来实现。
- 自界说降级逻辑:你也可以编写自界说的降级逻辑,比方,当服务不可用时,返回一个静态的错误页面或默认值。
4.3.1.1、简朴的降级
- @DubboReference(mock = "return null")
- private MyService myService;
复制代码 当myService调用失败时立马返回null。
4.3.1.2、自界说Mock
(1)实现降级方法
- public class MyServiceMock implements MyService {
- @Override
- public String someMethod(String param) {
- return "Mocked response for: " + param;
- }
- }
复制代码 (2)配置mock
- @DubboReference(mock = "com.example.service.MyServiceMock$someMethod")
- private MyService myService;
复制代码 4.3.2、服务熔断
服务熔断是一种保护机制,当一个服务的调用失败率到达一定水平时,Dubbo会自动“断开”对该服务的调用,直接返回错误或预界说的响应,而不是继续尝试调用可能已失败的服务。这可以防止大量哀求涌向已知有题目的服务,避免进一步的系统瓦解。
Dubbo可以通过集成Hystrix来实现服务熔断。Hystrix是Netflix开源的一个容错库,它可以监控服务调用的健康状态,并在必要时触发熔断机制。
要利用Hystrix进行熔断,你必要做以下几点:
- 引入Hystrix依赖:在项目中添加Hystrix的依赖。
- 配置Hystrix:配置Hystrix的规则,比如失败率阈值、熔断时间窗口等。
- 利用@HystrixCommand注解:在服务调用方法上添加@HystrixCommand注解,指定熔断的逻辑和回退方法。
- 界说回退方法:当服务调用被熔断时,Hystrix会调用你界说的回退方法来处理哀求。
在Dubbo中,你还可以通过配置circuitBreaker相干属性来控制熔断的行为:
- @DubboReference(circuitBreaker = "on", timeout = 3000, retries = 0)
- private DemoService demoService;
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |