[欢迎访问我的博客,专注于Java技术分享,共同进步。❤]
基本概念
(1)Nacos 是阿里巴巴推出来的一个新开源项目,是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您 快速实现动态服务发现、服务配置、服务元数据及流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。
(2)常见的注册中心:
- Eureka(原生,2.0遇到性能瓶颈,停止维护)
- Zookeeper(支持,专业的独立产品。例如:dubbo)
- Consul(原生,GO语言开发)
- Nacos
相对于 Spring Cloud Eureka 来说,Nacos 更强大。Nacos = Spring Cloud Eureka + Spring Cloud Config
Nacos 可以与 Spring, Spring Boot, Spring Cloud 集成,并能代替 Spring Cloud Eureka, Spring Cloud Config
通过 Nacos Server 和 spring-cloud-starter-alibaba-nacos-discovery 实现服务的注册与发现。
(3)Nacos是以服务为主要服务对象的中间件,Nacos支持所有主流的服务发现、配置和管理。
Nacos主要提供以下四大功能:
- 服务发现和服务健康监测
- 动态配置服务
- 动态DNS服务
- 服务及其元数据管理
使用Nacos服务
1、下载地址和版本
下载地址:https://github.com/alibaba/nacos/releases
下载版本:nacos-server-1.1.4.tar.gz或nacos-server-1.1.4.zip,解压任意目录即可
2、pom.xml引入依赖
<!--服务注册-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>${project.version}</version>
</dependency>
<!--服务调用-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>${project.version}</version>
</dependency>
3、yml文件中配置nacos
# 服务名
spring:
application:
name: service-ucenter
# nacos配置
spring
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
4、配置application.java
@EnableDiscoveryClient 开启服务注册发现功能,Nacos客户端注解
@EnableFeignClients 启用feign客户端,将远程服务中的方法映射为一个本地Java方法调用
5、调用service-vod服务中的方法
用于两个模块间的方法调用
/**
* 调用的服务名称
*
* @author Blue
* fallback方法的返回值一般是设置的默认值或者来自缓存.
*/
@FeignClient(name = "被调用的服务名", fallback = VodFileDegradeFeignClient.class)
@Component
public interface VodClient {
/**
* 定义调用的方法路径
* 根据视频id删除阿里云视频
* PathVariable注解一定要指定参数名称,否则出错
*
* @param id 视频id
*/
@DeleteMapping("/eduVod/video/removeAlyVideo/{id}")
public Result removeAlyVideo(@PathVariable String id);
/**
* 定义调用删除多个视频的方法
* 删除多个阿里云视频的方法
* 参数多个视频id List videoIdList
*
* @param videoIdList 多个视频id
*/
@DeleteMapping("/eduVod/video/deleteBatch")
public Result deleteBatch(@RequestParam("videoIdList") List<String> videoIdList);
}
常见问题:java.lang.RuntimeException: com.netflix.client.ClientException: Load balancer does not have available server for client: 服务名称
熔断器使用
1、雪崩效应
在微服务架构中通常会有多个服务层调用,基础服务的故障可能会导致级联故障,进而造成整个系统不可用的情况,这种现象被称为服务雪崩效应。服务雪崩效应是一种因“服务提供者”的不可用导致“服务消费者”的不可用,并将不可用逐渐放大的过程。
如果下图所示:A作为服务提供者,B为A的服务消费者,C和D是B的服务消费者。A不可用引起了B的不可用,并将不可用像滚雪球一样放大到C和D时,雪崩效应就形成了。
2、Spring Cloud调用接口过程
Spring Cloud 在接口调用上,大致会经过如下几个组件配合:
Feign ----->Hystrix —>Ribbon —>Http Client(apache http components 或者 Okhttp) 具体交互流程上,如下图所示:
(1)接口化请求调用当调用被@FeignClient注解修饰的接口时,在框架内部,将请求转换成Feign的请求实例feign.Request,交由Feign框架处理。
(2)Feign :转化请求Feign是一个http请求调用的轻量级框架,可以以Java接口注解的方式调用Http请求,封装了Http调用流程。
(3)Hystrix:熔断处理机制 Feign的调用关系,会被Hystrix代理拦截,对每一个Feign调用请求,Hystrix都会将其包装成HystrixCommand,参与Hystrix的流控和熔断规则。如果请求判断需要熔断,则Hystrix直接熔断,抛出异常或者使用FallbackFactory返回熔断Fallback结果;如果通过,则将调用请求传递给Ribbon组件。
(4)Ribbon:服务地址选择 当请求传递到Ribbon之后,Ribbon会根据自身维护的服务列表,根据服务的服务质量,如平均响应时间,Load等,结合特定的规则,从列表中挑选合适的服务实例,选择好机器之后,然后将机器实例的信息请求传递给Http Client客户端,HttpClient客户端来执行真正的Http接口调用;
(5)HttpClient :Http客户端,真正执行Http调用根据上层Ribbon传递过来的请求,已经指定了服务地址,则HttpClient开始执行真正的Http请求
3、在pom文件中引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<!--hystrix依赖,主要是用 @HystrixCommand -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!--服务注册-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--服务调用-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
4、在配置文件中添加
# 开启熔断机制
feign.hystrix.enabled=true
# 设置hystrix超时时间,默认1000ms
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=6000
5、创建熔断器的实现类
/**
* @author Blue
* 熔断器:出错就使用,比如 宕机
*/
@Component
public class VodFileDegradeFeignClient implements VodClient {
/**
* 出错之后会执行,这边还可以调用方法查数据...
*/
@Override
public Result removeAlyVideo(String id) {
return Result.error().message("删除视频失败");
}
@Override
public Result deleteBatch(List<String> videoIdList) {
return Result.error().message("批量删除视频失败");
}
}
6、修改VodClient接口的注解
@FeignClient(name = "被调用的服务名", fallback = VodFileDegradeFeignClient.class)
@Component
public interface VodClient {
// 被调用的方法
@DeleteMapping(value = "/eduvod/vod/{videoId}")
public R removeVideo(@PathVariable("videoId") String videoId);
@DeleteMapping(value = "/eduvod/vod/delete-batch")
public R removeVideoList(@RequestParam("videoIdList") List videoIdList);
}