淘先锋技术网

首页 1 2 3 4 5 6 7

2. Hystrix

2.1 基本公能介绍

hystrix 叫做断路器/熔断器,就是因为微服务模块太多,每一个模块出错都会引起服务整体出错。能通过提前配置的东西,让不影响整个系统、

2.2 基本用法

2.2.1 添加配置文件

<dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
      </dependency>


      <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
          <version>2.2.8.RELEASE</version>
      </dependency>
      <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
      </dependency>

      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-test</artifactId>
          <scope>test</scope>
      </dependency>
      

2.2.2 编写配置文件

spring.application.name=hystrix
server.port=3000
eureka.client.service-url.defaultZone=http://localhost:1111/eureka

2.2.3编写一个Service接口

@Service
public class HelloService {
    @Autowired
    RestTemplate restTemplate;

    public String hello(){
        return restTemplate.getForObject("http://provider/hello",String.class);
    }
}

调用这个接口

@RestController
public class HelloController {
    @Autowired
    HelloService helloService;


    /**
     * 在这个方法中。我们发起一个远程调用,去掉provider 中提供的/Hello接口,
     * 但这个调用可能会失败,
     * @return
     */
    @GetMapping("/hello")
    public  String Hello(){
        return helloService.hello();
    }
}

2.2.4 降级熔断

package com.example.hystrix;

import com.netflix.discovery.converters.Auto;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class HelloService {

    @Autowired
    RestTemplate restTemplate;
    /**
     * 添加这个注解HystricCommand,配置fallbackMethod属性,方法失败时就会调用这个方法
     * @return
     */
    @HystrixCommand(fallbackMethod = "error")
    public String hello(){
        return restTemplate.getForObject("http://provider/hello",String.class);
    }
   
    /**
     * |
     * 这个名要和fallbackMethod 属性一致;
     * @return
     */
    public String error(){
        return "当上面的方法,出问题时,就采用降级熔断来解决";
    }

}

注意 :
1 一个请求只能执行一次
2. 可以直接执行,可以先入队后执行


通过注解实现请求异步调用的

  @HystrixCommand(fallbackMethod = "error")
    public Future<String> Async(){
        return new AsyncResult<String>() {
            @Override
            public String invoke() {
                return restTemplate.getForObject("http://provider/hello",String.class);
            }
        };

    }

然后调用这个方法


//    异步调用
@GetMapping("/Asyn")
    public void Asyn(){
    Future<String> async = helloService.Async();
    try {
        String s = async.get();
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    }
}

2.3 异常处理

当服务调用时,如果不是providerde 的原因导致出错,而是consumer本身出错,导致请求失败,即consumer 抛出异常,也会进行服务降级,只不过这是个时候的降级,我们还需要知道哪里出了异样

package com.example.hystrix;
import com.netflix.discovery.converters.Auto;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.command.AsyncResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.concurrent.Future;
@Service
public class HelloService {

    @Autowired
    RestTemplate restTemplate;
    /**
     * 添加这个注解HystricCommand,配置fallbackMethod属性,方法失败时就会调用这个方法
     * @return
     */
    @HystrixCommand(fallbackMethod = "error")
    public String hello(){
       int i= 1/0;
        return restTemplate.getForObject("http://provider/hello",String.class);
    }
    @HystrixCommand(fallbackMethod = "error")
    public Future<String> Async(){
        return new AsyncResult<String>() {
            @Override
            public String invoke() {
                return restTemplate.getForObject("http://provider/hello",String.class);
            }
        };
    }
    /**
     * |
     * 这个名要和fallbackMethod 属性一致;
     * @return
     */
    public String error(Throwable t){
        return "当上面的方法,出问题时,就采用降级熔断来解决"+t.getMessage();
    }
}

2.4 请求合并

如果consumer中,频繁的的调用provider 中的一个接口,在调用接口时,只是参数不一样时,我们就可以合并请求,这样可以有效提高请求发送效率。
首先在provider 中写个请求合并的接口。

package com.king;

import org.example.commons.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

@RestController
public class UserController {

    @GetMapping("/user/{ids}") //假设consumer 传过来的多个id 的格式是 1 2 3 4
    public List<User> getUserByIds(@PathVariable String ids){
        String[] split = ids.split(",");
        List<User> users = new ArrayList<>();
        for (String s : split) {
            User e = new User();
            e.setId(Integer.parseInt(s));
            users.add(e);
        }
        return users;
    }
}

待续》》》

3.1OpenFegin

前面都是用RestTemplate调用的,存在1个问题
1,繁琐

3.1.1 helloWorld

继续使用proivide中的接口,
在这里插入图片描述
新建openfeign模块
项目创建成功后在application中注册到eureka中
在这里插入图片描述

3.1.2 在启动类上添加注解

在这里插入图片描述

3.1.3 创建helloService接口

在这里插入图片描述
定义Helloservice接口,去使用OpenFeign
最后调用HelloController 进行测试
在这里插入图片描述
调用结果

参数传值

和普通参数传递的区别
1 参数一定要绑定参数名
2 如果通过header 来传递参数,一定记得中文转码
测试的服务端接口,继续使用provider 提供的接口。
这里主要是在opefeign 中添加调用接口`

package com.example.opefeign;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    @Autowired
    HelloService helloService;

    @GetMapping("/hello")

    public String hello(){
        return helloService.hello();
    }

    @GetMapping("/hello")
    public String hello1(){
        String hello = helloService.hello();
        System.out.println(hello);
        return helloService.hello();
    }
}

继承特性

将provider和openfeign 中公共的部分提取出来,一起使用`

日志

5 .1 openFeign 日志级别:

1 NONE :不开启日志 ,就是默认
2.BASIC : 记录请求方法,URL ,响应状态码,执行时间
3. HEADERS: 在BASIC的基础上,添加请求/响应头
4. Full : 在HEADERS基础上,在增加body 以及请求数据

在这里插入图片描述

在这里插入图片描述

数据压缩

在这里插入图片描述