Netflix Hystrix 入门实例

前面章节对 Hystrix 进行了简单的介绍,在本章我们将通过一个简单的实例来介绍 Hystrix 的具体用法。本实例的主要步骤如下:

  • 配置 Eureka Server:提供服务注册、服务列表功能;

  • 提供 User 服务:提供一个简单服务,供 Hystrix 实例调用;

  • Hystrix 实例:简单的 Hystrix 实例;

配置 Eureka Server

pom.xml

在使用 Eureka Server 前,我们需要在 pom.xml 添加如下 maven 依赖:

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

application.yml

配置 Eureka Server 注册中心,配置文件内容如下:

# 服务端口
server:
  port: 8077
# 服务名称
spring:
  application:
    name: eureka-server
# 服务地址
eureka:
  instance:
    hostname: localhost
  client:
    # 向注册中心注册自己
    register-with-eureka: true
    # 取消检索服务
    fetch-registry: true
    # 启动独立模式的Eureka server
    # 关闭客户端行为,这样它就不会不断尝试并无法到达它的对等端
    # defaultZone 默认使用 http://localhost:8761/eureka/ 地址
    # 使 serviceUrl 指向与本地实例相同的主机
    service-url:
      defaultZone: http://127.0.0.1:8077/eureka/
  server:
    # 开启注册中心的保护机制,默认是开启
    enable-self-preservation: true
    # 设置保护机制的阈值,默认是0.85
    renewal-percent-threshold: 0.5

RibbonEurekaServerApplication.java

编写 Eureka Server 启动类,需要在启动类上添加 @EnableEurekaServer 注解,完整代码如下:

package com.hxstrive.springcloud.ribbon_eureka_server;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class RibbonEurekaServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(RibbonEurekaServerApplication.class, args);
    }

}

提供 User 服务

pom.xml

由于 User 服务需要将服务注册到 Eureka Server 注册中心,因此需要在 pom.xml 中添加 Eureka Clinet 的 maven 依赖。如下:

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

application.yml

在该配置文件中配置 Eureka Server 的注册中心信息,配置如下:

# 服务端口
server:
  port: 7001
spring:
  application:
    name: user
# 服务地址
eureka:
  instance:
    hostname: localhost
    # 心跳间隔5s,默认30s。每一个服务配置后,心跳间隔和心跳超时时间会被保存在server端,
    # 不同服务的心跳频率可能不同,server 端会根据保存的配置来分别探活
    lease-renewal-interval-in-seconds: 5
    # 心跳超时时间10s,默认90s。从client端最后一次发出心跳后,达到这个时间没有再次发出
    # 心跳,表示服务不可用,将它的实例从注册中心移除
    lease-expiration-duration-in-seconds: 10
  client:
    service-url:
      # 注册中心路径,表示我们向这个注册中心注册服务,如果向多个注册中心注册,用“,”进行分隔
      defaultZone: http://localhost:8077/eureka
appName:
  server: user1

RibbonServiceUsersApplication.java

编写 User 服务的启动类,在该类上添加 @EnableEurekaClient 注解开启 Eureka Client 功能。代码如下:

package com.hxstrive.springcloud.ribbon_service_users;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;

@RestController
@SpringBootApplication
@EnableEurekaClient
public class RibbonServiceUsersApplication {

    @Value("${appName:server}")
    private String appName;

    public static void main(String[] args) {
        SpringApplication.run(RibbonServiceUsersApplication.class, args);
    }

    @GetMapping("/info")
    public String getInfo() {
        try {
            Thread.sleep((long) (Math.random() * 1000));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "From " + appName + " - " + new Date();
    }

}

在 RibbonServiceUsersApplication 类中,仅仅提供了一个 /info 服务。该服务将使用 Thread.sleep() 方法模拟延迟功能,然后返回带有时间的字符串。

Hystrix 实例

pom.xml

在使用 Hystrix 之前,我们需要先添加 maven 依赖。如下:

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

application.yml

添加 application.yml 配置文件,在该配置文件中配置注册中心地址。内容如下:

server:
  port: 8080
spring:
  application:
    name: demo
# 服务地址
eureka:
  instance:
    hostname: localhost
    # 心跳间隔5s,默认30s。每一个服务配置后,心跳间隔和心跳超时时间会被保存在server端,
    # 不同服务的心跳频率可能不同,server 端会根据保存的配置来分别探活
    lease-renewal-interval-in-seconds: 5
    # 心跳超时时间10s,默认90s。从client端最后一次发出心跳后,达到这个时间没有再次发出
    # 心跳,表示服务不可用,将它的实例从注册中心移除
    lease-expiration-duration-in-seconds: 10
  client:
    service-url:
      # 注册中心路径,表示我们向这个注册中心注册服务,如果向多个注册中心注册,用“,”进行分隔
      defaultZone: http://localhost:8077/eureka

RestTemplateConfig.java

添加 RestTemplate 配置,并且在该 restTemplate() 上面添加 @LoadBalanced 注解。开启负载均衡策略功能,代码如下:

package com.hxstrive.springcloud.hystrix;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
 * RestTemplate 配置
 * @author Administrator 2021/3/11 13:35
 */
@Configuration
public class RestTemplateConfig {

    // 配置一个 RestTemplate
    @Bean
    // 添加该注解后,可以使得 RestTemplate 拥有负载均衡能力
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

}

DemoService.java

使用 RestTemplate 调用上面提供的 User 服务,代码如下:

package com.hxstrive.springcloud.hystrix;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

@Component
public class DemoService {

    @Autowired
    private RestTemplate restTemplate;

    public String getInfo() {
        System.out.println("restTemplate=" + restTemplate);
        // 如果你要实现负载均衡,调用地址不能写具体主机地址
        // 需要将主机地址替换成对于服务的服务名,即 spring.application.name 指定的值
        // 你也可以到 Eureka server 中去查看
        String url = "http://USER/info";
        ResponseEntity<String> resp = restTemplate.getForEntity(url, String.class);
        if(resp.getStatusCode().is2xxSuccessful()) {
            return resp.getStatusCode().value() + " :: " + resp.getBody();
        } else {
            return resp.getStatusCode().value() + " :: " + resp.getBody();
        }
    }

}

HystrixDemo1Application.java

实例代码,使用 @EnableCircuitBreaker 开启断路器功能。并且,在 index() 和 demo() 方法上面使用 @HystrixCommand 注解标记该方法启用 Hystrix 功能。通过 @HystrixCommand 注解的 fallbackMethod 属性指定当服务不可用时回调方法。代码如下:

package com.hxstrive.springcloud.hystrix;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@SpringBootApplication
// 启用断路器
@EnableCircuitBreaker
public class HystrixDemo1Application {

    @Autowired
    private DemoService demoService;

    public static void main(String[] args) {
        SpringApplication.run(HystrixDemo1Application.class, args);
    }

    @GetMapping({"/"})
    @HystrixCommand(fallbackMethod = "fallback")
    public String index() {
        return demoService.getInfo();
    }

    /**
     * 当服务调用失败时,调用此方法
     * @return
     */
    private String fallback() {
        return "很抱歉,网络拥挤!";
    }



    @GetMapping({"/demo"})
    @HystrixCommand(fallbackMethod = "fallback2")
    public String demo(String name) {
        return "name=" + name + ", " + demoService.getInfo();
    }

    /**
     * 当服务调用失败时,调用此方法
     * @return
     */
    private String fallback2(String name) {
        return "很抱歉,网络拥挤!name=" + name;
    }

}

熔断器的回调方法参数列表需要和主方法保持一致。例如:demo(String name) 和 fallback2(String name) 方法。

运行方式

第一步:启动 Eureka Server 服务;

第二步:启动 User 服务,然后通过浏览器查看 User 服务是否已经注册到 Eureka Server 中;

第三步:启动 Hystrix 实例,通过浏览器访问实例,访问正常。如果我们将 User 服务暂停,再次访问 Hystrix 实例,返回信息为回退方法返回的值。

说说我的看法
全部评论(
没有评论
关于
本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明,如果原文没有版权声明,请来信告知:hxstrive@outlook.com
公众号