SpringCloud——Ribbon和Feign负载均衡、远程调用、熔断

SpringCloud——Ribbon和Feign负载均衡、远程调用、熔断



一、Ribbon负载均衡、RPC远程调用——//访问地址:localhost:8001/mm

1、依赖环境

<dependency>

        <groupId>org.springframework.cloud</groupId>

        <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>

    </dependency>

2、在启动类中创建ribbon对象

@Bean

    @LoadBalanced

    public RestTemplate restTemplate(){

        return new RestTemplate();

    }

3、在client01中的controller类中代码(client01中调用client02中的服务)

//导入ribbonbean对象;

    @RestController

    public class DogController{

        @Autowired

        private RestTemplate restTemplate;

 

        //这里的请求类型没有要求(@RequestMapping@GetMapping@PostMapping);

        //注意:通过ribbon方式访问client02的方式时,client02中的请求方式必须是@RequestMapping@GetMapping方式才行;

        @PostMapping("/mm")

        public String mm(){

            //参数1Url字符串地址(client02:需要调用的服务的服务名称:——spring.application.name=client02;

            //参数2RPC远程调用服务的返回值的类型;

            String mm = restTemplate.getForObject("http://client02:8002/smallCat",String.class);

            return mm;

        }

    }

4、client02中的代码

@RestController

    public class CatController {

 

    //  @GetMapping("smallCat")

        @RequestMapping("smallCat")

        public String mm(){

            return "获取一致小猫咪!___point:8002";

        }

    }

SpringCloud——Ribbon和Feign负载均衡、远程调用、熔断

 

 

二、Feign负载均衡、RPC远程调用——//访问地址:localhost:8001/mm

1、依赖环境

    //Feign依赖配置

 

    <dependency>

        <groupId>org.springframework.cloud</groupId>

        <artifactId>spring-cloud-starter-openfeign</artifactId>

        <version>2.0.3.RELEASE</version>

    </dependency>

 

    //如果没有这个依赖项目启动会报错(找不到bean),这个是web项目需要的依赖(非Feign所必须依赖)

 

    <dependency>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-web</artifactId>

    </dependency>

 

2、创建Feign接口文件

 

    ①接口文件在本地项目中

    ②接口文件在一个其他的项目中(如工具Commen项目中,或者是一个单独的feign服务器中)

 

    2、1、Feign接口代码:

        不论Feign接口文件在多少层目录中,容器都能自动扫描到该接口(前提是启动类中有指定Feign接口文件位置)

        package dog.feign;或package dog.feign.a.b.c.feign;

 

        //value:用来指定要远程调用哪个服务提供者的服务名称;

        @FeignClient(value = "client02")

        public interface ToFeign {

            //下面的请求路径和方法mm就是要进行远程调用的路径和方法;

            //注意:通过Feign接口方式访问client02的方式时,client02中的请求方式与Feign中的请求方式必须相同;

            //(或者使用通用类型:@RequestMapping,但是此种混合用法有时候会出现"Request method 'GET' not supported"问题),之后呢在详细研究TODO

            //注意:请求路径、请求类型、方法名称,要与实际服务提供者中的一模一样

            //只是这里是在接口中,方法没有方法体;

            @RequestMapping("smallCat")

            //无参方法

            public String mm();

            //如果是有参方法,则在传递参数是接口文件中必须使用@RequestParam()来指定参数,否则参数传不过去;

            public String eat(@RequestParam("food")String food);

        }

 

 

===========重点所在========

 

2、2、在client01中启动类代码

 

    ①Feign接口在本地项目中

       

        -------@EnableFeignClients

        //如果Feign接口在本地项目中,则直接使用@EnableFeignClients就可以,而不需要专门指定Feign接口的包路径

        //如果手动指定了,就会按照指定地址去查找,如果找不到会报异常;

 

        @SpringBootApplication

        @EnableDiscoveryClient

        @EnableFeignClients

        public class StartClient01 {

            public static void main(String[] args) {

                SpringApplication.run(StartClient01.class,args);

                System.out.println("客户端01启动!");

            }

        }

 

    ②Feign接口文件在其他的项目中

          

           重点:::#如果在其他项目中,首先本项目应该引入其他项目的依赖到pom文件中,然后才能通过basePackages来指定feign接口的位置

          

           ---- @EnableFeignClients(basePackages = "com.dog.feign")

            //如果Feign接口文件在其他的项目中,

            //则必须手动指定Feign接口文件的包路径:@EnableFeignClients(basePackages = "com.dog.feign")

            //如果不指定会报异常!

            @SpringBootApplication

            @EnableDiscoveryClient

            @EnableFeignClients(basePackages = "com.dog.feign")

            public class StartClient01 {

                public static void main(String[] args) {

                    SpringApplication.run(StartClient01.class,args);

                    System.out.println("客户端01启动!");

                }

            }

重要:::: 如果是在其他项目中(例如:单独的feign服务器中),还可以添加一个FeignController类,添加@RestController,变成一个对外入口, 该入口中引入feign接口,通过feign接口 通过自定义路径访问该入口中的方法,来调用feign中的方法,进而调用到feign来实现远程调用和负载均衡功能;

(消费端的controller类中可以直接注入feign接口来使用,也可以注入feign中的controller类来使用)

还有:如果feign接口是在feign服务中,那么gaifeign服务的启动类中不能使用@EnableFeignClients注解,否则会造成引用feign就接口的消费者服务无法启动

会报出:The bean 'ayayou-AAAA.FeignClientSpecification' could not be registered. A bean with that name has already been defined and overriding is disabled.

以上问题报错的意思是一个项目中存在多个接口使用@FeignClient调用同一个服务,意思是说一个服务只能用@FeignClient使用一次。

 

2、3、在client01中的controller类中代码

            @RestController

            public class DogController{

                @Autowired

                private ToFeign toFeign;

 

                @PostMapping("/mm")

                public String mm(){

                    String mm = toFeign.mm();

                    return mm;

                }

            }

 

    2、4、client02中的代码

 

            @RestController

            public class CatController {

            //  @GetMapping("smallCat")

                @RequestMapping("smallCat")

                public String mm(){

                    return "获取一致小猫咪!___point:8002";

                }

            }

总结: ①Feign接口文件中的请求类型最好与远程服务中的请求类型相同; ②远程调用有参方法时,Feign接口文件中方法的参数必须使用@RequestParam()来指定参数,否则参数传不过去; ②客户端请求类型为post时,请求方法体中只能有一个参数(或者变量),否则会报异常; ③请求类型为get时可以有多个参数;

三、Hystrix熔断器简单使用(Hystrix和Feign一同使用)

1、引入依赖

因为Feign已经集成了Hystrix,所以不需要在单独添加Hystrix依赖;(前提是有Feign依赖)

2、添加配置

#  启用feign(系统默认关闭)

#注意:如果Hystrix在类路径下(Feign接口文件与调用者在相同项目中————在同一个Module中),

         #则系统默认启用(此时配置文件中可以省略feign的配置)

#个人理解:只要Hystrix的类在--启动类--的下级目录中,则系统都会默认开启

 

###同样:如果Hystrix不在类路径下(Feign接口文件与调用者在不同项目中————分别在两个Module中),

         #####则系统默认关闭(此时配置文件中需要手动配置feign开启)

 

#如果要禁用Feign的Hystrix支持,则需要在配置文件中设置feign.hystrix.enabled=false

该配置的位置是:需要进行服务调用的消费者的配置文件中进行配置开启或关闭(feign服务器中可以不用配置);

 

例如:

a要通过feign调用b,则,开启配置需要配置在阿德配置文件中

 

feign:

  hystrix:

         enabled: true

 

#一般情况下,开启配置的代码都可以省略不写

3、添加对Feign的支持

在启动类中添加注解@EnableFeignClients,以支持Feign来调用服务;

 

#注意:这里一定不要添加      @EnableHystrix这个注解,否则会报异常(待研究);

4、实现回调类(熔断后要执行的类)

创建一个继承与Feign接口文件ToFeign的实现类——ToFeignImpl类,重写方法,当做回调类;

 

#实现类代码中需要添加——@Component注解来实现自动注册——bean

 

#注意:如果一个服务中有多个方法,那么feign中就同样有多个相同的方法,因此feign的实现类中就会重写多个方法;

#注意:虽然“fallback = ToFeignImpl.class”属性中只填写一个实现类的字节码对象,但是每个重写的方法会自动对应各自方法的熔断机制

 

#这是实现类代码:

 

         @Component

         public class ToFeignImpl implements ToFeign {

 

                 @Override

                 public String mm() {

                          return "服务器出错,这里返回的是通过熔断器实现的方法!";

                 }

         }

5、添加fallback属性

#Feign接口类中需要添加——fallback属性,其值为实现类的字节码——ToFeignImpl.class

        

#这是Feign接口类代码:

 

         @FeignClient(value = "client02",fallback = ToFeignImpl.class)

         public interface ToFeign {

 

                 @RequestMapping("smallCat")

                 public String mm();

         }

6、测试

①服务都启动

         #输出:————获取一致小猫咪!___point:8002

②断掉服务提供者

         #输出:————服务器出错,这里返回的是通过熔断器实现的方法!


四、额外内容:@EnableFeignClients

https://blog.csdn.net/weixin_30399871/article/details/102364012?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522160255745019725222434856%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=160255745019725222434856&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v28-2-102364012.pc_first_rank_v2_rank_v28&utm_term=%40EnableFeignClients%E7%9A%84%E4%BD%9C%E7%94%A8&spm=1018.2118.3001.4187  

1、使用注解@EnableFeignClients启用feign客户端;

示例 :

@SpringBootApplication
@EnableFeignClients
public class TestApplication {
    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }
}

2、使用注解@FeignClient 定义feign客户端 ;

示例 : 该例子定义了一个feign客户端,将远程服务http://test-service/test/echo映射为一个本地Java方法调用。

@FeignClient(name = "test-service", path = "/test")
public interface TestService {
    @RequestMapping(value = "/echo", method = RequestMethod.GET)
    TestModel echo(@RequestParam("parameter") String parameter);
}

 

3、使用注解@Autowired使用上面所定义feign的客户端 ;

@Autowired
TestService testService;

public void run(){
    // 这里的使用本地Java API的方式调用远程的Restful接口
   
TestModel dto = testService.echo("Hello,你好!");
    log.info("echo : {}", dto);
}

上面的三个步骤,前两个步骤可以理解为定义feign客户端,第三步是使用所定义的feign客户端。
上一篇:Spring Cloud Feign的文件上传实现


下一篇:Spring Cloud实战小贴士:Feign的继承特性(伪RPC模式)