文章目录
- 一、Nacos
- 1、Nacos?
- 2、Nacos下载安装使用
- 1、下载
- 2、解压启动
- 二、注册微服务spring cloud
- 1、引入依赖
- 2、application.yml
- 3、启动类注解
- 4、测试
- 5、将处理小节,和处理阿里云视频点播的两个微服务都注册到Nacos
- 三、Feign(实现删除小节,删除对应视频)
- 1、引入依赖
- 2、application.yml(只是使用无需配置,这里配置接口访问超时限制上限(我的网速太慢,经常超时,所有扩大了一些))
- 2、启动类注解(给调用者加,我们是小节微服务调用阿里云视频点播微服务,所以给小节微服务加)
- 3、创建接口调用其它微服务的方法
- 1、常用注解介绍
- 2、编写接口
- 3、实现删除小节,删除阿里云中视频
- 4、测试
- 四、实现删除课程删除所有视频
- 1、重载工具类删除方法
- 2、controller
- 3、serviceImpl
- 4、Feign接口
- 5、编写删除课程的controller,调用批量删除视频接口
- 6、编写mapper映射xml(获取指定课程id所有的小节对应的视频id)
- 7、测试
- 五、spring cloud的接口请求流程(仔细观察多个组件是如何相互配合的)
- 六、Hystrix
- 1、引入依赖
- 2、配置application.yml
- 3、写Feign接口的实现类(我们自己写的调其它服务的接口),一旦出错既运行容错机制(我们自己写算法)
- 4、Feign接口注解重新配置
- 5、测试
一、Nacos
1、Nacos?
spring cloud是干什么的? |
它不是一个框架,它是多种技术的一个集合体它其实已经集成了一个注册中心,Eureka |
但因为Eureka在2.0以后性能遇到瓶颈,极难提升,所以官方已经放弃了对它的开发 |
那有什么更好的注册中心可以代替么? |
Nacos是阿里巴巴提供的一个注册中心 |
更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。 |
注册中心? |
我们为了分模快解耦合,将不同功能都写成了单独的微服务 |
这样做虽然很方便,但是会让不同微服务直接无法数据互通 |
这时出现了注册中心,只要需要互通的微服务全部注册到注册中心,即可实现数据互通 |
这个项目为什么要注册 |
我们现在要实现删除小节的时候,删掉在阿里云中的对应视频,这就需要小节微服务和阿里云视频点播微服务的数据互通,而实现数据互通,使用注册中心最为方便 |
2、Nacos下载安装使用
1、下载
GitHub:https://github.com/alibaba/nacos/releases |
2、解压启动
注意:此窗口可不能关哦!关了就不能用了 |
二、注册微服务spring cloud
1、引入依赖
注意:一旦你引入了依赖,此依赖作用范围内所有的微服务都需要进行配置,否则此微服务将无法使用 |
<!--springCloud 与 nacos的整合包-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
2、application.yml
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 #nacos的服务地址
3、启动类注解
@EnableDiscoveryClient //标识此微服务注册到nacos
4、测试
5、将处理小节,和处理阿里云视频点播的两个微服务都注册到Nacos
三、Feign(实现删除小节,删除对应视频)
Feign是Netflix开发的声明式、模板化的HTTP客户端, 可以帮我们更快捷、优雅地调用HTTP API |
我们要用一个微服务调用另一个微服务,虽然两个微服务都已经在注册中心了,但调用起来还是很麻烦 |
Feign可以帮我们非常方便的调用其它微服务接口 |
使用方法 |
引入依赖spring-cloud-starter-openfeign |
启动类配置注解@EnableFeignClients //开启Feign服务熔断 |
编写接口,在接口中调用其他微服务的方法 |
1、引入依赖
<!--springCloud 与Feign 的整合-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
2、application.yml(只是使用无需配置,这里配置接口访问超时限制上限(我的网速太慢,经常超时,所有扩大了一些))
feign:
client:
config:
default:
connect-timeout: 10000 #设置超时限制,必须超过10000ms才报错
read-timeout: 10000 #设置Feign服务熔断机制的最大超时限制
2、启动类注解(给调用者加,我们是小节微服务调用阿里云视频点播微服务,所以给小节微服务加)
@EnableFeignClients //开启Feign服务熔断
3、创建接口调用其它微服务的方法
1、常用注解介绍
@Component |
将接口注入到spirng容器(因为总忘了将它注入,所有拿出来提醒一下) |
@FeignClient(“你要互联的微服务名称(你想使用哪个微服的api接口就写谁的名字)”) |
标识在接口上,指定此接口用于调用哪个微服务的api接口 |
举例:@FeifnClient(“服务在注册中心的名字”) |
@GetMapping(“被调用微服务api接口的全路径(和前端api调用时类似)”) |
不同于controller层中的注解,它指定接口中方法调用的是哪个api接口,当然@DeleteMapping等也相同 |
举例:@GetMapping("/videoservice/{videoId}") |
@PathVariable(value = “它对应的参数名”) |
和controller中功能一样,用于表示路径中参数,但是在这里使用必须指定其value值 |
举例:@PathVariable(value = “id”) String id |
@RequestParam(value = “它对应的参数名”) |
和PathVariable作用表面上相同,都可以用来传参数,只不过此注解的参数是?后面的 |
推荐用此注解代替@PathVariable,因为它能让你避免很多Bug |
举例:@RequestParam(value=“is”) String id |
我踩过的坑 |
如果你一次远程调用多个接口,就会出现很多问题 |
1、@PathVariable问题 |
如果你两个接口中的@PathVariable(value=“id”) String id |
参数名字都叫id的话,你在调用的时候,参数名字是不可以为id的。这样会让你直接获取一个字符串{id},而不是正确的值 |
2、如果你调用后返回值为null,不是问题1,就是你忘了给启动类加注解了 |
3、等我以后遇到了再截图,以前踩的时候我没有写博客的习惯,所以没记录,暂时想不起来了 |
2、编写接口
package com.yzpnb.eduservice.feign;
import com.yzpnb.common_utils.Result;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient("service-video") //标识此接口是一个使用Feign的接口,参数是你要互联的微服务名(注册中心的名字(不是自己的,是你要互联的微服务))
@Component //标识此接口是一个组件
public interface FeignToVideoClient {
//定义你要调用的接口路径(和前端api调用类似)
/**
* 阿里云视频点播微服务的接口
* @param videoId 云端视频id
* @return
*/
@DeleteMapping("/videoservice/{videoId}")
public Result removeVideo(@PathVariable(value = "id") String videoId);
}
3、实现删除小节,删除阿里云中视频
//注入接口
@Autowired
private FeignToVideoClient feignToVideoClient;
完善删除接口
/**
* 删除
* TODO 之后会需要添加视频,删除小节时,需要将视频也删除掉
*/
@ApiOperation("根据id删除小节")
@DeleteMapping("{id}")
public Result deleteVideoById(@ApiParam(name="id",value="小节id")
@PathVariable String id){
//根据小节id获取小节对象中的视频id
String videoSourceId = eduVideoService.getById(id).getVideoSourceId();
if(!StringUtils.isEmpty(videoSourceId)){//判断当前小节是否有视频,使用的spirng提供的工具类
//调用Feign接口中方法,调用阿里云视频点播微服务中的根据视频id删除视频的方法
feignToVideoClient.removeVideo(videoSourceId);
}
//删除小节
eduVideoService.removeById(id);
return Result.ok();
}
4、测试
四、实现删除课程删除所有视频
涉及到一次删除多个视频,用以前的接口不行了,需要在写一个接口 |
1、重载工具类删除方法
/**
* 删除视频
* @paramT client 发送请求客户端
* @return DeleteVideoResponse 删除视频响应数据
* @throws Exception
*/
public void deleteVideo(List<String> idList) throws Exception {
client=initVodClient(accessKeyId,accessKeySecret);
DeleteVideoRequest request = new DeleteVideoRequest();
DeleteVideoResponse response = new DeleteVideoResponse();
StringBuffer stringBuffer=new StringBuffer();
for (String id:idList) {
stringBuffer.append(id + ",");//将所有视频id用逗号拼接
}
stringBuffer.deleteCharAt(stringBuffer.length()-1);//删除最后多余的逗号
//支持传入多个视频ID,多个用逗号分隔 request.setVideoIds("VideoId1,VideoId2");
request.setVideoIds(stringBuffer.toString());
try {
response=client.getAcsResponse(request);
} catch (Exception e) {
System.out.print("ErrorMessage = " + e.getLocalizedMessage());
}
System.out.print("RequestId = " + response.getRequestId() + "\n");
}
2、controller
3、serviceImpl
4、Feign接口
5、编写删除课程的controller,调用批量删除视频接口
6、编写mapper映射xml(获取指定课程id所有的小节对应的视频id)
# 获取指定课程id所有的小节对应的视频id
select
video_source_id
from
edu_video
where
course_id=18
7、测试
五、spring cloud的接口请求流程(仔细观察多个组件是如何相互配合的)
Created with Raphaël 2.2.0 接口化请求调用 Feign:Http APi接口调用 Hystrix:熔断机制:请求掉不到等情况无法获取连接,采取某种算法进行错误熔断 Ribbon:负载均衡:一个微服务如果有高并发的请求量,就会需要多个服务器(统称集群)来分摊压力,而负载均衡就是让每一台服务器都平均的均衡的处理请求,不会出现谁多谁少的情况 http client :根据ip端口号访问api接口? 响应请求 yes
六、Hystrix
Hystrix? |
一个供分布式系统使用,提供延迟和容错功能 |
保证复杂的分布式系统面临不可避免的失败时,任然能具有弹性 |
说白了就是当请求出现问题时,不要直接给用户报一个404什么的 |
而是我们自己写一些算法配合上Hystrix提供的算法,给予用户更好的反馈 |
熔断? |
我们分布式系统,每个微服务都单独部署到一台服务器或一个集群上 |
而当这个微服务挂掉的时候,熔断机制就可以限制用户,不让用户调用此服务 |
用户网慢或者服务响应时间过长,熔断机制就可以根据我们预先设置好的临界值,超时就将连接断掉 |
容错? |
当一个接口响应时间过长,或者出错 |
不要报404,而是执行我们预先定义好的逻辑,或者调用Hystrix的算法 |
如何使用? |
引入依赖、配置参数、然后给Feign的调用接口写一个实现类,在实现类里面写对应的容错算法 |
细节:你需要给这个实现类加@Component注解,并在Feign接口中的注解中指定你实现类的class对象,写法如下: |
@FeignClient(name = “微服务名”,fallback = 接口实现类.class) |
1、引入依赖
<!--springCloud 与 hystrix整合-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
2、配置application.yml
feign:
client:
config:
default:
connect-timeout: 10000 #设置超时限制,必须超过10000ms才报错
read-timeout: 10000 #设置Feign服务熔断机制的最大超时限制
hystrix:
enabled: true #开启熔断机制
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 6000 #设置hystri超时时间 默认1000ms(10s)
3、写Feign接口的实现类(我们自己写的调其它服务的接口),一旦出错既运行容错机制(我们自己写算法)
仔细观察,你可以发现,这里重写的方法都是有返回值的,那么我们在controller中或者其它地方也是可以使用到这些值的
4、Feign接口注解重新配置
/**
* name:要互联的微服务名
* fallback:指定此接口的实现类
*/
@FeignClient(name = "service-video",fallback = FeignToVideoClientImpl.class)
5、测试