在前面的文章中可以發(fā)現(xiàn)當(dāng)我們通過resttemplate調(diào)用其它服務(wù)的api時(shí),所需要的參數(shù)須在請(qǐng)求的url中進(jìn)行拼接,如果參數(shù)少的話或許我們還可以忍受,一旦有多個(gè)參數(shù)的話,這時(shí)拼接請(qǐng)求字符串就會(huì)效率低下,并且顯得好傻。
那么有沒有更好的解決方案呢?答案是確定的有,netflix已經(jīng)為我們提供了一個(gè)框架:feign。
feign是一個(gè)聲明式的web service客戶端,它的目的就是讓web service調(diào)用更加簡(jiǎn)單。feign提供了http請(qǐng)求的模板,通過編寫簡(jiǎn)單的接口和插入注解,就可以定義好http請(qǐng)求的參數(shù)、格式、地址等信息。
而feign則會(huì)完全代理http請(qǐng)求,我們只需要像調(diào)用方法一樣調(diào)用它就可以完成服務(wù)請(qǐng)求及相關(guān)處理。feign整合了ribbon和hystrix(關(guān)于hystrix我們后面再講),可以讓我們不再需要顯式地使用這兩個(gè)組件。
總起來說,feign具有如下特性:
- 可插拔的注解支持,包括feign注解和jax-rs注解;
- 支持可插拔的http編碼器和解碼器;
- 支持hystrix和它的fallback;
- 支持ribbon的負(fù)載均衡;
- 支持http請(qǐng)求和響應(yīng)的壓縮。
這看起來有點(diǎn)像我們springmvc模式的controller層的requestmapping映射。這種模式是我們非常喜歡的。feign是用@feignclient來映射服務(wù)的。
首先第一步,在原來的基礎(chǔ)上新建一個(gè)feign模塊,接著引入相關(guān)依賴,引入feign依賴,會(huì)自動(dòng)引入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/ |
接著在前面文章中的的的兩個(gè)provider1和provider2兩個(gè)模塊的服務(wù)新增幾個(gè)方法,如下代碼所示:
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; //序列化傳輸?shù)臅r(shí)候必須要有空構(gòu)造方法,不然會(huì)出錯(cuò) 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(“服務(wù)名稱”)映射服務(wù)調(diào)用。代碼如下:
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 這個(gè)類配置hystrix的一些精確屬性 //value=“你用到的服務(wù)名稱” @feignclient (value = "hello-service" ,fallback = feignfallback. class ) public interface feignservice { //服務(wù)中方法的映射路徑 @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這個(gè)接口,進(jìn)行遠(yuǎn)程服務(wù)調(diào)用,代碼如下:
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模塊的啟動(dòng)類哪里打上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); } } |
接著啟動(dòng)啟動(dòng)類,瀏覽器上輸入localhost:8083/consumer 運(yùn)行結(jié)果如下:
可以看到負(fù)載均衡輪詢出現(xiàn)hello1,hello2。
接著繼續(xù)在瀏覽器上輸入localhost:8083/consumer2,運(yùn)行結(jié)果如下:
接下來我們進(jìn)行feign聲明式調(diào)用服務(wù)下的,服務(wù)降級(jí)的使用,那么我們就必須新建一個(gè)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{ //實(shí)現(xiàn)的方法是服務(wù)調(diào)用的降級(jí)方法 @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" ; } } |
接著我們?cè)侔涯莾蓚€(gè)服務(wù)提供模塊provider1,provider2模塊進(jìn)行停止,運(yùn)行結(jié)果如下所示:
可以看到我們這幾個(gè)調(diào)用,都進(jìn)行了服務(wù)降級(jí)了。
那么如果我們想精確的控制一下hystrix的參數(shù)也是可以的,比方說跟hystrix結(jié)合的參數(shù),那么可以在feignclient注解里面配置一個(gè)configuration=xxx類.class屬性,在哪個(gè)類里面精確的指定一下屬性。
或者在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 #如果想對(duì)單獨(dú)的某個(gè)服務(wù)進(jìn)行詳細(xì)配置,如下 hello-service: ribbon: connecttimeout: 500 |
這里滿足了我們大部分場(chǎng)景的調(diào)用,但是有寫精細(xì)場(chǎng)景,還是要用原生的hystrix,跟我們之前的hystrix用法一下,不要走feign客戶端調(diào)用就行了,如下:
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 ; } } |
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。
原文鏈接:http://www.cnblogs.com/huangjuncong/p/9053576.html