代码示例
还是依赖于原来的项目,项目目录如下所示:
这里可以看到,eureka 作为 注册中心,eureka-server作为服务提供者, eureka-consumer作为服务消费者。
然后启动一个eureka,两个eureka-server,端口分别是11112,11116,启动一个eureka-consumer,项目git地址:
[项目地址](https://github.com/wuxiaobocom/springCloud.git)。
可以看到如图所示:
这个时候去访问消费者是没有问题的,如果关掉端口为11116的eureka-server时候,然后再去访问,结果如下图所示:
这个时候项目会发生报错。
为何引入Hystrix
在微服务架构中,存在着那么多的服务单元,若一个单元出现故障,就很容易因依赖关系而引发故障的蔓延,最终导致整个
系统的瘫痪,这样的架构相较传统架构更加不稳定。为了解决这样的问题,产生了断路器等一系列的服务保护机制。
针对上述问题, Spring Cloud Hystrix实现了断路器、线程隔离等一系列服务保护功能它也是基于Netflix的开源框架
Hystrix实现的,该框架的目标在于通过控制那些访问远程系统、服务和第三方库的节点,从而对延迟和故障提供更强大
的容错能力。Hystrix具备服务降级、服务熔断、线程和信号隔离、请求缓存、请求合并以及服务监控等强大功能。
如何使用
引入pom文件
注意,Hystrix是作用在消费者应用上,所以应该再eureka-consumer项目中引入Hystrix.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
在启动类上加上注解
package com.bobo.eurekacomsumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
/**
* @author [email protected]
*/
// 开启熔断器
@EnableCircuitBreaker
@EnableDiscoveryClient
@SpringBootApplication
public class EurekaComsumerApplication {
@LoadBalanced
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(EurekaComsumerApplication.class, args);
}
}
@EnableCircuitBreaker这个注解表示开启Hystrix。
编写service层代码
package com.bobo.eurekacomsumer.service;/**
* Created by wuxiaobo on 2018/10/21.
*/
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.client.RestTemplate;
/**
* @author [email protected]
* @create 2018-10-21 10:59
**/
@Service
public class HelloService {
@Autowired
@Qualifier(value = "restTemplate")
private RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "helloFeedback")
public String helloConsumer () {
return restTemplate.getForEntity("http://EUREKA-CLIENT/hello",
String.class).getBody();
}
public String helloFeedback() {
return "error";
}
}
controller 调用
package com.bobo.eurekacomsumer.controller;
import com.bobo.eurekacomsumer.service.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/**
* 消费者
*
* @author [email protected]
* @create 2018-10-16 18:54
**/
@RestController
public class ConsumerController {
@Autowired
private HelloService helloService;
@RequestMapping(value = "/ribbon-consumer", method = RequestMethod. GET)
public String helloConsumer () {
return helloService.helloConsumer();
}
}
结果
按照文章开头的介绍启动,然后结果是:
这里注意的是:由于使用robbin,因此存在客户端的负载均衡,同时负载均衡策略默认采取的是轮询算法。
所以是每隔一次才会触发。