preface
When we need to call other microservices or third-party interfaces, we may use Dubbo or Spring's own component RestTemplate, but compared with the previous two, I prefer to use Feign, a component of Spring cloud. In my opinion, Feign is more flexible.
OpenFeign basic use
I'm too lazy to write a micro service myself. Here I searched a third-party interface on the Internet:
https://api.imjad.cn/cloudmusic/?type=song&id=32785674
Take this interface as an example
Dependencies required to use OpenFeign
<dependencies> <!-- SpringBoot Dependent configuration of--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.5.0</version> <type>pom</type> <scope>import</scope> </dependency> <!--Remote interface call--> <!--openFeign--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <!-- SpringCloud Microservices --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>2020.0.3</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
Here, the 2.5.0 SpringBoot version I use is 2020.0.3
Write Feign related logic
1. First, you need to add @ EnableFeignClients to the main method class
2. Write feign's interface
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; @FeignClient(url="https://api.imjad.cn", name = "music") public interface RemoteMusicService { @GetMapping("/cloudmusic") public Object getMusic(@RequestParam("type") String type, @RequestParam("id") String id); }
3. Write a controller to call RemoteMusicService
import com.swagger.demo.remoteAPI.RemoteMusicService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class TestOpenFeign { @Autowired private RemoteMusicService remoteMusicService; @GetMapping("/testFeign") public Object getMusic(String type, String id) { return remoteMusicService.getMusic(type, id); } }
The test results after operation are as follows:
OpenFeign settings downgrade
When it comes to fusing and demotion, of course, the first thing we think of is Hystrix. Yes, we need it this time
1. Dependencies to add
<!--Fuse degraded use--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> <version>2.2.9.RELEASE</version> </dependency>
2. Add support for Hystrix on the main method class
3. Add configuration in the application configuration file (enable Feign's support for Hystrix)
#feign.hystrix.enabled=true feign.circuitbreaker.enabled=true
Note that my spring cloud version is 2020.0.3, and the configuration here is feign.circuitbreaker.enabled=true; If you are using a spring cloud version before 2020, the configuration information is feign.hystrix.enabled=true. (the problem with this version is still quite serious. I've planted it here before)
4. Set degradation for RemoteMusicService interface
There are two degradation methods here: fallback and fallbackFactory. Both can be degraded when the interface call fails. The latter can output more detailed information than the former. Next, let's all test it.
fallback mode:
First, write a fallback class and implement the corresponding degraded interface
import com.swagger.demo.remoteAPI.RemoteMusicService; import org.springframework.stereotype.Component; @Component public class MusicFallback implements RemoteMusicService { @Override public Object getMusic(String type, String id) { System.out.println("Ha ha, ha ha, reported wrong"); return "Ha ha ha"; } }
Don't forget to add @ Component here. When demoting, you need to get the bean object in the spring container
Add fallback configuration for RemoteMusicService:
Test output:
FallbackFactory mode:
First, write a FallbackFactory class and implement FallbackFactory < < corresponding degraded interface >
import com.swagger.demo.remoteAPI.RemoteMusicService; import org.springframework.cloud.openfeign.FallbackFactory; import org.springframework.stereotype.Component; @Component public class MusicFallbackFactory implements FallbackFactory<RemoteMusicService> { @Override public RemoteMusicService create(Throwable cause) { // Similar to fallback, you need to return an object corresponding to the interface return new RemoteMusicService() { @Override public Object getMusic(String type, String id) { System.out.println("Ha ha, ha ha, reported wrong"); return "Hahaha 123"; } }; } }
Add MusicFallbackFactory configuration for RemoteMusicService:
Test output: