尚硅谷谷粒学院项目第十天内容之SpringCloud
概念
微服务:是一种架构风格,指将一个服务拆分成多个独立的服务模块,从而解耦合
SpringCloud不是一个技术,而是多种技术的总称,SpringCloud依赖SpringBoot
attention:SpringCloud和SpringBoot之间有版本对应关系
SpringCloud里的技术:
版本区别
SNAPSHOT:快照版本,随时可能修改
M:MileStone,里程碑版本
SR:Service Release,正式版本
GA:Generally Avaliable,稳定版本
Nacos
在微服务中,service-edu和service-vod是两个独立的模块,现在要在service-edu模块中去调用service-vod模块,一个方法是引入依赖,可是,引入了依赖后,他们就不是互相独立的两个模块了
此时,我们通过nacos(注册中心)实现
安装
安装包解压,双击bin/startup.cmd启动nacos
访问:http://localhost:8848/nacos/
登录时用户名密码都是nacos
服务注册
在service模块中引入依赖
<!--服务注册-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
在service-edu的application.properties中配置nacos地址
#nacos服务地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
在service-edu的启动类上加上注解
@EnableDiscoveryClient //启用nacos
启动service-edu模块,在nacos的服务列表中可以
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
看到,service-edu注册到了nacos中
如果模块启动失败,可能是类路径下的配置文件没有被重新加载
在service-vod模块重复以上操作进行服务注册
Feign
服务调用feign用来解决两个独立的模块之间的相互调用问题
这两个独立的模块需要在nacos中进行注册
在service模块中引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
在调用端(service-edu)启动类上添加服务发现注解
@EnableFeignClients //启用feign
创建client/VodClient.java用来指明feign调用哪个服务
@FeignClient("service-vod") //调用service-vod
@Component
public interface VodClient {
//定义要调用的方法
//根据视频id删除视频
@DeleteMapping("vodservice/deleteVideo/{id}")
public R deleteVideo(@PathVariable("id") String id); //注意:@PathVariable要指明参数名称
}
完善删除小节功能
EduVideoController
//删除小节,同时删除小节对应的视频
@DeleteMapping("deleteVideo/{videoId}")
public R deleteVideo(@PathVariable String videoId){
videoService.deleteByVideoId(videoId);
return R.ok();
}
EduVideoServiceImpl.java
@Autowired
private VodClient vodClient; //先注入
@Override
public void deleteByVideoId(String videoId) {
EduVideo eduVideo = baseMapper.selectById(videoId);
String videoSourceId = eduVideo.getVideoSourceId();
if (!StringUtils.isEmpty(videoId)){
vodClient.deleteVideo(videoSourceId);//删除阿里云中的视频
}
baseMapper.deleteById(videoId); //删除小节
}
测试
根据课程id删除阿里云中的视频
service_vod模块
VodController
//根据多个视频id删除多个视频
@DeleteMapping("batchDeleteVideos")
public R batchDeleteVideos(@RequestParam("videoList") List<String> videoList){
vodService.batchDeleteVideos(videoList);
return R.ok();
}
VodServiceImpl
//删除多个视频
@Override
public void batchDeleteVideos(List<String> videoList) {
try{
DefaultAcsClient client = InitClient.initVodClient(ConstantUtils.ACCESS_KEY_ID, ConstantUtils.ACCESS_KEY_SECRET);
DeleteVideoRequest request = new DeleteVideoRequest();
String s = StringUtils.join(videoList, ",");
request.setVideoIds(s);
client.getAcsResponse(request);
}catch (Exception e){
throw new GuliException(20001,"删除视频失败");
}
}
service_edu模块中
VodClient
//根据多个视频id删除多个视频
@DeleteMapping("vodservice/batchDeleteVideos")
public R batchDeleteVideos(@RequestParam("videoList") List<String> videoList);
EduCourseServiceImpl
//删除课程
@Override
public void deleteCourse(String courseId) {
QueryWrapper<EduVideo> queryWrapper = new QueryWrapper<>();
queryWrapper.select("video_source_id");
queryWrapper.eq("course_id",courseId);
List<EduVideo> eduVideoList = videoService.list(queryWrapper);
List<String> videoList = new ArrayList<>();
if (!eduVideoList.isEmpty()){
for (EduVideo eduVideo:eduVideoList){
String videoSourceId = eduVideo.getVideoSourceId();
videoList.add(videoSourceId);
}
vodClient.batchDeleteVideos(videoList);
videoService.removeByCourseId(courseId);
}
baseMapper.deleteById(courseId); //删除edu_course
courseDescriptionService.removeById(courseId);
chapterService.removeByCourseId(courseId);
}
swagger测试
SpringCloud接口调用流程
1、接口化请求调用:定义调用谁
2、feign:根据映射路径发起Http请求
3、hystrix:被调用的模块宕机时,及时熔断两个模块之间的连接
4、ribbon:当被调用的模块是分布式部署时,将请求负载均衡到被调用的模块上
5、httpClient:执行http请求(调用生产者的接口)
熔断器Hystrix
管理生产者(被调用端)和消费者(调用端)之间的调用情况
当生产者宕机时,熔断消费者对生产者的调用
使用
添加熔断器依赖
<!--消费者调用生产者时的负载均衡-->
<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
创建VodClient接口的实现类,用于熔断后的处理
@Component
public class VodClientImpl implements VodClient{
//service-vod模块熔断后,此方法被调用
@Override
public R deleteVideo(String id) {
return R.error().message("service-vod模块被熔断了,删除视频失败");
}
@Override
public R batchDeleteVideos(List<String> videoList) {
return R.error().message("service-vod模块被熔断了,删除多个视频失败");
}
}
修改VodClient接口的注解,指明service-vod被熔断后执行的类
@FeignClient(value = "service-vod",fallback = VodClientImpl.class) //调用service-vod