1.Feign概述
? ? ? ??在上一篇的HelloService這個類中,我們有這樣一行代碼:
? ? ? ??return restTemplate.getForObject("http://hello-service/hello",String.class);
? ? ? ??對于代碼有一定潔癖的你來說,一定感覺到了,這個url應(yīng)該是可以被配置的。既然說到配置,那我們首先想到的就是使用java注解的方式。Feign就是這樣一個注解框架,它也是netflix為我們提供的,方便我們整合ribbon和hystrix(后面會學(xué)習(xí))。
? ? ? ??使用Feign,我們能很方便的通過編寫接口并插入注解,來定義和代理HTTP請求。Feign主要具備如下特性:
? ? ? ??支持Feign注解;
? ? ? ??支持Ribbon負載均衡;
? ? ? ??支持HTTP編碼器和解碼器;
? ? ? ??提供了熔斷器Hystrix;
2.Feign引入
? ? ? ??讓我們修改ribbon這個項目,使之支持feign。
? ? ? ??首先,pom引入,
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
? ? ? ? ?xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
? ? <parent>
? ? ? ? <artifactId>springcloud.parent</artifactId>
? ? ? ? <groupId>com.zuikc</groupId>
? ? ? ? <version>1.0-SNAPSHOT</version>
? ? </parent>
? ? <modelVersion>4.0.0</modelVersion>
? ? <packaging>war</packaging>
? ? <name>ribbon</name>
? ? <artifactId>ribbon</artifactId>
? ? <dependencyManagement>
? ? ? ? <dependencies>
? ? ? ? ? ? <dependency>
? ? ? ? ? ? ? ? <groupId>org.springframework.cloud</groupId>
? ? ? ? ? ? ? ? <artifactId>spring-cloud-dependencies</artifactId>
? ? ? ? ? ? ? ? <version>Greenwich.RELEASE</version>
? ? ? ? ? ? ? ? <type>pom</type>
? ? ? ? ? ? ? ? <scope>import</scope>
? ? ? ? ? ? </dependency>
? ? ? ? </dependencies>
? ? </dependencyManagement>
? ? <dependencies>
? ? ? ? <dependency>
? ? ? ? ? ? <groupId>org.springframework.boot</groupId>
? ? ? ? ? ? <artifactId>spring-boot-starter</artifactId>
? ? ? ? </dependency>
? ? ? ? <dependency>
? ? ? ? ? ? <groupId>org.springframework.cloud</groupId>
? ? ? ? ? ? <artifactId>spring-cloud-starter-eureka</artifactId>
? ? ? ? ? ? <version>1.4.6.RELEASE</version>
? ? ? ? </dependency>
? ? ? ? <dependency>
? ? ? ? ? ? <groupId>org.springframework.boot</groupId>
? ? ? ? ? ? <artifactId>spring-boot-starter-test</artifactId>
? ? ? ? ? ? <scope>test</scope>
? ? ? ? </dependency>
? ? ? ? <dependency>
? ? ? ? ? ? <groupId>org.springframework.boot</groupId>
? ? ? ? ? ? <artifactId>spring-boot-starter-web</artifactId>
? ? ? ? </dependency>
? ? ? ? <dependency>
? ? ? ? ? ? <groupId>org.springframework.cloud</groupId>
? ? ? ? ? ? <artifactId>spring-cloud-starter-feign</artifactId>
? ? ? ? ? ? <version>1.4.6.RELEASE</version>
? ? ? ? </dependency>
? ? </dependencies>
</project>
? ? ? ??注意pom中的粗體部分。引入Feign依賴,會自動引入Hystrix依賴。
? ? ? ??appcation.yml并不需要變動。
3.@EnableFeignClients
? ? ? ??修改ServiceRibbonApplication,加入注解@EnableFeignClients,這一步很重要,說明項目對于feign的支持,
package com.zuikc;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
/**
?* @ClassName ServiceRibbonApplication
?* @Description 我們提供咨詢和培訓(xùn)服務(wù),關(guān)于本文有任何困惑,請關(guān)注并聯(lián)系“碼農(nóng)星球”
?* @Author 碼農(nóng)星球
?**/
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class ServiceRibbonApplication {
? ? public static void main(String[] args) {
? ? ? ? SpringApplication.run(ServiceRibbonApplication.class, args);
? ? }
? ? @Bean
? ? @LoadBalanced
? ? RestTemplate restTemplate() {
? ? ? ? return new RestTemplate();
? ? }
}
4.服務(wù)接口
? ? ? ??創(chuàng)建一個接口,
package com.zuikc;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
@FeignClient(value = "hello-service")
public interface HelloService {
? ? //服務(wù)中方法的映射路徑
? ? @RequestMapping("/hello")
? ? String hello();
}
? ? ? ??這個接口就比較重要了。
? ? ? ??注解@FeignClient說明了,我們需要去eureka服務(wù)上去調(diào)用“hello-service”這個服務(wù)。
? ? ? ??注解@RequestMapping指的是我們需要調(diào)用的路徑。
5.控制器
? ? ? ??現(xiàn)在我們還需要最后一步,就是創(chuàng)建一個控制器來接受請求,然后讓robbin去分發(fā),
package com.zuikc;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
?* @ClassName ConsumerController
?* @Description 我們提供咨詢和培訓(xùn)服務(wù),關(guān)于本文有任何困惑,請關(guān)注并聯(lián)系“碼農(nóng)星球”
?* @Author 碼農(nóng)星球
?**/
@RestController
public class HelloController {
? ? @Autowired
? ? HelloService helloService;
? ? @RequestMapping("/hello")
? ? public String helloConsumer(){
? ? ? ? return helloService.hello();
? ? }
}
? ? ? ??當(dāng)一切處理完成,讓我們啟動這個項目,我們?nèi)耘f看到ribbon的這個服務(wù),

? ? ? ??然后,http://localhost:9291/hello吧,可以看到LB非常的成功。
? ? ? ??現(xiàn)在,假設(shè)其中一個服務(wù)提供者因為某種原因(比如異常、斷網(wǎng))停掉了,看看結(jié)果會是怎么樣的。為了模擬這個現(xiàn)象,讓我們關(guān)閉provider2,發(fā)現(xiàn)我們無論怎么刷新上面的url,LB永遠分配到provider1。這也是分布式系統(tǒng)容錯能力更強的一種保證!
? ? ? ??感謝關(guān)注“碼農(nóng)星球”。本文版權(quán)屬于“碼農(nóng)星球”。我們提供咨詢和培訓(xùn)服務(wù),關(guān)于本文有任何困惑,請關(guān)注并聯(lián)系我們。