1

1.feign 声明式客户端接口

微服务应用中 ribbon和hystrix总是同时出现 feign整合了两者 并提供了声明式消费者客户端

用feign代替hystrix+ribbon

image.png

新建项目
添加依赖
编辑yml文件
spring:
application:

name: feign

server:
port: 3001

eureka:
client:

service-url:
  defaultZone: http://eureka1:2001/eureka, http://eureka2:2002/eureka

主程序添加@EnableDiscoverClient和@EnableFeignClients
注解

Feign远程调用

Feign提供了声明式客户端 只需要定义一个接口 就可以通过
接口做远程调用 具体调用代码通过动态代理添加

// 调用商品服务的远程调用接口
// 通过注解配置3件事:调用哪个服务,调用什么路径,向这个路径提交什么参数

@FeignClient(name="item-service")

public interface ItemFeignClient {

@GetMapping("/{orderId}")

JsonResult<List<Item>> getItems(@PathVariable String orderId);

}

添加Feign声明式客户端
1.OpenFeign依赖
2.启动类@EnableFeignClients
3.定义声明式客户端接口
ItemFeignClient
UserFeignClient
OrderFeignClient

4.添加一个测试用的控制器 使用三个声明式客户端接口调用远程服务

image.png

image.png

image.png

FeignController
////////////////////////
package cn.tedu.sp09.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import cn.tedu.sp01.pojo.Item;
import cn.tedu.sp01.pojo.Order;
import cn.tedu.sp01.pojo.User;
import cn.tedu.sp09.service.ItemFeignService;
import cn.tedu.sp09.service.OrderFeignService;
import cn.tedu.sp09.service.UserFeignService;
import cn.tedu.web.util.JsonResult;

@RestController
public class FeignController {

@Autowired
private ItemFeignService itemService;
@Autowired
private UserFeignService userService;
@Autowired
private OrderFeignService orderService;

@GetMapping("/item-service/{orderId}")
public JsonResult<List<Item>> getItems(@PathVariable String orderId) {
    return itemService.getItems(orderId);
}

@PostMapping("/item-service/decreaseNumber")
public JsonResult decreaseNumber(@RequestBody List<Item> items) {
    return itemService.decreaseNumber(items);
}

/

@GetMapping("/user-service/{userId}")
public JsonResult<User> getUser(@PathVariable Integer userId) {
    return userService.getUser(userId);
}

@GetMapping("/user-service/{userId}/score") 
public JsonResult addScore(@PathVariable Integer userId, Integer score) {
    return userService.addScore(userId, score);
}

/

@GetMapping("/order-service/{orderId}")
public JsonResult<Order> getOrder(@PathVariable String orderId) {
    return orderService.getOrder(orderId);
}

@GetMapping("/order-service")
public JsonResult addOrder() {
    return orderService.addOrder();
}

}

调用流程

image.png

feign+ribbon负载均衡和重试

Feign默认启用了Ribbon的负载均衡和重试 无需额外配置

默认重试参数:
MaxAutoRetries=0
MaxAutoRetriesNextServer=1
ReadTimeout=1000

重试参数配置

对所有的服务都有效

ribbon:
MaxAutoRetries: 1

对item-service单独配置 对其他服务无效

item-service:
ribbon:

 MaxAutoRetries: 0
 
 

ribbon.xxx 全局配置
item-service.ribbon.xxx 对特定的服务实例的配置

/////////////////////////////////////////////
feign+hystrix降级

feign启用hystrix

feign默认没有启动hystrix 添加配置 启用hystrix

yml文件添加配置

feign:
hystrix:

enabled: true

启用hystrix后 访问服务

[http://localhost:3001/item-service/35]
默认1秒会快速失败,没有降级方法时,会显示白板页

可以添加配置 暂时减小降级超时时间 以便后续对降级进行测试

feign:
hystrix:

enabled: true

hystrix:
command:

default:
  execution:
    isolation:
      thread:
        timeoutInMilliseconds: 500
        

feign+hystrix降级

feign远程接口中的指定降级类

远程调用失败 会执行降级类中的代码

image.png

image.png

image.png

image.png

feign+hystrix监控和熔断测试

image.png

修改sp09-feign项目

主程序添加@EnableCircuitBreaker

////
配置actuator 暴露hystrix.stream监控端点

1.查看pom.xml 确认已经添加了actuator依赖

2.yml文件配置暴露 hystrix.stream端点

启动服务 查看监控端点

hystrix dashboard

启动hystrix dashboard服务 填入feign监控路径 开启监控
访问http://localhost:4001/hystrix

填入feign监控路径
http://localhost:3001/actuator/hystrix.stream

访问微服务 以产生监控数据

熔断测试
用ab工具 以并发50次 来发送20000个请求
ab -n 20000 -c 50 http://localhost:3001/item-service/35

断路为open状态 所有的请求都会被降级
直接降级执行callback方法

OrderService调用商品库存服务和用户服务

image.png

修改sp04-orderservice项目 添加feign 调用item service和user service

  1. pom.xml
  2. application.yml
  3. 主程序
  4. ItemFeignService
  5. UserFeignService
  6. ItemFeignServiceFB
  7. UserFeignServiceFB
  8. OrderServiceImpl

右击项目编辑起步依赖
actuator
feign
hystrix

image.png

image.png

image.png

image.png

image.png

image.png

package cn.tedu.sp04.order.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.tedu.sp01.pojo.Item;
import cn.tedu.sp01.pojo.Order;
import cn.tedu.sp01.pojo.User;
import cn.tedu.sp01.service.OrderService;
import cn.tedu.sp04.order.feignclient.ItemFeignService;
import cn.tedu.sp04.order.feignclient.UserFeignService;
import cn.tedu.web.util.JsonResult;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class OrderServiceImpl implements OrderService {


@Autowired
private ItemFeignService itemService;
@Autowired
private UserFeignService userService;

@Override
public Order getOrder(String orderId) {
    //调用user-service获取用户信息
    JsonResult<User> user = userService.getUser(7);
    
    //调用item-service获取商品信息
    JsonResult<List<Item>> items = itemService.getItems(orderId);
    
    
    Order order = new Order();
    order.setId(orderId);
    order.setUser(user.getData());
    order.setItems(items.getData());
    return order;
}

@Override
public void addOrder(Order order) {
    //调用item-service减少商品库存
    itemService.decreaseNumber(order.getItems());
    
    //TODO: 调用user-service增加用户积分
    userService.addScore(7, 100);
    
    log.info("保存订单:"+order);
}

}


廾匸
1 声望3 粉丝

« 上一篇
第五阶段day02
下一篇 »
第五阶段day05