nacos、ribbon和feign的簡明教程

bbird2018發表於2020-11-06

nacos簡明教程

為什麼需要nacos?

在微服務架構中,微服務之間經常要相互通訊和呼叫,而且一個服務往往存在多個例項來降低負荷或保證高可用。我們假定A服務要呼叫B服務,最簡單的方式把B服務的地址和埠儲存在A服務的配置檔案中。然後通過http請求去完成B服務的呼叫。但是B服務可能有好多個例項,而且可能會隨著業務的需求隨時的擴充套件或者停用掉一些例項,這個時候B服務的地址和埠可能會經常發生改變。如果記錄在配置檔案就多有不便。而且在眾多的B服務中,可能有一些服務會出現各種問題壞掉,我們可能還需要寫一個心跳檢測,看看是不是所有的服務都正常執行,及時地剔除掉那些不能用的服務。如果完備穩定的實現這些功能,是一個不小的工作量。還好凡是有困難的地方總有前人造輪子。而Nacos就是來解決這樣問題的輪子。

如圖所示,通過簡單的配置和註解,所有的微服務都把自己資訊登記到Nacos server中去。在需要呼叫的時候,通過登記到Nacos server的名字就可以完成微服務間的呼叫。比如有以前通過訪問 http://12.3.3.5:8090/service 來訪問微服務的,變成了http://provider/service 的方式來訪問,把服務與埠地址解耦。

如何使用Nacos

Nacos server的啟動

Nacos使用非常的簡單。從Nacos官網下載release包,linux\mac下面執行sh startup.sh -m standalone,windows下面執行startup.cmd -m standalone 然後就可以完成Nacosserver的啟動。

在微服務中使用Nacos做服務註冊和發現

通過maven架包使用Nacos發現服務

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <version>2.2.3.RELEASE</version>
</dependency>

在配置檔案中簡單配置

spring:
    application:
        name: provider  #這個很重要,是註冊到Nacos中呼叫的服務的名稱
    cloud:
        nacos:
        discovery:
            server-addr: 127.0.0.1:8848 #配置Nacos的服務地址

在啟動類上增加註解@EnableDiscoveryClient

@SpringBootApplication
@EnableDiscoveryClient 
public class ProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(ProviderApplication.class, args);
    }

}

通過簡單的幾步就可以完成了把微服務註冊到了Nacos Server。怎麼樣很簡單吧。當然Nacos除了做服務註冊和發現外,還可以做配置中心,使用方法大同小異。更多豐富的操作參考官方文件 Nacos官方網站

服務的呼叫

如果要通過http://provider/service的方式去呼叫微服務,還需要構造http請求,請求回來的結果還要做json解析等等一系列繁雜的工作。而Ribbon就用來解決這個問題的。在springcloud.alibaba的nacos發現服務的Maven包中,已經包含了ribbon.我們通過簡單的幾行程式碼,就可以完成微服務的呼叫。

假定在provider服務中有這麼一段程式碼,我們要呼叫

//例子來自Nacos官網
    @RequestMapping(value = "/echo/{string}",method = RequestMethod.GET)
    public String echo(@PathVariable String string)
    {
        return "Hello Nacos Discover" + string;
    }

我們只需要例項化一個RestTemplate

@Bean
    public RestTemplate restTemplate()
    {
        return new RestTemplate();
    }

然後就可以再想要呼叫的地方來通過下面的程式碼來非常簡單地呼叫。

String result = restTemplate.getForObject("http://provider/echo/"+str,String.class);

負載均衡的問題

前面講到,在微服務環境中常常同一個服務會有N多例項,我們不希望所有的呼叫都跑到一個例項上去,這個時候就需要用到負載均衡。我們只需要在啟動來加上 @LoadBalanced 註解。在配置檔案的spring.application.name相同的應用會被認為是同一個微服務,然後轉發可以通過ribbon內建的策略路由到不同的provider中去。

如果我們期望有的provider的優先順序比別的優先順序高一些,可以再provider的配置檔案中調節不同的權重。

spring:
  cloud:
    nacos:
      discovery:
        weight: 1 #配置權重

使用Feign

通過上面的方法,已經把微服務之間的相互呼叫變得非常的簡單了。但是還不夠,Feign可以讓呼叫更加簡單。

引用maven包

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>

然後我們針對要呼叫的provider定義一個介面,介面的方法為要呼叫的方法名,引數和呼叫引數同名。@FeignClient 註解中name為微服務的名稱。複雜一些的方法呼叫可能需要在介面中配合@RequestMapping指定具體的路由規則,然後就可以通過該介面直接呼叫微服務方法,是不是更加清晰簡單呢?

@FeignClient(name = "provider")
@Service
public interface TestService {
    String echo(String serviceName);
}
public class TestController {
    private final RestTemplate restTemplate;
    @Autowired
    private TestService testService;

    @GetMapping("/echo2/{str}")
    public String echo2(@PathVariable String str)
    {
        return testService.echo(str);
    }
}

相關文章