微服務註冊中心和配置中心Nacos 實戰總結

微服務註冊中心和配置中心Nacos 實戰總結

  • Nacos 註冊中心官網 , 快速入門 , github , 一個不錯的文檔

    • 註冊中心(動態服務發現, 基於 RPC 的服務發現): 註冊中心設計原理

    • 配置中心(動態配置服務)

      • 支持配置導出 和 導入,方便服務器遷移
      • 灰度配置 : 是指定部分客戶端IP進行新配置的下發,其餘客戶端配置保持不變,用以驗證新配置對客戶端的影響
    • 動態 DNS 服務 : 地址服務模塊 DNS: nacos-address-server-1.1.0

    • 健康檢查 : Nacos 監控 : Prometheus

  • 安裝 Nacos

    • 安裝方法1,下載源代碼

      unzip nacos-source.zip
      cd nacos/
      mvn -Prelease-nacos clean install -U
      cd nacos/distribution/target/nacos-server-1.1.4/nacos/bin
      
    • 安裝方法2, 下載運行包

      unzip nacos-server-1.1.4.zip OR tar -xvf nacos-server-1.1.4.tar.gz
      cd nacos/bin
      
    • 安裝方法3, docker , dockerfile

      docker pull nacos/nacos-server
      docker run --env MODE=standalone --name nacos -d -p 8848:8848 -v /mnt/logs/nacos:/home/nacos/logs nacos/nacos-server
      #測試URL: http://192.168.51.141:8858/nacos/index.html
      
    • 單機模式: 運行服務 和 停止服務

      sh startup.sh -m standalone  # standalone 模式啓動, 適合開發和測試環境
      sh shutdown.sh
      #nacos 管理界面 http://127.0.0.1:8848/nacos/
      #默認用戶名和密碼: nacos / nacos , config.server.service.LocalDataSourceServiceImpl
      
    • MySQL 配置

      -- 初始化mysql數據庫,手動創建 nacos 庫
      -- 然後在nacos庫中執行SQL文件:nacos-mysql.sql ,創建表,文件位置在 nacos-server/conf 目錄下
      
      #修改nacos-server/conf/application.properties文件,增加支持mysql數據源配置
      spring.datasource.platform=mysql
      
      db.num=1
      db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_dev?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
      db.user=root
      db.password=123456
      
  • 集羣模式部署 : 生產環境應採用集羣部署,需要3臺服務器 ,3臺配置都一樣, 修改日誌路徑

    • 修改 cluster.conf 文件
      cd /opt/nacos/conf & cp cluster.conf.example cluster.conf
      #在 cluster.conf 文件中,添加如下配置,ip:port
      192.168.1.38:8848
      192.168.2.38:8848
      192.168.3.38:8848
      
    • 修改 bin/startup.sh 文件中的 JVM Configuration, 推薦是 2G 內存
      if [[ "${MODE}" == "standalone" ]]; then
          JAVA_OPT="${JAVA_OPT} -Xms512m -Xmx512m -Xmn256m"
          JAVA_OPT="${JAVA_OPT} -Dnacos.standalone=true"
      else
          #JAVA_OPT="${JAVA_OPT} -server -Xms2g -Xmx2g -Xmn1g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"
          #-Xmx512m , 內存分配太小,會導致 Full GC 回收次數太多,CPU 太繁忙 , 現在改成 1G 試試
          JAVA_OPT="${JAVA_OPT} -server -Xms1g -Xmx1g -Xmn512m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"
          JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${BASE_DIR}/logs/java_heapdump.hprof"
          JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages"
      fi
      
    • 關閉 nacos accesslog ,因爲該文件太大
      #修改 conf/application.properties文件
      server.tomcat.accesslog.enabled=false  #默認是true
      
    • 修改nacos 相關日誌的路徑
      #修改 start.out 日誌文件的路徑 -- 這個配置不是很好,別用了
      #nohup $JAVA ${JAVA_OPT} nacos.nacos >> ${BASE_DIR}/logs/start.out 2>&1 &
      nohup $JAVA ${JAVA_OPT} nacos.nacos >> /mnt/logs/nacos/start.out 2>&1 &
      
      #修改nacos 日誌的路徑, 修改 conf/nacos-logback.xml文件 , 將logPah 屬性修改掉
      <springProperty scope="context" name="logPath" source="nacos.logs.path" defaultValue="${nacos.home}/logs"/>
      <property name="LOG_HOME" value="${logPath}"/>
      
      <springProperty scope="context" name="logPath" source="nacos.logs.path" defaultValue="/mnt/logs/nacos"/>
      
    • 啓動和停止 nacos server
      sh startup.sh  #啓動
      sh shutdown.sh # 停止
      
  • 常見問題

    • dubbo在向 Nacos 註冊時,如何使用外網IP註冊
    • dubbo 在註冊時,默認會根據主機名稱獲取本地ip
      • 要想使用外網IP,只要修改 /etc/hosts 文件中 主機名對應的IP即可,將內網IP改成外網IP
      • 帶來的問題:可能會找不到 provider,具體原因有待查找
    • dubbo 在向Nacos 註冊時,報Timeout錯誤,註冊失敗
      • 原因:可能是公司網絡不穩定導致的問題,可能是一臺路由器連接的設備太多
      • 解決辦法:Nacos 註冊中心啓動在本地,不使用開發環境的Nacos
  • 在dubbo 中使用 nacos 的註冊中心

    • 添加pom依賴

      <!-- 當項目中添加 dubbo-registry-nacos 後,您無需顯示地編程實現服務發現和註冊邏輯,實際實現由該三方包提供 -->
      <dependency>
          <groupId>org.apache.dubbo</groupId>
          <artifactId>dubbo-registry-nacos</artifactId>
          <version>2.7.4.1</version>
      </dependency>
      <!-- 如果沒有使用nacos配置中心,沒有添加 nacos-config-spring-boot-starter 依賴,則需要添加下面這個依賴 -->
      <dependency>
          <groupId>com.alibaba.nacos</groupId>
          <artifactId>nacos-client</artifactId>
          <version>1.1.4</version>
      </dependency>
      
    • 配置 nacos 註冊中心的地址

      dubbo.registry.address=nacos://127.0.0.1:8848
      
    • 只需這兩步,就可以讓Dubbo 使用 nacos 註冊中心了。

  • 在 dubbo中使用 nacos 的配置中心,實現動態配置

    • 添加pom 依賴

      <!-- 在Spring Boot 中使用配置中心, Version 0.2.x.RELEASE 兼容 Spring Boot 2.0.x -->
      <dependency>
          <groupId>com.alibaba.boot</groupId>
          <artifactId>nacos-config-spring-boot-starter</artifactId>
          <version>0.2.3</version>
      </dependency>
      
    • 配置 nacos 配置中心的地址

      nacos.config.server-addr=127.0.0.1:8848
      #不配置,是public 命名空間
      nacos.config.namespace=a5ffcb87-c011-45f9-849e-1f69c4484a64  
      
    • nacos 後臺 新增dubbo-demo-api 配置文件,在文件裏添加內容如下

      company=dfss+syp
      
    • 加載 dubbo-demo-api 配置文件 , 當然可以加載多個nacos中的配置文件,這樣就實現了配置共享

      @SpringBootApplication
      // 自動加載配置資源
      @NacosPropertySource(dataId = "dubbo-demo-api", autoRefreshed = true)
      @NacosPropertySource(dataId = "dubbo-demo-share.properties", autoRefreshed = true)
      public class NacosConfigApplication {
          public static void main(String[] args) {
              SpringApplication.run(NacosConfigApplication.class, args);
          }
      }
      
      @Controller
      public class UserController {
          // 使用 @NacosValue 獲取屬性值
          @NacosValue(value = "${company:none}", autoRefreshed = true)
          private String company;
        
          @RequestMapping("/sayHello/{name}")
          public String sayHello(@PathVariable String name) {
              return userService.sayHello(company + ": " + name);
          }
      }
      
    • 在dubbo中使用 spring-cloud-starter-alibaba-nacos-config 依賴也是可以的,請看下面《在spring cloud中使用nacos 配置中心》,用法完全一樣。具體怎麼選擇就看個人喜好了。

  • 在 springcloud 中使用 nacos的註冊中心

    • 添加pom 依賴

      <dependency>
          <groupId>com.alibaba.cloud</groupId>
          <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
          <version>2.2.0.RELEASE</version>
      </dependency>
      
    • 配置nacos 註冊中心的地址

      spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
      
    • 在啓動類上添加註解@EnableDiscoveryClient ,啓動服務註冊機制

      @SpringBootApplication
      @EnableDiscoveryClient
      public class PaymentServiceApplication {
      }
      
  • 在 springcloud 中使用 nacos的配置中心,實現動態配置 ;詳情配置可參見:Nacos Config

    • 添加pom 依賴 但是有個問題無法解決

      <dependency>
          <groupId>com.alibaba.cloud</groupId>
          <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
          <version>2.2.0.RELEASE</version>
      </dependency>
      
    • 在application.properties屬性文件中,配置nacos 配置中心的地址

      spring.profiles.active=dev
      server.port=8001
      spring.application.name=payment-service
      #配置中心地址
      spring.cloud.nacos.config.server-addr=127.0.0.1:8848
      spring.cloud.nacos.config.refresh-enabled=true
      
    • 新建 bootstrap.properties 屬性文件,添加共享配置,參見 spring-cloud-alibaba源碼 中的example

      #注意:一定要配置在這裏,如果放到application.properties中,則不能獲取到擴展配置文件中的配置
      #共享配置, 默認在默認的組,不支持動態刷新;
      spring.cloud.nacos.config.shared-configs[0].data-id=springcloud-demo-share.properties
      spring.cloud.nacos.config.shared-configs[0].group=DEFAULT_GROUP
      spring.cloud.nacos.config.shared-configs[0].refresh=true
      # share 比 extension 優先級高
      spring.cloud.nacos.config.extension-configs[0].data-id=share.properties
      spring.cloud.nacos.config.extension-configs[0].group=DEFAULT_GROUP
      spring.cloud.nacos.config.extension-configs[0].refresh=true
      
    • nacos 後臺 新增 payment-service-dev.properties 配置文件(不帶dev也可),文件內容如下

      sleep=1000
      
    • nacos 後臺 新增 share.properties 共享配置文件

      plateform=dubbo
      
    • 使用 nacos 配置中心的配置項

      // 在Controller 上添加 @RefreshScope註解,這樣 @Value("${sleep:0}") 就可以取得nacos上的值了
      @RestController
      @RefreshScope  // 別忘記這個註解,解決自動刷新問題
      public class PaymentController {
          @Value("${sleep:0}")
          private int sleep;
          // 在共享配置文件中配置
          @Value("${share.message:none}")
          private String message;
      
          @RequestMapping("/pay/balance")
          public Balance getBalance(@RequestParam Integer id) {
              System.out.println("request: /pay/balance?id=" + id + ", sleep: " + sleep);
              return new Balance(0, 0, 0, message);
          }
      }
      
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章