微服务消费者

上文【Java】Spring Cloud学习笔记03我们学到了微服务网关的一些基本概念。一个大型的系统由多个微服务组成,各模块需要进行通信,我们可以通过内部接口调用的形式,服务 A 提供一个接口,服务 B 通过 HTTP 请求调用服务 A 的接口,Spring Cloud 提供了一个基础组件OpenFeign来实现不同服务之间的 HTTP 调用 。

创建微服务消费者Feign

新建一个 module,命名为 eurekafeign:

<span class='yzk_title_1601'>【Java】Spring Cloud学习笔记04</span>-Maxchen个人博客

<span class='yzk_title_1601'>【Java】Spring Cloud学习笔记04</span>-Maxchen个人博客

<span class='yzk_title_1601'>【Java】Spring Cloud学习笔记04</span>-Maxchen个人博客

然后在 pom.xml 添加如下内容:

<span class='yzk_title_1601'>【Java】Spring Cloud学习笔记04</span>-Maxchen个人博客

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

接着在resources目录下创建 application.yml,内容如下:

<span class='yzk_title_1601'>【Java】Spring Cloud学习笔记04</span>-Maxchen个人博客

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
server:
  port: 8081
spring:
  application:
    name: eurekafeign

创建一个启动类ApplicationFeign:

@SpringCloudApplication
@EnableFeignClients //如果我们要使用 OpenFeign 声明式 HTTP 客户端,必须要在启动类加入这个注解,以开启 OpenFeign
public class ApplicationFeign {

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

}

我们的 OpenFeign 就已经集成完成了,那么如何通过 OpenFeign 去调用之前我们写的 HTTP 接口呢?创建接口 ApiService,并且通过注解@FeignClient配置要调用的服务地址:

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@FeignClient(value = "eurekaclient")
public interface ApiService {

    @RequestMapping(value = "/index",method = RequestMethod.GET)
    String index();

}

1、接下来在 OpenFeign 里面通过单元测试来查看效果,添加单元测试依赖:

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

2、添加测试代码TestDB:

<span class='yzk_title_1601'>【Java】Spring Cloud学习笔记04</span>-Maxchen个人博客

@SpringBootTest(classes = ApplicationFeign.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class TestDB {

    @Autowired
    private ApiService apiService;

    @Test
    public void test(){
        try {
            System.out.println(apiService.index());
        }catch (Exception e){
            e.printStackTrace();
        }
    }

}

3、最后分别启动单元测试类TestDB,发现控制台打印如下信息:由此可见,我们成功调用了服务提供者提供的接口。

<span class='yzk_title_1601'>【Java】Spring Cloud学习笔记04</span>-Maxchen个人博客

微服务异常处理

微服务部署在服务器上,难免会发生故障,其他服务去调用这个服务就会调不到,会一直卡在那里,用户体验不好。需要对服务接口做错误处理,一旦无法访问服务,则立即返回并报错,这个异常以可读化的字符串返回到前端。
为解决这个问题,我们使用OpenFeign的熔断器模型。
1、OpenFeign 是默认自带熔断器的,但是默认关闭的,修改 application.yml 的配置并开启:

<span class='yzk_title_1601'>【Java】Spring Cloud学习笔记04</span>-Maxchen个人博客

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
server:
  port: 8081
spring:
  application:
    name: eurekafeign
# 熔断器
feign:
  hystrix:
    enabled: true

2、新建类 ApiServiceError.java 并实现 ApiService中所带的方法:

@Component
//ApiServiceError用于实现ApiService中的index方法
public class ApiServiceError implements ApiService {

    @Override
    public String index() {
        return "服务发生故障!";
    }
}

3、在 ApiService 的@FeignClient注解中指定 fallback(这是一个熔断器方法):

<span class='yzk_title_1601'>【Java】Spring Cloud学习笔记04</span>-Maxchen个人博客

fallback = ApiServiceError.class

4、紧接着创建 Controller 类:ApiController:

<span class='yzk_title_1601'>【Java】Spring Cloud学习笔记04</span>-Maxchen个人博客

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ApiController {

    @Autowired
    private ApiService apiService;

    @RequestMapping("index")
    public String index(){
        return apiService.index();
    }
}

5、启动所有服务,然后访问:http://localhost:8081/index,可以看到顺利请求到EurekaClient的接口:

<span class='yzk_title_1601'>【Java】Spring Cloud学习笔记04</span>-Maxchen个人博客

紧接着关闭EurekaClient服务,发现熔断器开始生效了:

<span class='yzk_title_1601'>【Java】Spring Cloud学习笔记04</span>-Maxchen个人博客

熔断器的监控功能

Hystrix 有一个强大的功能 Dashboard。Dashboard 是一个 Web 界面,可以让我们监控 Hystrix Command 的响应时间、请求成功率等数据。
1、下面我们开始改造 eurekafeign 工程,修改eurekafeign 工程pom.xml 下的依赖(解决spring boot 2.0.X版本兼容问题):

<span class='yzk_title_1601'>【Java】Spring Cloud学习笔记04</span>-Maxchen个人博客

<!--<dependency>-->
<!--<groupId>org.springframework.cloud</groupId>-->
<!--<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>-->
<!--</dependency>-->
<!--<dependency>-->
<!--<groupId>org.springframework.cloud</groupId>-->
<!--<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>-->
<!--</dependency>-->
<dependency>
    <groupId>com.netflix.hystrix</groupId>
    <artifactId>hystrix-javanica</artifactId>
    <version>RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-netflix-hystrix-dashboard</artifactId>
</dependency>

2、然后在启动类 ApplicationFeign.java 中加入 @EnableHystrixDashboard,并增加一个 Bean 方法:

@SpringCloudApplication
@EnableFeignClients //如果我们要使用 OpenFeign 声明式 HTTP 客户端,必须要在启动类加入这个注解,以开启 OpenFeign
@EnableHystrixDashboard //添加熔断器dashboard
public class ApplicationFeign {

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

    @Bean //添加熔断器dashboard
    public ServletRegistrationBean getServlet(){
        HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet );
        registrationBean.setLoadOnStartup(1);
        registrationBean.addUrlMappings("/hystrix.stream");
        registrationBean.setName("HystrixMetricsStreamServlet");
        return registrationBean;
    }

}

3、在浏览器上输入网址http://localhost:8081/hystrix,可以看到如下页面:

<span class='yzk_title_1601'>【Java】Spring Cloud学习笔记04</span>-Maxchen个人博客

4、最后在窗口中输入地址http://localhost:8081/hystrix.stream可以查看结果:

<span class='yzk_title_1601'>【Java】Spring Cloud学习笔记04</span>-Maxchen个人博客

<span class='yzk_title_1601'>【Java】Spring Cloud学习笔记04</span>-Maxchen个人博客

<span class='yzk_title_1601'>【Java】Spring Cloud学习笔记04</span>-Maxchen个人博客

记录你的想法-丰富你的知识
  • <span class='yzk_title_1668'>【Java】Spring Cloud学习笔记05</span>
    【Java】Spring Cloud学习笔记05
  • <span class='yzk_title_1492'>【Java】Spring Cloud学习笔记03</span>
    【Java】Spring Cloud学习笔记03
  • <span class='yzk_title_1425'>【Java】Spring Cloud学习笔记02</span>
    【Java】Spring Cloud学习笔记02
  • <span class='yzk_title_1416'>【Java】Spring Cloud学习笔记01</span>
    【Java】Spring Cloud学习笔记01
  • <span class='yzk_title_1402'>【Java】Spring boot学习笔记05</span>
    【Java】Spring boot学习笔记05
  • <span class='yzk_title_1394'>【Java】Spring boot学习笔记04</span>
    【Java】Spring boot学习笔记04
发表评论

坐等沙发