微服务架构中,微服务之间相互调用,springcloud可以用feign方式和RestTemplate+ribbon方式来实现服务间的相互调用。但如果某一个服务出现问题,所有调用该出问题的服务都将出现阻塞,如果有大量的请求,则Servlet容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩”效应。
为了解决这个问题,业界提出了断路器模型。
1.ribbon中使用断路器hystrix
build.gradle文件
buildscript {
ext {
springBootVersion = '2.0.4.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
ext {
springCloudVersion = 'Finchley.SR1'
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.cloud:spring-cloud-starter-netflix-eureka-client')
compile('org.springframework.cloud:spring-cloud-starter-netflix-hystrix')
compile('org.springframework.cloud:spring-cloud-starter-netflix-ribbon')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
application.yml文件
server:
port: 8797
spring:
application:
name: service-ribbon-hystrix
eureka:
client:
service-url:
defaultZone: http://localhost:8791/eureka/
主方法
package com.example.serviceribbonhystrix;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@EnableHystrix
@EnableEurekaClient
@SpringBootApplication
public class ServiceRibbonHystrixApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceRibbonHystrixApplication.class, args);
}
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
}
HelloService.java文件
package com.example.serviceribbonhystrix;
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;
@HystrixCommand(fallbackMethod = "errorMsg")
public String hiService() {
return restTemplate.getForObject("http://EUREKA-CLIENT-SAY-HI/hi", String.class);
}
public String errorMsg(){
return "I am ribbon with hystrix,Wrong!";
}
}
HelloController.java文件
package com.example.serviceribbonhystrix;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@Autowired
HelloService helloService;
@RequestMapping("/hi")
public String sayHi() {
return helloService.hiService();
}
}
只是单独启动该服务,不启动eureka-client-say-hi服务,访问http://localhost:8797/hi
返回要返回的信息,此时断路器已经生效了:
2.feign中使用断路器hystrix
因为feign是自带断路器的,所以依赖中就不需要加hystrix
build.gradle
buildscript {
ext {
springBootVersion = '2.0.4.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
ext {
springCloudVersion = 'Finchley.SR1'
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.cloud:spring-cloud-starter-netflix-eureka-client')
compile('org.springframework.cloud:spring-cloud-starter-openfeign')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
application.yml文件
server:
port: 8796
spring:
application:
name: service-feign-hystrix
eureka:
client:
service-url:
defaultZone: http://localhost:8791/eureka/
feign:
hystrix:
enabled: true #feign自带断路器,但需要打开
主方法:
package com.example.servicefeignhystrix;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableEurekaClient
@EnableFeignClients
@SpringBootApplication
public class ServiceFeignHystrixApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceFeignHystrixApplication.class, args);
}
}
接口SayHiService.java文件
package com.example.servicefeignhystrix;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@FeignClient(value = "eureka-client-say-hi",fallback = SayHiServiceWithHystrix.class)
public interface SayHiService {
@RequestMapping(value = "/hi", method = RequestMethod.GET)
String sayHiFromClient();
}
SayHiServiceWithHystrix.java文件
package com.example.servicefeignhystrix;
import org.springframework.stereotype.Component;
@Component
public class SayHiServiceWithHystrix implements SayHiService {
@Override
public String sayHiFromClient() {
return "sorry,I am wrong";
}
}
HelloController.java文件
package com.example.servicefeignhystrix;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@Autowired
SayHiService sayHiService;
@RequestMapping("/hi")
public String sayHi(){
return sayHiService.sayHiFromClient();
}
}
此时启动eureka-server,以及eureka-client-say-hi项目的两个实例,以及刚才新建的项目service-feign-hystrix.
访问http://localhost:8796/hi
出现以下两种场景:
和
如果关掉8792端口的服务,则会返回hi,I am port 8793
如果关掉eureka-client-say-hi服务的8792和8793两个端口实例,则会返回
此时标明,feign的断路器已经生效了。
现在加Java高级架构群即可获取Java工程化、高性能及分布式、高性能、高架构。性能调优、Spring,MyBatis,Netty源码分析和大数据等多个知识点高级进阶干货的直播免费学习权限及领取相关资料群号是:83563&8062