springcloud入門系列(2)-Feign、Ribbon實現Rest介面請求和負載平衡_springcloud

來源:互聯網
上載者:User

前面我們介紹了通過springcloud的eureka服務註冊組件實現,並且實現了多機互備的HA,同時也將之前寫的springboot的服務註冊到了eureka上,今天我們主要來介紹下作為服務使用者如何去使用這些服務介面並且實現基於服務化的軟負載平衡。對於之前實現的springboot的rest介面服務,一般來說進行restful介面的接收和拆組包,可以通過apache的httpclient、jdk的URLConnection、okhttp等http請求庫,也可以通過spring提供的resttemplate,這裡我們使用springcloud推薦的feign來進行報文解析來體會下它的優勢,為什麼spring會大力推薦一個新的rest請求組件,比傳統的使用httpclient等有什麼優勢。 1. POM增加Feign和Ribbon相關依賴庫

建立一個springboot工程,並添加cloud的依賴,本文中使用的是1.4.7版本,具體的代碼可以參見文後的源碼,這裡需要在pom中添加對ribbon和feign的依賴。還需要加入對Zuul網關組件的依賴,如果沒有網關組件,在啟動的時候會報Hystrix的錯誤,“Caused by: java.lang.ClassNotFoundException: com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect。“

        <dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-starter-zuul</artifactId>        </dependency>        <dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-starter-ribbon</artifactId>        </dependency>        <dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-starter-feign</artifactId>        </dependency>
2. Application啟動類增加Feign依賴

在application類中需要增加在類名前面增加@EnableFeignClients的註解,這個註解的意思就是在該應用被啟動的時候,會去所有類中搜尋定義為FeignClient的介面,並自動註冊到spring ioc容器中,然後會對所有使用client實作類別的對象進行自動依賴注入。這裡還有EurekaClient的註解是因為後面定義FeignClient的時候需要定義介面的服務名而不是ip地址,需要定義EurekaClient才能發現相關服務,並且實現軟負載。

@SpringCloudApplication@EnableFeignClients@EnableEurekaClientpublic class Application {    public static void main(String[] args) {        SpringApplication.run(Application.class, args);    }}
3. 建立Feign Client介面

下面來到最重要的一步,就是定義Feign的Client介面,這裡Client介面其實就是對提供服務的restful介面的本地定義,定義好後,在其他類中就可以像使用RPC本地介面類一樣使用遠程服務介面了,想想我們用httpclient、okhttp是怎麼實現報文接收的功能的,首先我們需要定義httpclient對象,按照服務端的介面要求組合json報文,然後定義是get還是post,不同的傳輸方法還需要調用不同的方法(doGet、doPost),這才將一個請求發出去,然後從inputstream中迴圈讀取位元組流或者從Reader中讀取字元流,再將字元流還原序列化成對象,全部需要編碼實現,整個過程雖然結構很清晰但是很繁瑣,為什麼之前RPC很火,就是因為使用RPC會讓client端調用遠程服務介面簡單化,就好像使用本機物件一樣簡單,但是使用RPC的最大的弊端就是每個client都需要維護一個服務端的client jar包,這個jar包中其實就是定義了介面,一旦服務端介面有變化,服務使用方就需要更新jar包,這就使得用戶端對服務端產生了強依賴,feign就很好的解決了這個問題,在client和server端沒有依賴的情況下,讓client使用服務就像使用本地介面一樣簡單,廢話不多少,下面來定義feign client的介面,這裡服務端的介面就使用之前定義的getUser介面。

@FeignClient("usercenter-provider")public interface UserFeignClient {    //Feign定義服務提供者介面    @RequestMapping(value = "/getUser", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"})    String getUser(@RequestBody String data);}

@FeignClient("usercenter-provider")註解的意思是該介面裡定義的方法全部是“usercenter-provider”這個serviceid提供的方法,注意這裡的serviceid需要和eureka server裡定義的服務提供者的名字一致,不然feign是無法找到相關服務的,feign內部整合了Ribbon所以通過serviceid找到服務後,會通過ribbon自動實現服務訪問的負載平衡,可以通過定義ribbon的負載平衡方法來實現自己想要的,預設得是隨機存取方法也可以定義成順序、訪問權重或者自訂負載演算法,這裡就使用了預設的負載,預設負載已經能夠滿足大部分需求了。在介面的方法前面需要定義該方法訪問路徑和存取方法和編碼格式等資訊,對於請求參數也可以通過@requestBody或者@RequestParameter的value方法進行設定,這裡就使用和入參名同名的參數設定。是不是很簡單,這樣就定義好了遠程服務端介面。 4. 遠程服務介面使用

上面定義好了Feign Client介面,後面使用就很簡單了,這裡按照日常項目結構定義了service層和controller,將feign的介面調用放在了service的實作類別中,在controller類中進行service的調用,這裡需要注意一個問題,之前在測試的過程中自己遇到了,因為不小心寫錯了,犯了一個很低級的錯誤,找了1個小時才找到原因。。因為feign的client是通過@AutoWired啟動的時候自動注入的,這就使得如果client的調用是在service裡的時候需要將service也放在spring的ioc中進行託管,不然就會報你的Service沒有定義,並且在Controller使用這個Service的時候也要通過ioc容器自動注入Service實現,不然會報clientnull 指標的錯誤,如果調試過程中發現FeignClient調用的時候報nullpoint,基本就是由於ioc bean託管導致的問題,我就是因為寫錯了一行代碼導致了這個問題。
UserServiceImpl.java

@Servicepublic class UserServiceImpl implements UserService {    @Autowired    private UserFeignClient userFeignClient;    @Override    public String getUSer(String data) {        return "Feign: " + userFeignClient.getUser(data);    }}

UserController.java

@RestControllerpublic class UserController {    @Autowired    private UserService userService;    @RequestMapping(value = "/getUser", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"})    public String getUser(@RequestBody String data){        return userService.getUSer(data);    }}
5. application.yml參數設定

在配置中主要是要配置eureka server叢集的地址,因為需要定義在哪個eureka叢集中找到feign使用的serviceid。

spring:  application:    name: springcloud-feign-ribbonserver:  port: 8080eureka:  client:    serviceUrl:      defaultZone: http://node1:8761/eureka/,http://node2:8762/eureka/
小結

最後我們啟動eureka server、usercenter-provider的服務,再啟動本次寫的應用。
image
下面通過httprequester來發起請求,地址欄輸入 http://node1:8080/getUser,body欄輸入{"name":"feiweiwei"},可以看到返回了Feign {"name":"feiweiwei"}
image

源碼Git地址:https://github.com/feiweiwei/springcloud-feign

作者:monkey01
連結:https://www.jianshu.com/p/270f3cd658f1
來源:簡書
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.