前面我们提到,对外提供接口通过 zuul 服务网关实现。一个大型的系统由多个微服务模块组成,各模块之间不可避免需要进行通信,一般我们可以通过内部接口调用的形式,服务 A 提供一个接口,服务 B 通过 HTTP 请求调用服务 A 的接口,为了简化开发,Spring Cloud 提供了一个基础组件方便不同服务之间的 HTTP 调用,那就是 Feign。

什么是 Feign

Feign 是一个声明式的 HTTP 客户端,它简化了 HTTP 客户端的开发。使用 Feign,只需要创建一个接口并注解,就能很轻松的调用各服务提供的 HTTP 接口。Feign 默认集成了 Ribbon,默认实现了负载均衡。

创建 Feign 服务

在根项目上创建一个 module,命名为 feign,然后在 pom.xml 添加如下内容:

<dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
        </dependency>
    </dependencies>

创建 application.yml,内容如下:

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

最后创建一个启动类 Application:

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class Application {

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

}

我们可以看到启动类增加了一个新的注解:@EnableFeignClients,如果我们要使用 Feign 声明式 HTTP 客户端,必须要在启动类加入这个注解,以开启 Feign。

这样,我们的 Feign 就已经集成完成了,那么如何通过 Feign 去调用之前我们写的 HTTP 接口呢?请看下面的做法。

首先创建一个接口 ApiService,并且通过注解配置要调用的服务地址:

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

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

分别启动注册中心 EurekaServer、服务提供者EurekaClient(这里服务提供者启动两次,端口分别为8762、8763,以观察 Feign 的负载均衡效果)。

然后在 Feign 里面通过单元测试来查看效果。

1.添加单元测试依赖。

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

2.添加测试代码。

@SpringBootTest(classes = Application.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();
        }
    }
}

最后分别启动两次单元测试类,我们可以发现控制台分别打印如下信息:

Hello World!,端口:8762
Hello World!,端口:8763

由此可见,我们成功调用了服务提供者提供的接口,并且循环调用不同的接口,说明它自带了负载均衡效果。


taojin
41 声望4 粉丝

Java开发工程师


引用和评论

0 条评论