Spring Cloud Alibaba Nacos 服務發現


1.Nacos 簡介

發音: /nɑ:kəʊs/
全稱:Name and Config Service,nacos 是其首字母的拼寫。
Nacos 的核心功能 = 服務注冊 + 動態配置
可以理解為 Nacos = SpringCloud Eureka + SpringCloud Config

2.什么是服務發現

服務消費者怎么找到服務提供者的機制就是服務發現。

3.實現服務發現機制需要解決很多的問題

健康檢查:
問題:服務實例故障了,無法主動注銷自己的信息怎么辦?
方案:通過心跳機制進行健康檢查,注冊中心刪除無心跳的實例信息

本地緩存:
問題:每次服務調用之前都查詢注冊中心,性能差、不可靠,怎么辦?
方案:本地緩存、定時更新(定時查詢服務列表、服務注冊中心主動推送)

數據同步:
問題:注冊中心集群中各個節點的數據如何同步?
方案:強一致性,例如 ZooKeeper。弱一致性,例如 Eureka。

4.Nacos 特征與優勢

 

 

 

 

 5.Nacos環境搭建

官網文檔:https://nacos.io/zh-cn/docs/quick-start.html

下載地址:https://gitee.com/mirrors/Nacos、https://github.com/alibaba/nacos/releases

Spring Boot 2.3.x:https://github.com/alibaba/nacos/releases/tag/1.4.1

 

windows安裝方式

選擇 nacos-server-1.4.1.zip 進行下載

解壓進入到 C:\Software\nacos-server-1.4.1\bin 目錄

雙擊 startup.cmd 一閃而過代表失敗,注意Java環境是否安裝和配置。

瀏覽器訪問:http://127.0.0.1:8848/nacos

用戶名和密碼都是nacos

服務注冊(linux)

curl -X POST 'http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=nacos.naming.serviceName&ip=20.18.7.10&port=8080'

服務發現(linux)

curl -X GET 'http://127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=nacos.naming.serviceName'

使用 Postman

File => Import => Raw test

粘貼curl命令

6.服務提供者和消費者整合Nacos

6.1 provider(服務提供者)

6.1.1 加依賴

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

6.1.2 加注解

package com.example.serviceprovider;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
// 加注解(開啟服務發現)
@EnableDiscoveryClient
public class ServiceProviderApplication {

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

}

6.1.3 改配置

server:
  port: 8081
spring:
  application:
    name: service-provider
# 添加 nacos 地址 cloud: nacos: discovery: server
-addr: localhost:8848 namespace: 23ffbc32-5bde-4451-9683-c346220fa282 group: g1 cluster-name: beijing

6.1.4 創建測試接口

package com.example.serviceprovider;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

    @GetMapping("hello")
    public String hello(@RequestParam String name){
        return "hello " + name;
    }
}

6.2 consumer(消費者)

6.2.1 加依賴

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

6.2.2 加注解

package com.example.serviceprovider;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
// 加注解(開啟服務發現)
@EnableDiscoveryClient
public class ServiceConsumerApplication {

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

}

6.2.3 改配置

server:
  port: 8082
spring:
  application:
    name: service-consumer
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848

6.2.4  配置 RestTemplate

package com.example.serviceprovider;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

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

6.2.5 發起服務調用

package com.example.serviceprovider;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.net.URI;


@RestController
public class TestController {
    // 引入 RestTemplate
    @Autowired
    RestTemplate restTemplate;

    // 引入 LoadBalancerClient
    @Autowired
    LoadBalancerClient loadBalancerClient;

    @GetMapping("hello")
    public String hello(@RequestParam String name) {
        String result = "";

        // 根據服務名獲取服務實例
        ServiceInstance serviceInstance = loadBalancerClient.choose("service-provider");

        // 發起調用
        URI uri = serviceInstance.getUri();
        result = restTemplate.getForObject(uri + "/hello?name=test", String.class);

        // 返回結果
        return result;
    }
}

 7.Nacos 服務領域模型

 

 

namespace :命名空間ID

group:組

cluster-name:集群

Nacos 三層數據模型:NameSpace, Group, Service

Nacos 服務領域模型:NameSpace, Group, Service,Cluster, Instance
8.負載均衡與權重

負載均衡的類型 

服務端負載均衡:如nginx 根據負載均衡策略選擇某個實例轉發請求

客服端負載均衡:根據自己實現的負載均衡策略選擇

8.1 provider(服務提供者),使用配置的服務端口號

package com.example.serviceprovider;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {
    @Value("${server.port}")
    Integer port;

    @GetMapping("hello")
    public String hello(@RequestParam String name){
        return "hello " + name + " " + port;
    }
}

8.2 consumer(消費者),使用負載均衡注解

package com.example.serviceprovider;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class ConsumerConfig {
    // 使用負載均衡注解
    @LoadBalanced
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

}

服務調用

package com.example.serviceprovider;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class TestLBController {
    @Autowired
    RestTemplate restTemplate;

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

負載均衡策略

 

 

  SpringBoot 配置文件修改負載均衡策略

package com.example.serviceprovider;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

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

   // 負載均衡策略
    @Bean
    public IRule iRule(){
return new RandomRule();
  } }

8.3 自定義基於權重的負載均衡策略的方法

 

 

 服務消費者中實現基於權重的負載均衡策略

package com.example.serviceprovider;

import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.cloud.nacos.ribbon.NacosServer;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.BaseLoadBalancer;
import com.netflix.loadbalancer.Server;
import org.springframework.beans.factory.annotation.Autowired;

public class NacosWeightRule extends AbstractLoadBalancerRule {
    // 引入 NacosDiscoveryProperties
    @Autowired
    private NacosDiscoveryProperties nacosDiscoveryProperties;

    // 重寫 choose 方法
    @Override
    public Server choose(Object o) {
        // 獲取服務提供者的名字
        // 拿到 nacos 的命名服務對象
        // 通過 nacos 的命名服務根據權重獲取實例
        // 封裝 server 對象,返回

        BaseLoadBalancer loadBalancer = (BaseLoadBalancer) this.getLoadBalancer();
        String name = loadBalancer.getName();
NamingService namingService
= nacosDiscoveryProperties.namingServiceInstance(); try { Instance instance = namingService.selectOneHealthyInstance(name); return new NacosServer(instance); }catch (Exception e){ e.printStackTrace(); } return null; } @Override public void initWithNiwsConfig(IClientConfig iClientConfig) { } }

Nacos配置修改權重配置

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

    @Bean
    public IRule iRule(){
       //根據權重的負載均衡策略
        return new NacosWeightRule();
    }

}

9.Nacos集群部署

 

9.1 創建數據庫和表

使用sql腳本創建數據庫

nacos-server => conf  => nacos-mysql.sql

 

9.2 配置MySQL連接

nacos-server => conf  =>  application.properties

# 表明用MySQL作為后端存儲
spring.datasource.platform=mysql
# 有幾個數據庫實例
db.num=1
# 第1個實例的地址
db.url.0=jdbc:mysql://[mysqlIP]/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout
=3000&autoReconnect=true
db.user=[數據庫用戶名]
db.password=[數據庫密碼]

 

9.3 配置集群節點IP端口

nacos-server => conf  =>  application.properties

 

# nacos01
server.port=8841


# nacos02
server.port=8842


# nacos03
server.port=8843

 

nacos-server => conf  =>  cluster.conf.example 復制一份 去掉后綴example ,每個集群實例配置,相同配置文件。

server 127.0.0.1:8841; server 127.0.0.1:8842; server 127.0.0.1:8843;

啟動各個nacos 

9.4 配置Nginx

nginx.conf 配置文件 include servers/* 意思是加載servers文件夾下所以配置文件,所以進入到servers文件夾 創建 nocos.conf 配置文件,以下是nocos.conf 內容

upstream nacos {
 server 127.0.0.1:8841;
 server 127.0.0.1:8842;
 server 127.0.0.1:8843;
}
server { listen
9090; server_name localhost; location /nacos/ { proxy_pass http://nacos; } }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM