Nacos(注册中心)/Feign(服务调用)/Hystrix(熔断器)

一、Nacos

1、基本概念

(1)Nacos 是阿里巴巴推出来的一个新开源项目,是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。

(2)Nacos是以服务为主要服务对象的中间件,Nacos支持所有主流的服务发现、配置和管理。

Nacos主要提供以下四大功能:

  1. 服务发现和服务健康监测

  2. 动态配置服务

  3. 动态DNS服务

  4. 服务及其元数据管理

2、Nacos下载和安装

(1)下载地址和版本
下载地址:https://github.com/alibaba/nacos/releases

下载版本:nacos-server-1.1.4.tar.gz或nacos-server-1.1.4.zip,解压任意目录即可

(2)启动nacos服务

  • Linux/Unix/Mac

启动命令(standalone代表着单机模式运行,非集群模式)

启动命令:sh startup.sh -m standalone

  • Windows

启动命令:cmd startup.cmd 或者双击startup.cmd运行文件。

访问:http://localhost:8848/nacos

用户名密码:nacos/nacos

pom依赖

注意版本号

<!--服务注册-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

2、添加服务配置信息

配置application.properties,在客户端微服务中添加注册Nacos服务的配置信息
注意:服务器名 尽量不要加下划线_

# nacos服务地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
#服务器名尽量不要加下划线_
spring.application.name=service-edu

3、添加Nacos客户端注解

在客户端微服务启动类中添加注解 SpringBoot的启动类上加

@EnableDiscoveryClient

二、Feign

1、基本概念

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;
}

批量删除阿里视频案例(具体配置查看博客中阿里删除的代码)

一、vod服务

1、业务

业务接口: 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();
        }

    }
}

2、web层接口

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;

    }
}

二、edu服务(调用着)

启动类

@SpringBootApplication
@ComponentScan(basePackages = {"com.yzh"})//为了可以扫描到common的配置类
@EnableDiscoveryClient//Nacos启动注解
@EnableFeignClients//Feign启动注解
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

1、client

VodClient.java(接口)

@FeignClient("service-vod")
@Component
public interface VodClient {
//删除多条视频
    @DeleteMapping("/vod/deleteBatch")
    Result deleteBatch(@RequestParam("vodIdList") List<String> vodIdList);
}

2、业务

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概念

Hystrix 是一个供分布式系统使用,提供延迟和容错功能,保证复杂的分布系统在面临不可避免的失败时,仍能有其弹性。

比如系统中有很多服务,当某些服务不稳定的时候,使用这些服务的用户线程将会阻塞,如果没有隔离机制,系统随时就有可能会挂掉,从而带来很大的风险。SpringCloud使用Hystrix组件提供断路器、资源隔离与自我修复功能。下图表示服务B触发了断路器,阻止了级联失败
Nacos(注册中心)/Feign(服务调用)/Hystrix(熔断器)_第1张图片

二、feign结合Hystrix使用

改造service-edu模块(调用端)

1、在service(父模块)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>

2、在配置文件中添加hystrix配置

#开启熔断机制
feign.hystrix.enabled=true
# 设置hystrix超时时间,默认1000ms
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=6000

3、在service-edu的client包里面创建熔断器的实现类

@Component
public class VodFileDegradeFeignClient implements VodClient {
   
@Override
    public Result deleteBatch(List<String> vodIdList) {
        return Result.error().message("time out");
    }
}

4、修改VodClient接口的注解

@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);
}

5.业务层调用加上返回值

 //调用vod服务删除远程视频
        if (vodIds.size() > 0) {
            Result result = vodClient.deleteBatch(vodIds);
            //如果失败
            if (result.getCode() == 20001) {
                System.out.println("视频删除失败");

            }
        }

你可能感兴趣的:(java,springCloud)