接上篇文章Docker下的Nacos:服務注冊與發現。在上篇文章中,已經給大家介紹了Nacos的注冊功能,我們通過項目yl-nacos-provider注冊了一個名稱為yl-nacos-provider的服務。在本篇文章中,我們繼續完善yl-nacos-provider這個項目,讓它作為服務提供者提供服務,同時實作一個消費者完成對服務的調用,消費者我們将采用兩種不同的方式來實作:Feign和Ribbon。先給展示基本用法,最後再總結Feign和Ribbon的異同。
依然需要說明一點,項目都是在Maven建構父子工程建構的基礎上,一步一步添加不同的功能不斷完善起來的。
一、首先是服務提供者yl-nacos-provider的改造
之前,我們已經在該項目中完成了Nacos注冊功能的實作,在這裡再給大家展示一下相應代碼片段。
- 配置檔案application.yml
server:
port: 9101
spring:
application:
name: yl-nacos-provider
cloud:
nacos:
discovery:
server-addr: localhost:8849
ip: localhost
- pom依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>0.2.2.RELEASE</version>
</dependency>
- 啟動類注解@EnableDiscoveryClient
@SpringBootApplication
@EnableDiscoveryClient
public class YlNacosProviderApplication {
public static void main(String[] args) {
SpringApplication.run(YlNacosProviderApplication.class, args);
}
}
在本文中,為了實作服務提供者提供服務的能力,我們增加一個controller類對外提供服務,代碼如下:
@RestController
@RequestMapping("/ylnacos/provider")
public class YlNacosController {
@RequestMapping("/hello")
public String hello(@RequestParam("name") String name) {
System.out.println("hello:" + name);
return "hello," + name;
}
}
啟動項目,再去Nacos的服務清單查詢一下我們的服務是否注冊成功:
在浏覽器裡調用一下我們的服務接口:
至此,我們的服務提供者已經準備好。
二、服務消費者yl-nacos-consumer
在我們目前整體項目結構下,新增一個module項目yl-nacos-consumer,新增方法見Maven建構父子工程。
為服務消費者新增Nacos能力的支援。
server:
port: 9102
spring:
application:
name: yl-nacos-consumer
cloud:
nacos:
discovery:
server-addr: localhost:8849
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>0.2.2.RELEASE</version>
</dependency>
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class YlNacosConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(YlNacosConsumerApplication.class, args);
}
}
2.1Feign實作
Feign能夠實作像調用普通方法那樣調用我們的controller接口,實作方式如下。
為了讓服務消費者支援Feign能力,需要添加的内容如下:
- pom新增Feign依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
- 啟動類新增注解@EnableFeignClients,這部分可以看啟動類注解@EnableDiscoveryClient這裡
- Feign服務接口類的實作
@FeignClient("yl-nacos-provider:8849")
public interface INacosFeignService {
@RequestMapping("/ylnacos/provider/hello")
String hello(@RequestParam("name") String name);
}
說明:寫一個接口類,注意是接口,在接口類上面添加@FeignClient("yl-nacos-provider:8849")注解,注解裡面的value值為服務提供者在Nacos注冊的服務名稱和Nacos的端口。
hello方法需要和服務提供者提供的服務接口的path以及參數完全一緻。例如我們服務提供者的服務接口在浏覽器裡的通路路徑為:localhost:9101/ylnacos/provider/hello?name=我是服務提供者接口消息,那麼在服務消費者的Feign接口類的方法的path為/ylnacos/provider/hello,參數name也必須一緻。這樣Feign在拼接調用路徑時,才能拼接出正确的通路URL。例如本例中拼接後的URL為:yl-nacos-provider:8849/ylnacos/provider/hello?name=XX。至于,怎麼把yl-nacos-provider:8849轉換成真實的URL域名(localhost:9101),這就是Feign做的事情了,想了解原理的同學,可以去看下。
完成Feign服務接口類後,再提供一個供我們調用的controller接口,把我們的Feign服務接口類注入進來,就可以像調用普通方法的方式來調用我們的服務接口了,代碼如下:
@RestController
@RequestMapping("/ylnacos/consumer")
public class YlNacosConsumerController {
@Autowired
INacosFeignService feignService;
@RequestMapping("/hello")
public String hello() {
System.out.println("consumer hello");
return feignService.hello("我是feign消費者");
}
}
完成以上的準備工作後,啟動我們的服務消費者,然後通路我們的消費接口:
成功輸出結果。
2.2Ribbon實作
支援Ribbon能力的代碼如下。
在啟動類裡初始化RestTemplate對象,該對象用來進行遠端調用。
啟動類的完整代碼如下:
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class YlNacosConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(YlNacosConsumerApplication.class, args);
}
@LoadBalanced
@Bean
public RestTemplate initRestTemplate(){
return new RestTemplate();
}
}
在YlNacosConsumerController類新增一個接口:
@Autowired
RestTemplate restTemplate;
@RequestMapping("/ribbon/hello")
public String ribbonHello(){
return restTemplate.getForObject("http://yl-nacos-provider:8849/ylnacos/provider/hello?name=我是Ribbon消費者", String.class);
}
啟動服務消費者,在浏覽器裡通路該接口,如下:
2.3總結
Feign是一款Java語言編寫的HttpClient綁定器,在Spring Cloud微服務中用于實作微服務之間的聲明式調用。Feign 可以定義請求到其他服務的接口,用于微服務間的調用,不用自己再寫http請求,在用戶端實作,調用此接口就像調用本地方法一樣來調用遠端服務。Feign是一個聲明式的web service用戶端,它使得編寫web service用戶端更為容易。建立接口,為接口添加注解,即可使用Feign。Feign可以使用Feign注解或者JAX-RS注解,還支援熱插拔的編碼器和解碼器。Spring Cloud為Feign添加了Spring MVC的注解支援,并整合了Ribbon和Eureka來為使用Feign時提供負載均衡。
Ribbon 作為負載均衡,在用戶端實作,服務端可以啟動兩個端口不同但servername一樣的服務,Ribbon是Netflix釋出的開源項目,主要功能是提供用戶端的軟體負載均衡算法,将Netflix的中間層服務連接配接在一起。Ribbon用戶端元件提供一系列完善的配置項如連接配接逾時,重試等。簡單的說,就是在配置檔案中列出Load Balancer後面所有的機器,Ribbon會自動的幫助你基于某種規則(如簡單輪詢,随機連接配接等)去連接配接這些機器。我們也很容易使用Ribbon實作自定義的負載均衡算法。簡單地說,Ribbon是一個用戶端負載均衡器。Ribbon工作時分為兩步:第一步先選擇 Eureka Server, 它優先選擇在同一個Zone且負載較少的Server;第二步再根據使用者指定的政策,在從Server取到的服務注冊清單中選擇一個位址。其中Ribbon提供了多種政策,例如輪詢、随機、根據響應時間權重等。
是以說,其實Feign提供的是HTTP請求,而具體請求哪個URL是由Ribbon來實作的。
下一篇:服務提供者和服務消費者在Docker的運作