微服务项目实战技术点汇总:“尚硅谷的谷粒在线教育”六、spring cloud实现不同微服务互联(使用阿里巴巴的Nacos开源项目作为注册中心,Feign和Hystrix组件)

一、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、测试

在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/grd_java/article/details/106426614