当我们学习完hystrix,首选想到的是它能不能结合起feign起到远程调用的作用,答案肯定是可以的。下面让我们一步一步来解析这整个过程:
一、创捷一个父项目springcould,在父项目里面创捷公共接口的子模块commons-interface,其目录结构如下
其中:
bean包是实体类包
client包是feign远程调用包
service包是所有提供者的service层接口
1.1 commons-interface模块的pom.xml的主要依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--客户端feign依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
1.2创建一个实体类对象UserBean
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserBean implements Serializable {
private Integer userId;
private String userName;
private Integer age;
}
1.3创建UserService接口
public interface UserService {
UserBean getUser();
}
1.4创建Feign远程调用的UserClient接口
其中的@FeignClient中的value属性是提供者的微服务的名称,fallback属性是发生熔断回调执行的方法类
@FeignClient(value = "provider",fallback = UserClientFeignFallBack.class)//调用的服务名称
public interface UserClient {
@GetMapping("user")
UserBean getOne();
}
1.5创建发生熔断回调的UserClientFeignFallBack类
@Service
public class UserClientFeignFallBack implements UserClient {
@Override
public UserBean getOne() {
UserBean userBean = new UserBean();
userBean.setUserName("服务器正忙,请稍后重试");
return userBean;
}
}
二、在父项目里面创建提供者的子模块provide01,其目录结构如下:
其中:
controller包是提供者的控制层包
service包是提供者的服务层包
2.1provide01子模块的application.yml
server:
port: 8081
spring:
application:
name: provider #服务的名称
cloud:
nacos:
server-addr: localhost:8848
2.2provide01子模块的pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--统一的接口规范-->
<dependency>
<groupId>com.neuedu</groupId>
<artifactId>commons-interface</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- nacos客户端依赖包 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--nacos的配置管理依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
</dependencies>
2.3在controller包创建UserController类
@RestController
@RequestMapping("user")
public class UserController {
@Autowired
private UserService service;
@GetMapping
public UserBean getOne(){
return service.getUser();
}
}
2.4在service包的impl包创建UserServiceImpl类
@Service
public class UserServiceImpl implements UserService {
@Override
public UserBean getUser() {
return new UserBean(100,"张三",18);
}
}
2.5provide01模块的Provider01Application 类
@SpringBootApplication
@EnableDiscoveryClient
public class Provider01Application {
public static void main(String[] args) {
SpringApplication.run(Provider01Application.class, args);
}
}
三、在父项目里面创建用户消费者的子模块userconsumer01,其目录结构如下:
其中:
controller包是用户消费者的控制层
3.1userconsumer01子模块的application.yml
server:
port: 8083
spring:
application:
name: consumer
cloud:
nacos:
server-addr: localhost:8848
feign:
client:
config:
default: #default是所有服务都开启,可以指定某个服务名称(provider)进行开启
loggerLevel: FULL #开启日志
hystrix:
enabled: true # feign中的熔断器hystrix是关闭的,需要手动打开
httpclient:
enabled: true #支持httpclient的开关
max-connections: 200 #最大连接数
max-connections-per-route: 50 #单个路径的最大连接数
sentinel:
enabled: true
#设定Hystrix熔断超时时间 ,理论上熔断时间应该大于总连接超时时间
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 6000
3.2userconsumer01子模块的pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- nacos客户端依赖包 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--统一的接口规范-->
<dependency>
<groupId>com.neuedu</groupId>
<artifactId>commons-interface</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!--客户端feign依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--引入httpclient依赖-->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
<!-- 流量控制sentinel依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
<!--熔断器(断路器)-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
</dependencies>
3.3在controller包创建UserController类
@RestController
@RequestMapping("userConsumer")
public class UserController {
@Autowired
private UserClient userClient;
@GetMapping("getOne")
public UserBean getOne()
return userClient.getOne();
}
}
3.4userconsumer01模块的Userconsumer01Application 类
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker //开启熔断机制
@EnableFeignClients(basePackages = "com.neuedu.client") //开启客户端feign,指定访问的包,防止两个项目的路径出现不一致的问题
public class Userconsumer01Application {
public static void main(String[] args) {
SpringApplication.run(Userconsumer01Application.class, args);
}
@Bean
public RestTemplate getTempalte(){
return new RestTemplate();
}
}
至此,springcould中的熔断器hystrix与远程调用feign相结合的全部代码实现过程到此完成,至于为什么会出现fallback不生效的问题,原因是在userconsumer01子模块的application.yml中忘记添加了如下代码:
feign:
hystrix:
enabled: true
因为feign的hystrix默认是false关闭的,需要我们手动打开