1.简介
Spring Cloud Alibaba其实是阿里的微服务解决方案,是阿里巴巴结合自身微服务实践,开源的微服务全家桶,在Spring Cloud项目中孵化成为Spring Cloud的子项目。第一代的Spring Cloud标准中很多组件已经停更,如:Eureak,zuul等。所以Spring Cloud Alibaba很有可能成为Spring Cloud第二代的标准实现,所以许多组件在业界逐渐开始使用,已有很多成功案例。
值得一提的是Spring Cloud Alibaba对Dubbo做了很好的兼容,同时也提供了一些强大的功能,如 Sentinel 流控 ,Seata 分布式事务,Nacos 服务发现与注册等等。
2.Alibaba功能
Spring Cloud Alibaba是阿里巴巴结合自身的微服务实践开源的微服务全家桶,我个人觉得其组件比Spring Cloud 中的组件更加好用和强大。并且对的Spring Cloud组件做了很好的兼容。比如在Spirng Cloud Alibaba中依然可以使用Feign作为服务调用方式,使用Eureak做服务注册发现等等。Spring Cloud Alibaba主要的功能如下:
- 流控制和服务降级:支持WebServlet,WebFlux,OpenFeign,RestTemplate,Dubbo访问限制和降级流的功能。它可以在运行时通过控制台实时修改限制和降级流的规则,并且还支持监视限制和降级度量标准。
- 服务注册和发现:可以注册服务,并且客户可以使用Spring托管的bean(自动集成功能区)发现实例。(Nacos)
- 分布式配置:支持分布式系统中的外部配置,配置更改时自动刷新。(Nacos)
- Rpc服务:扩展Spring Cloud客户端RestTemplate和OpenFeign以支持调用Dubbo RPC服务。
- 事件驱动:支持构建与共享消息系统连接的高度可扩展的事件驱动微服务。
- 分布式事务:支持高性能且易于使用的分布式事务解决方案。
- 阿里云对象存储:大规模,安全,低成本,高度可靠的云存储服务。支持随时随地在任何应用程序中存储和访问任何类型的数据。
- 阿里云SchedulerX:准确,高度可靠,高可用性的计划作业调度服务,响应时间在几秒钟内。
- 阿里云短信:阿里云短信服务覆盖全球,提供便捷,高效,智能的通信功能,帮助企业快速联系客户。
3.Nacos服务注册与发现
3.1Nacos和Eureka的区别?
Eureka 服务发现Pull的方,Nacos它是采用Pull和push的方式(简单理解,eureka是每隔30秒到服务注册中心拉取通信地址,但是如果31s的时候注册中心通信地址发生改变了之后,要等到下一次拉取的时候,客户端才会发现通信地址发生了改变,但是Nacos它采用的方式是pull和push2种方案来保证数据的实时更新--如果注册中心通信地址发生改变,nacos会主动向客户端推送最新的通信地址)
3.2Nacos安装
下载地址:Releases · alibaba/nacos · GitHub
启动Nacos:解压后,
- windows执行bin目录下的startup命令 :
startup.cmd -m standalone
- linux 执行 :sh startup.sh -m standalone
3.3Nacos配置
3.3.1基于数据库持久化
第一步:修改配置文件
找到nacos安装目录config/application.properties 文件,编辑数据库信息,修改内容如下
spring.datasource.platform=mysql
### Count of DB:
db.num=1
### Connect URL of DB:
db.url.0=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.0=root
db.password.0=123456
第二步:导入sql
找到config/ nacos-mysql.sql 文件 ,创建数据库 nacos-config,然后导入该sql脚本文件
3.3.2:启动方式集群/单机
set MODE="standalone"
3.3.3:开启账号密码认证
开启鉴权之后nacos的application.properties中的配置信息为:
### If turn on auth system:
nacos.core.auth.system.type=nacos
nacos.core.auth.enabled=true
3.4快速入门
3.4.1导包
1.父工程管理版本
<dependencyManagement>
<dependencies>
<!--SpringClou-alibaba依赖-->
<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>
<!--SpringCloud依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2021.0.5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2.导入nacos客户端
<!--服务注册与发现-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
3.4.2编写配置文件yml
server:
port: 1010
spring:
application:
name: user-server
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 #注册中心地址
3.4.3命名空间
修改yml配置文件
server:
port: 1010
spring:
profiles:
active: dev
application:
name: user-server
cloud:
nacos:
discovery:
server-addr: localhost:8848 #注册中心
group: DEFAULT_GROUP
namespace: 1a230c28-e48a-4ef0-86ca-38d0ef85d8e0 #命名空间的ID
3.4.4开启认证
server:
port: 1010
spring:
profiles:
active: dev
application:
name: user-server
cloud:
nacos:
discovery:
server-addr: localhost:8848 #注册中心
username: nacos
password: nacos
group: DEFAULT_GROUP
namespace: 1a230c28-e48a-4ef0-86ca-38d0ef85d8e0 #命名空间的ID
3.4.5引入配置中心
3.4.5.1导包
<!--配置中心-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--对bootstrap.yaml的支持-->
<dependency>
<groupId>org.springframework.cloud </groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
3.4.5.2修改配置文件bootstrap.yml
spring:
cloud:
nacos:
config: #配置中心
server-addr: localhost:8848 #配置中心地址
namespace: alibaba-dev #命名空间
prefix: pay-application #配置文件前缀
file-extension: yml #配置文件格式
username: nacos
password: nacos
3.4.5.3Nacos添加配置文件
3.4.6抽取公共配置文件
3.4.6.1修改配置文件
spring:
cloud:
nacos:
config:
server-addr: localhost:8848 #配置中心地址
namespace: alibaba-dev #命名空间
prefix: pay-application #配置文件前缀
file-extension: yml #配置文件格式
shared-configs: #共享的配置文件
- dataId: shared-config.yml
refresh: true
username: nacos
password: nacos
3.4.6.2Nacos添加抽取公共配置文件
4.Sentienl限流
4.1快速入门
4.1.1导包
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
4.1.2配置
spring:
cloud:
sentinel:
transport:
dashboard: localhost:1111
4.1.3@SentinelResource配置限流接口
@GetMapping("/user/{id}")
//限流降级
@SentinelResource(value="getById",blockHandler="exceptionHandler")
public User getById(@PathVariable Long id){
System.out.println(notify);
return new User(id,"zs:"+id, "我是zs");
}
// 限流与阻塞处理 : 参数要和 被降级的方法参数一样
public User exceptionHandler(@PathVariable Long id, BlockException ex) {
ex.printStackTrace();
System.out.println("限流了...");
return new User(-1L,"限流了","限流了");
}
4.2Sentinel设置限流策略
4.2.1Sentinel流控模式
4.2.1.1直接
Sentinel默认的流控处理就是【直接->快速失败】,QPS达到阈值,当前资源直接失败。在流控规则中配置如下:
4.2.1.2关联
关联的资源达到某个阈值,限流自己,如:限流的资源是/user/delete ,关联的资源是/user/list,当/user/list达到阈值,限流user/delete , 举例: 支付并发太高,可以限制下单的流量
4.2.1.2链路
限流线路调用链路的入口,如 /user/list 资源中 调用了 /dept/list ,对/dept/list添加限流,当/dept/list达到阈值,其实限流的是/user/list,因为他是访问的入口
4.2.2Sentinel流控效果
4.2.2.1快速失败
快速失败:(RuleConstant.CONTROL_BEHAVIOR_DEFAULT)是默认的流控方式,当流量达到阀值直接返回异常,QPS达到任何规则阈值后,后续请求就会立即拒绝,并抛出FlowException 异常。简单理解:并发太高,直接请求拒绝
4.2.2.2Warm Up预热
Warm Up预热:(RuleConstant.CONTROL_BEHAVIOR_WARM_UP)方式,根据codeFactor(默认3)的值,从(阀值/codeFactor)为初始阀值,经过预热时长,才到达设置的QPS的阀值,即预热/冷启动方式。简单理解:慢慢的增大处理并发的能力
提示:初始的QPS阈值为 100 / 3 =33 ,10秒后 QPS阈值达到 100.
当系统长期并发不高,流量突然增加可能会直接把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值的上限,给系统一个预热的时间,避免冷系统被压垮。
4.2.2.3排队等待
排队等(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER),忽然增加的请求并发量达到了限流阈值后续请求会被拒绝,有时候我们可能更希望后续的请求可以加入队列进行排队,慢慢执行,而不是直接拒绝请求,这种方式后严格控制请求通过的时间间隔,也即是让请求以均匀的速度通过,对应的是漏桶算法,这种方式主要用于处理间隔性突发的流量,例如消息队列。 简单理解:突发流量处理不过来,让请求排队。
4.2.2.4热点限流
还有一种特殊的动态限流规则,用于限制动态的热点资源 , 比如对同一个用户的请求频率做限定,比如对参数进行限定,比如对参数的值做限定(比如对商品ID为1的资源做限流)。
4.2.2.4.1参数限流
参数限流就是 对资源的参数进行限流,我们来编写一个方法,接受两个参数:p1,和p2并设置好限流降级
//限流降级
@SentinelResource(value="/parameterLimit",blockHandler="parameterLimitHandler")
@GetMapping(value="/parameterLimit")
public String parameterLimit(@RequestParam("p1") String p1 ,@RequestParam("p2") String p2){
return "parameterLimit方法调用成功...";
}
// 限流与阻塞处理
public String parameterLimitHandler(@RequestParam("p1") String p1 ,@RequestParam("p2") String p2,BlockException ex) {
return "限流了...";
}
配置热点规则 , 对第一个参数限流 , 当第一个参数超过了1的QPS就熔断降级。
4.2.2.5参数值限流
对某一个参数的值满足某种条件的时候就进行限流,如下配置
意思是第一个参数的值为 haha 的时候限流阈值为10 , 超过 QPS > 10的并发就限流。
举例:应用场景比如说商品名称为“华为p40”的商品并发特别高,我们可以针对参数商品名为“华为p40”的商品进行限流
4.2.2.5系统规则
配置全局限流规则
系统规则可以看做是总的限流策略,所有的只要都要受到系统规则的限制。
上面的意思是最大并发只能允许 10 个线程数,并且是作用于全局的。
4.3Gateway网关集成sentienl
4.3.1导包
<!-- 限流和gataway使用-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
4.3.2修改配置文件
spring:
cloud:
sentinel:
transport:
dashboard: localhost:1111
4.3.3配置限流规则
启动Gateway,登录sentinel控制台,对url资源进行流控限制,配置方式和前面的配置方式一样
4.3.4自定义降级数据
@Configuration
public class SentinelConfig {
public SentinelConfig(){
GatewayCallbackManager.setBlockHandler(new BlockRequestHandler() {
@Override
public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
return ServerResponse.ok().body(Mono.just("限流啦,请求太频繁"),String.class);
}
});
}
}
4.4Sentienl集成Nacos持久化限流规则
4.4.1导包
<!--Sentinel和Nacos做持久的-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>1.5.2</version>
</dependency>
4.4.2配置Nacos持久化地址
cloud:
sentinel: #限流与熔断
datasource:
flow:
nacos: #限流持久配置
server-addr: localhost:8848 #使用nacos的持久
dataId: sentinel-pay-flow #获取限流的数据源的dataId
groupId: DEFAULT_GROUP
rule-type: flow #类型:限流
namespace: alibaba-dev
username: nacos
password: nacos
NacosDataSourceProperties 配置类具体含义如下:
- spring.cloud.sentinel.datasource.ds.nacos.server-addr:nacos的访问地址
- spring.cloud.sentinel.datasource.ds.nacos.groupId:nacos中存储规则的groupId
- spring.cloud.sentinel.datasource.ds.nacos.dataId:nacos中存储规则的dataId
- spring.cloud.sentinel.datasource.ds.nacos.rule-type:该参数是用来定义存储的规则类型。所有的规则类型可查看枚举类:...datasource.RuleType,每种规则的定义格式可以通过各枚举值中定义的规则对象来查看,比如限流规则可查看:...flow.FlowRule
简而言之,这里是配置了Sentinel持久化针对于Nacos的相关信息,程序会去地址为localhost:8848的Nacos中查找DataId为 application-user-sentinel-dev,GourpId为 DEFAULT_GROUP的文件作为限流策略(rule-type: flow代表限流)。
4.4.3Nacos持久化Sentinel限流规则配置
第一步:在配置列表增加配置:
[
{
"resource": "getOrderById",
"limitApp": "default",
"grade": 1,
"count": 10,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
}
]
这里做一个解释
- resource:对那个资源进行限流
- limitApp:这个是流控的调用者,default 代表不区分调用者
- grade:限流方式0是根据并发数量限流,1是表根据QPS来限流
- count:限流阈值,达到这个阈值就被限流,触发降级。
- strategy:基于调用链的流控制策略。0 直接,1 关联 2 链路
- controlBehavior:流控效果,0 直接拒绝,1是Warm Up,2是匀速排队
- clusterMode:是否为集群
第二步:启动sentienl界面
这里我们看到,我们并没有在Sentinel设置流控规则,而是通过Nacos配置的流控规则,在客户端对Sentinel做Nacos持久配置,那么Sentinal自动会去同步Nacos中的流控规则,同时同步到客户端本地,只要Nacos是做了持久化的,流控规则就不会丢失。
5.Sentienl熔断
Sentinel的服务熔断机制会对`调用链上的某个不稳定(宕机,异常,超时)的资源,做出请求限制,快速失败,避免影响到其它的服务而导致级联错误`。资源熔断后,在`后续的一定时间(时间窗口)之内,对该服务的请求都自动熔断,抛出 DegradeException异常。`
Sentinel拥有比Hystrix更强大和丰富的功能,能满足我们的各种应用场景,并且经历过淘宝双十一的考验,是微服务架构中熔断机制的不二选择
5.1Sentienl熔断快速入门
5.1.1@SentinelResource`注解的fallback 属性指定降级方法
// 限流降级
public User exceptionHandler(@PathVariable Long id, BlockException ex) {
ex.printStackTrace();
System.out.println("限流了...");
return new User(-1L,"限流了","限流了");
}
// 熔断降级,参数和返回值与源方法一致
public User getByIdfallback(@PathVariable Long id){
System.out.println(notify);
return new User(id,"zs:"+id, "熔断托底了");
}
@GetMapping("/user/{id}")
//限流降级
@SentinelResource(value="user",blockHandler="exceptionHandler",fallback = "getByIdfallback")
public User getById(@PathVariable Long id){
int i = 1 / 0; //方法异常,触发熔断
return new User(id,"zs:"+id, "我是zs");
}
注意:这里可以通过 @SentinelResource注解的 exceptionsToTrace 属性忽略异常,即针对某个异常不熔断
5.1.2配置降级策略
在Sentinel控制台,在族点链路菜单中找到资源,然后点击“降级”按钮添加降级策略,如下:
5.1.3配置熔断策略
5.2降级策略
5.2.1平均响应RT
这里配置的RT是200意思是对资源的多次请求平均响应时间都超过200毫秒,意思是 1s 内持续进入 5 个请求(即 QPS >= 5),这五个请求的平均响应时间都超过了200,后续的2秒之内(时间窗口)请求这个方法都被熔断,触发降级
总结一下:RT其实就是**平均相应时间太长**资源熔断
5.2.2异常比例
这个资源的异常比例超过了0.5,即10个请求有5个都异常了,资源被熔断,在接下来的2秒钟之后请求这个方法都被熔断,触发降级。
总结一下:异常比例就是按**照资源的请求失败率**来熔断。
5.3.3异常数
这里的意思是1秒内10个超过2个异常请求,服务进行熔断。后续请求都拒绝。
注意:异常降级仅针对业务异常,对 Sentinel 限流降级本身的异常(BlockException)不生效
总结一下:异常数就是按照 一分钟的异常的数量 来熔断。
5.3Feign整合熔断
5.3.1导入Sentienl包
5.3.2开启Sentinel
feign:
sentinel:
enabled: true #熔断
5.3.3fallback给Feign接口降级
@FeignClient(value = "user-server",path = "/user",fallbackFactory = UserFallback.class)
public interface UserFegin {
@GetMapping("/{id}")
String hello(@PathVariable Long id);
}
5.3.4编写降级类
@Component
public class UserFallback implements FallbackFactory<UserFegin> {
@Override
public UserFegin create(Throwable cause) {
return id -> "服务挂了,fegin熔断了";
}
}
5.4Sentienl熔断持久化Nacos
5.4.1导包
<!--Sentinel和Nacos做持久的-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>1.5.2</version>
</dependency>
5.4.2修改配置文件
cloud:
sentinel: #限流与熔断
datasource:
flow:
nacos: #限流持久配置
server-addr: localhost:8848 #使用nacos的持久
dataId: sentinel-pay-flow #获取限流的数据源的dataId
groupId: DEFAULT_GROUP
rule-type: flow #类型:限流
namespace: alibaba-dev
username: nacos
password: nacos
degrade: #降级的配置
nacos:
server-addr: 127.0.0.1:8848
dataId: sentinel-pay-degrade
groupId: DEFAULT_GROUP
rule-type: degrade
namespace: alibaba-dev
username: nacos
password: nacos
5.4.3Nacos持久化Sentinel熔断规则
[
{
"resource": "GetUserByID",
"grade": 0,
"count": 10,
"timeWindow": 5
}
]
- resources : 资源名
- grade : (RT)慢调用比例 0 ;异常比例 1 ;异常数 2;
- count : 最大RT,最大平均响应时间
- timeWindow :时间窗口,即熔断时长
6.SpringBootAdmin
1.简介
我们知道在微服务架构的应用中服务众多,对于各个微服务的监控是微服务架构应用中不可缺少的一个环节,比如:服务的内存使用情况,JVM信息等等都需要做数据监控以便在资源使用告急时方便运维人员做出相应的配置调整。
SpringBoot Admin 它是在 Spring Boot Actuator 的基础上用于监控 Spring Boot 的应用,且提供简洁的可视化 WEB UI界面。Spring Boot Admin 提供了很多功能,可以监控如:spring-boot项目的基本信息,详细的Health信息、内存信息、JVM信息、垃圾回收信息、各种配置信息(比如数据源、缓存列表和命中率)等,还可以直接修改logger的level
2.快速入门
2.1搭载服务端
2.1.1导包
<dependencies>
<!-- 实现 Spring Boot Admin Server 服务端 -->
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
<version>2.6.1</version>
</dependency>
<!--nacos依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<!--nacos配置中心依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
2.1.2启动类加注解@EnableAdminServer
@SpringBootApplication
@EnableAdminServer
public class AdminApplication{
...
}
2.1.3配置yaml文件
management:
endpoints:
web:
exposure:
include: "*" #暴露所有的端点我们可以看到更多应用相关信息
endpoint:
health:
show-details: ALWAYS #health endpoint是否必须显示全部细节
health:
defaults:
enabled: false #禁用健康检查,启动可能报错
2.1.4浏览器访问服务端
2.2服务集成客户端
2.2.1导包
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>2.6.1</version>
</dependency>
2.2.2yml配置客户端
# 2.0开始,actuator默认不开放,所以要设置为开放
management:
endpoints:
web:
exposure:
include: "*" #暴露所有的端点我们可以看到更多应用相关信息
endpoint:
health:
show-details: ALWAYS #health endpoint是否必须显示全部细节
spring:
boot:
admin:
client:
url: http://localhost:10200 #监控中心地址
instance:
name: service-name #服务名
7.SpringBoot集成Dubbo远程调用
1.代码演示结构
parent---父工程
springcloudalibaba-dubbo-api---公共模块
springcloudalibaba-dubbo-consumer-1080---消费者(调用方)
springcloudalibaba-dubbo-server-1070---提供者(被调用方)
2.编写公共模块的公共方法
//用户的API接口
public interface UserService {
String getUserInfo(Long id);
}
注意:这个接口是公用的,消费者和提供者都会用到
3.编写提供者模块(被调用方)
3.1导入包
<dependencies>
<!-- 第一步中构建的公共API包 -->
<dependency>
<groupId>org.example</groupId>
<artifactId>springcloudalibaba-dubbo-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- 监控的依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 整合dubbo-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
<!-- nacos服务发现-->
<dependency>
<groupId>com.alibaba.cloud </groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
3.2修改yml配置文件
spring:
application:
name: dubbo-provider
cloud:
nacos:
discovery:
server-addr: localhost:8848 #nacos注册中心
main:
allow-bean-definition-overriding: true #设置是否覆盖Bean定义 ,防止bean的重复定义而报错
server:
port: 1070
dubbo:
scan:
base-packages: org.example.service #dubbo 的api实现类扫描包
protocol:
name: dubbo #通信协议:dubbo
port: 20880 #dubbo通信端口
registry:
address: spring-cloud://localhost #注册中心地址,使用springcloud的注册中心
3.3实现暴露被调用的接口
该实现是提供者服务的具体服务的实现,在这里去实现 UserService 接口,返回相关的数据,消费者调用提供者的时候就是调用的该实现,---- 我们可以简单的理解为这里暴露了一个服务准备让消费者去调用
//用户的API接口实现
//@Service : dubbo的注解 , 通过该注解把api发布出去
@org.apache.dubbo.config.annotation.Service
public class UserServiceImpl implements UserService {
@Override
public String getUserInfo(Long id) {
return "成功获取到用户信息";
}
}
需要注意的是,这里使用的是 dubbo的@Service注解,意思是发布一个远程服务
4.编写消费者模块(调用方)
4.1导包
<dependencies>
<!-- 第一步中构建的API包 -->
<dependency>
<groupId>org.example</groupId>
<artifactId>springcloudalibaba-dubbo-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 整合dubbo-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud </groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
4.2修改yml配置文件
spring:
application:
name: dubbo-consumer
cloud:
nacos:
discovery:
server-addr: localhost:8848 #nacos注册中心
main:
allow-bean-definition-overriding: true #设置是否覆盖Bean定义 ,防止bean的重复定义而报错
server:
port: 1080
dubbo:
scan:
base-packages: org.example.service #dubbo 的api实现类扫描包
protocol:
name: dubbo #通信协议:dubbo
port: 20881 #dubbo通信端口
registry:
address: spring-cloud://localhost #注册中心地址,使用springcloud的注册中心
cloud:
subscribed-services: dubbo-provider #订阅的服务,指向提供者的服务名
4.3发起远程调用
@RestController
public class UserController {
@org.apache.dubbo.config.annotation.Reference
private UserService userService ;
@GetMapping("/userinfo/{id}")
public String getUserInfo(@PathVariable("id")Long id){
return userService.getUserInfo(id);
}
}
这里通过 userService.getUserInfo 实现远程服务的调用,感觉在调用本地Service,其实不是,在UserService上使用的是@Reference标签而不是@Autowired 自动注入,通过@Reference标签,Dubbo会自动代理UserServcie,实现服务的远程调用,所以这里其实调用的是提供者服务的UserService实现。
5.总结
1.首先提供者服务对UserService做了实现,并且通过 @Service发布服务
2.消费者服务在Controller中通过@Reference引入UserService ,该UserServer接口当然也会被代理掉,在调用接口时会向提供者发起远程访问
3.提供者监听到请求,执行相关的业务逻辑,并返回数据
4.消费者获取到结果,最终把数据展示到浏览器上