When we finish learning hystrix, the first thing we think of is whether it can be combined with feign to play the role of remote call, and the answer is definitely yes. Let’s analyze this whole process step by step:
1. Chuangjie is a parent project springcould, in the parent project, the sub-module commons-interface of Chuangjie public interface, its directory structure is as follows
in:
The bean package is the entity class package
The client package is a feign remote call package
The service package is the service layer interface of all providers
1.1 The main dependency of the pom.xml of the commons-interface module
<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> <!--Client feign depends on --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> </dependencies>
1.2 Create an entity class object UserBean
@Data @AllArgsConstructor @NoArgsConstructor public class UserBean implements Serializable { private Integer userId; private String userName; private Integer age; }
1.3 Create UserService interface
public interface UserService { UserBean getUser(); }
1.4 Create a UserClient interface for Feign remote calls
The value attribute in @FeignClient is the name of the provider’s microservice, and the fallback attribute is the method class for the execution of the circuit breaker callback
@FeignClient(value = "provider",fallback = UserClientFeignFallBack.class)//The name of the service called public interface UserClient { @GetMapping("user") UserBean getOne(); }
1.5 Create a UserClientFeignFallBack class with a circuit breaker callback
@Service public class UserClientFeignFallBack implements UserClient { @Override public UserBean getOne() { UserBean userBean = new UserBean(); userBean.setUserName("The server is busy, please try again later"); return userBean; } }
2. Create the provider’s submodule provide01 in the parent project, and its directory structure is as follows:
in:
The controller package is the provider’s control layer package
The service package is the provider’s service layer package
application.yml of 2.1provide01 submodule
server: port: 8081 spring: application: name: provider #The name of the service cloud: nacos: server-addr: localhost:8848
pom.xml of the 2.2provide01 submodule
<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> <!--Unified interface specification--> <dependency> <groupId>com.neuedu</groupId> <artifactId>commons-interface</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <!-- nacos client dependency package --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--nacos configuration management dependencies --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> </dependencies>
2.3 Create a UserController class in the controller package
@RestController @RequestMapping("user") public class UserController { @Autowired private UserService service; @GetMapping public UserBean getOne(){ return service. getUser(); } }
2.4 Create the UserServiceImpl class in the impl package of the service package
@Service public class UserServiceImpl implements UserService { @Override public UserBean getUser() { return new UserBean(100,"Zhang San",18); } }
Provider01Application class of 2.5provide01 module
@SpringBootApplication @EnableDiscoveryClient public class Provider01Application { public static void main(String[] args) { SpringApplication.run(Provider01Application.class, args); } }
3. Create a submodule userconsumer01 in the parent project, and its directory structure is as follows:
in:
The controller package is the control layer for user consumers
3.1 application.yml of the userconsumer01 submodule
server: port: 8083 spring: application: name: consumer cloud: nacos: server-addr: localhost:8848 Feign: client: config: default: #default is all services are enabled, you can specify a service name (provider) to enable loggerLevel: FULL #Open log hystrix: enabled: true # The fuse hystrix in feign is closed and needs to be opened manually httpclient: enabled: true #Support httpclient switch max-connections: 200 #Maximum number of connections max-connections-per-route: 50 #The maximum number of connections per route sentinel: enabled: true #Set the Hystrix fuse timeout, theoretically the fuse time should be greater than the total connection timeout hystrix: command: default: execution: isolation: thread: timeoutInMilliseconds: 6000
3.2 The pom.xml of the userconsumer01 submodule
<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 client dependency package --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--Unified interface specification--> <dependency> <groupId>com.neuedu</groupId> <artifactId>commons-interface</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <!--Client feign depends on --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!--Introduce httpclient dependency--> <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-httpclient</artifactId> </dependency> <!-- flow control sentinel dependency --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <version>2.2.0.RELEASE</version> </dependency> <!--Fuse (circuit breaker)--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> </dependencies>
3.3 Create a UserController class in the controller package
@RestController @RequestMapping("userConsumer") public class UserController { @Autowired private UserClient userClient; @GetMapping("getOne") public UserBean getOne() return userClient. getOne(); } }
3.4Userconsumer01Application class of the userconsumer01 module
@SpringBootApplication @EnableDiscoveryClient @EnableCircuitBreaker //Enable the circuit breaker mechanism @EnableFeignClients(basePackages = "com.neuedu.client") //Enable the client feign, specify the package to be accessed, and prevent the inconsistency of the paths of the two projects public class Userconsumer01Application { public static void main(String[] args) { SpringApplication.run(Userconsumer01Application.class, args); } @Bean public RestTemplate getTemplate(){ return new RestTemplate(); } }
So far, the entire code implementation process of combining the fuse hystrix in springcould and the remote call feign has been completed. As for why the fallback does not take effect, the reason is that the following code was forgotten to be added in the application.yml of the userconsumer01 submodule:
feign: hystrix: enabled: true
Because feign’s hystrix is false and closed by default, we need to open it manually