In the previous article, we can find that when we call the API of other services through RestTemplate, the required parameters must be spliced in the requested URL. If there are fewer parameters, we may be able to tolerate it. Once there are multiple parameters, splicing the request string will be inefficient and seem stupid.
So is there a better solution? The answer is certain, and Netflix has provided us with a framework: Feign.
Feign is a declarative Web Service client, and its purpose is to make Web Service calls simpler. Feign provides a template for HTTP requests. By writing simple interfaces and insertion annotations, you can define the parameters, formats, addresses and other information of HTTP requests.
Feign will completely proxy HTTP requests, and we just need to call it like calling a method to complete the service request and related processing. Feign integrates Ribbon and Hystrix (we will talk about Hystrix later), so we can no longer use these two components explicitly.
In short, Feign has the following characteristics:
This looks a bit like the RequestMapping mapping of the Controller layer of our springmvc pattern. This pattern is something we really like. Feign uses @FeignClient to map services.
First, the first step is to create a new Feign module on the original basis, then introduce related dependencies and Feign dependencies, which will automatically introduce Hystrix dependencies, as follows:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> <version>1.3.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> <version>1.4.0.RELEASE</version> </dependency>
The application.yml configuration is as follows:
server: port: 8083spring: application: name: feign-consumereureka: client: service-url: defaultZone: http://localhost:8888/eureka/,http://localhost:8889/eureka/
Then, in the previous article, several new methods are added to the two provider1 and provider2 modules service, as shown in the following code:
/** * Created by cong on 2018/5/8. */@RestControllerpublic class HelloController { @RequestMapping("/hello") public String hello(){ System.out.println("Access comes 1..."); return "hello1"; } @RequestMapping("/hjcs") public List<String> laowangs(String ids){ List<String> list = new ArrayList<>(); list.add("laowang1"); list.add("laowang2"); list.add("laowang3"); return list; } //Added method @RequestMapping(value = "/hellol", method= RequestMethod.GET) public String hello(@RequestParam String name) { return "Hello " + name; } @RequestMapping(value = "/hello2", method= RequestMethod.GET) public User hello(@RequestHeader String name, @RequestHeader Integer age) { return new User(name, age); } @RequestMapping(value = "/hello3", method = RequestMethod.POST) public String hello (@RequestBody User user) { return "Hello "+ user. getName () + ", " + user. getAge (); }}Next is the User class required for the above code, the code is as follows:
/** * Created by cong 2017/12/2. */public class User { private String name; private Integer age; //There must be an empty constructor when serializing the transmission, otherwise an error will occur. public User() { } public User(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; }}Next, use Feign's @FeignClient ("service name") to map the service call. The code is as follows:
package hjc;import org.springframework.cloud.netflix.feign.FeignClient;import org.springframework.web.bind.annotation.*;/** * Created by cong on 2018/5/17. *///configuration = xxx.class This class configures some precise properties of Hystrix //value = "The service name you used" @FeignClient(value = "hello-service",fallback = FeignFallBack.class)public interface FeignService { // Mapping path of method in the service @RequestMapping("/hello") String hello(); @RequestMapping(value = "/hellol", method= RequestMethod.GET) String hello(@RequestParam("name") String name) ; @RequestMapping(value = "/hello2", method= RequestMethod.GET) User hello(@RequestHeader("name") String name, @RequestHeader("age") Integer age); @RequestMapping(value = "/hello3", method= RequestMethod.POST) String hello(@RequestBody User user);}Then inject FeiService interface into the Controller layer to perform remote service calls. The code is as follows:
/** * Created by cong on 2018/5/17. */@RestControllerpublic class ConsumerController { @Autowired FeignService feignService; @RequestMapping("/consumer") public String helloConsumer(){ return feignService.hello(); } @RequestMapping("/consumer2") public String helloConsumer2(){ String r1 = feignService.hello("hjc"); String r2 = feignService.hello("hjc", 23).toString(); String r3 = feignService.hello(new User("hjc", 23)); return r1 + "-----" + r2 + "----" + r3; }}Then, where to annotate the Eureka client in the Feign module's startup class @EnableDiscoveryClient Feign client annotation
@EnableFeignClients, the code is as follows: @SpringBootApplication@EnableDiscoveryClient@EnableFeignClientsspublic class FeignApplication { public static void main(String[] args) { SpringApplication.run(FeignApplication.class, args); }}Then start the startup class, enter localhost:8083/consumer in the browser, and the running result is as follows:
You can see that the load balancing polling appears hello1 and hello2.
Then continue to enter localhost:8083/consumer2 in the browser, and the running result is as follows:
Next, we use the service downgrade under the Feign declarative call service. Then we must create a new FeignFallBack class to inherit FeiService. The code is as follows:
package hjc;import org.springframework.stereotype.Component;/** * Created by cong on 2018/5/17. */@Componentpublic class FeignFallBack implements FeignService{ //The implementation method is a downgrade method of service call @Override public String hello() { return "error"; } @Override public String hello(String name) { return "error"; } @Override public User hello(String name, Integer age) { return new User(); } @Override public String hello(User user) { return "error"; }}Then we stop the two service provider modules provider1 and provider2 modules, and the running results are as follows:
You can see that our calls have all downgraded services.
Then if we want to accurately control the parameters of Hystrix, for example, the parameters combined with Hystrix, you can configure a Configuration=XXX class.class attribute in the FeignClient annotation to specify the properties accurately in which class.
Or configure it in application.yml, as follows:
hystrix: command: default: execution: isolation: thread: timeoutinMilliseconds: 5000ribbon: connectTimeout: 500 #If you want to configure a separate service in detail, as follows hello-service: ribbon: connectTimeout: 500
This satisfies the calls of most of our scenarios, but if you write fine scenarios, you still need to use native Hystrix and follow our previous usage of Hystrix. Just don't use Feign client calls, as follows:
/** * Created by cong on 2018/5/17. */public class HjcCommand extends HystrixCommand { protected HjcCommand(HystrixCommandGroupKey group) { super(group); } @Override protected Object run() throws Exception { return null; }}The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.