nacos--简单入门

目录

1.0.Nacos

1.1.Nacos概要

1.1.1.Nacos是什么?

1.Nacos特性:

2.动态配置服务:

3.动态DNS服务:

4.服务及其元数据管理:

5.Nacos版图:

6.Nacos生态图:

1.1.2.Nacos架构

1.基本架构

2.逻辑结构及组件

3.领域模型

1.2.Nacos安装

1.2.1.官方安装教程

1.预备环境准备

2.下载源码或者安装包

3.添加MySql

2.0.Nacos功能应用

2.1.Nacos服务注册与发现

 2.2.负载均衡

 2.3.配置中心

2.3.1.配置管理

2.3.2.多环境切换

2.3.3.多/共享配置

 2.3.4.配置刷新

2.3.4.1.Environment自动刷新

2.3.4.2.@Value刷新

2.3.5.灰度发布

3.0.Nacos集群

3.1.集群架构节点

3.2.Nacos集群部署

3.3.客户端接入Nacos集群


1.0.Nacos

NacosAlibaba微服务生态组件中的重要组件之一,主要用它实现应用的动态服务发现配置管理

服务管理

Nacos discovery · alibaba/spring-cloud-alibaba Wiki · GitHub

1.1.Nacos概要

1.1.1.Nacos是什么?

 Nacos致力于帮助您发现、配置和管理微服务Nacos提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。

Nacos帮助您更敏捷和容易地构建、交付和管理微服务平台。Nacos是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。

Nacos支持几乎所有主流类型的“服务”的发现、配置和管理:

1:Kubernetes Service

2:gRPC & Dubbo RPC Service

3:Spring Cloud RESTful Service

1.Nacos特性:

服务发现和服务健康监测:

1. Nacos支持基于DNS和基于RPC的服务发现。服务提供者使用 原生SDK、OpenAPI、或一个独立的Agent TODO注册Servic 后,服务消费者可以使用DNSTODO或HTTP&API查找和发现服务。

2. Nacos提供对服务的实时的健康检查,阻止向不健康的主机或服务实例发送请求。Nacos支持传输层(PING 或 TCP)和应用层 (如 HTTP、MySQL、用户自定义)的健康检查。 对于复杂的云环境和网络拓扑环境中(如 VPC、边缘网络等)服务的健康检查,Nacos提供了agent上报模式和服务端主动检测2种健康检查模式。Nacos还提供了统一的健康检查仪表盘,帮助您根据健康状态管理服务的可用性及流量。

2.动态配置服务:

1. 动态配置服务可以让您以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置。

2. 动态配置消除了配置变更时重新部署应用和服务的需要,让配置管理变得更加高效和敏捷。

3. 配置中心化管理让实现无状态服务变得更简单,让服务按需弹性扩展变得更容易。

4. Nacos提供了一个简洁易用的UI (控制台样例 Demo) 帮助您管理所有的服务和应用的配置。Nacos

提供包括配置版本跟踪、金丝雀发布、一键回滚配置以及客户端配置更新状态跟踪在内的一系列开箱即用的配置管理特性,帮助您更安全地在生产环境中管理配置变更和降低配置变更带来的风险。

3.动态DNS服务:

1. 动态DNS服务支持权重路由,让您更容易地实现中间层负载均衡、更灵活的路由策略、流量控制以及数据中心内网的简单DNS解析服务。动态DNS服务还能让您更容易地实现以DNS协议为基础的服务发现,以帮助您消除耦合到厂商私有服务发现API上的风险。

2. Nacos提供了一些简单的DNSAPIs TODO帮助您管理服务的关联域名和可用的 IP:PORT 列表.

4.服务及其元数据管理:

1. Nacos能让您从微服务平台建设的视角管理数据中心的所有服务及元数据,包括管理服务的描述、生命周期、服务的静态依赖分析、服务的健康状态、服务的流量管理、路由及安全策略、服务的SLA以及最首要的metrics统计数据。

5.Nacos版图:

 • 特性大图:要从功能特性,非功能特性,全面介绍我们要解的问题域的特性诉求

• 架构大图:通过清晰架构,让您快速进Nacos世界

• 业务大图:利用当前特性可以支持的业务场景,及其最佳实践

• 生态大图:系统梳理Nacos和主流技术生态的关系

• 优势大图:展示Nacos核心竞争力

• 战略大图:要从战略到战术层面讲Nacos的宏观优势

6.Nacos生态图:

 Nacos无缝支持一些主流的开源生态:

1:Spring Cloud

2:Apache Dubbo and Dubbo Mesh

3:Kubernetes and CNCF

使用Nacos简化服务发现、配置管理、服务治理及管理的解决方案,让微服务的发现、管理、共享、组合更加容易。

1.1.2.Nacos架构

1.基本架构

 服务(Service):服务是指一个或一组软件功能(例如特定信息的检索或一组操作的执行),其目的是不同的客户端可以为不同的目的重用(例如通过跨进程的网络调用)。Nacos支持主流的服务生态,如Kubernetes Service、gRPC|Dubbo RPC Service 或者Spring Cloud RESTful Service。

服务注册中心(Service Registry):服务注册中心,它是服务,其实例及元数据的数据库。服务实例在启动时注册到服务注册表,并在关闭时注销。服务和路由器的客户端查询服务注册表以查找服务的可用实例。服务注册中心可能会调用服务实例的健康检查API来验证它是否能够处理请求。

服务元数据(Service Metadata):服务元数据是指包括服务端点(endpoints)、服务标签、服务版本号、服务实例权重、路由规则、安全策略等描述服务的数据。

服务提供方(Service Provider):是指提供可复用和可调用服务的应用方。

服务消费方(Service Consumer):是指会发起对某个服务调用的应用方。

配置(Configuration):在系统开发过程中通常会将一些需要变更的参数、变量等从代码中分离出来独立管理,以独立的配置文件的形式存在。目的是让静态的系统工件或者交付物(如 WAR,JAR 包等)更好地和实际的物理运行环境进行适配。配置管理一般包含在系统部署的过程中,由系统管理员或者运维人员完成这个步骤。配置变更是调整系统运行时的行为的有效手段之一。

配置管理(Configuration Management):在数据中心中,系统中所有配置的编辑、存储、分发、变更管理、历史版本管理、变更审计等所有与配置相关的活动统称为配置管理。

名字服务(Naming Service):提供分布式系统中所有对象(Object)、实体(Entity)的“名字”到关联的元数据之间的映射管理服务,例如 ServiceName -> Endpoints Info, Distributed Lock Name -> Lock Owner/Status Info, DNS Domain Name -> IP List, 服务发现和 DNS 就是名字服务的2大场景。

配置服务(Configuration Service):在服务或者应用运行过程中,提供动态配置或者元数据以及配置管理的服务提供者。

2.逻辑结构及组件

 服务管理:实现服务CRUD,域名CRUD,服务健康状态检查,服务权重管理等功能

配置管理:实现配置管CRUD,版本管理,灰度管理,监听管理,推送轨迹,聚合数据等功能

元数据管理:提供元数据CURD 和打标能力

插件机制:实现三个模块可分可合能力,实现扩展点SPI机制

事件机制:实现异步化事件通知,sdk数据变化异步通知等逻辑

日志模块:管理日志分类,日志级别,日志可移植性(尤其避免冲突),日志格式,异常码+帮助文档

回调机制sdk通知数据,通过统一的模式回调用户处理。接口和数据结构需要具备可扩展性

寻址模式:解决ip,域名,nameserver、广播等多种寻址模式,需要可扩展

推送通道:解决server与存储、server间、serversdk间推送性能问题

容量管理:管理每个租户,分组下的容量,防止存储被写爆,影响服务可用性

流量管理:按照租户,分组等多个维度对请求频率,长链接个数,报文大小,请求流控进行控制

缓存机制:容灾目录,本地缓存,server缓存机制。容灾目录使用需要工具

启动模式:按照单机模式,配置模式,服务模式,dns模式,或者all模式,启动不同的程序+UI

一致性协议:解决不同数据,不同一致性要求情况下,不同一致性机制

存储模块:解决数据持久化、非持久化存储,解决数据分片问题

Nameserver:解决namespaceclusterid的路由问题,解决用户环境与nacos物理环境映射问题

CMDB:解决元数据存储,与三方cmdb系统对接问题,解决应用,人,资源关系

Metrics:暴露标准metrics数据,方便与三方监控系统打通

Trace:暴露标准trace,方便与SLA系统打通,日志白平化,推送轨迹等能力,并且可以和计量计费系统打通

接入管理:相当于阿里云开通服务,分配身份、容量、权限过程

用户管理:解决用户管理,登录,sso等问题

权限管理:解决身份识别,访问控制,角色管理等问题

审计系统:扩展接口方便与不同公司审计系统打通

通知系统:核心数据变更,或者操作,方便通过SMS系统打通,通知到对应人数据变更

OpenAPI:暴露标准Rest风格HTTP接口,简单易用,方便多语言集成

Console:易用控制台,做服务管理、配置管理等操作

SDK:多语言sdk

Agent:dns-f类似模式,或者与mesh等方案集成

CLI:命令行对产品进行轻量化管理,像git一样好用

3.领域模型

数据模型:Nacos数据模型Key由三元组唯一确定, Namespace默认是空串,公共命名空间(public),分组默认是 DEFAULT_GROUP

 服务领域模型

 配置领域模型:围绕配置,主要有两个关联的实体,一个是配置变更历史,一个是服务标签(用于打标分类,方便索引),由ID关联。

 类视图:Nacos-SDK类视图

1.1.3.构建物、部署及启动模式

 两种交付工件:Nacos支持标准Docker镜像(TODO: 0.2版本开始支持)及zip(tar.gz)压缩包的构建物。

两种启动模式:Nacos支持将注册中心(Service Registry)与配置中心(Config Center)在一个进程合并部署或者将2者分离部署的两种模式。

免费的公有云服务模式:除了您自己部署和启动Nacos服务之外,在云计算时代,Nacos也支持公有云模式,在阿里云公有云的商业产品(如 MSE,  EDAS)中会提供Nacos的免费的公有云服务。

1.2.Nacos安装

1.2.1.官方安装教程

您可以在Nacos的 release notes及 博客中找到每个版本支持的功能的介绍,当前推荐的稳定版本为2.1.1。

1.预备环境准备

Nacos依赖  Java 环境来运行。如果您是从代码开始构建并运行Nacos,还需要为此配置  Maven环境,请确保是在以下版本环境中安装使用:

1.64 bit OS,支持 Linux/Unix/Mac/Windows,推荐选用Linux/Unix/Mac。

2.64 bit JDK 1.8+; 下载 &  配置。

3.Maven 3.2.x+; 下载 &  配置。

2.下载源码或者安装包

下载编译后压缩包方式

下载 nacos-server-$version.zip 包 GitHub - alibaba/nacos at 2.1.1。

unzip nacos-server-$version.zip

或者

tar -xvf nacos-server-$version.tar.gz

cd nacos/bin

 3.修改配置文件(单机学习部署不用配置)

在2.2.0.1和2.2.1版本时,必须执行此变更,否则无法启动;其他版本为建议设置。修改conf目录下的application.properties文件。

设置其中的nacos.core.auth.plugin.nacos.token.secret.key值,详情可查看 鉴权-自定义密钥.

注意,文档中的默认值SecretKey012345678901234567890123456789012345678901234567890123456789和VGhpc0lzTXlDdXN0b21TZWNyZXRLZXkwMTIzNDU2Nzg=为公开默认值,可用于临时测试,实际使用时请务必更换为自定义的其他有效值。

 4.启动服务器

注:Nacos的运行建议至少在2C4G 60G的机器配置下运行。

Linux/Unix/Mac:启动命令(standalone代表着单机模式运行,非集群模式):

sh startup.sh -m standalone

如果您使用的是ubuntu系统,或者运行脚本报错提示[[符号找不到,可尝试如下运行:

bash startup.sh -m standalone

Windows:启动命令(standalone代表着单机模式运行,非集群模式):

startup.cmd -m standalone

5.服务注册&发现和配置管理

服务注册:

[root@hecs-336721 ~]# curl -X POST 'http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=nacos.naming.serviceName&ip=20.18.7.10&port=8080'

ok

 服务发现:

[root@hecs-336721 ~]# curl -X GET 'http://127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=nacos.naming.serviceName'

{"name":"DEFAULT_GROUP@@nacos.naming.serviceName","groupName":"DEFAULT_GROUP","

clusters":"","cacheMillis":10000,"hosts":[{"instanceId":"20.18.7.10#8080#DEFAULT#DEFAULT_GROUP

@@nacos.naming.serviceName","ip":"20.18.7.10","port":8080,"weight":1.0,"healthy":false,"enabled":true,"

ephemeral":true,"clusterName":"DEFAULT","serviceName":"DEFAULT_GROUP@@nacos.naming.

serviceName","metadata":{},"instanceHeartBeatInterval":5000,"instanceIdGenerator":"simple",

"instanceHeartBeatTimeOut":15000,"ipDeleteTimeout":30000}],"lastRefTime":1687948051490,

"checksum":"","allIPs":false,"reachProtectionThreshold":false,"valid":true}

 发布配置:

[root@hecs-336721 ~]# curl -X POST "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test&content=HelloWorld"

true

 获取配置:

[root@hecs-336721 ~]# curl -X GET "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test"

HelloWorld

 6.关闭服务器

Linux/Unix/Mac

sh shutdown.sh

Windows

shutdown.cmd

或者双击shutdown.cmd运行文件。 

3.添加MySql

添加MySql配置从github上获取SQL脚本:SQL:

https://github.com/alibaba/nacos/blob/develop/config/src/main/resources/META-INF/nacos-db.sql

 进入到nacos配置目录下打开application.properties文件配置MySql链接信息。 

集群模式:

1.使用内置数据源:sh startup.sh -p embedded

2.使用外置数据源:sh startup.sh

2.0.Nacos功能应用

2.1.Nacos服务注册与发现

服务发现是微服务架构体系中最关键的组件之一。如果尝试着用手动的方式来给每一个客户端来配置所有服务提供者的服务列表是一件非常困难的事,而且也不利于服务的动态扩缩容。Nacos Discovery Starter可以帮助您将服务自动注册到Nacos服务端并且能够动态感知和刷新某个服务实例的服务列表。除此之外,Nacos Discovery Starter也将服务实例自身的一些元数据信息-例如hostport,健康检查URL,主页等-注册到Nacos

接下来我们学习一下如何使用Nacos作为服务的注册中心,并实现服务注册和服务发现。当前项目开发主流技术是SpringBoot,我们就讲解基于SpringBoot如何使用Nacos实现服务注册与发现。

关于SpringCloud AlibabaSpringBoot的版本,我们可以通过 https://start.spring.io/actuator/info查看。

 在项目中导入nacos依赖

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

<!-- nacos-config -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    <version>2.2.5.RELEASE</version>
</dependency>

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

• bootstrap.yml ( bootstrap.properties )用来在程序引导时执行,应用于更加早期配置信息读取,如可以使用来配置application.yml中使用到参数等。

• application.yml ( application.properties )应用程序特有配置信息,可以用来配置后续各个模块中需使用的公共参数等。 application.yml中配置nacas地址会一直报错:Server check fail, please check server localhost ,port 9848 is available , error ={}。

• bootstrap.yml 先于application.yml 加载。项目中如果使用Nacos,需要使用bootstrap.yml,因此我们需要将项目中的 application.yml 换成bootstrap.yml 。

创建测试项目producerconsumer项目学习nacos的应用。

consumer

 在bootstrap.yml配置nacos服务地址:

server:
  port: 10088
spring:
  application:
    name: consumer-server
  cloud:
    nacos:
      config:
        server-addr: 123.60.23.244:8848
      discovery:
        server-addr: 123.60.23.244:8848

feign:
  compression:
    request:
      enabled: true # 开启请求压缩
      # 设置压缩的数据类型(默认值)
      mime-types: text/html,application/xml,application/json
      # 设置触发压缩的大小下限(默认值)
      min-request-size: 2048
    response:
      enabled: true # 开启响应压缩

logging:
  level:
    dream.myself.consumer: debug

consumer Feign调用接口及配置:

ProducerFeign:

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient(value = "producer-server")
public interface ProducerFeign {

    @GetMapping("/producer/status/{status}")
    String consumer(@PathVariable(value = "status") String status);
}

ConsumerController:

import dream.myself.consumer.api.ProducerFeign;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("consumer")
public class ConsumerController {
    private ProducerFeign producer;

    public ConsumerController(ProducerFeign producer) {
        this.producer = producer;
    }

    @GetMapping("getMessage")
    public String consumerMessage(){
        return producer.consumer("ready");
    }
}

ConsumerApplication:

@SpringBootApplication
@EnableFeignClients(basePackages = "dream.myself.consumer.api")
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }

    @Bean
    public Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }
}

producer

 在bootstrap.yml配置nacos服务地址:

server:
  port: 10086
spring:
  application:
    name: producer-server
  cloud:
    nacos:
      config:
        server-addr: 123.60.23.244:8848
      discovery:
        server-addr: 123.60.23.244:8848

ProducerController:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("producer")
public class ProducerController {
    private static final Logger LOGGER = LoggerFactory.getLogger(ProducerController.class);

    private final Environment environment;

    public ProducerController(Environment environment) {
        this.environment = environment;
    }

    @GetMapping("/status/{status}")
    String consumer(@PathVariable(value = "status") String status) {
        String port = environment.getProperty("server.port");
        LOGGER.info("server.port:" + port);
        return "Producer massage:" + status + ", Receive request server port:" + port;
    }
}

discovery表示可以发现服务,config表示可以配置服务信息。这两个值会默认访问localhostnacas运行在本地时只需要配置一个即可,如果nacos运行在远端,需要将两个参数均配置远端IP地址,否则会一直报错查找本地localhost地址。

启动项目,可以看到producerconsumer都已经注册到nacos服务中去了。

在本地IDEA中可以看到项目中已经成功拉取了远端的nacos服务信息。

 2.2.负载均衡

复制项目启动项,并分别配置各自的端口号(--server.port=10094),模拟生产环境多微服务结构。

 我们可以发现服务注册到Nacos中,有一个权重属性,这个权重属性就是Nacos的负载均衡机制,此时需要用到Nacos的负载均衡策略NacosRule,我们可以在程序中先初始化负载均衡算法,再到bootstrap.yml中配置权重。

1)初始化负载均衡算法

在调用者consumer 中初始化负载均衡算法。

import com.alibaba.cloud.nacos.ribbon.NacosRule;
import com.netflix.loadbalancer.IRule;
import feign.Logger;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;

@SpringBootApplication
@EnableFeignClients(basePackages = "dream.myself.consumer.api")
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }

    @Bean
    public Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }

    /**
     * nacos负载均衡算法
     * prototype非单例模式
     */
    @Bean
    @Scope(value = "prototype")
    public IRule loadBalanceRule() {
        return new NacosRule();
    }
}

2)权重配置

server:
  port: 10086
spring:
  application:
    name: producer-server
  cloud:
    nacos:
      config:
        server-addr: 123.60.23.244:8848
      discovery:
        server-addr: 123.60.23.244:8848
        weight: 5

为了演示集群效果,在复制的producer启动项中分别设置不同的权重(--server.port=10094 --spring.cloud.nacos.discovery.weight=10)。

 启动一个consumer服务三个producer服务,请求consumer服务http://127.0.0.1:10088/consumer/getMessage,10086端口被调用比例占1/6、10094端口被调用比例占1/3、10096端口被调用比例占1/2。

如果我们把算法NacosRule注释,默认就开启Ribbon的负载均衡轮询策略。 

import feign.Logger;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@EnableFeignClients(basePackages = "dream.myself.consumer.api")
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }

    @Bean
    public Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }

    /**
     * nacos负载均衡算法
     * prototype非单例模式
     */
    /*@Bean
    @Scope(value = "prototype")
    public IRule loadBalanceRule() {
        return new NacosRule();
    }*/
}

Ribbon的负载均衡轮询策略默认是开启的,如果需要关闭,可以在配置文件中配置实现。

server:
  port: 10088
spring:
  application:
    name: consumer-server
  cloud:
    nacos:
      config:
        server-addr: 123.60.23.244:8848
      discovery:
        server-addr: 123.60.23.244:8848

ribbon:
  nacos:
    enabled: false

feign:
  compression:
    request:
      enabled: true # 开启请求压缩
      # 设置压缩的数据类型(默认值)
      mime-types: text/html,application/xml,application/json
      # 设置触发压缩的大小下限(默认值)
      min-request-size: 2048
    response:
      enabled: true # 开启响应压缩

logging:
  level:
    dream.myself.consumer: debug

此时再访问consumer服务会因为找不到producer服务而请求失败,原因是关闭了nacosribbon负载均衡的支持。

 另外我们还可以配置一些元数据信息,nacos可以用来存储元数据信息,在配置中使用metadata属性来配置,例如在灰度发布的时候就可以使用到元数据功能。

server:
  port: 10088
spring:
  application:
    name: consumer-server
  cloud:
    nacos:
      config:
        server-addr: 123.60.23.244:8848
      discovery:
        server-addr: 123.60.23.244:8848
        metadata:
          version: 10.01.20
          type: consumer-version

feign:
  compression:
    request:
      enabled: true # 开启请求压缩
      # 设置压缩的数据类型(默认值)
      mime-types: text/html,application/xml,application/json
      # 设置触发压缩的大小下限(默认值)
      min-request-size: 2048
    response:
      enabled: true # 开启响应压缩

logging:
  level:
    dream.myself.consumer: debug

打开nacos控制台可以看见配置文件中配置的元数据信息。

 2.3.配置中心

Nacos提供用于存储配置和其他元数据的key/value存储,为分布式系统中的外部化配置提供服务器端和客户端支持。使用Spring Cloud Alibaba Nacos Config,您可以在Nacos Server集中管理你Spring Cloud应用的外部属性配置。

Spring Cloud Alibaba Nacos Config 是Config ServerClient的替代方案,客户端和服务器上的概念与Spring EnvironmentPropertySource有着一致的抽象,在特殊的bootstrap阶段,配置被加载到Spring环境中。当应用程序通过部署管道从开发到测试再到生产时,您可以管理这些环境之间的配置,并确保应用程序具有迁移时需要运行的所有内容。

2.3.1.配置管理

我们可以在Nacos控制台配置项目的配置数据,先打开Nacos控制台,在命名空间中添加新建命名空间,如下图:

 在[配置管理>配置列表]中添加,命名空间选择刚刚创建的BeMyself命名空间,如下图:

 再将项目中的配置内容拷贝到表单中,比如我们可以把consumer原来在bootstrap中的配置填写到下面表单中,如下图:

 注意Data ID和服务名字保持一致,作为程序默认加载配置。

图片中的配置如下:

server:
  port: 10088

spring:
  application:
    name: consumer-server
  cloud:
    nacos:
      config:
        server-addr: 123.60.23.244:8848
      discovery:
        server-addr: 123.60.23.244:8848
        metadata:
          version: 10.01.20
          type: consumer-version

feign:
  compression:
    request:
      enabled: true # 开启请求压缩
      # 设置压缩的数据类型(默认值)
      mime-types: text/html,application/xml,application/json
      # 设置触发压缩的大小下限(默认值)
      min-request-size: 2048
    response:
      enabled: true # 开启响应压缩

logging:
  level:
    dream.myself.consumer: debug

项目中需要先引入依赖包,我们以consumer为例,在pom.xml中引入如下依赖:

<!--nacos-config-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    <version>2.2.9.RELEASE</version>
</dependency>

配置文件中添加配置中心地址,在consumerbootstrap.yml中删除所有配置,添加如下配置:

spring:
  application:
    name: consumer-server
  cloud:
    nacos:
      config:
        server-addr: 123.60.23.244:8848
        namespace: 1e327238-6212-4179-9a28-4c186039485f
        file-extension: yaml
      discovery:
        server-addr: 123.60.23.244:8848
        namespace: 1e327238-6212-4179-9a28-4c186039485f

namespace的值为刚刚创建的命名空间ID:

 file-extension的值为配置中文件类型(文件后缀):

我们启动consumer服务,默认加载${spring.application.name}.${file-extension:properties}配置,加载完成后配置数据会生效

 在启动日志中可以看到拉取了nacos上注册服务,目前只注册了一个服务。

[

{

"ip": "192.168.1.7",

"port": 10088,

"weight": 1.0,

"healthy": true,

"enabled": true,

"ephemeral": true,

"clusterName": "DEFAULT",

"serviceName": "DEFAULT_GROUP@@consumer-server",

"metadata": {

"type": "consumer-version",

"preserved.register.source": "SPRING_CLOUD",

"version": "10.01.20"

},

"ipDeleteTimeout": 30000,

"instanceHeartBeatInterval": 5000,

"instanceHeartBeatTimeOut": 15000

}

]

如果此时配置文件名字如果和当前服务名字不一致,可以使用name属性来指定配置文件名字:

spring:
  application:
    name: consumer-server
  cloud:
    nacos:
      config:
        #Nacos服务地址
        server-addr: 123.60.23.244:8848
        #分组
        group: DEFAULT_GROUP
        #Nacos中命名空间的ID
        namespace: 1e327238-6212-4179-9a28-4c186039485f
        #Nacos中配置文件的后缀为yaml
        file-extension: yaml
        #指定配置文件名字
        name: consumer-server.yaml
      discovery:
        #Nacos服务地址
        server-addr: 123.60.23.244:8848
        #分组
        group: DEFAULT_GROUP
        #Nacos中命名空间的ID
        namespace: 1e327238-6212-4179-9a28-4c186039485f

2.3.2.多环境切换

spring-cloud-starter-alibaba-nacos-config 在加载配置的时候,不仅仅加载了以Data ID为${spring.application.name}.${file-extension:properties} 为前缀的基础配置,还加载了Data ID为 ${spring.application.name}-${profile}.${file-extension:properties} 的基础配置。在日常开发中如果遇到多套环境下的不同配置,可以通过Spring提供的

${spring.profiles.active}这个配置项来配置。

比如开发环境我们可以在nacos中创建 consumer-server-dev.yaml ,测试环境可以在配置中创建consumer-server-test.yaml,创建如下:

consumer-server-dev.yaml

 consumer-server-test.yaml

修改consumer服务逻辑,在请求服务后返回当前服务的端口号。

import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("consumer")
public class ConsumerController {
    private final Environment environment;

    public ConsumerController(Environment environment) {
        this.environment = environment;
    }

    @GetMapping("getPort")
    String consumerPort() {
        String port = environment.getProperty("server.port");
        return " Receive request server port:" + port;
    }
}

修改consumerbootstrap.yml 配置文件:

spring:
  profiles:
    active: dev #对应consumer-server-dev.yaml
  application:
    name: consumer-server
  cloud:
    nacos:
      config:
        server-addr: 123.60.23.244:8848
        group: DEFAULT_GROUP
        namespace: 1e327238-6212-4179-9a28-4c186039485f
        file-extension: yaml
      discovery:
        server-addr: 123.60.23.244:8848
        group: DEFAULT_GROUP
        namespace: 1e327238-6212-4179-9a28-4c186039485f

测试访问consumer服务http://127.0.0.1:10100/consumer/getMessage:

active值改为test再次测试http://127.0.0.1:10098/consumer/getMessage:

2.3.3.多/共享配置

在实际的业务场景中应用和共享配置间的关系,Spring Cloud Alibaba Nacos Config从0.2.1版本后,可支持自定义Data Id的配置,通过它可以解决配置共享问题。

我们可以先创建一个配置datasource.yaml 用于配置数据库连接,如下图:

 在consumer中添加mysql驱动与jdbc访问数据库,从数据库中查询数据。

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.11</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
    <version>2.2.10.RELEASE</version>
</dependency>

从数据库中查询一条测试数据,返回给前端。

import dream.myself.consumer.api.ProducerFeign;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.sql.SQLException;
import java.util.List;

@RestController
@RequestMapping("consumer")
public class ConsumerController {
    private ProducerFeign producer;
    private final Environment environment;
    private JdbcTemplate template;


    public ConsumerController(ProducerFeign producer, Environment environment, JdbcTemplate template) {
        this.producer = producer;
        this.environment = environment;
        this.template = template;
    }

    @GetMapping("getMessage")
    public String consumerMessage() {
        return producer.consumer("ready");
    }

    @GetMapping("getPort")
    String consumerPort() throws SQLException {
        List<String> result = template.queryForList("SELECT canvas_name FROM graph", String.class);
        String port = environment.getProperty("server.port");
        return " Receive request server port:" + port + " data:" + result.get(0);
    }
}

bootstrap.yml中引入数据源配置需要使用extension-configs属性,配置如下:

spring:
  profiles:
    active: test
  application:
    name: consumer-server
  cloud:
    nacos:
      config:
        server-addr: 123.60.23.244:8848
        group: DEFAULT_GROUP
        namespace: 1e327238-6212-4179-9a28-4c186039485f
        file-extension: yaml
        extension-configs[0]:
          data-id: datasource.yaml
      discovery:
        server-addr: 123.60.23.244:8848
        group: DEFAULT_GROUP
        namespace: 1e327238-6212-4179-9a28-4c186039485f

这里的extension-configs[0]指定下标为0,因为自定义的配置可能存在多个,这里注入的是一个集合对象,需要从集合中获取数据。

这里extension-configs[n]中n越大,优先级越高,它既能解决一个应用多个配置,同时还能解决配置共享问题。

测试访问consumer服务:http://127.0.0.1:10098/consumer/getPort,查询到数据库中一条数据。

 2.3.4.配置刷新

配置自动刷新对程序来说非常重要,Nacos支持配置自动刷新,并且提供了多种刷新机制。 但是配置刷新对于共享配置无效:extension-configs[0]: data-id:  datasource.yml。

但是共享配置我们可以将其读取到程序中创建一个Bean对象,这个时候可以对Bean对象实时变更。

2.3.4.1.Environment自动刷新

spring-cloud-starter-alibaba-nacos-config支持配置的动态更新Environment能实时更新到最新的配置信息,启动Spring Boot应用测试的代码如下:

import com.alibaba.cloud.nacos.ribbon.NacosRule;
import com.netflix.loadbalancer.IRule;
import feign.Logger;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;

import java.util.concurrent.TimeUnit;

@SpringBootApplication
@EnableFeignClients(basePackages = "dream.myself.consumer.api")
public class ConsumerApplication {
    public static void main(String[] args) throws InterruptedException {
        ConfigurableApplicationContext applicationContext = SpringApplication.run(ConsumerApplication.class, args);
        while (true) {
            //当动态配置刷新时,会更新到 Enviroment中,因此这里每隔5秒中从Enviroment中获取配置
            String port = applicationContext.getEnvironment().getProperty("server.port");
            System.out.println("port:" + port);
            TimeUnit.SECONDS.sleep(5);
        }
    }

    @Bean
    public Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }

    @Bean
    @Scope(value = "prototype")
    public IRule loadBalanceRule() {
        return new NacosRule();
    }
}

修改nacostext配置的port端口号。

 从控制台得到了刷新的数据。

2.3.4.2.@Value刷新

程序中如果写了@Value注解,可以采用@RefreshScope实现刷新,只需要在指定类上添加该注解即可,如下代码:

import dream.myself.consumer.api.ProducerFeign;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.sql.SQLException;
import java.util.List;

@RestController
@RequestMapping("consumer")
@RefreshScope
public class ConsumerController {
    private ProducerFeign producer;
    private JdbcTemplate template;

    public ConsumerController(ProducerFeign producer, JdbcTemplate template) {
        this.producer = producer;
        this.template = template;
    }

    @Value(value = "${id}")
    private String id;

    @GetMapping("getMessage")
    public String consumerMessage() {
        return producer.consumer("ready");
    }

    @GetMapping("getPort")
    String consumerPort() throws SQLException {
        List<String> result = template.queryForList("SELECT canvas_name FROM graph", String.class);
        return " Receive request server id:" + id + " data:" + result.get(0);
    }
}

在配置文件中添加一个id值让consumer服务去获取这个值。

 访问http://127.0.0.1:10098/consumer/getPort,并更改配置文件中的id,可以发现修改前后获取的id值是不同的。

2.3.5.灰度发布

灰度发布一般在项目升级过程中会使用,要求项目升级到某些配置版本。

灰度配置指的是指定部分客户端IP进行新配置的下发,其余客户端配置保持不变,用以验证新配置对客户端的影响,保证配置的平稳发布。灰度配置是生产环境中一个比较重要的功能,对于保证生产环境的稳定性非常重要。在1.1.0中,Nacos支持了以IP为粒度的灰度配置,具体使用步骤如下:

在配置列表页面,点击某个配置的“编辑配置”按钮,勾选“Beta发布”,在文本框里填入要下发配置配置的IP,多个IP用逗号分隔,操作如下:

修改配置内容,点击“发布Beta”按钮,即可完成灰度配置的发布,点击“发布Beta”后,“发布Beta”按钮变灰,此时可以选择“停止Beta”或者“发布”。“停止Beta”表示取消停止灰度发布,当前灰度发布配置的IP列表和配置内容都会删除,页面回到正常发布的样式。“发布”表示将灰度配置在所有客户端生效,之前的配置也会被覆盖,同时页面回到正常发布的样式:

 这里指定的IP为需要灰度发布的版本所在的服务器IPBeta版本的配置只会在指定配置的IP服务器上生效,正常稳定的服务器不会受到Beta版本配置的影响。现在访问正式版本服务器与Beta版本的服务会读取到不同的配置信息。

3.0.Nacos集群

在生产环境Nacos一般都不是单节点存在,如果是单节点,很容易存在单点故障,因此生产环境一般都以集群形式存在。

3.1.集群架构节点

Nacos集群模式有多种,但其实无论哪种都是将3Nacos服务进行集群发布,而且必须采用数据共享模式进行配置信息共享,也就是要将数据存入到同一个数据库中,我们对每种集群模式进行说明:

1)直连模式

http://ip1:port/openAPI直连ip模式,机器挂则需要修改ip才可以使用。比如我现在有3Nacos,每次操作数据的时候,都需要使用IP端口的模式,这种模式效率极低,并且一旦节点故障无法识别,因此官方不推荐这种模式。

2)VIP模式

http://VIP:port/openAPI 挂载SLB模式(内网SLB,不可暴露到公网,以免带来安全风险),直连SLB即可,下面挂server真实ip,可读性不好。

3)域名模式

http://nacos.com:port/openAPI 域名+ SLB模式(内网SLB,不可暴露到公网,以免带来安全风险),可读性好,而且换ip方便,因此官方推荐该模式,该模式的结构图如下:

3.2.Nacos集群部署

我们搭建Nacos集群环境,集群环境配置如下:

节点

IP

端口

Nacos1

192.168.211.145

8848

Nacos2

192.168.211.146

8848

Nacos3

192.168.211.147

8848

1)服务下载

在https://github.com/alibaba/nacos/releases/下载需要的服务,当前使用的是1.4.1, 我们可以选择下载1.4.1版本,版本如下:

解压压缩包后,包结构如下:

 2)配置数据库

修改conf/application.properties 配置数据库,配置如下:

 3)集群配置

修改 conf/cluster.conf 配置集群:

192.168.211.145:8848

192.168.211.146:8848

192.168.211.147:8848

4)节点同步

将修改好的服务分别上传到 192.168.211.146 、 192.168.211.147 服务:

scp -r Nacos 192.168.211.146:/usr/local/server/alibaba/

scp -r Nacos 192.168.211.147:/usr/local/server/alibaba/

5)启动每个节点

进入到每个节点Nacos/bin目录下,执行启动:

sh startup.sh

访问任何一个单节点,信息如下:

3.3.客户端接入Nacos集群

客户端接入,不建议写多个节点的IP:Port,建议以域名的方式连接Nacos,因此需要配置Nacos域名,在 192.168.211.145节点中配置域名Nacos.hailtaxi.com,nginx配置如下:

#负载均衡池配置(轮询)

upstream hailtaxi-nacos{

server 192.168.211.145:8848;

server 192.168.211.146:8848;

server 192.168.211.147:8848;

}

server {

listen 80;

server_name Nacos.hailtaxi.com;

location / {

proxy_pass http://hailtaxi-nacos;

}

}

配置Nacos.hailtaxi.com 域名映射:

#修改hosts文件

vi /etc/hots

#添加如下映射关系

192.168.211.145 hailtaxinacos.com

保存Nginx配置,并启动Nginx,修改本地 C:\Windows\System32\drivers\hosts ,添加如下配置:

192.168.211.145 hailtaxinacos.com

访问 http://hailtaxinacos.com/Nacos,效果如下:

 项目中Nacos地址可以把多个地址写到一起,用逗号隔开,如下代码:

难拳
关注 关注
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Nacos简单入门
m0_50804764的博客
05-04 262
1. Nacos是什么? ​ Nacos(Dynamic Naming and Configuration Service)是阿里巴巴开源项目 ​ 他专注于服务发现和配置管理领域 致力于帮助您发现、配置和管理微服务。Nacos支持几乎所有的主流类型的“服务”的发现、配置和管理。 ​ 总之,Nacos=Spring Cloud注册中心 +Spring Cloud配置中心 2. 快速入门 安装Nacos 在官网下载nacos-server软件,本案例使用Windows环境。 下载解压到安装目录
nacos-server-2.2.3.zip
06-30
5. **README.md**:提供了Nacos的基本使用指南和快速入门信息。 6. **新建 文本文档 (2).txt**:这个文件可能是创建过程中的一个意外,通常压缩包不应该包含这样的临时文件。如果这不是必要的,你可以忽略它。 ...
Nacos 入门教程
老照片
11-08 326
Nacos 入门教程
Nacos入门
最新发布
abfwaaf的博客
09-07 2230
在上一个博客里讲到了使用eureka来进行,在这一节我们使用另外一个技术来代替eureka实现这个功能,它就是,比起eureka,它的功能更加的全面,可视化界面更加清爽,使用体验较高。
Nacos快速入门
java领域博主
11-16 461
1.Nacos服务搭建下载安装包解压在bin目录下运行指令:startup.cmd -m standalone2.Nacos服务注册或发现引入nacos.discovery依赖配置nacos地址spring.cloud.nacos.server-addr。
Nacos-入门
码说芯语的博客
03-16 785
1、Nacos-配置管理: 1.1什么是配置: 应用程序在启动和运行的时候往往需要读取一些配置信息,配置基本上伴随着应用程序的整个生命周期,比如:数据库连接参数、启动参数等。配置主要有以下几个特点: 配置是独立于程序的只读变量: 配置对于程序是只读的,程序通过读取配置来改变自己的行为,但是程序不应该去改变配置。 配置伴随应用的整个生命周期: 配置贯穿于应用的整个生命周期,应用在启动时通过配置来初始化,在运行时根据配置调整行为。比如:启动时需要读取服务的端口号、系统在运行过程中需要读取定时策略执行定时
nacos-server(2.0.3).zip
08-25
5. **文档**:可能会有相关的用户指南、API文档或者快速入门文档,帮助用户了解如何部署和使用Nacos。 6. **示例代码或配置**:Nacos有时会提供一些示例配置或客户端代码,帮助开发者快速理解和使用其服务注册与...
nacos-server-1.4.2.zip
10-21
- **README.md**:Nacos的快速入门指南,提供了简单启动和使用教程。 安装和启动Nacos服务器非常简单,只需执行bin目录下的启动脚本,并根据实际情况配置conf目录下的配置文件。在成功启动后,可以通过默认的8848...
nacos-server-1.1.4.zip
02-27
压缩包中的文档通常会包含Nacos的安装指南、快速入门、API参考、最佳实践等内容,帮助开发者快速理解和使用Nacos。这些文档是学习和部署Nacos的关键资源。 7. **性能优化** Nacos 1.1.4版本在性能方面做了优化,...
nacos-server-1.3.2.zip
10-15
8. **安装与运行**:对于Windows用户,Nacos 1.3.2提供了一个简单的安装包,用户可以通过解压“nacos-server-1.3.2.zip”并按照Readme.txt中的说明进行快速启动和配置,降低了入门难度。 总的来说,Nacos 1.3.2针对...
nacos入门
qq_56892136的博客
08-20 292
版本对照:https://github.com/alibaba/spring-cloud-alibaba/wiki/版本说明。配置startup.cmd以standalone启动。点击startup启动nacos 默认端口8848。startup.cmd 在bin目录下。修改此处配置为standalone。sql文件在conf文件夹下。数据库配置好以后解开。
微服务新秀之Nacos,看了就会,我说的!
Cbuc丶的博客
10-11 683
大家好,我是小菜,一个渴望在互联网行业做到蔡不菜的小菜。可柔可刚,点赞则柔,白嫖则刚! 死鬼~看完记得给我来个三连哦! 本文主要介绍 微服务中的Nacos 如有需要,可以参考 如有帮助,不忘 点赞 ❥ 微信公众号已开启,小菜良记,没关注的同学们记得关注哦! 在讲 Nacos 之前,我们需要了解什么是 NacosNacos 是阿里的一个开源产品,它是针对微服务架构中的 服务发现、配置管理、服务治理 的综合性解决方案。 官网给出的回答: Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供
Spring Cloud快速入门:案例解读Nacos与Dubbo
资源摘要信息:"SpringCloud入门案例 nacos dubbo" 1. Spring Cloud概念及入门 Spring Cloud是一系列框架的集合,它利用Spring Boot的开发便利性简化了分布式系统(服务发现、配置管理、消息总线、负载均衡、断路器...
写文章

热门文章

  • Microsoft Visual Studio C++2022 Windows 11 SDK环境 8996
  • Microsoft Visual Studio C++2017+Windows 11 SDK环境 7422
  • MinGW Make CMake安装使用 —Windows 11系统 6132
  • nacos--简单入门 2079
  • Windows环境运行Linux命令——Cygwin安装 1931

分类专栏

  • Visual Studio 2篇
  • Windows 11 SDK 3篇
  • CLion 2篇
  • OpenJDK 3篇
  • Cygwin 2篇
  • make 1篇
  • CMake 1篇
  • MinGW 1篇

最新评论

  • 编译OpenJDK12——Windows 11系统

    sslnwf: 这个错大家有遇到么 /out:conftest.exe conftest.obj LINK : fatal error LNK1104: cannot open file 'kernel32.lib' configure:38513: $? = 2 configure:38554: result: no configure: failed program was: | /* confdefs.h */ | #define PACKAGE_NAME "OpenJDK" | #define PACKAGE_TARNAME "openjdk" | #define PACKAGE_VERSION "openjdk" | #define PACKAGE_STRING "OpenJDK openjdk" | #define PACKAGE_BUGREPORT "build-dev@openjdk.java.net" | #define PACKAGE_URL "http://openjdk.java.net" | /* end confdefs.h. */ | | int | main (void) | { | | ; | return 0; | } configure:38559: error: in '/cygdrive/c/jdk12/jdk12-06222165c35f': configure:38561: error: C compiler cannot create executables See 'config.log' for more details

  • Microsoft Visual Studio C++2017+Windows 11 SDK环境

    sslnwf: SDK 要删除注册列表中相关安装路径配置怎么删

  • Microsoft Visual Studio C++2022 Windows 11 SDK环境

    Jason_from_China: 哈哈表情包 还是膜拜一下

  • Microsoft Visual Studio C++2022 Windows 11 SDK环境

    难拳: 表情包我其实也是一知半解,我工作中是个写Java的

  • Microsoft Visual Studio C++2022 Windows 11 SDK环境

    Jason_from_China: 对于sdk那一条,我很认同,有时候头文件不能解析大部分可能是sdk的问题,不是找不到文件的问题

大家在看

  • Docker安装ocserv教程(效果极佳) 1
  • Python酷库之旅-第三方库Pandas(160) 593
  • Golang | Leetcode Golang题解之第500题键盘行 141
  • 【数据结构与算法】Java中的基本数据结构:数组、链表、树、图、散列表等。
  • C++ -string -常见用法3 1279

最新文章

  • 有向无环图-Java版
  • TypeScript官方文档手抄版一镜到底(下篇)
  • TypeScript官方文档手抄版一镜到底(中篇)
2024年4篇
2023年25篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

玻璃钢生产厂家北京创意玻璃钢雕塑辽宁玻璃钢造型雕塑公司花朵校园玻璃钢景观雕塑定做青海景区玻璃钢雕塑定做广州玻璃钢卡通雕塑定制玻璃钢无头的天使雕塑赏析商场美陈秋季方案北京佛像玻璃钢雕塑图片户外玻璃钢雕塑联系方式玻璃钢和水泥雕塑哪个好广东玻璃钢卡通雕塑报价天津玻璃钢雕塑效果图粤港澳商场灯光美陈石龙玻璃钢雕塑设计创意商场门头美陈佛山玻璃钢人物雕塑出售玻璃钢雕塑好学吗圣诞节商场美陈分享合肥玻璃钢雕塑价格太湖石校园玻璃钢景观雕塑厂新开业商场美陈通道商场美陈哪里买玻璃钢雕塑公司艺鑫实力厂家合肥玻璃钢雕塑订做价格如何计算大城玻璃钢花盆花器武威玻璃钢雕塑厂广州装饰商场美陈广州做玻璃钢雕塑陆丰玻璃钢南瓜屋雕塑荷叶玻璃钢卡通雕塑设计香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化