一,RestTemplate

使用之前需要先定义一个RestTemplate的实例,方便别的地方注入:

@Configuration
public class MyRestTemplateConfig {
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

之后通过如下方式使用:

// 通过ip地址(域名)直接访问
AllType allType =  restTemplate.getForObject("http://localhost:8081/type/", AllType.class);

restTemplate api参考

举个例子:

首先定义一个被调用服务入口,这里是 http://localhost:8081/getName/2

@RestController
@RequestMapping("/")
public class HouseController {

    
    @GetMapping("/getName/{id}")
    public String getName(@PathVariable int id) {
        System.out.println("====================");
        return "房屋id="+id;
    }
}

然后在定义了RestTemplate的项目中定义对被调用服务的访问:

@RestController
@RequestMapping("/contract")
public class ContractController {

    @Autowired
    RestTemplate restTemplate;
    //http://ip:port/conteact/test-rest?id=1
    @RequestMapping("test-rest")
    public String tesRest(int id) {
        String forObject = restTemplate.getForObject("http://localhost:8081/getName/" + id, String.class);
        return forObject;
    }
}

二,Ribbon

微服务架构中会有服务实例间的互相调用,实例之间的远程调用可能需要使用RestTemplate来进行。当被调用的服务部署多个实例后,请求需要公平的发送到这些实例(负载均衡),这时 就需要Ribbon来帮助RestTemplate来实现。

Ribbon 负载均衡策略

  • com.netflix.loadbalancer.RandomRule //随机
  • com.netflix.loadbalancer.RoundRobinRule //轮询
  • com.netflix.loadbalancer.RetryRule //轮询的基础上加上重试
  • com.netflix.loadbalancer.WeightedResponseTimeRule //轮询的基础上加上响应时间权重
  • com.netflix.loadbalancer.BestAvailableRule //并发最小
  • com.netflix.loadbalancer.AvailabilityFilteringRule //过滤掉故障实例,并发最小
  • com.netflix.loadbalancer.ZoneAwareLoadBalancer //考虑到区域相同

添加ribbon依赖

<!-- 负载均衡 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>

增加被调用服务的实例

上节课已经配置过Eureka集群(高可用),步骤大致如下:

  • 增加配置文件,例如:application-02.yml
  • 添加运行入口,右上角 Edit Configuration
  • 运行入口中指定使用的配置文件 Active Profiles

使用负载均衡

修改RestTemplate实例定义,增加负载均衡能力。

@Configuration
public class MyRestTemplateConfig {
    @Bean
    @LoadBalanced //为RestTemplate添加负载均衡能力,
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

修改restTemplate对远程服务的访问方式

将原来对某ip地址的访问改成对服务的访问,restTemplate会在运行时将服务名称改为服务名对应的ip地址。

// 接入eureka和ribbon后, RestTemplate在发起调用前会将type替换为真是的服务器地址
AllType allType =  restTemplate.getForObject("http://type/type/", AllType.class);

更换ribon负载均衡算法

@Bean
IRule myRule() {
    return new RandomRule();
}

上述代码需要放在 @Configuration修饰的类中。

三,Hystrix - 熔断与降级

hystrix介绍 Hystrix的作用:

  • 保护线程资源
//信号量限流
@HystrixCommand(
 commandProperties= {
   @HystrixProperty(name="execution.isolation.strategy", value="SEMAPHORE"),
   @HystrixProperty(name="execution.isolation.semaphore.maxConcurrentRequests", value="20")
 },
 fallbackMethod = "errMethod"
)
//线程池限流
@HystrixCommand(
    commandProperties = {
            @HystrixProperty(name = "execution.isolation.strategy", value = "THREAD")
    },
    threadPoolKey = "createOrderThreadPool",
    threadPoolProperties = {
            @HystrixProperty(name = "coreSize", value = "20"),
   @HystrixProperty(name = "maxQueueSize", value = "100"),
            @HystrixProperty(name = "maximumSize", value = "30"),
            @HystrixProperty(name = "queueSizeRejectionThreshold", value = "120")
    },
    fallbackMethod = "errMethod"
)
  • 快速失败机制

  • 提供降级方案

//在被调用方的方法上放置
@HystrixCommand(fallbackMethod="耗时方法", commandProperties = 
{
    {@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds", value="5000")}
})
//客户端配置
feign:
  hystrix:
    enabled: true

######################配置请求超时时间##########################
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 7000
####################配置具体方法超时时间 为 3 秒########################
    DeptHystrixService#deptInfo_Timeout(Integer):
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 3000
  • 防止故障扩散
  • 监控功能 负责服务的熔断与降级,考虑如下的服务调用:

服务调用

引入依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

按开关

//二选一
//@EnableCircuitBreaker
@EnableHystrix

HystrixCommand

使用方法

在需要实现服务降级的方法上添加注解 @HystrixCommand . 然后配置 fallbackMethod 属性,其参数为发生异常时要降级到的方法的名称,此降级方法需要与 @HystrixCommand修饰的方法返回类型及参数保持一致。

HystrixCommand参数介绍

  • fallbackMethod:指定服务降级处理方法;
  • ignoreExceptions:忽略某些异常,不发生服务降级;

fallbackMethod (回调方法)

指定降级到的方法,此方法的返回类型及参数需要与@HystrixCommand修饰的方法返回类型及参数保持一致。

ignoreExceptions (忽略异常)

指定忽略掉某些异常,设置忽略这些异常后,在发生这些异常后不会进行降级处理。

@HystrixCommand(fallbackMethod = "fallback", ignoreExceptions = {NullPointerException.class})
public String getName(@PathVariable int id) {
    System.out.println("====================");
    if(1==1){
        throw new NullPointerException();
    }
    return "房屋id="+id;
}

//降级方法,返回值及参数需要和上面被HystrixCommand修饰的方法保持一致,方法名就是上面fallbackMethod指定的方法名。
public String fallback(@PathVariable int id) {
    return "降级方法id="+id;
}

超时配置

hystrix可以配置是否启用超时,以及超多多久时间视为超时。

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 500
        timeout:
          enabled: true

扩展--熔断状态

graph LR;
N[关闭状态]--有异常-->V{验证}
V--10S_and_50%-->S[启动状态]
S--所有请求直接进入-->F((fallback))
R{重试}--重试失败-->F
S --5秒后--> R
R---一旦请求成功则关闭熔断--->N