赞
踩
这两天在折腾升级项目框架,springboot由2.2.2.RELEASE升级到2.7.6,springcloud由Hoxton.SR1升级到2021.0.6
直接替换版本发现代码有报错,有些注解报错了,所以学习了下,在此做个学习笔记。
作为入门篇,先不深究openfeign和hystrix怎么实现的,有啥详细配置;大概知道有什么作用就行。
openfeign:实现RPC调用
hystrix:实现接口熔断,即被调用的接口出现异常,或者调用超时,调用方直接返回备胎方法
准备一个Eureka注册中心,一个订单服务order-service(接口提供方),一个商品服务goods-service(接口调用方)。
我们先整合openfeign,测试ok再整合hystrix。
1、订单服务order-service
order-service的pom.xm引入l如下
- <dependencies>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
-
- <!-- spring-cloud -->
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-dependencies</artifactId>
- <version>2021.0.6</version>
- <type>pom</type>
- <scope>import</scope>
- </dependency>
-
- <!-- 整合openfeign -->
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-openfeign</artifactId>
- <version>3.1.5</version>
- </dependency>
-
- <!-- 整合eureka客户端 -->
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
- <version>3.1.5</version>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-test</artifactId>
- <scope>test</scope>
- </dependency>
-
- <!-- swagger -->
- <dependency>
- <groupId>com.github.xiaoymin</groupId>
- <artifactId>knife4j-spring-boot-starter</artifactId>
- <version>3.0.3</version>
- </dependency>
- </dependencies>
yml配置文件内容如下
server: port: 8088 spring: application: name: order-service # swagger用到的配置 mvc: pathmatch: matching-strategy: ant_path_matcher eureka: client: # 需要将我的服务注册到eureka上 register-with-eureka: true # 需要检索服务 fetch-registry: true service-url: # 当前服务注册到eureka地址 defaultZone: http://localhost:8761/eureka/ # 从eureka服务器注册表中获取注册信息的时间间隔(s),默认为30秒 registry-fetch-interval-seconds: 15 # 心跳检测与续约时间 # 测试时将值设置小些,保证服务关闭后注册中心及时剔除服务 instance: # Eureka客户端向服务端发送心跳的间隔时间,单位秒 lease-renewal-interval-in-seconds: 15 # 服务端在收到最后一次心跳之后等待的时间上限,单位秒,超过则剔除 lease-expiration-duration-in-seconds: 30 # 以IP地址注册到服务中心,相互注册使用IP地址 prefer-ip-address: true
随便定义一个Order实体类:
- import io.swagger.annotations.ApiModel;
- import io.swagger.annotations.ApiModelProperty;
-
- @ApiModel(value = "订单实体", description = "")
- public class Order {
-
- @ApiModelProperty(value = "订单号", required = true, example = "123")
- private String orderNo;
-
- @ApiModelProperty(value = "数量", required = true, example = "456")
- private Integer num;
-
- public String getOrderNo() {
- return orderNo;
- }
-
- public void setOrderNo(String orderNo) {
- this.orderNo = orderNo;
- }
-
- public Integer getNum() {
- return num;
- }
-
- public void setNum(Integer num) {
- this.num = num;
- }
- }
定义一个测试用的Controller接口
- @Api(tags = "订单接口")
- @RestController
- @RequestMapping("/order")
- public class OrderController {
-
- @ApiOperation(value = "列表查询", notes = "")
- @PostMapping(value = "/list")
- public BaseResult getList(@RequestBody Order params) {
- List<Order> list = new ArrayList<Order>();
- Order order = new Order();
- order.setOrderNo("123");
- order.setNum(456);
- list.add(order);
- return BaseResult.success(list);
- }
- }
启动类增加注解,如下:
- @EnableDiscoveryClient
- @EnableFeignClients
- @SpringBootApplication
- public class SpringcloudApplication {
-
- public static void main(String[] args) {
- SpringApplication.run(SpringcloudApplication.class, args);
- }
-
- }
2、商品服务goods-service
pom.xm引入和订单服务一样,yml配置也一样,修改下端口。Order实体也复制过去(实际项目中可以抽出来放到公共模块),启动类注解也一样。
定义一个远程调用的接口
- import org.springframework.cloud.openfeign.FeignClient;
- import org.springframework.web.bind.annotation.PostMapping;
- import org.springframework.web.bind.annotation.RequestBody;
-
- import com.example.springcloud.base.BaseResult;
- import com.example.springcloud.entity.Order;
-
- @FeignClient(value = "order-service") // 订单服务的应用名
- public interface OrderServiceFeign {
-
- @PostMapping(value = "/order/list") // 接口路径
- public BaseResult getList(@RequestBody Order params); //参数和订单服务的controller一致
- }
定义一个测试用的Controller接口,并且调用订单服务Controller的接口
- @Api(tags = "商品接口")
- @RestController
- @RequestMapping("/goods")
- public class GoodsController {
-
- @Autowired
- private OrderServiceFeign orderServiceFeign;
-
- @ApiOperation(value = "列表订单查询", notes = "")
- @PostMapping(value = "/orderList")
- public BaseResult getList(@RequestBody Order params) {
- return orderServiceFeign.getList(params);
- }
- }
3、启动服务
启动两个服务,可以在Eureka看到两个服务都注册上来了
然后打开商品服务的swagger,调用接口
响应内容是我们在订单服务controller接口设置的,测试没问题,说明能正常远程调用。
4、整合hystrix
在商品服务(调用方)的pom.xml引入:
- <!-- 整合hystrix -->
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
- <version>2.2.10.RELEASE</version>
- </dependency>
yml文件加入以下:
- hystrix:
- command:
- default:
- execution:
- isolation:
- thread:
- # 接口超时时间3s
- timeoutInMilliseconds: 3000
启动类加入@EnableHystrix注解:
- @EnableHystrix
- @EnableDiscoveryClient
- @EnableFeignClients
- @SpringBootApplication
- public class SpringcloudApplication {
-
- public static void main(String[] args) {
- SpringApplication.run(SpringcloudApplication.class, args);
- }
-
- }
商品测试服务的controller定义熔断方法fallbackMethodOne,并在测试接口加入注解@HystrixCommand,指定熔断方法:
- @Api(tags = "商品接口")
- @RestController
- @RequestMapping("/goods")
- public class GoodsController {
-
- @Autowired
- private OrderServiceFeign orderServiceFeign;
-
-
- @HystrixCommand(fallbackMethod = "fallbackMethod")
- @ApiOperation(value = "列表订单查询", notes = "")
- @PostMapping(value = "/orderList")
- public BaseResult getList(@RequestBody Order params) {
- return orderServiceFeign.getList(params);
- }
-
- // 熔断方法,注意这里参数要和上面方法的参数一致
- public BaseResult fallbackMethod(@RequestBody Order params) {
- return BaseResult.fail(500,"fail,接口熔断");
- }
- }
4.1、测试场景1:被调用的方法出现异常
在订单服务的接口增加异常:
- @ApiOperation(value = "列表查询", notes = "")
- @PostMapping(value = "/list")
- public BaseResult getList(@RequestBody Order params) {
- List<Order> list = new ArrayList<Order>();
- Order order = new Order();
- order.setOrderNo("123");
- order.setNum(456);
- list.add(order);
- System.out.println(1/0); //设置异常
- return BaseResult.success(list);
- }
继续swagger上调用,结果如下
符合预期
4.2、测试场景2:被调用的方法超时未返回
在订单服务的接口增加sleep,睡眠4s或者更长,因为我们配置文件设置的超时时间是3s
- @Api(tags = "订单接口")
- @RestController
- @RequestMapping("/order")
- public class OrderController {
-
- @ApiOperation(value = "列表查询", notes = "")
- @PostMapping(value = "/list")
- public BaseResult getList(@RequestBody Order params) {
- List<Order> list = new ArrayList<Order>();
- Order order = new Order();
- order.setOrderNo("123");
- order.setNum(456);
- list.add(order);
- //System.out.println(1/0); //设置异常
- try {
- // 设置睡眠
- Thread.sleep(4*1000L);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return BaseResult.success(list);
- }
- }
继续swagger上调用,结果如下
可以看到接口耗时3s,等待订单服务接口响应3s,超时未返回,返回了备胎的熔断方法结果,
测试符合预期。
到此整合结束。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。