文章目录
- 一、搭建Nacos服务
- 1、Nacos
- 2、安装Nacos
- 3、Docker安装Nacos
- 二、OpenFeign和Dubbo远程调用Nacos的服务
- 1、搭建SpringCloudAlibaba的开发环境
- 1.1 构建微服务聚合父工程
- 1.2 创建子模块cloud-provider-payment8001
- 1.3 创建子模块cloud-consumer-order80
- 2、远程服务调用OpenFeign
- 2.1 Dubbo和OpenFeign的区别
- 2.2 创建子模块cloud-consumer-openfeign-order80
- 2.3 OpenFeign实现服务降级
- 3、远程服务调用Dubbo
- 3.1 创建接口服务工程cloud-service-api
- 3.2 创建支付生产者工程cloud-dubbo-provider-payment8001
- 3.3创建消费者cloud-dubbo-consumer-order80
- 3.4 Dubbo实现服务降级
- 总结
一、搭建Nacos服务
1、Nacos
- Nacos是阿里巴巴开源的服务注册中心以及配置中心,致力于给开发者提供一款便捷、简单上手的开源框架。
Nacos包含了SpringCloud的注册中心Eureka、服务配置Config、服务总线Bus。 - Nacos提供四大功能,分别是服务发现和服务健康监测、动态配置服务、动态DNS服务、服务及其元数据管理。
1)服务发现和服务健康监测
Nacos使服务更容易注册,并通过DNS或HTTP接口发现其他服务,Nacos还提供服务的实时健康检查,以防止向不健康的主机或服务实例发送请求。
2)动态配置服务
动态配置服务允许在所有环境中以集中和动态的方式管理所有服务的配置。Nacos消除了在更新配置时重新部署应用程序,这使得配置的更改更加高效和灵活。
3)动态DNS服务
Nacos提供基于DNS协议的服务发现能力,旨在支持异构语言的服务发现,支持将注册在Nacos上的服务以域名的方式暴露端点,让第三方应用方便查阅及发现。
4)服务及其元数据管理
Nacos能让你从微服务平台建设的视觉去管理数据中心的所有服务及元数据,包括管理服务的描述、生命周期、服务的静态依赖分析、服务的健康状态、服务的流量管理、路由及安全策略。
2、安装Nacos
- 在官网下载Linux的Nacos安装包:
https://github.com/alibaba/nacos/releases
- 通过mobax将安装包上传到虚拟机的/opt目录下
- 解压到/usr/local目录下:
tar -zxvf nacos-server-2.2.3.tar.gz -C /usr/local
- 需要在虚拟机上配置JDK8以上的环境:
https://blog.csdn.net/weixin_49076273/article/details/126636650
- 进入到nacos的bin目录下,启动单机模式的nacos服务器:
sh startup.sh -m standalone
- 在浏览器访问:
http://192.168.126.32:8848/nacos/
3、Docker安装Nacos
-
安装Docker:
https://blog.csdn.net/weixin_49076273/article/details/126532188
-
使用Docker拉取镜像:
docker pull nacos/nacos-server:v2.2.0
-
单机版部署:
docker run --name nacos -d -p 8848:8848 -p 9848:9848 -p 9849:9849 -e MODE=standalone -e NACOS_SERVER_IP=192.168.126.32 nacos/nacos-server:v2.2.0
-
在浏览器访问:
http://192.168.126.32:8848/nacos/
帐号密码都是nacos使用docker容器搭建nacos,如果是nacos2.x需要把9848,9849这两个端口开放出来即可,这样就可以使用IDEA连接上Nacos。如果是1.x则直接使用8848端口即可
二、OpenFeign和Dubbo远程调用Nacos的服务
1、搭建SpringCloudAlibaba的开发环境
1.1 构建微服务聚合父工程
-
创建父工程springcloudalibaba
-
配置注解生效激活
-
Java编译版本选择
-
父工程的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.zzx</groupId> <artifactId>springcloudalibaba</artifactId> <version>1.0-SNAPSHOT</version> <!-- 统一管理jar包版本 --> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <spring-cloud.version>2021.0.0</spring-cloud.version> <spring-boot.version>2.6.3</spring-boot.version> </properties> <!-- 子模块继承之后,提供作用:锁定版本+子modlue不用写groupId和version --> <dependencyManagement> <dependencies> <!--spring boot 2.6.3--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!--spring cloud 2021.0.0--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> </project>
-
IDEA开启Dashboard
1)修改配置文件.idea/workspace.xml
2)添加如下配置<component name="RunDashboard"> <option name="ruleStates"> <list> <RuleState> <option name="name" value="ConfigurationTypeDashboardGroupingRule" /> </RuleState> <RuleState> <option name="name" value="StatusDashboardGroupingRule" /> </RuleState> </list> </option> <option name="configurationTypes"> <set> <option value="SpringBootApplicationConfigurationType" /> </set> </option> </component>
-
删除src目录
1.2 创建子模块cloud-provider-payment8001
-
在父工程下,右键创建子模块cloud-provider-payment8001
-
在cloud-provider-payment8001的POM文件中添加如下依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies>
-
创建cloud-provider-payment8001的主启动类
package com.zzx; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; /** * 主启动类 */ // 注解开启注册发现服务功能 @EnableDiscoveryClient @SpringBootApplication @Slf4j public class PaymentMain8001 { public static void main(String[] args) { SpringApplication.run(PaymentMain8001.class,args); log.info("****** PaymentMain8001 启动成功 ******"); } }
-
在cloud-provider-payment8001的com.zzx.controller包下,创建PaymentController
package com.zzx.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * 支付控制层 */ @RestController @RequestMapping("payment") public class PaymentController { @GetMapping("index") public String index(){ return "payment success"; } }
-
在cloud-provider-payment8001的resources中,创建application.yml文件
server: port: 8001 spring: application: name: payment-provider cloud: nacos: discovery: # Nacos服务的地址 server-addr: 192.168.126.32:8848
-
启动payment8001项目后,在Nacos中的服务管理的服务列表中会出现该服务
1.3 创建子模块cloud-consumer-order80
-
在父工程下,右键创建子模块cloud-consumer-order80
-
在cloud-consumer-order80的POM文件中添加如下依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies>
-
创建cloud-consumer-order80的主启动类
package com.zzx; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; /** * 主启动类 */ // 注解开启注册发现服务功能 @EnableDiscoveryClient @SpringBootApplication @Slf4j public class OrderMain80 { public static void main(String[] args) { SpringApplication.run(OrderMain80.class,args); log.info("****** OrderMain80 启动成功 ******"); } }
-
在cloud-consumer-order80的resources中,创建application.yml文件
server: port: 80 spring: application: name: order-consumer cloud: nacos: discovery: # Nacos服务的地址 server-addr: 192.168.126.32:8848
-
启动order80项目后,在Nacos中的服务管理的服务列表中会出现该服务
2、远程服务调用OpenFeign
2.1 Dubbo和OpenFeign的区别
- Apache Dubbo是一款微服务开发框架,他提供了RPC通信与微服务治理两大关键能力。这意味着使用Dubbo开发的微服务,将具备相互之间的远程发现和通信能力,同时利用Dubbo提供的丰富服务治理能力,可以实现诸如服务发现、负载均衡、流量调控等服务治理诉求。
- SpringCloud的通信采用OpenFeign组件。Feign基于Http传输协议,底层实现是Rest。从OSI7层模型上来看Rest属于应用层。
OpenFeign在高并发场景下性能不够理想,成为性能瓶颈。
使用场景:并发不高,性能要求也不高 - Dubbo框架的通信协议采用RPC协议,属于传输层协议,性能上自然比rest高。提升了交互的性能,保持了长连接,高性能。
Dubbo性能更好,比如支持异步调用、Netty性能更好。
使用场景:数据小,并发高
2.2 创建子模块cloud-consumer-openfeign-order80
-
在父工程下,右键创建子模块cloud-consumer-openfeign-order80
-
在cloud-consumer-openfeign-order80的POM文件中添加如下依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <!-- 引入openfeign依赖包 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!-- 引入负载均衡器依赖包 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-loadbalancer</artifactId> </dependency> </dependencies>
-
创建cloud-consumer-openfeign-order80的主启动类
package com.zzx; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; /** * 主启动类 */ // 注解开启注册发现服务功能 @EnableDiscoveryClient // 开启feign扫描 @EnableFeignClients @SpringBootApplication @Slf4j public class OrderOpenFeignMain80 { public static void main(String[] args) { SpringApplication.run(OrderOpenFeignMain80.class,args); log.info("****** OrderOpenFeignMain80 启动成功 ******"); } }
-
在cloud-consumer-openfeign-order80的com.zzx.service包中,创建IPaymentFeignService接口
package com.zzx.service; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.GetMapping; /** * OpenFeign远程调用 */ @Service @FeignClient(value = "payment-provider") public interface IPaymentFeignService { @GetMapping("/payment/index") String index(); }
-
在cloud-consumer-openfeign-order80的com.zzx.controller包中,创建OrderController
package com.zzx.controller; import com.zzx.service.IPaymentFeignService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * 订单微服务 */ @RestController @RequestMapping("order") public class OrderController { @Autowired private IPaymentFeignService iPaymentFeignService; /** * 测试OpenFeign * @return */ @GetMapping("index") public String index(){ return iPaymentFeignService.index(); } }
-
在cloud-consumer-openfeign-order80的resources中,创建application.yml文件
server: port: 80 spring: application: name: order-consumer-openfeign cloud: nacos: discovery: # Nacos服务的地址 server-addr: 192.168.126.32:8848
-
启动openfeign-order80项目后,在Nacos中的服务管理的服务列表中会出现该服务
-
在浏览器上测试使用OpenFeign进行远程服务调用,输入:
http://localhost/order/index
此时返回payment success即调用成功
2.3 OpenFeign实现服务降级
-
在cloud-consumer-openfeign-order80的POM文件中,引入服务降级的依赖
<!-- 引入服务降级依赖包 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency>
-
在cloud-consumer-openfeign-order80的resources下的application.yml文件中,添加如下配置开启openfeign对sentinel的支持
feign: sentinel: enabled: true
-
在cloud-provider-payment8001的PaymentController中添加如下超时方法
@GetMapping("timeout") public String timeout(){ try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { throw new RuntimeException(e); } return "payment success"; }
-
在cloud-consumer-openfeign-order80的OrderController中添加如下超时方法
@GetMapping("timeout") public String timeout(){ return iPaymentFeignService.timeout(); }
-
在cloud-consumer-openfeign-order80的IPaymentFeignService中添加如下超时方法
@GetMapping("/payment/timeout") String timeout();
-
在浏览器上测试使用OpenFeign进行远程服务调用,输入:
http://localhost/order/timeout
此时返回报500错误,控制台显示读取超时
-
实现服务降级的回调方法
-
需要在cloud-consumer-openfeign-order80的IPaymentFeignService接口中指定服务降级回调类
@FeignClient(value = "payment-provider",fallback = PaymentServiceFallback.class)
2)在cloud-consumer-openfeign-order80的com.zzx.fallback包下,创建PaymentServiceFallback服务降级回调类
package com.zzx.fallback; import com.zzx.service.IPaymentFeignService; import org.springframework.stereotype.Component; @Component public class PaymentServiceFallback implements IPaymentFeignService { @Override public String index() { return null; } /** * 服务降级方法 * @return */ @Override public String timeout() { return "系统繁忙,请稍后再试"; } }
- 在浏览器访问:
http://localhost/order/timeout
此时会进行服务降级,回调服务降级类对应的方法
3、远程服务调用Dubbo
3.1 创建接口服务工程cloud-service-api
-
在父工程下,右键创建子模块cloud-service-api
-
创建一个公共支付接口
package com.zzx.service; /** * 支付接口 */ public interface IPaymentService { String index(); }
3.2 创建支付生产者工程cloud-dubbo-provider-payment8001
-
在父工程下,右键创建子模块cloud-dubbo-provider-payment8001
-
在cloud-dubbo-provider-payment8001的POM文件中,添加如下依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>com.zzx</groupId> <artifactId>cloud-service-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-dubbo</artifactId> <version>2021.0.1.0</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.12.0</version> </dependency> </dependencies>
-
在cloud-dubbo-provider-payment8001中创建主启动类PaymentDubboMain8001
package com.zzx; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; /** * 主启动类 */ @SpringBootApplication @Slf4j @EnableDiscoveryClient public class PaymentDubboMain8001 { public static void main(String[] args) { SpringApplication.run(PaymentDubboMain8001.class,args); log.info("********** PaymentDubboMain8001 启动成功 ***********"); } }
-
在cloud-dubbo-provider-payment8001的resources中,创建application.yml,添加如下配置
server: port: 8001 spring: main: allow-bean-definition-overriding: true allow-circular-references: true application: # 应用名 name: payment-provider-dubbo cloud: nacos: discovery: # Nacos服务地址 server-addr: 192.168.126.32:8848 # dubbo配置 dubbo: # dubbo 服务实现类扫描包 scan: base-packages: com.zzx.service registry: # 注册地址 address: nacos://192.168.126.32:8848 timeout: 10000 # Dubbo服务暴露协议的配置 protocol: name: dubbo # port为协议端口,(-1表示自增端口,从20880开始) port: -1
-
在cloud-dubbo-provider-payment8001中,创建支付业务层PaymentServiceImpl
package com.zzx.service.impl; import com.zzx.service.IPaymentService; import org.apache.dubbo.config.annotation.DubboService; import org.apache.dubbo.config.annotation.Method; /** * 支付业务层 */ //以下是只将index方法注册到dubbo中 @DubboService(timeout = 5000,methods = {@Method(name="index",retries = 2)}) public class PaymentServiceImpl implements IPaymentService { @Override public String index() { return "dubbo payment"; } }
-
启动该服务后,查看该服务是否在Nacos中注册
3.3创建消费者cloud-dubbo-consumer-order80
-
在父工程下,右键创建子模块cloud-dubbo-consumer-order80
-
在cloud-dubbo-consumer-order80的POM文件中,添加如下依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>com.zzx</groupId> <artifactId>cloud-service-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-dubbo</artifactId> <version>2021.0.1.0</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.12.0</version> </dependency> </dependencies>
-
创建cloud-dubbo-consumer-order80的主启动类
package com.zzx; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication @Slf4j @EnableDiscoveryClient public class OrderDubboMain80 { public static void main(String[] args) { SpringApplication.run(OrderDubboMain80.class,args); log.info("******* OrderDubboMain80 启动成功 ******"); } }
-
在cloud-dubbo-consumer-order80的resources中,创建application.yml配置文件,添加如下配置
server: port: 80 spring: main: allow-circular-references: true #在 Spring Boot 2.1 以及更高的版本增加该设定,因为 Spring Boot 默认调整了 Bean 定义覆盖行为。 allow-bean-definition-overriding: true application: #应用名字 name: order-consumer-dubbo cloud: nacos: discovery: #Nacos地址 server-addr: 192.168.126.32:8848 #dubbo配置 dubbo: cloud: #dubbo.cloud.subscribed-services:表示要订阅服务的服务名,可以配置'*',代表订阅所有服务,不推荐使用。若需订阅多应用,使用 "," 分割。 subscribed-services: "*" registry: # 注册至Nacos address: nacos://192.168.126.32:8848 # 超时时间 timeout: 10000 protocol: # 协议Dubbo name: dubbo # 端口号 port: -1 consumer: check: false
-
在cloud-dubbo-consumer-order80中创建订单业务层OrderService
package com.zzx.service; import org.apache.dubbo.config.annotation.DubboReference; import org.springframework.stereotype.Service; /** * 订单业务层 */ @Service public class OrderService { //支付服务远程调用 @DubboReference private IPaymentService iPaymentService; public String index(){ return iPaymentService.index(); } }
-
在cloud-dubbo-consumer-order80中创建订单控制层OrderController
package com.zzx.controller; import com.zzx.service.OrderService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * 订单控制层 */ @RestController @RequestMapping("/order") public class OrderController { @Autowired private OrderService orderService; /** * 测试Dubbo远程调用服务 * @return */ @GetMapping("/index") public String index(){ return orderService.index(); } }
-
启动该服务后,在浏览器访问:
http://localhost/order/index
3.4 Dubbo实现服务降级
-
在cloud-dubbo-provider-payment8001的PaymentServiceImpl实现类中,设置服务生产者集群容错模式cluster
@DubboService(timeout = 5000,methods = {@Method(name="index",retries = 2)},cluster = "failfast")
1)Failfast Cluster模式:这种模式称为快速失败模式,调用只执行一次,失败则立即报错。
2)Failsafe Cluster模式:失败安全模式,如果调用失败, 则直接忽略失败的调用,而是要记录下失败的调用到日志文件。
3)Failback Cluster模式:失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。
4)Forking Cluster模式:并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。
5)Broadcast Cluster模式:配置值为broadcast。广播调用所有提供者,逐个调用,任意一台报错则报错(2.1.0开始支持)。通常用于通知所有提供者更新缓存或日志等本地资源信息。 -
在cloud-dubbo-consumer-order80中,创建服务降级的回调类PaymentServiceFallback
package com.zzx.service.fallback; import com.zzx.service.IPaymentService; /** * 支付服务降级处理 */ public class PaymentServiceFallback implements IPaymentService { @Override public String index() { return "服务繁忙,请稍后再试!"; } }
-
在cloud-dubbo-consumer-order80的OrderService中,在DubboReference注解中添加一个mock指定回调类
@DubboReference(mock = "com.zzx.service.fallback.PaymentServiceFallback")
-
先将dubbo的生产者跟消费者启动,然后关闭生产者,再访问:
http://localhost/order/index
即配置了访问服务生产者失败后,立刻调用服务降级类的对应方法。
总结
- 在高并发场景下使用Dubbo,因为Dubbo长连接,如果不是高并发会浪费资源;低并发或者性能要求不高使用OpenFeign,因为OpenFeign不是长连接并且便于使用。