springcloud入门(一):整合openfeign和hystrix

一、背景介绍

这两天在折腾升级项目框架,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,超时未返回,返回了备胎的熔断方法结果,

测试符合预期。

到此整合结束。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值