一個實例,輕鬆演示Spring Cloud集成Nacos實例

前言

學習一個技術框架,最快速的手段就是將其集成到項目中,體驗一下它的功能。在這個過程當中,你還踩到不少坑。而排坑的過程,又是一次能力的提高。java

前面咱們寫了一些列Nacos的文章,通過《學習Nacos?咱先把服務搞起來,實戰教程》的介紹,咱們已經能夠把Nacos Server給啓動起來了。git

這篇文章,咱們就來學習一下如何將Nacos集成到Spring Cloud項目中,同時實例演示一下,基於Nacos的微服務之間的兩種調用形式。github

集成與版本

爲了演示這個案例,你們首先要將Nacos Server跑起來。同時會構建兩個微服務:服務提供方(Provider)和服務消費方(Consumer)。而後,經過兩個服務之間的調用及配合查看Nacos Server中的註冊信息來進行驗證。web

咱們知道,Nacos隸屬於Spring Cloud Alibaba系列中的組件。因此,在進行集成以前,有一件事必定要注意,那就是要確保Spring Cloud、Spring Boot、Spring Cloud Alibaba版本的一致。否則發生一些莫名其妙的異常。spring

關於版本信息能夠在https://spring.io/projects/sp...app

這裏採用Spring Boot的版本爲2.4.2,Spring Cloud採用2020.0.0、Spring Cloud Alibaba採用2021.1。如你採用其餘版本,必定確保對照關係。負載均衡

Nacos服務提供者

依賴配置

建立項目Spring Boot的項目spring-cloud-alibaba-nacos-provider1,在pom文件中添加定義依賴的版本限制:框架

<properties>
    <java.version>1.8</java.version>
    <spring-boot.version>2.4.2</spring-boot.version>
    <spring-cloud.version>2020.0.0</spring-cloud.version>
    <cloud-alibaba.version>2021.1</cloud-alibaba.version>
</properties>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>${cloud-alibaba.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

而後添加依賴:ide

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

其中actuator爲健康檢查依賴包,nacos-discovery爲服務發現的依賴包。spring-boot

配置文件

提供者添加配置(application.yml)

server:
  port: 8081

spring:
  application:
    name: user-service-provider
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

其中Nacos Server的地址和端口號默認是127.0.0.1:8848。name用來指定此服務的名稱,消費者可經過註冊的這個名稱來進行請求。

業務代碼

在編寫業務代碼以前,咱們先來看一下提供者的啓動類:

// 版本不一樣,低版本須要明確使用@EnableDiscoveryClient註解
//@EnableDiscoveryClient
@SpringBootApplication
public class NacosProviderApplication {

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

注意上面的註釋部分,此版本已經不須要@EnableDiscoveryClient註解了,而較低的版本須要添加對應的註解。

下面新建一個UserController服務:

@RestController
@RequestMapping("/user")
public class UserController {

    private static final Logger logger = LoggerFactory.getLogger(UserController.class);

    @GetMapping("/getUserById")
    public UserDetail getUserById(Integer userId) {
        logger.info("查詢用戶信息,userId={}", userId);
        UserDetail detail = new UserDetail();
        if (userId == 1) {
            detail.setUserId(1);
            detail.setUsername("Tom");
        } else {
            detail.setUserId(2);
            detail.setUsername("Other");
        }
        return detail;
    }
}

其中用到的實體類UserDetail爲:

public class UserDetail {

    private Integer userId;

    private String username;

    // 省略getter/setter
}

而後啓動服務,查看Nacos Server,會發現已經成功註冊。

Nacos服務消費者

消費者的建立與提供者基本一致,惟一不一樣的是調用相關的功能。

創項目

建立Spring Boot項目spring-cloud-alibaba-nacos-consumer1,pom中的依賴與提供者基本一致,但還須要在它的基礎上增長兩個依賴:

<!-- consumer須要額外添加負載均衡的依賴-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
<!-- 基於Feign框架進行調用-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

其中loadbalancer是用來作服務調用負載均衡的,若是不添加此依賴,在調用的過程當中會出現以下一次:

java.net.UnknownHostException: user-provider
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:196) ~[na:1.8.0_271]
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:394) ~[na:1.8.0_271]
    at java.net.Socket.connect(Socket.java:606) ~[na:1.8.0_271]
    at java.net.Socket.connect(Socket.java:555) ~[na:1.8.0_271]

而openfeign是用來實現基於feign框架的微服務調用,也就是讓服務之間的調用更加方便。這個框架是可選的,若是你想基於RestTemplate方式進行調用,則不須要此框架的依賴。

配置文件

消費者添加配置(application.yml):

spring:
  application:
    name: user-service-consumer
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

# 消費者將要去訪問的微服務名稱(註冊成功進nacos的微服務提供者)
service-url:
  nacos-user-service: http://user-service-provider

一樣server-addr指定註冊Nacos Server的地址和端口。而配置中定義的service-url中便用到了服務提供者的服務名稱user-service-provider。

業務代碼

關於啓動類上的註解,與提供者同樣,若是根據使用的版本決定是否使用@EnableDiscoveryClient註解。

建立UserController:

@RestController
@RequestMapping("/order")
public class UserController {

    @Resource
    private UserFeignService userFeignService;

    @Resource
    private RestTemplate restTemplate;

    @Value("${service-url.nacos-user-service}")
    private String userProvider;

    @GetMapping("getUserInfo")
    public UserDetail getUserInfo() {
        int userId = 1;
        ResponseEntity<UserDetail> result = restTemplate.getForEntity(userProvider + "/user/getUserById?userId=" + userId, UserDetail.class);
        return result.getBody();
    }

    @GetMapping("getUserInfo1")
    public UserDetail getUserInfoByFeign() {
        return userFeignService.getUserById(2);
    }

}

上述代碼中展現了兩種方式的請求,其中注入的RestTemplate和getUserInfo方法是一組,注入的UserFeignService和getUserInfoByFeign方法是一組。前者是基於RestTemplate方式請求,後者是基於Feign框架的模式進行請求的。

先來看基於RestTemplate方式的配置,須要先來實例化一下RestTemplate:

@Configuration
public class RestTemplateConfig {

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

}

注意,這裏使用了@LoadBalanced註解,RestTemplateCustomizer會給標有@LoadBalance的RestTemplate添加一個攔截器,攔截器的做用就是對請求的URI進行轉換獲取到具體應該請求哪一個服務實例ServiceInstance。若是缺乏這個註解,也會報上面提到的異常。

基於Feign的模式對應的UserFeignService以下:

@FeignClient(name = "user-service-provider")
public interface UserFeignService {

    /**
     * 基於Feign的接口調用
     *
     * @param userId 用戶ID
     * @return UserDetail
     */
    @GetMapping(value = "/user/getUserById")
    UserDetail getUserById(@RequestParam Integer userId);
}

其中@FeignClient經過name屬性指定調用微服務的名稱,下面定義的方法則對應提供者的接口。

啓動服務,查看Nacos Server的註冊狀況。

結果驗證

此時,本地分別請求兩個URL地址:

http://localhost:8080/order/getUserInfo
http://localhost:8080/order/getUserInfo1

訪問一下,能夠成功的返回結果:

// getUserInfo對應結果
{
"userId": 1,
"username": "Tom"
}
// getUserInfo1對應結果
{
"userId": 2,
"username": "Other"
}

至此,Spring Cloud集成Nacos實例演示完畢,完整的源代碼地址:https://github.com/secbr/spri...

小結

通過上述實例,咱們成功的將Nacos集成到了Spring Cloud當中。相對來講,整個過程仍是比較簡單的,在實踐時,你們惟一須要注意的就是版本問題。Spring Cloud的不一樣版本,內容和用法調整較大,多參考官方文檔的說明。

相關文章
相關標籤/搜索