在微服务中经常会出现这样一个场景,比如我有一个服务 admin,里面有着获取用户信息的接口,我有一个服务 service-a,需要用户信息,这时我需要通过 service-a 去调用 admin  服务的接口来获得用户信息

通过 Feign,我们不需要自己来写个 http 请求发送获取数据,也不需要引用其他服务来获取数据,做到服务间的解耦

Feign 会自动通过轮询的方式去进行负载均衡,且开启 Feign 的 Hystrix 支持后就会自动对宕机的服务进行拦截,防止雪崩效应

1.引入依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

2.编写一个 admin 服务

这个服务端口号 8181 ,服务名是 service-admin

#配置端口号
server:
  port: 8181

spring:
  application:
    #配置服务名
    name: service-admin
@RestController
@RequestMapping(value = "/serviceAdmin")
public class AdminController {

    @GetMapping(value = "/admin")
    public String admin() {
        return "admin 信息";
    }
}

先来访问下

接下来编写一个服务A,来请求这个admin获取数据

3.编写 service-a 服务

这个服务端口号 8182 ,服务名是 service-a

#配置端口号
server:
  port: 8182

spring:
  application:
    #配置服务名
    name: service-a

启动类上加上 @EnableFeignClients 注解来启用 Feign

@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class TestApplication {
    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }
}

TestController:

@RestController
@RequestMapping(value = "/serviceTest")
public class TestController {

    @Resource
    private TestService testService;

    @GetMapping(value = "/admin")
    public Object admin() {
        return testService.admin();
    }
}

TestService:

通过 @FeignClient 注解会在 Eureka 中找到 service-admin 服务,然后根据路径找到对应的接口
所以 @FeignClient 的 name 是要访问的服务的服务名
@RequestMapping 的 value 是要访问的接口的路径
Feign会自动根据 服务名 + 路径的方式去发送 Http 请求来获取数据
这里的 TestService 不需要写实现,因为是去请求另外一个服务,本就没有实现

@FeignClient(name = "service-admin")
public interface TestService {

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

把两个服务启动,就可以在 Eureka 上看到这两个服务了

先来访问下

可以看到通过 service-a 服务,成功访问 service-admin 的服务

4.结合 Hystrix 进行异常捕获处理

这时候 service-admin 的服务突然宕机了
虽然我这里已经做了,全局的异常捕获,但是出异常了我需要特殊的处理怎么办?

Feign 中启用 hystrix 支持

#配置端口号
server:
  port: 8182

#feign 配置
feign:
  hystrix:
    #开启feign的hystrix支持,默认是false
    enabled: true

spring:
  application:
    #配置服务名
    name: service-a

编写 TestFallBack 来进行异常处理
注意 @Component 注解别漏了

@Component
public class TestFallBack implements FallbackFactory<TestService> {
    @Override
    public TestService create(Throwable throwable) {
        return new TestService(){
            @Override
            public String admin() {
                return "请求没成功啊,数据没了!!!!!!!";
            }
        };
    }
}

在 TestService 的 @FeignClient 中引用 TestFallBack

@FeignClient(name = "service-admin", fallbackFactory = TestFallBack.class)
public interface TestService {

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

现在再来通过 service-a 服务,调用下已经宕机的 service-admin 服务

可以看到,返回的不再是之前被捕获的异常,而是在出现异常后我进行的特殊处理
 

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐