(1)Nacos 是阿里巴巴推出来的一个新开源项目,是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。
(2)Nacos是以服务为主要服务对象的中间件,Nacos支持所有主流的服务发现、配置和管理。
Nacos主要提供以下四大功能:
服务发现和服务健康监测
动态配置服务
动态DNS服务
服务及其元数据管理
(1)下载地址和版本
下载地址:https://github.com/alibaba/nacos/releases
下载版本:nacos-server-1.1.4.tar.gz或nacos-server-1.1.4.zip,解压任意目录即可
(2)启动nacos服务
启动命令(standalone代表着单机模式运行,非集群模式)
启动命令:sh startup.sh -m standalone
启动命令:cmd startup.cmd 或者双击startup.cmd运行文件。
访问:http://localhost:8848/nacos
用户名密码:nacos/nacos
注意版本号
<!--服务注册-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
配置application.properties,在客户端微服务中添加注册Nacos服务的配置信息
注意:服务器名 尽量不要加下划线_
# nacos服务地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
#服务器名尽量不要加下划线_
spring.application.name=service-edu
在客户端微服务启动类中添加注解 SpringBoot的启动类上加
@EnableDiscoveryClient
Feign是Netflix开发的声明式、模板化的HTTP客户端, Feign可以帮助我们更快捷、优雅地调用HTTP API。
Feign支持多种注解,例如Feign自带的注解或者JAX-RS注解等。
Spring Cloud对Feign进行了增强,使Feign支持了Spring MVC注解,并整合了Ribbon和Eureka,从而让Feign的使用更加方便。
Spring Cloud Feign是基于Netflix feign实现,整合了Spring Cloud Ribbon和Spring Cloud Hystrix,除了提供这两者的强大功能外,还提供了一种声明式的Web服务客户端定义的方式。
Spring Cloud Feign帮助我们定义和实现依赖服务接口的定义。在Spring Cloud feign的实现下,只需要创建一个接口并用注解方式配置它,即可完成服务提供方的接口绑定,简化了在使用Spring Cloud Ribbon时自行封装服务调用客户端的开发量
1、需求
删除课时的同时删除云端视频
2.添加pom依赖
<!--服务调用-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
3、在**调用端**的启动类(SpringBoot)添加注解
@EnableFeignClients
4、在**调用端**创建包和接口(interface)
创建client包
@FeignClient注解用于指定从哪个服务中调用功能 ,名称与被调用的服务名保持一致。
@GetMapping注解用于对被调用的微服务进行地址映射。
@PathVariable注解一定要指定参数名称,否则出错
@Component注解防止,在其他位置注入CodClient时idea报错
package com.guli.edu.client;
@FeignClient("service-vod")//被调用的服务名
@Component
public interface VodClient {
//定义调用方法路径(Controller全路径)
@DeleteMapping(value = "/eduvod/vod/video/{videoId}")
//@PathVariable注解一定要指定参数名称,否则出错
public Result removeVideo(@PathVariable("videoId") String videoId);
}
5、调用微服务
在调用端的VideoServiceImpl中注入VoidClient并调用client中的方法
@Autowired
private VodClient vodClient;
@Override
public boolean removeVideoById(String id) {
//查询云端视频id
Video video = baseMapper.selectById(id);
String videoSourceId = video.getVideoSourceId();
//判断小节是否有视频
if(!StringUtils.isEmpty(videoSourceId)){
//视频的id(阿里云)
//根据视频id,远程调用实现删除视频资源(查看博客中阿里删除的代码)
vodClient.removeVideo(videoSourceId);
}
//删除数据库中的数据
Integer result = baseMapper.deleteById(id);
return null != result && result > 0;
}
业务接口: VodService.java
public interface VodService {
//删除多条视频
Result deleteBatch(List<String> vodIdList);
}
业务实现:VodServiceImp .java
@Service
public class VodServiceImp implements VodService {
//删除多条视频
@Override
public Result deleteBatch(List<String> vodIdList) {
try {
//初始化
DefaultAcsClient client = InitVod.initVodClient(ConstPropertiesUtils.ACCESS_KEY_ID, ConstPropertiesUtils.ACCESS_KEY_SECRET);
DeleteVideoRequest request = new DeleteVideoRequest();
//注意导包 org.apache.commons.lang.StringUtils
//把集合用逗号分隔成字符串
String vodIds = StringUtils.join(vodIdList.toArray(), ",");
//支持传入多个视频ID,多个用逗号分隔
//设置视频id
request.setVideoIds(vodIds);
//调用初始化对象删除
client.getAcsResponse(request);
return Result.success();
} catch (Exception e) {
e.printStackTrace();
return Result.error();
}
}
}
controller
@RestController
@RequestMapping("/vod")
@CrossOrigin
@Api(value = "视频Controller", tags = {"视频"})
public class VodController {
@Autowired
private VodService vodService;
@ApiOperation("删除多个视频")
@DeleteMapping("deleteBatch")
public Result deleteBatch(@RequestParam("vodIdList") List<String> vodIdList){
Result result = vodService.deleteBatch(vodIdList);
return result;
}
}
启动类
@SpringBootApplication
@ComponentScan(basePackages = {"com.yzh"})//为了可以扫描到common的配置类
@EnableDiscoveryClient//Nacos启动注解
@EnableFeignClients//Feign启动注解
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
VodClient.java(接口)
@FeignClient("service-vod")
@Component
public interface VodClient {
//删除多条视频
@DeleteMapping("/vod/deleteBatch")
Result deleteBatch(@RequestParam("vodIdList") List<String> vodIdList);
}
VideoServiceImpl.java
@Service
public class VideoServiceImpl extends ServiceImpl<VideoMapper, Video> implements VideoService {
//注入接口
@Autowired
private VodClient vodClient;
//删除小节
//删除小节视频
@Override
public void deleteCourseId(String courseId) {
//根据课程id查询所有视频列表
QueryWrapper<Video> vodWrapper = new QueryWrapper<>();
vodWrapper.eq("course_id", courseId);
vodWrapper.select("video_source_id");//查出只需要的字段
List<Video> videos = baseMapper.selectList(vodWrapper);
//得到所有视频列表的云端原始视频id
ArrayList<String> vodIds = new ArrayList<>();
for (int i = 0; i < videos.size(); i++) {
Video video = videos.get(i);
String videoSourceId = video.getVideoSourceId();
if (!StringUtils.isEmpty(videoSourceId)) {
vodIds.add(videoSourceId);
}
}
//调用vod服务删除远程视频
//也可以用循环的方式调用 根据id删除视频的方法
if (vodIds.size() > 0) {
vodClient.deleteBatch(vodIds);
}
//删除数据库记录
QueryWrapper<Video> wrapper = new QueryWrapper<>();
wrapper.eq("course_id", courseId);
baseMapper.delete(wrapper);
}
}
Hystrix概念
Hystrix 是一个供分布式系统使用,提供延迟和容错功能,保证复杂的分布系统在面临不可避免的失败时,仍能有其弹性。
比如系统中有很多服务,当某些服务不稳定的时候,使用这些服务的用户线程将会阻塞,如果没有隔离机制,系统随时就有可能会挂掉,从而带来很大的风险。SpringCloud使用Hystrix组件提供断路器、资源隔离与自我修复功能。下图表示服务B触发了断路器,阻止了级联失败
改造service-edu模块(调用端)
<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>
#开启熔断机制
feign.hystrix.enabled=true
# 设置hystrix超时时间,默认1000ms
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=6000
@Component
public class VodFileDegradeFeignClient implements VodClient {
@Override
public Result deleteBatch(List<String> vodIdList) {
return Result.error().message("time out");
}
}
@FeignClient(name = “service-vod”, fallback = VodFileDegradeFeignClient.class)
@FeignClient(name = "service-vod", fallback = VodFileDegradeFeignClient.class)
@Component
public interface VodClient {
//删除多条视频
@DeleteMapping("/vod/deleteBatch")
Result deleteBatch(@RequestParam("vodIdList") List<String> vodIdList);
}
//调用vod服务删除远程视频
if (vodIds.size() > 0) {
Result result = vodClient.deleteBatch(vodIds);
//如果失败
if (result.getCode() == 20001) {
System.out.println("视频删除失败");
}
}