1. OpenFeign和Ribbon 介绍
前面说到了微服务架构系统中系统会被拆分成各个小的模块单独提供服务,我们知道了可以使用注册中心(eureka)来互相感知彼此的存在,但是实际调用该怎么做呢?
这里Spring Cloud OpenFeign和Ribbon就是做这个事情的。Spring Cloud OpenFeign 是Spring Cloud的一个子项目,为微服务架构下服务之间的调用提供了解决方案。这是一种声明式的方式来调用,并且集成了Ribbon来做负载均衡。
2. 准备
- 准备一个服务
在 之前的order-service项目中 写一个简单的服务,如下,提供一个获取订单服务列表的服务
@RestController
@RequestMapping("order")
public class OrderController {
@Value("${server.port}")
private String port;
@GetMapping("list")
public String orderList() {
return "获取订单列表,端口:" + port;
}
}
- 工程结构:
并将这个工程服务注册到eureka (注意添加依赖)
2. Spring Cloud OpenFeign 使用
- 添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
- 添加注解开启Feign 在启动类上 添加@EnableFeignClients
@SpringBootApplication
//开启feign
@EnableFeignClients
public class LinnWebApplication {
public static void main(String[] args) {
SpringApplication.run(LinnWebApplication.class, args);
}
}
-
代码编写 结构
3.1 首先 编写 FeignCall 接口 (我写在了 feign包下)
@FeignClient(value = "ORDER-SERVICE") @Component public interface FeignCall { /** * 获取订单列表 * 注意这里 要和 order-service中的那个方法一致 ,并注意 访问路径 * @return */ @GetMapping("order/list") String orderList(); }
3.2 在controller中调用
@RestController @RequestMapping("feignCall") public class FeignCallController { @Autowired private FeignCall feignCall; @RequestMapping("orderList") public String orderList(){ //通过feign调用 return feignCall.orderList(); } }
-
调用测试
在浏览器中 访问 localhost:8080/feignCall/orderList
3. Ribbon 简单使用
- 添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
- 注入RestTemplate 这里我直接在 启动类中加入了
@SpringBootApplication
//开启feign
@EnableFeignClients
public class LinnWebApplication {
public static void main(String[] args) {
SpringApplication.run(LinnWebApplication.class, args);
}
/**
* @LoadBalanced 注解必须添加 否则会报 java.net.UnknownHostException 找不到服务名称
* @return
*/
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
}
-
代码编写 结构
3.1 首先编写RibbonCall 类 (我写在了ribbon包下)
@Component public class RibbonCall { /** * 注入 restTemplate */ @Autowired private RestTemplate restTemplate; /** * 调用 订单服务 获取订单列表 * 直接在URL中写明 使用ORDER-SERVICE 表示订单服务,后接地址 * @return */ public String orderList(){ return restTemplate.getForObject("http://ORDER-SERVICE/order/list",String.class); } }
3.2 在controller中调用
@RestController @RequestMapping("ribbonCall") public class RibbonCallController { /** * 注入 RibbonCall */ @Autowired private RibbonCall ribbonCall; /** * 测试 * @return */ @RequestMapping("orderList") public String orderList(){ return ribbonCall.orderList(); } }
-
调用测试 浏览器中 访问 http://localhost:8080/ribbonCall/orderList
4. 服务集群配置发布测试
之前的order-service是单节点的端口是 9001,现在再启动(用profiles指定不同的配置)一个同样的服务 端口为 9002,这样就构成了集群了 ,同样的,访问 http://localhost:8080/feignCall/orderList 或者 http://localhost:8080/ribbonCall/orderList,会看到端口 来回显示 9001,9002。 这是因为 多节点时,ribbon的负载均衡策略 默认是 轮询的机制。还有其他的策略可以自己配置,这个后面再看吧。