在前面的文章中可以發現當我們通過resttemplate調用其它服務的api時,所需要的參數須在請求的url中進行拼接,如果參數少的話或許我們還可以忍受,一旦有多個參數的話,這時拼接請求字符串就會效率低下,并且顯得好傻。
那么有沒有更好的解決方案呢?答案是確定的有,netflix已經為我們提供了一個框架:feign。
feign是一個聲明式的web service客戶端,它的目的就是讓web service調用更加簡單。feign提供了http請求的模板,通過編寫簡單的接口和插入注解,就可以定義好http請求的參數、格式、地址等信息。
而feign則會完全代理http請求,我們只需要像調用方法一樣調用它就可以完成服務請求及相關處理。feign整合了ribbon和hystrix(關于hystrix我們后面再講),可以讓我們不再需要顯式地使用這兩個組件。
總起來說,feign具有如下特性:
- 可插拔的注解支持,包括feign注解和jax-rs注解;
- 支持可插拔的http編碼器和解碼器;
- 支持hystrix和它的fallback;
- 支持ribbon的負載均衡;
- 支持http請求和響應的壓縮。
這看起來有點像我們springmvc模式的controller層的requestmapping映射。這種模式是我們非常喜歡的。feign是用@feignclient來映射服務的。
首先第一步,在原來的基礎上新建一個feign模塊,接著引入相關依賴,引入feign依賴,會自動引入hystrix依賴的,如下:
1
2
3
4
5
6
7
8
9
10
11
|
<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> |
application.yml配置如下:
1
2
3
4
5
6
7
8
9
|
server: port: 8083 spring: application: name: feign-consumer eureka: client: service-url: defaultzone: http: //localhost:8888/eureka/,http://localhost:8889/eureka/ |
接著在前面文章中的的的兩個provider1和provider2兩個模塊的服務新增幾個方法,如下代碼所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
/** * created by cong on 2018/5/8. */ @restcontroller public class hellocontroller { @requestmapping ( "/hello" ) public string hello(){ system.out.println( "訪問來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; } //新增的方法 @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 (); } } |
接著是上面代碼所需用到的user類,代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
/** * created by cong 2017/12/2. */ public class user { private string name; private integer age; //序列化傳輸的時候必須要有空構造方法,不然會出錯 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; } } |
接下來用feign的@feignclient(“服務名稱”)映射服務調用。代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
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 這個類配置hystrix的一些精確屬性 //value=“你用到的服務名稱” @feignclient (value = "hello-service" ,fallback = feignfallback. class ) public interface feignservice { //服務中方法的映射路徑 @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); } |
接著在controller層注入feiservice這個接口,進行遠程服務調用,代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
/** * created by cong on 2018/5/17. */ @restcontroller public 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; } } |
接著在feign模塊的啟動類哪里打上eureka客戶端的注解@enablediscoveryclient feign客戶端的注解
1
2
3
4
5
6
7
8
9
10
11
|
@enablefeignclients ,代碼如下: @springbootapplication @enablediscoveryclient @enablefeignclients public class feignapplication { public static void main(string[] args) { springapplication.run(feignapplication. class , args); } } |
接著啟動啟動類,瀏覽器上輸入localhost:8083/consumer 運行結果如下:
可以看到負載均衡輪詢出現hello1,hello2。
接著繼續在瀏覽器上輸入localhost:8083/consumer2,運行結果如下:
接下來我們進行feign聲明式調用服務下的,服務降級的使用,那么我們就必須新建一個feignfallback類來繼承feiservice,代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
package hjc; import org.springframework.stereotype.component; /** * created by cong on 2018/5/17. */ @component public class feignfallback implements feignservice{ //實現的方法是服務調用的降級方法 @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" ; } } |
接著我們再把那兩個服務提供模塊provider1,provider2模塊進行停止,運行結果如下所示:
可以看到我們這幾個調用,都進行了服務降級了。
那么如果我們想精確的控制一下hystrix的參數也是可以的,比方說跟hystrix結合的參數,那么可以在feignclient注解里面配置一個configuration=xxx類.class屬性,在哪個類里面精確的指定一下屬性。
或者在application.yml里面配置,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
hystrix: command: default : execution: isolation: thread: timeoutinmilliseconds: 5000 ribbon: connecttimeout: 500 #如果想對單獨的某個服務進行詳細配置,如下 hello-service: ribbon: connecttimeout: 500 |
這里滿足了我們大部分場景的調用,但是有寫精細場景,還是要用原生的hystrix,跟我們之前的hystrix用法一下,不要走feign客戶端調用就行了,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
/** * 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 ; } } |
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://www.cnblogs.com/huangjuncong/p/9053576.html