Spring Cloud 微服務實戰——nacos 服務註冊中心搭建(附原始碼)

小碼code發表於2021-11-02

作為微服務的基礎功能之一的註冊中心擔任重要的角色。微服務將單體的服務拆分成不同的模組下的服務,而不同的模組的服務如果進行通訊呼叫呢?這就需要服務註冊與發現。本文將使用阿里開源專案 nacos 搭建服務中心。

Nacos 致力於幫助您發現、配置和管理微服務。Nacos 提供了一組簡單易用的特性集,幫助您快速實現動態服務發現、服務配置、服務後設資料及流量管理。

Nacos 幫助您更敏捷和容易地構建、交付和管理微服務平臺。 Nacos 是構建以“服務”為中心的現代應用架構 (例如微服務正規化、雲原生正規化) 的服務基礎設施。

下載以及安裝 nacos

nacos官網找到 nacos 安裝包,下載下圖的 gz 字尾檔案。

解壓檔案進入bin目錄,執行下面命令。

sh startup.sh -m 

啟動成功
新建一個 springboot 專案

搭建服務生產者

  • 新增maven依賴
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
 <dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-test</artifactId>
	<scope>test</scope>
</dependency>
  • 配置application.yml 檔案
server:
  port: 8020
spring:
  application:
    name: service-provider
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
  • 在Application.java 啟動檔案新增 @EnableDiscoveryClient 註解

@SpringBootApplication
@EnableDiscoveryClient
public class Application {

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

}
  • 新增服務提供的介面
@RestController
public class ProviderController {

	@Autowired
	private Environment environment;

	@GetMapping("/hello")
	public String hello(String name){
		return "hello4  " + name + " port:" + environment.getProperty("local.server.port");
	}
}

啟動上面的服務(Application.java 裡面的main方法),啟動成功以後,登入 nacos 控制檯http://127.0.0.1:8848/nacos, 預設登入名和密碼都是nacos,可以發現服務列表多了一個服務。說明服務提供者已經成功註冊進了服務中心。


請求訪問 http://127.0.0.1:8020/hello,成功返回資料,說明服務能正常訪問。

搭建服務消費者

  • 新增maven依賴
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
        <!--如果只使用 ribbon 不需要下面兩個依賴,如果使用 feign ,下面兩個依賴都需要。-->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-openfeign</artifactId>
		</dependency>

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

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

這裡相對於服務提供者,多新增了ribbon和feign依賴。

  • 配置 application.yml 檔案
server:
  port: 8030
spring:
  application:
    name: service-consume
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
  • 修改 Application.java 檔案,新增註冊
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class NacosConsumeApplication {

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

}

這裡新增 @EnableDiscoveryClient 註解和 @EnableFeignClients,其中 @EnableDiscoveryClient 是將服務註冊進註冊中心,@EnableFeignClients 搭配feign客戶端使用。

  • 啟動上面的服務(Application.java 裡面的main方法),啟動成功以後,登入 nacos 控制檯,發現消費服務也註冊進了註冊中心。

服務呼叫有兩種方式:feign 和 ribbon

1. 使用 feign 呼叫服務

  • 配置客戶端
@FeignClient(value = "service-provider")
public interface ProductClient {

    @GetMapping("/hello")
    String product(@RequestParam("name") String name);
}

這裡的 @FeignClient 裡面的配置 value 對應的是服務提供者的服務名稱,@GetMapping裡面的value對應服務提供者的 @GetMapping 路徑。

  • 呼叫服務端
@RestController
public class FeignController {


    //這個錯誤是編譯器問題。 因為這個Bean是在程式啟動的時候注入的,編譯器感知不到,所以報錯。
    @Autowired
    private ProductClient productClient;

    @GetMapping("/feign")
    public String feign(String name){
        return productClient.product(name);
    }

}

使用 ribbon 呼叫服務員

  • 配置 RestTemplate bean
@Configuration
public class RibbonConfig {

    @LoadBalanced
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}
  • 呼叫服務
@RestController
public class RibbonController {

	@Autowired
	private RestTemplate restTemplate;

	@GetMapping("/ribbon")
	public String ribbon(String name){
		String result = restTemplate.getForObject("http://service-provider/hello?name="+name,String.class);
		return result;
	}
}

原始碼

相關文章