关于nacos:CICDNacos双云双活及Nacos数据横向同步原理

背景2022年,37手游实现了业务双云架构的部署2023年,通过故障注入,确认任一单云故障下,都能够逃生到另外一朵云此刻,尽管业务具备了双云双活能力,但也发现了一些边缘组件不具备,其中cicd依赖nacos就是其中之一 利用场景?那么咱们在nacos的应用场景是什么呢?其实次要用在CICD编译这个环节 面临的问题一旦腾讯云整体故障,那么咱们的cicd平台就无奈应用,即便业务逃生到另外一朵云,无论是利用公布、重启,都将受到影响,如下构图,cicd单云 于是,咱们做了cicd双云v1版本后期没有关注度到nacos的强依赖,在理论应用上,任然是单点(nacos单云) cicd v2版本一开始,将nacos当做无状态服务,间接双云部署,而后烟囱式拜访 cicd v2版本存在的问题:批改配置后,配置数据不统一在理论的故障注入演练中,咱们发现,在一朵云的nacos批改了配置后,尽管它们都是用的雷同的数据库,无奈同步到另外一朵云,如下架构 nacos双云不能同步的起因Nacos利用会将数据库的配置数据缓存在本地内存,而后每6小时去全量dump更新一次,所以比方咱们从腾讯云nacos集群入口批改配置,批改了nacos数据库,然而阿里云nacos容器集群因为不晓得数据库配置已被批改,因而就导致,腾讯云是新批改的配置,阿里云还是旧的缓存数据,须要6小时后才会同步更新 那么腾讯云nacos容器集群内的所有Pod为什么是都是新的呢nacos集群内,是有一个横向告诉机制的,要搞明确这个问题,要先搞清楚,nacos集群运作的以下几个原理 nacos数据一致性原理:raft算法1.raft算法选举Leader过程1.1 如一个nacos集群有3个节点,节点一开始启动时都是Follow跟随者状态,会进入一个选举超时工夫,期待Leader或者Candidate发送心跳包1.2 如果期待超时,如第一个节点期待超时就会变为Candidate候选者,向其余节点发动投票选举本人为Leader1.3 其余Follow节点收到Candidate发动的投票批准后,第一个节点节点成为Leader 2.raft算法的选举超时机制在raft算法中,选举超时工夫(Election Timeout)是用来定义Follower在主动转化为Candidate前的等待时间 默认的选举超时工夫是在固定值(1000ms)的根底上,减少150ms到300ms随机值的值。这个工夫设置是为了避免集群中的所有节点同时发动投票,导致选举无奈进行 例如,如果集群由3个节点组成,每个节点的选举超时工夫别离为168ms、210ms和200ms。在这个过程中,最先达到选举超时工夫的节点会最先成为Candidate,并向其余两个节点发动投票申请。如果其余节点收到投票申请并且返回了投票,那么最先成为Candidate的节点会因为取得了过半数节点的投票而从Candidate状态转变为Leader状态 每个节点的选举超时工夫是随机调配的,这个随机工夫范畴是150ms到300ms,能够无效地避免所有节点同时发动投票。如果一个节点在选举超时工夫内没有收到来自Leader的心跳音讯,它会从Follower状态主动转化为Candidate状态,并发动选举 nacos数据一致性原理:读写申请nacos集群为了保证数据一致性,无论读写申请都会通过Leader节点,架构如下 如上图,第一步:客户端申请nacos的入口LB,随机申请到Follower2,第二步:Follower2会将读写申请都转给Leader节点,第三步:如果是一个读申请,那么Leader节点会将读申请解决后再返回给Follower2,第四步:再由Follower2节点返回给客户端数据 通过下面4个步骤,能够保障所有的写申请都由Leader节点解决,从而保证数据的一致性 nacos数据一致性原理:Leader节点故障期间如果Leader节点挂掉了,那么集群会进行新的选举产生新的Leader,之前挂掉的Leader重启后作为Follower退出集群,并同步新选举的Leader上的数据。这样能够保障即便在Leader节点故障的状况下,也能保证数据的可靠性和一致性 那么Leader故障或者失联期间,Follower是否单独解决呢?答案是必定的,见架构图如上图,如果Leader故障,且又没有新的的Leader产生时,Follower接到申请后,还是依照原门路申请Leader,但此时是不通的,所以这个中央Follower就有个超时机制,毫秒级,如果拿不到Leader的返回,就将缓存的数据返回给客户端 nacos数据一致性原理:节点数据同步Nacos通过发送心跳的形式来放弃Leader和Follower之间的数据同步,Leader节点会定期向每个Follower节点发送心跳,这个心跳的默认工夫是30秒,也就是30秒同步一次,并带上所有的key和key对应的工夫戳。Follower节点收到心跳后,会查看其中的key是否存在或者工夫戳是否较小,如果不满足条件,则会向Leader发送申请拿取最新的数据。这样能够保障各个节点数据的实时性和一致性 基于Nacos的原理,37手游的nacos双云双活设计已知,Nacos能够在集群节点内,Follower节点都会从Leader节点同步数据,但问题是不同集群间,Nacos是无奈做到同步的,也就是说,Nacos是有肯定状态的,并非齐全无状态,看看新旧架构比照 老的架构做法从上图能够看到,老的架构因为是2个集群,尽管他们都读取了同一个数据库,但当任一一朵云的Nacos有写操作,都不会及时同步到另外一朵云,此时两朵云读取的配置信息是有差别的,起因是因为nacos有一层缓存存在,这个缓存工夫默认6小时,每隔6小时,Leader会全量dump数据库的信息到本地缓存 新的架构做法如上图,将2集群合并成一个集群,双云之间通过专线买通网络,拜访和读取还是烟囱式,只是数据库还是单边,这样做的益处是,在任一一朵云批改数据,都会将腾讯云和阿里云所有节点都同步到,因为他们是同一个集群,应用原生的nacos集群同步形式 总结在nacos集群的应用上,咱们的业务场景次要还是cicd公布时须要读取配置,是一个读多写少的场景,基本上能够认为,只有读胜利,咱们的cicd就能残缺运行,因而在设计上,咱们优先思考读场景的可用性,无论哪一朵云故障,咱们的cicd零碎都能失常运行,因为在个别故障状况下,咱们也很少会写nacos 因而从架构上看,在腾讯云故障下,写是无奈在阿里云进行的,因为阿里云只有2个节点,无奈投票成为Leader,也就无奈实现写入,因而失常状况下,是读写nacos双云双活,极其状况下,阿里云故障,腾讯云读写nacos无异样,腾讯云故障,阿里云能够读,但无奈写

September 21, 2023 · 1 min · jiezi

关于nacos:Nacos-核心原理解读高性能微服务系统实战

download:Nacos 外围原理解读+高性能微服务零碎实战《模仿人生4》(The Sims 4)是一款由Maxis和The Sims Studio开发,由Electronic Arts发行的模仿人生游戏。它被宽泛认为是模仿人生系列中最好玩的一部分。本文将向您介绍TS4的入门常识。 TS4的基本概念在TS4中,你能够创立本人的虚拟世界并管制其中的角色。每个角色都有本人的特点、情感和属性。你须要治理他们的日常事务,例如吃饭、睡觉、工作和社交活动等,以确保他们有一个高兴、衰弱、富有成效的生存。 为了开始玩TS4,你须要购买游戏并下载安装。当你进入游戏时,你能够抉择创立新的家庭或加载现有的家庭。在初始阶段,你须要创立本人的角色并为他们抉择外貌、性情和技能。而后,你须要为他们建造屋宇或购买曾经建好的屋宇,并为他们购买必要的设施、家具和装饰品。 游戏中的操作在游戏中,你能够应用鼠标和键盘来管制你的角色。通过单击菜单按钮,你能够查看可用的操作选项。例如,你能够抉择让你的角色去吃饭、睡觉、工作或社交活动等。你还能够应用鼠标拖动和调整物品的地位和大小。此外,你能够应用游戏中的相机性能来浏览你的家庭和城市。 在TS4中,每个角色都有本人的技能和事业。这些技能能够通过一直的练习和学习来进步。当你的角色把握了某项特定技能时,他们将有机会取得更好的工作和更高的支出。 游戏中的社交互动与其余角色进行社交互动是TS4中的重要局部。通过与其余角色互动,你能够建设深厚的关系,并增进彼此之间的友情。你能够通过向其余角色打招呼、聊天、分享感情和密切接触等形式来建立联系。此外,你还能够邀请其余角色来加入你的派对和社交活动。 TS4的扩大包除了根本游戏之外,还有许多扩大包可用于TS4,这些扩大包能够减少新的游戏选项和性能。例如,你能够购买“城市生存”扩大包,以减少城市环境和城市居民的元素。或者,你能够购买“节令”扩大包,以减少天气变动和节令循环的元素。 论断在TS4中,你能够创立本人的虚拟世界,并管制其中的角色。通过治理他们的日常事务并与其余角色进行社交互动,你能够建设深厚的关系并取得更好的工作和更高的支出。如果你心愿更多地理解TS4,能够思考购买扩大包或查看游戏手册。

May 19, 2023 · 1 min · jiezi

关于nacos:Nacos-配置管理最佳实践

Nacos 简介Nacos 是一个更易于构建云原生利用的微服务根底平台,外围蕴含动静服务发现,配置管理,服务治理平台。 残缺内容请点击下方链接查看: https://developer.aliyun.com/article/1155681?utm_content=g_10... 版权申明:本文内容由阿里云实名注册用户自发奉献,版权归原作者所有,阿里云开发者社区不领有其著作权,亦不承当相应法律责任。具体规定请查看《阿里云开发者社区用户服务协定》和《阿里云开发者社区知识产权爱护指引》。如果您发现本社区中有涉嫌剽窃的内容,填写侵权投诉表单进行举报,一经查实,本社区将立即删除涉嫌侵权内容。

May 18, 2023 · 1 min · jiezi

关于nacos:完结Nacos-核心原理解读高性能微服务系统实战无密

微服务架构曾经成为越来越多企业的首选计划,然而在理论利用中,微服务的数量往往会十分宏大。因而,服务发现和配置管理变得尤为要害。Nacos就是一个十分好的解决方案。本文将具体介绍 Nacos+微服务 的应用办法。download:https://www.97yrbl.com/t-1655.html 服务注册与发现在微服务架构中,每个服务都能够独立地部署在不同的机器上。因而,咱们须要一种机制来主动地将服务注册到注册核心,并在须要时进行服务发现。Nacos能够帮忙咱们实现这些性能。 首先,咱们能够通过Nacos提供的API将服务注册到注册核心。例如: curl -X POST 'http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=my-service&ip=192.168.0.100&port=8080'其中,serviceName是服务名,ip是服务所在的IP地址,port是服务监听的端口号。 而后,咱们能够通过Nacos提供的API来实现服务发现。例如: curl -X GET 'http://127.0.0.1:8848/nacos/v1/ns/instances?serviceName=my-service'这个API会返回所有注册了 my-service 这个服务的实例列表,包含它们的IP地址、端口号等信息。咱们能够依据这些信息来调用服务。 对立配置管理在微服务架构中,服务的配置通常须要依据不同的环境进行调整。应用Nacos,咱们能够将所有的配置文件都放在一个中央,并能够随时进行批改。当某个服务须要更新配置时,它能够从Nacos中获取最新的配置信息。 首先,咱们须要在Nacos中创立一个配置集和一个配置项。例如,咱们能够创立一个名为 my-config 的配置集,并增加一个名为 timeout 的配置项: curl -X POST 'http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=my-config&group=my-group&content=timeout=5000'其中,dataId是配置项的ID,group是配置项所属的组。content是配置项的具体内容。 而后,咱们能够通过Nacos提供的API来获取配置信息。例如: curl -X GET 'http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=my-config&group=my-group'这个API会返回 my-config 这个配置集中的所有配置项。 健康检查Nacos还提供了健康检查性能。咱们能够通过Nacos来监控每个微服务的状态,并及时进行解决。如果某个服务呈现故障或者异样,咱们能够通过Nacos来实现主动切换到备用服务,从而确保整个零碎的稳定性和可用性。 首先,咱们须要在Nacos中创立一个健康检查配置。例如: curl -X POST 'http://127.0.0.1:8848/nacos/v1/ns/health/checker?serviceName=my-service&groupName=my-其中,serviceName是服务名,groupName是服务所属的组。healthCheckerType是健康检查类型,这里抉择了HTTP形式。healthCheckerProperties是健康检查相干的属性,例如HTTP申请门路。 而后,咱们能够通过Nacos提供的API来获取服务的衰弱状态。例如: curl -X GET 'http://127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=my-service&groupName=my-group&healthyOnly=true'这个API会返回 my-service 这个服务中所有衰弱的实例列表。 综上所述,Nacos是一个十分好的工具,能够帮忙咱们更加不便地构建和治理微服务架构。无论是对于开发人员还是运维人员来说,都是一个不可或缺的利器。

May 13, 2023 · 1 min · jiezi

关于nacos:Nacos-核心原理解读高性能微服务系统实战不若鼠横行

download:Nacos 外围原理解读+高性能微服务零碎实战运维部署:如何疾速无效地治理软件系统关键字:运维、部署、自动化、监控、平安古代软件系统由多个组件形成,这些组件须要一直地进行更新和保护。为了保证系统的稳定性和可靠性,咱们须要一个高效的运维部署流程。本文将介绍如何疾速无效地治理软件系统,进步运维效率和品质。 首先,自动化部署是进步运维效率和品质的要害。通过应用自动化工具和脚本,能够轻松地进行软件部署和配置,缩小手动操作带来的谬误和提早。同时,自动化部署还可能实现疾速回滚和版本控制,保证系统的稳定性和可靠性。 其次,监控是保障系统运行的重要伎俩。通过对系统各个组件的监控和告警,能够及时发现并解决问题,防止因故障而导致的业务中断。同时,监控数据也能够作为优化和改善零碎的根据,进步零碎的性能和效率。 另外,平安是运维部署的重要方面。在进行软件部署和保护时,须要留神爱护零碎的安全性,例如加密敏感信息、限度拜访权限等。同时,也须要定期进行破绽扫描和修复,确保零碎不受攻打和毁坏。 最初,团队合作和常识治理也是运维部署的重要方面。通过建设良好的团队合作机制和常识共享平台,能够增强团队成员之间的交换和单干,进步运维效率和品质。 综上所述,运维部署是软件系统治理中不可或缺的一环。通过自动化部署、监控、平安爱护和团队合作等伎俩,能够进步运维效率和品质,实现疾速无效地治理软件系统。

May 13, 2023 · 1 min · jiezi

关于nacos:nacos初探

我的项目和文档github国内镜像站https://kgithub.com/nacos我的项目地址https://kgithub.com/alibaba/nacos/releasesnacos-docker我的项目地址https://kgithub.com/nacos-group/nacos-docker/blob/master/READ...nacos中文文档https://nacos.io/zh-cn/docs/quick-start.html镜像和部署最新的docker镜像(nacos服务端)docker pull nacos/nacos-server:v2.2.0数据库初始化脚本下载https://raw.kgithub.com/alibaba/nacos/develop/distribution/co...将数据库初始化脚本mysql-schema.sql搁置到docker-compose.yml文件的同一个目录nacos docker-compose配置version: "3.8"services: nacos-server: image: nacos/nacos-server:v2.2.0 environment: # 系统启动形式: 集群/单机,cluster/standalone 默认 cluster MODE: standalone # 数据库类型 SPRING_DATASOURCE_PLATFORM: mysql # mysql地址:能够间接援用docker-compose内的服务名称,也能够援用主机ip MYSQL_SERVICE_HOST: nacos-mysql # 如果mysql地址用的是服务名,这里就用容器端口;如果mysql地址用的是主机ip,那么就用主机映射端口 MYSQL_SERVICE_PORT: "3306" MYSQL_SERVICE_DB_NAME: nacos_devtest MYSQL_SERVICE_USER: root MYSQL_SERVICE_PASSWORD: root MYSQL_SERVICE_DB_PARAM: "characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true" # 内存参数 JVM_XMS: "1g" JVM_XMX: "1g" # 是否开启近程调试 NACOS_DEBUG: "n" volumes: - "./logs:/home/nacos/logs" ports: # 主端口,web端口 - "8848:8848" # grpc端口,应该等于 映射主端口 + 1000 (Nacos2.0的gRPC端口均通过主端口的偏移量计算产生,因而端口转发也须要满足该偏移量) - "9848:9848" # grpc端口,应该等于 映射主端口 + 1001 - "9849:9849" depends_on: nacos-mysql: condition: service_healthy# restart: on-failure nacos-mysql: image: mysql:5.7 environment: # root用户明码 MYSQL_ROOT_PASSWORD: root # 运行时须要创立的数据库名称 MYSQL_DATABASE: nacos_devtest # 运行时须要创立的用户名 MYSQL_USER: nacos # 运行时须要创立的用户,对应的明码 MYSQL_PASSWORD: nacos volumes: - "./mysql-schema.sql:/docker-entrypoint-initdb.d/nacos-mysql.sql" - "nacos-mysql_data:/var/lib/mysql" ports: - "8806:3306" command: - "--character-set-server=utf8mb4" - "--collation-server=utf8mb4_unicode_ci" healthcheck: test: [ "CMD", "mysqladmin", "-uroot", "-proot" ,"ping", "-h", "localhost" ] interval: 5s timeout: 10s retries: 10volumes: nacos-mysql_data:目录构造如启动/进行命令docker-compose up &docker-compose stop ...

March 13, 2023 · 1 min · jiezi

关于nacos:Higress-Nacos-微服务网关最佳实践

在去年11月的云栖大会上,咱们开源了云原生网关 Higress,时隔 2 月,Higress 的 Github 我的项目曾经播种了 700+ star,以及大量社区小伙伴的关注。在社区的交换中咱们发现有不少微服务开发者在应用如 Spring Cloud Gateway/Zuul 等微服务网关对接 Nacos 注册核心实现微服务的路由,并且心愿理解迁徙到 Higress 网关能带来哪些益处。 Higress 的 Github 我的项目:https://github.com/alibaba/hi...本文将介绍 Higress 组合 Nacos 作为微服务网关能力,并介绍微服务网关倒退的两个趋势,为网关的选型指明路线: 趋势一:对立 API 规范,向云原生微服务架构演进趋势二:合并平安&流量网关,向 DevSecOps 演进Higress:Nacos 的最佳拍档 Higress 和 Nacos 其实是师出同门——阿里中间件团队。在 Higress 撑持阿里外部业务的阶段,Higress 就曾经搭配 Nacos 作为微服务网关应用,凭借高性能撑持了双十一的洪峰流量;到了云产品商业化阶段,Higress 和 Nacos 持续基于阿里云 MSE(Microservices Engine)产品,严密合作演进产品性能;Higress 开源之后,如果想要自建微服务网关,抉择 Higress 配合 Nacos 应用,具备以下劣势: 比照 Spring Cloud Gateway/Zuul 等传统 Java 微服务网关性能高出 2-4 倍,能够显著升高资源老本作为云原生网关,实现了 Ingress/Gateway API 规范,兼容 Nginx Ingress 大部分注解,反对业务渐进式向基于 K8s 的微服务架构演进与 Dubbo/OpenSergo/Sentinel 等开源微服务生态深度整合,提供最佳实际Higress 的装置部署请点击原文参考 Higress 官网文档,这里默认曾经装置好 Higress,搭配 Nacos 应用的具体形式如下: ...

February 15, 2023 · 2 min · jiezi

关于nacos:Nacos-配置管理最佳实践

Nacos 简介 Nacos 是一个更易于构建云原生利用的微服务根底平台,外围蕴含动静服务发现,配置管理,服务治理平台。 配置管理是 Nacos 的外围性能,它提供了运行期不重启利用的状况下动静批改配置值的性能。 Nacos 配置核心倒退历程 Nacos 配置核心是从阿里团体内配置核心 Diamond 孵化而来,其整体倒退分为三个阶段: 1.阿里团体外部孵化期 nacos 配置核心诞生于阿里巴巴团体外部的配置核心 Diamond,后期次要服务于团体外部对动静配置的需要。 2.开源&商业化摸索尝试 团体 Diamond 经验了从开源再到闭源的过程,公布了商业化产品 ACM,并在 2018 年以 Nacos 配置核心为载体再次开源,期间对配置核心的开源及商业化进行了摸索。 3.三位一体交融倒退 明确三位一体倒退策略,以开源 Nacos 为内核,插件化反对团体 Diamond &商业化 MSE 定制的配置核心,三位一体交融倒退。 开源:以开源 Nacos 2.0 为内核,重构通信协议,性能扩展性晋升10倍,反对 10w 级实例规模,晋升开放性,联结开源微服务生态独特倒退。 商业化:反对 Nacos2.0 和专业版,目前 20% 用户降级到 Nacos2.0,并且反对配置鉴权和加密能力,推送轨迹等高级性能。 团体:关注性能和高可用能力,反对大促 1 小时建站,10 分钟反对响应;实现 Diamond Over Nacos2.0 架构演进,扩展性晋升 1 倍,反对 500w 实例规模。 利用场景&双十一实际Nacos 配置管理利用场景 配置核心在业务域,根底技术域都有着宽泛的利用,包含业务利用的开关,微服务生态的服务路由及元数据,高可用生态的预案,切流规定及降级开关等,前端生态的各类文案布告,数据库生态的外围配置参数,动静切库等配置。 在每年阿里团体的双十一大促中,配置核心也是一个不可或缺的根底组件,包含后期热点商品推送,大促气氛流动标调整,大促期间数据库主备切换开关,外围性能降级,各类名单调整,预案限流调整,各种根底中间件的外围参数动静,大促完结后各类预案的复原,大促态到日常态的状态切换,都是配置核心所反对的场景。 配置核心应用指引1.配置核心原理 业务利用:nacos 的应用方,通过 nacos-client 实现配置的公布,查问,监听回调的等根底操作。负载平衡 SLB:与后端的 nacos 服务节点进行交互的地址,在用户自建或者调试的场景下,也能够采纳直连 IP 或者地址服务器 endpoint 的模式。Nacos Server:nacos 服务端存储以后集群全量配置的内存和磁盘缓存,集群节点之间进行程度告诉配置变更事件,和后端数据库进行对账保证数据一致性。Nacos 控制台:治理控制台,能够进行配置查看,配置公布,监听查问等运维性能。商业化 Nacos 反对推送轨迹,监控,事件核心等高级性能。数据库:配置长久化存储的数据库,个别是主备库架构进行容灾。用户在接入 nacos 次要有两种模式,一种是通过原生 nacos-client 的 ConfigService 组件的根底 API 接入,第二种是通过 Spring 框架或者其余相似框架组件接入,包含 SpringCloud 和 SpringBoot 等。 ...

February 14, 2023 · 2 min · jiezi

关于nacos:Nacos-中的配置文件如何实现加密传输

小伙伴们晓得,Spring Cloud Config 很早就提供了配置文件的加解密性能,并且反对对称加密和非对称加密两种不同的模式。Nacos 作为分布式配置核心+服务注册核心的合体,在配置文件加密这块始终差点意思,不过好在,如果你应用的 Nacos 版本大于 2.0.4 这个版本,那么当初也能够通过插件的形式来实现配置文件加密了。 1. 配置文件加密松哥在之前的微服务视频中讲过,Spring Cloud Config 的对称加密和非对称加密,加密后的文件格式相似上面这样: name={cipher}密文password={cipher}密文能够看到,在 Spring Cloud Config 中,对配置文件的加密是针对字段一个一个加密的。 而 Nacos 中的加密,则是对整个配置文件的内容进行加密,这点和 Spring Cloud Config 不同。 Nacos 中是通过 SPI 的机制形象出加密和解密的操作,Nacos 默认提供 AES 对称加密的实现,不过用户也能够自定义加解密的实现形式。 在 Nacos 服务端启动的时候就会加载所有依赖的加解密算法,而后通过公布配置的 dataId 的前缀来进行匹配是否须要加解密和应用的加解密算法。 客户端公布的配置会在客户端通过 filter 实现加解密,也就是配置在传输过程中都是密文的,而控制台公布的配置会在服务端进行解决。 换言之,用了 Nacos 的配置文件加密插件之后,咱们在 Nacos 治理页面上配置的配置文件,将会以加密的密文模式存储在数据库中,也会以密文的模式传输到客户端,而后在客户端主动实现解密操作。大抵上就是这样一个过程。接下来咱们就来看看具体的用法。 2. 实际首先咱们须要下载 nacos 源码进行编译,编译实现之后,须要将之装置到本地 Maven 仓库(因为编译加密插件须要用到 Nacos)。 首先 clone nacos 源码,如下: git clone https://github.com/alibaba/nacos.git下载之后,集体倡议用 IDEA 去编译,操作不便一些(因为后续还有其余操作)。 所以咱们先用 IDEA 关上我的项目,确认我的项目所需依赖均已下载结束,而后点击 install 按钮,将我的项目编译装置到本地仓库: 接下来 clone 配置文件加解密的插件,如下: ...

November 28, 2022 · 1 min · jiezi

关于nacos:Nacos设置配置数据源到Mysql

1. 首先要配置数据库源,个别都用MySQL:关上conf文件夹下的application.properties,批改数据库信息: 2,再应用MySQL创立数据库,数据库名为nacos(上图显示),可更改。创立好数据库后,执行conf文件夹下mysql-schema.sql文件即可。 3,重启Nacos杀掉Nacos: sudo lsof -i:8848kill 指定PID重启: 启动胜利:

November 24, 2022 · 1 min · jiezi

关于nacos:ubuntu部署Nacos

1,下载Nacos,并放到服务器 2,进度到Nacos所在目录并解压 3,进入到nacos目录并启动 http://192.168.xxx.xxx:8848/nacos/index.html默认登陆账号和明码账号:nacos明码:nacos4,进入我的项目配置信息(此处为spring-boot我的项目,文档和代码示例能够再次看:https://nacos.io/zh-cn/docs/q...) 5,测试能够失常应用:@RestController@NacosPropertySource(dataId = "test",autoRefreshed = true)public class test1 { @NacosValue(value = "${url:kason}", autoRefreshed = true) private String url = ""; @NacosValue(value = "${user:kason}", autoRefreshed = true) private String user = ""; @NacosValue(value = "${pass:pass}", autoRefreshed = true) private String pass = ""; @GetMapping(value="/testNacos") public Map<String,String> testNacos() { Map<String, String> map = new HashMap<>(); map.put("url", url); map.put("user", user); map.put("pass", pass); return map; } @GetMapping(value="/test01") public String test01() { return "how are you?"; } } ...

November 1, 2022 · 1 min · jiezi

关于nacos:注册中心高并发场景微服务实战九

你好,我是程序员Alan. 我在《文言服务治理—高并发场景微服务实战(八)》中,简略介绍了微服务常见组件性能,从本篇开始我将进一步解说各个组件的内容和利用。 服务调用的问题在《需要剖析—高并发常见微服务实战(二)》剖析业务需要时,其中有个简略的性能点:订票服务能够申请不同的航空公司查问机票信息,订购指定航空公司航班机票。这里就波及到两个或多个服务间的调用问题。 服务调用能够简略的分为单实例状况和多实例状况。 单实例状况能够采纳 IP + Port + 接口的模式,采纳点对点的HTTP间接调用。这种状况有个显著的毛病就是如果服务增多,将会造成蜘蛛网的模式,十分不利于开发保护。 多实例状况在理论生产场景中,咱们通常会采纳多实例集群部署,来应答服务的压力。但多实例部署后,间接面临一个问题,即调用方如何通晓调用哪个实例,当实例运行失败后,如何转移到别的实例下来解决申请?此时咱们可能会抉择Nginx负载平衡,但往往是动态的,在服务不可用时,如何动静的更新负载平衡列表,保障调用者的失常调用呢? 面对以上两种状况,咱们须要将所有的服务对立的、动静的治理起来,此时注册核心就应运而生。 服务注册核心服务注册核心作分布式服务框架的外围模块,要实现的性能是服务的注册、订 阅、登记、告诉 。 所有的服务都与注册核心产生连贯,由注册核心对立配置管理,不再由实例本身间接调用。服务治理过程大抵过程如下图所示: 从图中,能够看到一个残缺的,服务注册和发现的过程: 1.服务提供者启动时,将服务提供者的信息被动提交到服务注册核心进行服务注册。 2.服务调用者启动时,将服务提供者信息从注册核心下载到调用者本地,调用者从本地的 服务提供者列表中,基于某种负载平衡策略抉择一台服务实例发动近程调用,这是一个点到点调用的形式。 3.服务注册核心可能感知服务提供者某个实例下线,同时将该实例服务提供者信息从注册核心革除,并告诉服务调用者集群中的每一个实例,告知服务调用者不再调用本实例,免得调用失败。 从这个过程中能够看出,有了注册核心之后,服务节点的减少和缩小对于客户端就是通明的。这样,除了能够实现不重启客户端,就能动静地变更服务节点以外,还能够实现优雅敞开的性能。 Nacos利用目前业界有很多可供你来抉择的注册核心组件,例如 ZooKeeper,阿里的微服务注册核心 Nacos,Spring Cloud 的 Eureka 等等。 我集体比拟罕用的组件是Nacos,它的定位是一个更易于构建云原生利用的动静服务发现、配置管理和服务治理平台。 装置NacosNacos官网地址:https://nacos.io/en-us/,本文采纳Nacos 1.1.4 版本。 下载后解压,应用对应命令启动。 下载后解压,应用对应命令启动。 startup.cmd -m standalone (standalone代表着单机模式运行,非集群模式) 启动日志如下: 启动胜利后,关上http://127.0.0.1:8848/nacos,输出默认的用户名 nacos、明码 nacos,就能够看到如下界面。 能够看到Nacos左侧菜单栏看到Nacos提供的次要性能,本次咱们只用到Nacos服务治理性能,其余性能前面章节再讲。 服务中利用Nacos本文演示如何在Sping Boot我的项目中启动Nacos的服务发现性能。 1.增加依赖 <dependency> <groupId>com.alibaba.boot</groupId> <artifactId>nacos-discovery-spring-boot-starter</artifactId> <version>0.2.7</version></dependency>留神:版本 0.2.x.RELEASE 对应的是 Spring Boot 2.x 版本,版本 0.1.x.RELEASE 对应的是 Spring Boot 1.x 版本。 \2. 在application.yml中配置Nacos server的地址 nacos: discovery: server-addr: 127.0.0.1:8848\3. 应用 @NacosInjected 注入 Nacos 的 NamingServerice 实例 ...

November 1, 2022 · 1 min · jiezi

关于nacos:聊聊使用RefreshScope与nacos2整合踩到的坑

前言本文的素材来源于敌人整合nacos2作为配置核心进行动静刷新时,踩到的坑。他过后遇到的问题,如下截图因为那段时间比较忙,于是我在没看敌人我的项目代码的根底上,就找个了看似解决方案的答案,扔了过来前面敌人加了这个配置,问题果然没有解决。前面就抽了一点工夫,要了他的我的项目代码来看下。 代码示例因为他这个我的项目次要是他自学nacos的我的项目,也没波及啥敏感信息。本文就间接拿他的我的项目示例演示 1、我的项目pom依赖<properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <java.version>1.8</java.version> <spring-boot.version>2.3.12.RELEASE</spring-boot.version> <spring-cloud.version>Hoxton.SR12</spring-cloud.version> <spring-cloud-alibaba.version>2.2.8.RELEASE</spring-cloud-alibaba.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${spring-cloud-alibaba.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> </dependencies>注: nacos服务端版本为2.1.1 2、nacos配置核心地址,配置在bootstrap.yml外面spring: cloud: nacos: server-addr: localhost:88483、我的项目的根本信息配置在application.yml外面#spring: application: name: nacos-configserver: port: 80304、编写一个须要动静刷新获取值的controller@RestController@RequestMapping("/config")@RefreshScopepublic class ConfigController { @Value("${user.userName:123}") private String userName; @RequestMapping("/get") private String get(){ return userName; }}5、业务我的项目在nacos服务端上配置如下 ...

September 8, 2022 · 1 min · jiezi

关于nacos:Nacos集成Spring-Cloud-Gateway实现动态路由

Nacos集成Spring Cloud Gateway实现动静路由后面咱们曾经介绍了Nacos 的装置与配置,Spring Cloud 集成Nacos 作为服务的注册核心和配置核心,集成Nacos 实现服务的负载平衡和一些常见的负载平衡策略、应用Dubbo、OpenFegin进行RPC调用以及整合Spring Cloud Gateway作为服务的网关和Gateway的过滤器配置接下来就让咱们一起来看看Spring Cloud Gateway的动静路由以及负载平衡关联服务名的动静路由之前咱们都是这样来配置的路由 service-url: user-service: http://localhost:...spring: cloud:   gateway:     routes:       - id: path_route         uri: ${service-url.user-service}/user/get/{id}         predicates:           - Path=/user/get/{id}复制代码置信同学们都发现了一个问题,在微服务集群部署中一个服务可能会有多台主机,咱们这样配置路由不够灵便,每更改一次服务的主机信息都要从新编写一次配制文件,而后还须要重启Gateway服务器。咱们要晓得,在真正的我的项目中重启服务是很耗时的,咱们应该尽量避免这种状况Spring Cloud Gateway提供了lb//服务名的形式来动静的配置路由,网关会依据注册核心的服务名动静的获取服务的URL,这样即使该服务的某一台主机地址扭转或者挂掉,网关都不用再跟着扭转因而,咱们能够将路由更改成这种形式 spring: cloud:   gateway:     routes:       - id: path_route          # uri: ${service-url.user-service}/user/get/{id}         uri: lb://user-service         predicates:           - Path=/user/get/{id}复制代码留神,引入依赖时须要排除Nacos中ribbon的依赖,而后再导入loadbalancer的依赖 ...

September 3, 2022 · 3 min · jiezi

关于nacos:Nacos的注册和使用

1.服务注册导入Nacos依赖<!-- SpringCloudAlibaba无关依赖 --><dependency> <groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2.2.5.RELEASE</version><type>pom</type><scope>import</scope></dependency> 复制代码客户端导入依赖,如果有eureka的依赖得先注掉<!-- nacos客户端起步依赖 --><dependency> <groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency> 复制代码 1.1 批改配置文件 注册cloudcloud: nacos: server-addr: localhost:8848 # nacos 服务地址复制代码 到后盾在配置文件中查看 2.NacosRule负载平衡2.1.配置集群属性 在配置文件cloud的属性下中增加cluster-name 设置集群昵称,就会主动调配 2.2 依据集群配置负载平衡 NFLoadBalancerRuLeClassName 同个集群下有多个服务时会采纳随机的形式来负载平衡。增加以下配置文件spring:userservice: #要做配置的微服务名称 ribbon: NFLoadBalancerRuLeClassName: 配置负载平衡的规定复制代码 呈现跨集群拜访时,控制台会输入正告信息,提醒运维人员。 2.3 依据权重负载平衡 3.环境隔离 在没有设置空间下节点默认都是放在命名空间的public默认空间 3.1 新建空间 命名空间后会发现多进去了一个空间ID,在会到服务列表会看到咱们新增的一个命名空间 3.2 代码对接命名空间 在配置文件中增加namespace:前面跟着命名空间的id 4.和Eureka的区别 Eureka通过被动询问来判断服务是否还存活,Nacos是通过心跳的来判断。 5.Nacos配置管理5.1 创立配置文件实现热更新新增配置 配置文件昵称必须是要惟一的用于对立治理, 配置内容是把有热更新需要的放进来,如固定格局的配置不须要更新的就不须要填写。 ...

August 24, 2022 · 1 min · jiezi

关于nacos:记一次使用nacos2踩到的坑

前言本文素材起源敌人学习nacos2.1.1踩到的坑。间接上正菜 坑点一:呈现端口被占用因为是学习应用,敌人就在物理机搭建了搭建了nacos伪集群,即ip都一样,端口别离为8848,8847,8849。然而启动nacos服务器后,一台失常启动,其余两台都报了端口被占用 呈现这种状况的起因,官网有做了解释通过官网咱们能够很容易得悉,这个端口被占用次要是因为grpc引起的,因为他端口的生成形式,是由主端口+1000、主端口+1001生成。 解决办法集群的端口不要采纳相邻数字,步长尽量搞大点。比方设置为7777、8888、9999之类的 坑二:微服务项目启动呈现com.alibaba.nacos.api.exception.NacosException: Client not connected, current status:STARTING异样这个问题呈现在敌人在我的项目中配置的nacos地址为nginx地址,配置示例如下 spring.cloud.nacos.discovery.server-addr=nginx ip一开始敌人nginx的配置示例如下 upstream nacos-cluster { server 127.0.0.1:7777; server 127.0.0.1:8888; server 127.0.0.1:9999; } server { listen 80; server_name localhost; location / { proxy_pass http://nacos-cluster; } }浏览器通过nginx拜访没问题,然而我的项目中把nacos服务地址配置为nginx ip就报了 com.alibaba.nacos.api.exception.NacosException: Client not connected, current status:STARTING这个异样信息,前面敌人查资料,官网上有写 于是他就将转发形式改为TCP,他的nginx版本是1.9+以上版本,默认就反对TCP代理了,不必额定装置stream模块。nginx配置TCP的示例形如下 stream { upstream nacos-cluster-grpc{ # nacos2版本,grpc端口与要比主端口多1000,主端口为7777、8888、9999 server 127.0.0.1:8777; server 127.0.0.1:9888; server 127.0.0.1:10999; } server{ listen 9848; proxy_pass nacos-cluster-grpc; }}当敌人配置好nginx tcp代理转发后,通过telnet命令 telnet 127.0.0.1 9848来看是否能失常转发给nacos服务端,通过验证,网络能够连通。接着敌人在微服务项目的nacos配置填写如下地址 spring.cloud.nacos.discovery.server-addr=127.0.0.1:9848 #nginx代理tcp的地址原本认为高枕无忧,后果我的项目一启动,依然报 com.alibaba.nacos.api.exception.NacosException: Client not connected, current status:STARTING于是敌人懵了,啥状况?就来找我交换一下其实在nacos官网的FAQ就有提到相应的解题思路了 ...

August 19, 2022 · 1 min · jiezi

关于nacos:On-NacosSpringCloud-方式使用-Nacos

如果大家想要理解更多的 Nacos 教程,欢送 star 《on-nacos》开源我的项目。基于 Nacos 2.x 的入门、原理、源码、实战介绍,帮忙开发者疾速上手 Nacos。本文介绍下如何在 Spring Cloud 我的项目中应用 Nacos,Nacos 次要分为两个局部,配置核心和服务注册与发现。在应用 Spring Cloud 我的项目中应用 Nacos ,首先要保障启动一个 Nacos 服务,具体能够参考《疾速上手 Nacos》来搭建一个单机的 Nacos 服务。 Nacos 接入 Spring Cloud 的源代码能够参考 spring-cloud-alibaba 这个我的项目,感兴趣的敌人能够查看源代码。Spring Cloud Alibaba 的版本对应关系能够参考:版本阐明 Wiki 本篇文章的具体的代码示例点击【nacos-spring-cloud】查看 配置核心创立配置关上控制台 http://127.0.0.1:8848/nacos ,进入 配置管理-配置列表 点击+号新建配置,这里创立个数据源配置例子: nacos-datasource.yaml spring: datasource: name: datasource url: jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=UTF-8&characterSetResults=UTF-8&zeroDateTimeBehavior=convertToNull&useDynamicCharsetInfo=false&useSSL=false username: root password: root driverClassName: com.mysql.jdbc.Driver 增加依赖配置创立好就能够在控制台 配置管理-配置列表中查看到。接下来演示下怎么在 Spring Cloud 我的项目中获取到 Nacos 中的配置信息。 须要在我的项目中增加以下依赖: <!--配置核心--><dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <version>${latest.version}</version></dependency>如果我的项目的 Spring Boot 版本 小于 2.4.0 须要在我的项目中创立 bootstrap.properties 而后在我的项目中的 bootstrap.properties 文件中增加 nacos 的一些配置: ...

June 29, 2022 · 2 min · jiezi

关于nacos:服务管理与通信基础原理分析

波及轻微的源码展现,可释怀参考;一、根底简介服务注册发现是微服务架构中最根底的能力,上面将从源码层面剖析实现逻辑和原理,在这之前要先来看下依赖工程的根底构造,波及如下几个外围组件: commons:服务组件的形象申明,本文只剖析注册发现与负载平衡;nacos:当下罕用的注册核心组件,用来进行服务治理;feign:服务间通信交互组件,在服务申请时波及负载平衡的策略;ribbon:在服务间通信申请时,提供多种负载平衡的策略实现;在相熟工程依赖之间的构造时,还要明确服务间交互的流程和原理,这样在剖析源码设计时,有一个清晰的思路与轮廓;如何实现上面的服务交互模式,在浏览源码工程时,围绕如下两个外围逻辑: 注册发现:注册时如何上报服务的信息数据,这些数据以怎么的形式治理;负载平衡:当申请的服务同时存在多个时,以什么样的策略抉择执行申请的服务;在这里先简略的聊一下集体在浏览源码工程时的基本思路,比方微服务组件:通常从配置参数作为切入口,察看基于参数构建的外围对象,再重点剖析对象的管理模式,以及适配的扩大能力,最初联合我的项目的利用场景即可: 浏览源码最重要的是耐着情绪缓缓看,并顺手画下外围流程,实际上如果有肯定的编程教训,不论是浏览什么工程的源码,只有用心去剖析单点的实现原理,都算不上适度简单,然而组件通常为了复用能力,会去适配多种简单的场景,这样势必要采纳形象的封装和设计模式,源码工程的复杂度天然就会相应进步,这个话题后续会细聊。 二、服务注册1、服务配置首先从Nacos配置参数开始,这里只设置服务发现的两个参数:1Nacos注册核心的服务端地址,2在服务的元数据中加载分支号;而后来具体的看源码流程: 在配置参数加载的过程中,有很多缺省的默认值,所以须要关注最终会提供的参数信息,来判断是否须要自定义设置,另外AutoConfig配置要重点看实例化的对象;断点的流程能够依照如下的形式做设置,这里排列的是在配置加载阶段的几个外围节点: 参数:NacosDiscoveryProperties#getNacosProperties配置:NacosServiceAutoConfiguration#nacosServiceManager构建:NacosServiceManager#buildNamingService NamingService是Nacos服务治理接口,波及注册、查问、撤销、查看等多个办法,即对应的是Nacos服务端的相应API申请,在注册执行的阶段会细说用法。 2、注册构建看完服务配置之后再看注册配置,对于配置中简单的设计,须要重点关注两个信息:ConditionalOn和matchIfMissing,这样很容易发现默认加载: 配置:NacosServiceRegistryAutoConfiguration#nacosServiceRegistry注册:NacosServiceRegistry#register实例:NacosServiceRegistry#getNacosInstanceFromRegistration 在构建服务注册的外围类NacosServiceRegistry时,通过服务的注销信息转换为注册的实例化对象,而后通过NamingService接口办法,上报实例化对象;须要留神的是,尽管这里只看了Nacos中的相干API,但实际上API实现了诸多spring-cloud-commons包中申明的接口,比方Registration、ServiceInstance等。 3、执行上报通常微服务的注册核心组件,都是基于server-client架构和部署形式,客户端须要依据本身启动状态去上报或者撤销注册,服务端负责对立保护注册数据: 实现:NacosNamingService#registerInstance执行:NamingProxy#registerService接口:InstanceController#register 在最终执行服务注册时,其动作实质就是申请Nacos服务端的一个Post办法,并将配置数据上报,例如:IP地址、端口、元数据、权重等;这样客户端注册逻辑执行实现,而后再看服务端数据可视化界面,就能够看到注册的客户端服务。 至于Nacos服务端是如何治理这些注册数据的,参考部署版本的nacos-naming模块源码,浏览上报接口和页面中的列表加载的实现即可;留神在初始的配置文件中,退出的branch分支参数也在元数据结构中。 在NamingService接口中,波及多个服务治理的办法,在执行原理上基本相同就不在赘述,这样注册核心的Client端和Server端就造成了通信机制,接下来再看Client端之间的通信。 三、服务通信1、根底配置Feign在配置方面比较复杂,提供了多个场景下的适配能力,这里只以两个常见的参数作为切入点:1通信超时工夫,2Http选型(采纳默认值); 参数:FeignClientProperties#getConfig注解:FeignClientsRegistrar#registerFeignClients配置:FeignAutoConfiguration#feignContext构建:FeignClientFactoryBean#getTarget 这里要重点关注的是注解的扫描和注册以及容器治理,要了解Feign的上下文环境须要明确上文中形容的服务间交互原理,而后参考FeignClientFactoryBean工厂类中构建逻辑。 2、通信逻辑尽管Feign注解的形式能够简化开发,然而在具体执行的时候还是Http的申请响应模式,这里能够参考LoadBalancerFeignClient类中的execute办法: 配置:FeignRibbonClientAutoConfiguration通信构建:LoadBalancerFeignClient#execute负载平衡:AbstractLoadBalancerAwareClient#executeWithLoadBalancer 不论是Feign组件还是Spring框架,默认的负载平衡策略都是采纳Ribbon的实现形式,在上述流程中配置和负载平衡命令都依赖Ribbon组件,接下来看服务抉择策略。 四、负载平衡1、命令构建这里构建了调用负载平衡接口的命令,ILoadBalancer接口中提供服务治理的相干办法,其中最外围的就是chooseServer办法,而后联合具体的策略规定实现服务的抉择的性能: 命令构建:LoadBalancerCommand.Builder#build负载容器:LoadBalancerContext#getServerFromLoadBalancer抉择接口:ILoadBalancer#chooseServer 2、策略规定Ribbon组件中负载平衡的策略有好几种规定,比方随机抉择、Key匹配、权重歪斜等;在工作中罕用的就是默认规定即RoundRobinRule,以及基于Key设计的灰度模式,简略做法就是服务启动时在元数据中增加的分支号作为匹配的标识; 规定设置:BaseLoadBalancer#setRule随机策略:RoundRobinRule#choose过滤策略:PredicateBasedRule#choose 当初回到流程的开始看,通过Nacos组件进行服务注册和治理,通过Feign组件基于Ribbon负载平衡策略做服务通信,如果单看各节点组件的逻辑还比拟容易了解,然而通过Spring框架做组件之间的合作调度时,复杂程度明显提高; 如果是刚开始浏览源码的阶段,能够只关注相应流程的外围逻辑,选择性疏忽细节的实现原理,当然重点还是要多读读Spring的设计,这样工夫久了天然会有很多播种。 五、参考源码编程文档:https://gitee.com/cicadasmile/butte-java-note利用仓库:https://gitee.com/cicadasmile/butte-flyer-parent

June 8, 2022 · 1 min · jiezi

关于nacos:Nacos配置中心介绍与应用微服务开发标配组件

配置核心作为散布式微服务开发的标配组件,业界已有很多胜利的典型利用,如:携程 Apollo 分布式配置核心、百度 Disconf 分布式配置核心等。盘古开发框架配置核心基于阿里的 Nacos 提供动静配置服务。 鉴于文档可读性,盘古教程和参考范例都应用的本地配置的形式。本文将介绍如何基于配置核心让盘古利用取得动静配置服务的能力。在理论利用中,如无非凡需要咱们个别都倡议采纳配置核心的形式来开发。配置核心介绍Nacos 动静配置服务能够让你以中心化、内部化和动态化的形式治理所有环境的利用配置和服务配置。动静配置打消了配置变更时重新部署利用和服务的须要,让配置管理变得更加高效和麻利。配置中心化治理让实现无状态服务变得更简略,让服务按需弹性扩大变得更容易。它还提供了一个简洁易用的 UI 帮忙你治理所有的服务和利用的配置,包含配置版本跟踪、金丝雀公布、一键回滚配置等一系列开箱即用的配置管理个性,帮忙你更平安地在生产环境中治理配置变更和升高配置变更带来的危险。 疾速 QA:前文中 Nacos 用于服务注册,为什么配置核心也是它? Nacos 是构建以“服务”为核心的古代利用架构 (例如微服务范式、云原生范式) 的服务基础设施。致力于发现、配置和治理微服务,完满的整合了配置核心和服务注册核心。因而,Nacos 不仅是服务注册核心也是功能完善的分布式配置核心。 疾速 QA:单体分层架构的开发模式也能够应用配置核心进行配置吗? 配置核心是散布式微服务架构开发环境下强烈建议的必选标配组件。但如果你是基于单体分层架构开发,配置核心也是一样能够应用的。对于这些根底能力,无论是微服务还是单体,盘古框架都做了完满适配,只须要依赖 pangu-spring-boot-starter 就能够实现开箱即用。 相干名词解释命名空间用于进行租户粒度的配置隔离。不同的命名空间下,能够存在雷同的 Group 或 Data ID 的配置。Namespace 的罕用场景之一是不同环境的配置的辨别隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。 配置管理系统配置的编辑、存储、散发、变更治理、历史版本治理、变更审计等所有与配置相干的流动。 配置项一个具体的可配置的参数与其值域,通常以 param-key=param-value 的模式存在。例如咱们常配置零碎的日志输入级别( logLevel=INFO|WARN|ERROR )就是一个配置项。 配置集一组相干或者不相干的配置项的汇合称为配置集。在零碎中,一个配置文件通常就是一个配置集,蕴含了零碎各个方面的配置。例如,一个配置集可能蕴含了数据源、线程池、日志级别等配置项。 配置集IDNacos 中的某个配置集的 ID。配置集 ID 是组织划分配置的维度之一。一个零碎或者利用能够蕴含多个配置集,每个配置集都能够被一个有意义的名称标识。(比方:应用利用名称作为 Data ID) 配置快照Nacos 的客户端 SDK 会在本地生成配置的快照。当客户端无奈连贯到 Nacos Server 时,能够应用配置快照显示零碎的整体容灾能力。配置快照相似于 Git 中的本地 commit,也相似于缓存,会在适当的机会更新,然而并没有缓存过期( expiration )的概念。 本地配置与配置核心比照本地配置(配置文件) 配置扩散、与利用耦合、动态配置无环境隔离无版本反对,容易引发生产事变无平安审计配置核心 配置集中、内部化、动态化实时失效多环境隔离多版本反对,较平安配置权限管制、操作变更审计配置核心实战上面介绍一个应用配置核心的例子。其它基于本地配置的范例都能够参考这个例子改为基于配置核心的动静配置。 装置相干盘古模块盘古 Parent<parent> <groupId>com.gitee.pulanos.pangu</groupId> <artifactId>pangu-parent</artifactId> <version>latest.version.xxx</version> <relativePath/></parent>根底模块<dependency> <groupId>com.gitee.pulanos.pangu</groupId> <artifactId>pangu-spring-boot-starter</artifactId></dependency>本地配置基于配置核心的配置也是须要一个本地配置文件的,但这个配置文件是固定的模版格局。用于配置一些与配置核心进行数据通信相干的根底类参数。如下所示。 ...

June 6, 2022 · 1 min · jiezi

关于nacos:Nacos源码学习系列第2篇服务搭建集群模式

明天咱们搭建一个3个node的nacos 集群我的项目配置把我的项目的源码整体复制2份到新的文件夹【naco2】和【nacos3】 参照【Nacos源码学习系列第1篇服务搭建-单机模式】导入我的项目并设置启动端口别离为【8060】和【8070】 数据库连贯配置3个服务能够共用一套, 不用反复创立数据库我的项目启动区别于单机模式的vm启动参数配置, VM参数须要设置为 -Dnacos.standalone=false 为每个服务创立3个独立的运行时文件目录 同时在该目录下创立一个conf子目录并创立 cluster.conf文件 文件目录构造: 【起始目录 -> nacos1 -> nacos -> conf -> cluster.conf】 【起始目录 -> nacos2 -> nacos -> conf -> cluster.conf】 【起始目录 -> nacos3 -> nacos -> conf -> cluster.conf】 文件内容对立如下: 你的ip:8860你的ip:8850你的ip:8870留神: 每个我的项目肯定要配置独立的运行目录, 共用的话服务启动会失败别离为每个我的项目设置VM 参数  -Duser.home=起始目录/nacos1 -Duser.home=起始目录/nacos2 -Duser.home=起始目录/nacos3 debug 模式运行 【cosole】模块下的 【Nacos.java】 看到上面的日志阐明启动胜利,启动过程有点慢,大略要2分钟左右: 2022-05-21 21:51:16.486 INFO 266344 --- [acos-starting.0] c.a.n.c.l.StartingApplicationListener : Nacos is starting...2022-05-21 21:51:17.507 INFO 266344 --- [acos-starting.0] c.a.n.c.l.StartingApplicationListener : Nacos is starting...2022-05-21 21:51:18.566 INFO 266344 --- [acos-starting.0] c.a.n.c.l.StartingApplicationListener : Nacos is starting...2022-05-21 21:51:19.585 INFO 266344 --- [acos-starting.0] c.a.n.c.l.StartingApplicationListener : Nacos is starting...2022-05-21 21:51:20.590 INFO 266344 --- [acos-starting.0] c.a.n.c.l.StartingApplicationListener : Nacos is starting...2022-05-21 21:51:21.595 INFO 266344 --- [acos-starting.0] c.a.n.c.l.StartingApplicationListener : Nacos is starting...2022-05-21 21:51:22.345 INFO 266344 --- [ main] c.a.n.c.l.StartingApplicationListener : Nacos started successfully in cluster mode. use external storage如果启动过程中碰到上面的谬误,起因是没有找到运行目录下的集群配置文件【nacos -> conf -> cluster.conf】:Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'serverMemberManager' defined in file [D:\code\nacos2\core\target\classes\com\alibaba\nacos\core\cluster\ServerMemberManager.class]: Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.alibaba.nacos.core.cluster.ServerMemberManager]: Constructor threw exception; nested exception is ErrCode:500, ErrMsg:jmenv.tbsite.net at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:304) at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:285) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1338) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1185) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:554) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:514) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:321) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:319) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:277) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1276) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1196) at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:857) at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:760) ... 90 common frames omittedCaused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.alibaba.nacos.core.cluster.ServerMemberManager]: Constructor threw exception; nested exception is ErrCode:500, ErrMsg:jmenv.tbsite.net at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:187) at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:117) at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:300) ... 104 common frames omittedCaused by: com.alibaba.nacos.api.exception.NacosException: java.net.UnknownHostException: jmenv.tbsite.net at com.alibaba.nacos.core.cluster.lookup.AddressServerMemberLookup.run(AddressServerMemberLookup.java:152) at com.alibaba.nacos.core.cluster.lookup.AddressServerMemberLookup.doStart(AddressServerMemberLookup.java:100) at com.alibaba.nacos.core.cluster.AbstractMemberLookup.start(AbstractMemberLookup.java:55) at com.alibaba.nacos.core.cluster.ServerMemberManager.initAndStartLookup(ServerMemberManager.java:185) at com.alibaba.nacos.core.cluster.ServerMemberManager.init(ServerMemberManager.java:165) at com.alibaba.nacos.core.cluster.ServerMemberManager.<init>(ServerMemberManager.java:146) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:175) ... 106 common frames omittedCaused by: java.net.UnknownHostException: jmenv.tbsite.net at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:184) at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) at java.net.Socket.connect(Socket.java:606) at sun.net.NetworkClient.doConnect(NetworkClient.java:175) at sun.net.www.http.HttpClient.openServer(HttpClient.java:463) at sun.net.www.http.HttpClient.openServer(HttpClient.java:558) at sun.net.www.http.HttpClient.<init>(HttpClient.java:242) at sun.net.www.http.HttpClient.New(HttpClient.java:339) at sun.net.www.http.HttpClient.New(HttpClient.java:357) at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1226) at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1162) at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1056) at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:990) at com.alibaba.nacos.common.http.client.request.JdkHttpClientRequest.execute(JdkHttpClientRequest.java:114) at com.alibaba.nacos.common.http.client.NacosRestTemplate.execute(NacosRestTemplate.java:482) at com.alibaba.nacos.common.http.client.NacosRestTemplate.get(NacosRestTemplate.java:72) at com.alibaba.nacos.core.cluster.lookup.AddressServerMemberLookup.syncFromAddressUrl(AddressServerMemberLookup.java:175) at com.alibaba.nacos.core.cluster.lookup.AddressServerMemberLookup.run(AddressServerMemberLookup.java:143) ... 116 common frames omitted查看控制台浏览器关上控制台 ...

May 31, 2022 · 2 min · jiezi

关于nacos:Nacos源码学习系列第1篇服务搭建之单机模式

服务搭建咱们分成3个局部服务端单机部署、服务端集群部署、客户端集成别离解说 本篇学习指标:能把Nacos服务端2.1.0版本的源码以Debug模式运行再IDE中 源码下载进入nacos我的项目的的github地址,咱们抉择版本2.1.0(在分支抉择框外面点击tags上面的2.1.0)  把我的项目代码下载到本地目录。https://github.com/alibaba/nacos 我的项目导入   把我的项目导入 idea, 在导入之前倡议把我的项目名由【nacos-2.1.0】 改成【nacos1】, 因为前面咱们在搭建服务端集群的时候会同时启动多个nacos server。    批改console模块下的 application.properties 文件 找到端口配置项【server.port】如果么有找到则增加设置启动端口(这里咱们选用8850 默认端口是8848) server.port=8850导入数据库须要大家提前装置好数据环境,创立数据库【nacos】, 并导入执行 【console】我的项目目录下 \src\main\resources\META-INF\schema.sql 数据库脚本 批改【console】我的项目下的 application.properties 文件, 增加数据库连贯配置 db.num=1 db.url.0=jdbc:mysql://数据库地址:数据库端口/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTCdb.user.0=数据库用户名db.password.0=数据库明码 留神: db.num=1  这个属性不能够少 单机模式下大家还能够应用内置存储的形式启动而不依赖内部数据, 只须要在vm启动配置加上 【-DembeddedStorage=true】 留神集群模式不能用内置存储否则无奈启动 编译启动找到console模块下的服务启动类【Nacos.java】 启动之前 设置 VM 参数: -Dnacos.standalone=true 而后以debug模式启动【Nacos.java】 此时你肯定会在控制台遇到相似上面的编译错误信息: Error:(19, 44) java: 程序包com.alibaba.nacos.consistency.entity不存在Error:(20, 44) java: 程序包com.alibaba.nacos.consistency.entity不存在Error:(21, 44) java: 程序包com.alibaba.nacos.consistency.entity不存在Error:(72, 22) java: 找不到符号 符号: 类 ReadRequest 地位: 接口 com.alibaba.nacos.consistency.ConsistencyProtocol<T,P>Error:(72, 5) java: 找不到符号 符号: 类 Response 地位: 接口 com.alibaba.nacos.consistency.ConsistencyProtocol<T,P>Error:(80, 42) java: 找不到符号 符号: 类 ReadRequest 地位: 接口 com.alibaba.nacos.consistency.ConsistencyProtocol<T,P>Error:(80, 23) java: 找不到符号 符号: 类 Response 地位: 接口 com.alibaba.nacos.consistency.ConsistencyProtocol<T,P>Error:(90, 20) java: 找不到符号 符号: 类 WriteRequest 地位: 接口 com.alibaba.nacos.consistency.ConsistencyProtocol<T,P>Error:(90, 5) java: 找不到符号 符号: 类 Response 地位: 接口 com.alibaba.nacos.consistency.ConsistencyProtocol<T,P>Error:(100, 44) java: 找不到符号 符号: 类 WriteRequest 地位: 接口 com.alibaba.nacos.consistency.ConsistencyProtocol<T,P>Error:(100, 23) java: 找不到符号 符号: 类 Response 地位: 接口 com.alibaba.nacos.consistency.ConsistencyProtocol<T,P>D:\code\nacos3\consistency\src\main\java\com\alibaba\nacos\consistency\RequestProcessor.javaError:(19, 44) java: 程序包com.alibaba.nacos.consistency.entity不存在Error:(20, 44) java: 程序包com.alibaba.nacos.consistency.entity不存在Error:(21, 44) java: 程序包com.alibaba.nacos.consistency.entity不存在Error:(38, 40) java: 找不到符号 符号: 类 ReadRequest 地位: 类 com.alibaba.nacos.consistency.RequestProcessorError:(38, 21) java: 找不到符号 符号: 类 Response 地位: 类 com.alibaba.nacos.consistency.RequestProcessorError:(46, 38) java: 找不到符号 符号: 类 WriteRequest 地位: 类 com.alibaba.nacos.consistency.RequestProcessorError:(46, 21) java: 找不到符号 符号: 类 Response 地位: 类 com.alibaba.nacos.consistency.RequestProcessorD:\code\nacos3\consistency\src\main\java\com\alibaba\nacos\consistency\ProtoMessageUtil.javaError:(19, 44) java: 程序包com.alibaba.nacos.consistency.entity不存在Error:(20, 44) java: 程序包com.alibaba.nacos.consistency.entity不存在Error:(21, 44) java: 程序包com.alibaba.nacos.consistency.entity不存在Error:(22, 44) java: 程序包com.alibaba.nacos.consistency.entity不存在Error:(85, 54) java: 找不到符号 符号: 类 Log 地位: 类 com.alibaba.nacos.consistency.ProtoMessageUtilError:(85, 19) java: 找不到符号 符号: 类 WriteRequest 地位: 类 com.alibaba.nacos.consistency.ProtoMessageUtilError:(100, 52) java: 找不到符号 符号: 类 GetRequest 地位: 类 com.alibaba.nacos.consistency.ProtoMessageUtilError:(100, 19) java: 找不到符号 符号: 类 ReadRequest 地位: 类 com.alibaba.nacos.consistency.ProtoMessageUtilError:(54, 30) java: 找不到符号 符号: 变量 ReadRequest 地位: 类 com.alibaba.nacos.consistency.ProtoMessageUtilError:(56, 30) java: 找不到符号 符号: 变量 WriteRequest 地位: 类 com.alibaba.nacos.consistency.ProtoMessageUtilError:(65, 13) java: 找不到符号 符号: 类 GetRequest 地位: 类 com.alibaba.nacos.consistency.ProtoMessageUtilError:(65, 34) java: 找不到符号 符号: 变量 GetRequest 地位: 类 com.alibaba.nacos.consistency.ProtoMessageUtilError:(71, 13) java: 找不到符号 符号: 类 Log 地位: 类 com.alibaba.nacos.consistency.ProtoMessageUtilError:(71, 23) java: 找不到符号 符号: 变量 Log 地位: 类 com.alibaba.nacos.consistency.ProtoMessageUtilError:(86, 16) java: 找不到符号 符号: 变量 WriteRequest 地位: 类 com.alibaba.nacos.consistency.ProtoMessageUtilError:(101, 16) java: 找不到符号 符号: 变量 ReadRequest 地位: 类 com.alibaba.nacos.consistency.ProtoMessageUtil问题起因: 因为nacos 2.x 应用了grpc 作为底层通信协定,这些对象都是以proto文件模式定义在proto文件夹中,须要咱们应用maven插件手动编译成java class. ...

May 30, 2022 · 4 min · jiezi

关于nacos:Spring-Cloud-Alibaba入门实践一-概述

Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此我的项目蕴含开发分布式应用服务的必须组件,不便开发者通过 Spring Cloud 编程模型轻松应用这些组件来开发分布式应用服务。 依靠 Spring Cloud Alibaba,您只须要增加一些注解和大量配置,就能够将 Spring Cloud 利用接入阿里分布式应用解决方案,通过阿里中间件来迅速搭建分布式应用零碎。目前 Spring Cloud Alibaba 提供了如下性能: 服务限流降级:反对 WebServlet、WebFlux, OpenFeign、RestTemplate、Dubbo 限流降级性能的接入,能够在运行时通过控制台实时批改限流降级规定,还反对查看限流降级 Metrics 监控。服务注册与发现:适配 Spring Cloud 服务注册与发现规范,默认集成了 Ribbon 的反对。分布式配置管理:反对分布式系统中的内部化配置,配置更改时主动刷新。Rpc服务:扩大 Spring Cloud 客户端 RestTemplate 和 OpenFeign,反对调用 Dubbo RPC 服务音讯驱动能力:基于 Spring Cloud Stream 为微服务利用构建音讯驱动能力。分布式事务:应用 @GlobalTransactional 注解, 高效并且对业务零侵入地解决分布式事务问题。阿里云对象存储:阿里云提供的海量、平安、低成本、高牢靠的云存储服务。反对在任何利用、任何工夫、任何地点存储和拜访任意类型的数据。分布式任务调度:提供秒级、精准、高牢靠、高可用的定时(基于 Cron 表达式)任务调度服务。同时提供分布式的工作执行模型,如网格工作。网格工作反对海量子工作平均调配到所有 Worker(schedulerx-client)上执行。阿里云短信服务:笼罩寰球的短信服务,敌对、高效、智能的互联化通信能力,帮忙企业迅速搭建客户触达通道。涵盖其次要组件 NacosSentinelOauth2ZuulRocketMQSeataSkywalking

May 27, 2022 · 1 min · jiezi

关于nacos:无法连接读取-nacos-配置中心及文件能踩的坑都踩了

之前做我的项目不相熟 nacos 导致一个配置核心弄了整整一天,第二天尽管弄好了,然而又因为开发中代码出错回滚了一下,这下回滚不要紧,间接把我之前配置好的 nacos 文件也一起回滚了,因为遗记了上次哪里出错,又从新配了一天,能够说是网上有的没的我都踩了。。。。。 先说一下运行环境,或者因为你我的版本不一样,解决的办法也不一样 SpringBoot版本SpringCloud版本cloud Alibaba版本2.1.8.RELEASEGreenwich.SR62.1.4.RELEASEnamespace 填写的是命名空间的ID不是名称本地配置文件名称是 application.yml(properties) 和 bootstrap.yam(properties) 不要因为 nacos 下面有个 yaml 选项就把后缀写的一样SpringBoot 不辨认 bootstrap 文件,须要增加依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId><version>3.0.1</version></dependency>若要应用 @Value 读取本地配置文件,记得导入正确的包以及 @Value(${"key"}) key为你要读取的配置名称,这能力读取到重点!!! 在 nacos 上新建配置文件的 Data Id 不能随便乱写,依据官网文档是由这几局部组成 ${prefix}-${spring.profiles.active}.${file-extension}prefix :注册在 nacos 上的服务名 spring.application.name 的值 spring.profiles.active :配置的开发环境是开发还是测试,比方 dev,test,prod 这个最好写上 prefix 和 spring.profiles.active 之间有一个 - 连接符,如果不写 spring.profiles.active 的话那么间接 prefix 和 file-extension 拼接,没有连接符 file-extension :这个和你抉择的扩展名以及本地扩展名这三个值统一 yml 文件中留神这几个层级关系以及缩进 file-extension的层级关系为 spring.cloud.nacos.config.file-extension 写错了会导致申请被回绝 本地配置文件的写错会导致无法访问网站申请被拒连贯配置核心的参数须要写在 bootstrap 外面,写在 application 外面无奈连贯配置核心bootstrap 比 application 先执行,且内容无奈笼罩(具体差别网上说的挺具体)留神连贯 nacos 的地址,如果是虚拟机启动 nacos,而在本地连接的话,地址为虚拟机地址而不是本地 localhost(127.0.0.1)先写到这,有坑再填 ...

April 14, 2022 · 1 min · jiezi

关于nacos:微服务Nacos的使用

如何应用Nacos作为配置核心对立治理配置首先,批改 pom.xml 文件,引入 Nacos Config Starter。 <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency>在微服务resources文件夹下,创立bootstrap.properties 并写入。 spring.application.name=mznzmall-product spring.cloud.nacos.config.server-addr=127.0.0.1:8848启动nacos并拜访http://127.0.0.1:8848/nacos/#...在配置列表写增加 数据集( Data Id) 利用名.properties利用名.properties增加任何配置动静获取配置@RefreshScope:动静刷新并获取配置 @Value("${配置项的名字}"):获取到配置如果配置核心和以后利用的配置文件中都配置了雷同的项,优先应用配置核心的配置 细节命名空间:配置隔离;默认:public(保留空间);默认新增的所有配置都在public(保留空间)。 开发,测试,生产:利用命名空间来做环境隔离。 留神:在bootstrap.properties配置上,须要应用哪个命名空间下的配置 spring.cloud.nacos.config.namespace=943865ec-f45b-4baa-84a2-d4abc6d205b0每一个微服务之间相互隔离配置,每一个微服务都创立本人的命名空间,只加载本人命名空间下的所有配置配置集:所有配置的汇合配置集ID:相似于文件名。Data ID:类型于文件名 配置分组默认所有的配置集都属于:DEFAULT_GROUP 能够应用dev,test,prod,618,11-11,12-12来辨别 每个微服务创立本人的命名空间,应用配置分组辨别环境,dev,test,prod同时加载多个配置集微服务任何配置信息,任何配置文件都能够放在配置文件中只须要在bootstrap.properties阐明加载配置核心中哪些配置文件以前SpringBoot任何办法从配置文件中获取值,都能应用。 @Value,@ConfigurationProperties等等配置核心有的优先应用配置核心的。

March 1, 2022 · 1 min · jiezi

关于nacos:功能回顾Apache-APISIX-基于-Nacos-实现服务发现

本文为您介绍 Apache APISIX、Nacos 基本概念以及注册核心的作用,并为您展现了 Apache APISIX 基于 Nacos 实现服务发现的具体操作。 背景信息对于 Apache APISIXApache APISIX 是一个动静、实时、高性能的 API 网关,提供负载平衡、动静上游、灰度公布、服务熔断、身份认证、可观测性等丰盛的流量治理性能。Apache APISIX 不仅领有泛滥实用的插件,而且反对插件动静变更和热插拔。 对于 NacosNacos 是阿里巴巴开源的一个易于应用的动静服务发现、配置和服务治理平台。它提供了一组简略易用的个性集,能够帮忙您疾速实现动静服务发现,服务配置,服务元数据及流量治理,让您更麻利和容易地构建,交付和治理微服务平台。Nacos 是构建以“服务”为核心的古代利用架构(例如微服务范式、云原生范式)的服务基础设施。 注册核心什么是注册核心服务注册核心是服务要实现服务化治理的外围组件,相似于目录服务的作用,也是微服务架构中最根底的设施之一,次要用来存储服务信息,譬如服务提供者 URL 、路由信息等。注册核心的实现是通过一种映射的形式,将简单的服务端信息映射为简略易懂的信息提供给客户端。 注册核心的外围性能为以下三点: 服务注册:服务提供方向注册核心进行注册。服务发现:服务生产方能够通过注册核心寻找到服务提供方的调用路由信息。衰弱检测:确保注册到注册核心的服务节点是能够被失常调用的,防止有效节点导致的调用资源节约等问题。为什么须要注册核心?注册核心实质上是为了解耦服务提供者和服务消费者,在微服务体系中,各个业务服务之间会频繁相互调用,并且须要对各个服务的 IP、port 等路由信息进行对立的治理。然而要如何进行治理呢?咱们能够通过注册核心的 服务注册 性能将已有服务的相干信息提供到对立的注册核心进行治理。 通过上述形容,您能够理解到注册核心能够帮忙用户通过映射疾速找到服务和服务地址。随着业务更新迭代,服务会频繁发生变化,在服务端中注册了新的服务或者服务宕机后,客户端依然能够通过注册核心的 服务发现 性能拉取服务列表,如果注册核心的服务节点产生变更,注册核心会发送申请告诉客户端从新拉取。 如果服务端的服务忽然宕机,并且没有向注册核心反馈,客户端能够通过注册核心的健康检查性能,进行固定工夫距离的被动上报心跳形式向服务端表明本人的服务状态。如果服务状态异样,则会告诉注册核心,注册核心能够及时把曾经宕机的服务节点进行剔除,防止资源的节约。 Apache APISIX + Nacos 为用户提供了什么利用场景?Apache APISIX + Nacos 能够将各个微服务节点中与业务无关的各项管制,集中在 Apache APISIX 中进行对立治理,即通过Apache APISIX 实现接口服务的代理和路由转发的能力。各个微服务在 Nacos 上注册后,Apache APISIX 能够通过 Nacos 的服务发现性能获取服务列表,查找对应的服务地址从而实现动静代理。 [外链图片转存失败,源站可能有防盗链机制,倡议将图片保留下来间接上传(img-Sk6XaUbU-1645607132156)(https://tfzcfxawmk.feishu.cn/...)] Apache APISIX 基于 Nacos 实现服务发现前提条件本文操作基于以下环境进行。 操作系统 Centos 7.9。已装置 Apache APISIX 2.12.1,详情请参考:Apache APISIX how-to-bulid。已装置 Nacos 2.0.4,详情请参考:quick start。已装置 Node.js,详情请参考:node.js Installation。步骤一:服务注册应用 Node.js 的 Koa 框架在 3005 端口启动一个简略的测试服务作为上游(Upstream)。const Koa = require('koa');const app = new Koa();app.use(async ctx => { ctx.body = 'Hello World';});app.listen(3005);在命令行中通过申请 Nacos Open API 的形式进行服务注册。curl -X POST 'http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=APISIX-NACOS&ip=127.0.0.1&port=3005&ephemeral=false'执行服务注册后应用以下命令查问以后服务状况。curl -X GET 'http://127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=APISIX-NACOS'正确返回后果示例如下: ...

February 23, 2022 · 2 min · jiezi

关于nacos:nacos和gateway服务路由缓存刷新

gateway的服务注册路由默认是第一次启动的时候就加载,有个监听器RouteRefreshListener类,外面定义了一些事件,比方ContextRefreshEvent,HeartbeatEvent等事件,而后都会调用ApplicationEventPubilsher.publishEvent(new RereshRoutesEvent(this));这里应该就是程序启动时进行的路由刷新操作了。 而后gateway有一个刷新的endpoint,/actuator/gateway/refresh,能够找到这个控制器,外面也调用的ApplicationEventPubilsher.publishEvent(new RereshRoutesEvent(this));办法,这是spring的事件驱动,能够看出gateway都是通过这个事件来触发服务路由设置的。 顺着找到了监听事件的实现类,CachingRouteLocator,这同时也是gateway的缓存路由解决类,这是个包装类(路由配置起源有yaml配置,服务注册核心的配置,这里就蕴含了PropertiesRouteDefinitionLocator,DiscoveryClientRouteDefinitionLocator类),咱们是应用nacos依据服务发现主动配置的,所以咱们关注DiscoveryClientRouteDefinitionLocator这个类。 能够看到外面的getRouteDefinitions()办法,次要就是serviceInstances字段转换成routeDefinition的,而这个serviceInstances是通过DiscoveryClient.getServices()得来的,(这个DiscoveryClient和NacosReactiveDiscoveryClient能够去看我的对于spring和nacos服务注册相干的文章)。 这就是gateway加载nacos注册服务路由的流程。 这里就有个问题了,当nacos新注册一个服务的时候,gateway不晓得,其实nacos有定义一个NacosWatch的bean,这个bean的会应用NamingService.subscribe(serviceName, groupName,clusterName,eventListener)向nacos注册一个监听器,NamingEvent(蕴含实例列表等信息)事件,而后向spring发送一个HeartbeatEvent事件,第一段说了这个事件,触发这个事件是能够刷新路由配置的,然而实际上并不是如此。 因为咱们向nacos注册监听器的时候,有个参数是serviceName,这里默认取的就是以后服务名spring.application.name,只有当这个服务的实例发生变化时才告诉,如果是一个新的服务,则不告诉(这里我本人写了一个监听器,并监听了一个其余服务的名称,那个服务启动时,这边是会触发的)。 我用的nacos版本是2.x的,看了网上的一些文章,如同0.9版本的能够获取到所有服务的变更事件,难道nacos只能启动的时候获取服务列表,前面都不进行动静更新了?目前我还在找这个办法.... https://github.com/theonefx/s...

November 3, 2021 · 1 min · jiezi

关于nacos:Nacos配置文件的实用知识

1、入门在spring cloud生态下应用nacos config很容易,引入pom依赖: <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>创立bootstrap.properties文件,并增加nacos server的连贯地址即可: spring.application.name=demo-apispring.cloud.nacos.config.server-addr=nacos服务器地址spring.cloud.nacos.config.prefix=nacos匹配配置前缀,默认为${spring.application.name}2、配置文件2.1. 规定配置nacos上的dataId残缺格局如下: ${prefix}-${spring.profile.active}.${file-extension}prefix:取自bootstrap配置文件外面spring.cloud.nacos.config.prefix的值,而该配置的默认值又为${spring.application.name}spring.profile.active:取以后环境的profile。如果我的项目spring.profile.active为空,dataId格局变成 ${prefix}.${file-extension}file-exetension:为配置内容的数据格式,能够通过配置项 spring.cloud.nacos.config.file-extension来配置。目前只反对 properties和yaml类型,默认properties。理论测试,如果配置了spring.profile.active,我的项目会被动获取nacos服务器上的配置文件包含:${prefix}-${spring.profile.active}.${file-extension}、${prefix}.${file-extension} 2.2. 共享配置大一点的我的项目,通常须要将配置信息拆分成多个配置文件,如:数据库连贯信息、多语言配置等。因而就存在了两种状况: 一个我的项目会加载多个配置文件。多个我的项目会共享同一个配置文件。此时能够应用 shared-configs 或 extension-configs ,始终没发现二者之间有啥区别,作用和用法根本一样。例如: spring.cloud.nacos.config.shared-configs[0].data-id=mysql.propertiesspring.cloud.nacos.config.shared-configs[0].group=DATABASE_GROUPspring.cloud.nacos.config.shared-configs[1].data-id=redis.propertiesspring.cloud.nacos.config.shared-configs[1].group=DATABASE_GROUPspring.cloud.nacos.config.shared-configs[2].data-id=common-i18n.propertiesspring.cloud.nacos.config.shared-configs[2].group=I18N_GROUPspring.cloud.nacos.config.shared-configs[2].refresh=true上述配置中,将 shared-configs[n] 替换成 extension-configs[n],并没有任何不同。 3. 优先级1.配置文件优先级依照后面介绍的,在应用nacos后,我的项目的配置文件起源多了起来,依照从高到低的优先级程序别离为: 通过外部相干规定 ${prefix}-${spring.profile.active}.${file-extension} 主动生成相干的Data Id配置。通过 extension-configs 形式反对的Data Id配置。通过 shared-configs 形式反对的Data Id配置。2. 共享配置外部优先级共享配置 shared-configs[n]、extension-configs[n]外部,n的值越大,优先级越高。 后面的例子中优先级程序:common-i18n.properties > redis.properties > mysql.properties 3. 本地优先级如果在配置文件中开启了nacos config,在nacos服务器和我的项目本地,都创立了同样的配置文件。nacos服务器上的配置项,优先级比本地高。 4. 通过日志查看优先级当你切实搞不清naco配置文件加载的优先级时,不要慌,间接看启动我的项目日志即可。 在spring我的项目中开启nacos config后,启动我的项目会在控制台打印出nacos加载的所有配置文件,而且依照优先级程序从前往后排序。 如依照后面的配置,打印进去的日志为: [PropertySourceBootstrapConfiguration.java:112] [] [ ] - Located property source: [BootstrapPropertySource {name='bootstrapProperties-demo-api-native.properties,DEFAULT_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-demo-api.properties,DEFAULT_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-demo-api,DEFAULT_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-common-i18n.properties,I18N_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-redis.properties,DATABASE_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-mysql.properties,DATABASE_GROUP'}] ...

September 3, 2021 · 1 min · jiezi

关于nacos:06篇-Nacos-Client本地缓存及故障转移

学习不必那么功利,二师兄带你从更高维度轻松浏览源码~本篇文章咱们来通过源码剖析一下Nacos的本地缓存及故障转移性能,波及到外围类为ServiceInfoHolder和FailoverReactor。 ServiceInfoHolder性能概述ServiceInfoHolder类,顾名思义,服务信息的持有者。后面文章曾经屡次波及到ServiceInfoHolder类,比方每次客户端从注册核心获取新的服务信息时都会调用该类的processServiceInfo办法来进行本地化的解决,包含更新缓存服务、公布事件、更新本地文件等。 除了上述性能,该类在实例化时,还做了蕴含本地缓存目录初始化、故障转移初始化等操作。上面咱们就逐个剖析一下。 ServiceInfo的本地内存缓存ServiceInfo,注册服务的信息,其中蕴含了服务名称、分组名称、集群信息、实例列表信息、上次更新工夫等。也就是说,客户端从注册核心获取到的信息在本地都以ServiceInfo作为承载着。 而ServiceInfoHolder类又持有了ServiceInfo,通过一个ConcurrentMap来存储: public class ServiceInfoHolder implements Closeable { private final ConcurrentMap<String, ServiceInfo> serviceInfoMap;}这就是Nacos客户端对服务注册信息的第一层缓存。后面剖析processServiceInfo办法时,咱们曾经看到,当服务信息变更时会第一工夫更新serviceInfoMap中的信息。 public ServiceInfo processServiceInfo(ServiceInfo serviceInfo) {// .... // 缓存服务信息 serviceInfoMap.put(serviceInfo.getKey(), serviceInfo); // 判断注册的实例信息是否已变更 boolean changed = isChangedServiceInfo(oldService, serviceInfo); if (StringUtils.isBlank(serviceInfo.getJsonFromServer())) { serviceInfo.setJsonFromServer(JacksonUtils.toJson(serviceInfo)); } // ....}对于serviceInfoMap的应用就这么简略,当变动实例向其中put最新数据即可。当应用实例,依据key进行get操作即可。 而serviceInfoMap在ServiceInfoHolder的构造方法中进行初始化,默认创立一个空的ConcurrentMap。但当配置了启动时从缓存文件读取信息时,则会从本地缓存进行加载。 // 启动时是否从缓存目录读取信息,默认false。设置为true会读取缓存文件if (isLoadCacheAtStart(properties)) { this.serviceInfoMap = new ConcurrentHashMap<String, ServiceInfo>(DiskCache.read(this.cacheDir));} else { this.serviceInfoMap = new ConcurrentHashMap<String, ServiceInfo>(16);}这里波及到了本地缓存目录,在processServiceInfo办法中,当服务实例变更时,会看到通过DiskCache#write办法向该目录写入ServiceInfo信息。 // 服务实例已变更if (changed) { NAMING_LOGGER.info("current ips:(" + serviceInfo.ipCount() + ") service: " + serviceInfo.getKey() + " -> " + JacksonUtils.toJson(serviceInfo.getHosts())); // 增加实例变更事件,会被推动到订阅者执行 NotifyCenter.publishEvent(new InstancesChangeEvent(serviceInfo.getName(), serviceInfo.getGroupName(), serviceInfo.getClusters(), serviceInfo.getHosts())); // 记录Service本地文件 DiskCache.write(serviceInfo, cacheDir);}上面就来聊聊本地缓存目录。 ...

August 18, 2021 · 3 min · jiezi

关于nacos:跟二师兄学Nacos02篇-Nacos的临时与持久化实例傻傻分不清

学习不必那么功利,二师兄带你从更高维度轻松浏览源码~本篇文章Nacos外围逻辑篇,给大家解说一下「长期实例」与「长久化实例」的区别及使用场景。 Nacos的长期实例与长久化实例在Nacos Client进行实例注册时,咱们晓得是通过Instance对象来携带实例的根本信息的。在Instance中有一个ephemeral字段,用来示意该实例是长期实例,还是长久化实例。 public class Instance implements Serializable { /** * If instance is ephemeral. * * @since 1.0.0 */ private boolean ephemeral = true; // 省略其余}从源码能够看出ephemeral字段是1.0.0版本新增的,用来示意注册的实例是否是长期实例还是长久化实例。 目前,无论是Nacos 1.x版本,还是2.x版本,ephemeral的默认值都是true。在1.x版本中服务注册默认采纳http协定,2.x版本默认采纳grpc协定,但这都未影响到ephemeral字段的默认值。 也就是说,始终以来,Nacos实例默认都是以长期实例的模式进行注册的。 当然,也是能够通过application的配置来扭转这里默认值的。比方: # false为永恒实例,true示意长期实例spring.cloud.nacos.discovery.ephemeral=false下面是基于Spring Cloud进行配置,false为永恒实例,true示意长期实例,默认为true。 长期实例与长久化实例的区别长期实例与长久化实例的区别次要体现在服务器对该实例的解决上。 长期实例向Nacos注册,Nacos不会对其进行长久化存储,只能通过心跳形式保活。默认模式是:客户端心跳上报Nacos实例衰弱状态,默认距离5秒,Nacos在15秒内未收到该实例的心跳,则会设置为不衰弱状态,超过30秒则将实例删除。 长久化实例向Nacos注册,Nacos会对其进行长久化解决。当该实例不存在时,Nacos只会将其衰弱状态设置为不衰弱,但并不会对将其从服务端删除。 另外,能够应用实例的ephemeral来判断健康检查模式,ephemeral为true对应的是client模式(客户端心跳),为false对应的是server模式(服务端查看)。 为什么要设计两种模式?下面说了两种模式的不同和解决上的区别,那么Nacos为什么设计两种模式,它们是为了应答什么样的场景而存在呢? 对于长期实例,健康检查失败,则间接能够从列表中删除。这种个性就比拟适宜那些须要应答流量突增的场景,服务能够进行弹性扩容。当流量过来之后,服务停掉即可主动登记了。 对于长久化实例,健康检查失败,会被标记成不衰弱状态。它的益处是运维能够实时看到实例的衰弱状态,便于后续的正告、扩容等一些列措施。 除了上述场景之外,长久化实例还有另外一个场景用的到,那就是爱护阈值。 Nacos的爱护阈值对于爱护阈值,在后面的文章中专门写到过。 Nacos中能够针对具体的实例设置一个爱护阈值,值为0-1之间的浮点类型。实质上,爱护阈值是⼀个⽐例值(以后服务衰弱实例数/以后服务总实例数)。 ⼀般状况下,服务消费者要从Nacos获取可⽤实例有衰弱/不衰弱状态之分。Nacos在返回实例时,只会返回衰弱实例。 但在⾼并发、⼤流量场景会存在⼀定的问题。比方,服务A有100个实例,98个实例都处于不衰弱状态,如果Nacos只返回这两个衰弱实例的话。流量洪峰的到来可能会间接打垮这两个服务,进一步产生雪崩效应。 爱护阈值存在的意义在于当服务A衰弱实例数/总实例数 < 爱护阈值时,阐明衰弱的实例不多了,爱护阈值会被触发(状态true)。 Nacos会把该服务所有的实例信息(衰弱的+不衰弱的)全副提供给消费者,消费者可能拜访到不衰弱的实例,申请失败,但这样也⽐造成雪崩要好。就义了⼀些申请,保障了整个零碎的可⽤。 这里咱们看到了不衰弱实例的另外一个作用:避免产生雪崩。 那么,如果所有的实例都是长期实例,当雪崩场景产生时,Nacos的阈值爱护机制是不是就没有足够的(蕴含不衰弱实例)实例返回了?如果有一部分实例是长久化实例,即使它们曾经挂掉,状态为不衰弱的,但当触发阈值爱护时,还是能够起到分流的作用。 小结对于Nacos长期实例与长久化实例就聊这么多了。如果想更深刻理解,其实能够读一下源码。因为基于gRPC的实现过于简单,可读性不够强,如果想浏览,倡议浏览基于Http的实现。 如果文章内容有问题或想技术探讨请分割我(微信:zhuan2quan,备注Nacos),如果感觉写的还不错,值得一起学习,那就关注一下吧。 博主简介:《SpringBoot技术底细》技术图书作者,热爱钻研技术,写技术干货文章。 公众号:「程序新视界」,博主的公众号,欢送关注~ 技术交换:请分割博主微信号:zhuan2quan

August 5, 2021 · 1 min · jiezi

关于nacos:Nacosnacos启动报orgspringUnable-to-start-embedded-Tomcat错

nacos启动报org.springframework.context.ApplicationContextException: Unable to start web server; nested错

July 29, 2021 · 1 min · jiezi

关于nacos:nacos学习

摘要nacos作为微服务项目的注册核心、配置核心;同时也作为大数据我的项目文件配置。 内容1.nacos源码nacos源码分析:https://www.cnblogs.com/dyg08... 2.nacos源码编译部署参考官网:https://nacos.io/zh-cn/docs/q...

July 23, 2021 · 1 min · jiezi

关于nacos:跟二师兄学Nacos吧EXT03篇-Nacos中此处为什么采用反射机制

学习不必那么功利,二师兄带你从更高维度轻松浏览源码~大家可能看到过很多写Java反射机制的文章,但如果在浏览源码的过程中,遇到反射机制的应用,你是否想过为什么要这么用吗? 这篇文章就带大家来看看Nacos中对Java反射机制的一处实际案例。这篇文章既属于知识点的剖析,也属于Nacos设计层面的剖析。 Nacos中反射机制实际先来介绍一下Nacos反射机制应用的背景。 nacos-client我的项目中,能够通过NacosFactory取得NamingService,而后基于NamingService来进行服务实例的注册性能: NamingService namingService = NacosFactory.createNamingService(properties);namingService.registerInstance("nacos.test.1", instance);而在NacosFactory中又是基于NamingFactory来实现NamingService的创立的: public static NamingService createNamingService(Properties properties) throws NacosException { return NamingFactory.createNamingService(properties);}NamingFactory具体创立局部代码如下: public static NamingService createNamingService(Properties properties) throws NacosException { try { Class<?> driverImplClass = Class.forName("com.alibaba.nacos.client.naming.NacosNamingService"); Constructor constructor = driverImplClass.getConstructor(Properties.class); return (NamingService) constructor.newInstance(properties); } catch (Throwable e) { throw new NacosException(NacosException.CLIENT_INVALID_PARAM, e); }}到这里,终于看到了反射机制的应用了,通过Class#forName办法获取Class对象,而后获取构造方法,创立实例。 如果你浏览源码时只看到这些,可能你会错过一些有意思的设计和事件。你是否思考过,为什么这里要采纳反射机制呢?间接new一个对象不行吗? 在解答上述问题之前,咱们先来简略科普一下Java发反射机制。 Java反射机制这里从基本概念、原理、简略实际说起。 Java反射简介Java是预编的语言,对象的类型在编译期曾经确定。在程序运行时可能须要动静加载某些类,这些类之前用不到,所以就没有被加载到JVM中。须要时,可通过反射在运行时动静地创建对象并调用其属性或办法,而不须要在编译期就晓得运行的对象是谁。 Java反射机制的外围是在程序运行时动静加载类并获取类的详细信息,从而可能操作类或对象的属性和办法。 Java反射的优缺点Java反射的长处: 减少程序的灵活性,防止将程序写死到代码里;代码简洁,进步代码的复用率,内部调用不便;对于任意一个类,都可能晓得这个类的所有属性和办法;对于任意一个对象,都可能调用它的任意一个办法;反射的原理在理解反射的基本原理之前,咱们须要晓得在Java程序编译实现之后,会把所有class文件中所蕴含的类的根本元信息装载到JVM内存中,以Class类的模式保留。Class类可了解为形容类的类,每一个Class类对象代表一个具体类的根本元信息。反射就是在Class类的根底上进行的,Class类对象存储着类的所有相干信息。 对于JVM外部的操作步骤,咱们这里不做拓展。须要理解的就是Class对象是JVM加载.class文件之后生成的对象,而反射机制提供了获取该对象,能够基于此进行属性拜访或对象结构。而这一步是产生在运行时期间。 反射的根本应用通常应用反射有三种形式: // 形式一:应用Class.forName静态方法Class clz = Class.forName("java.lang.String");// 形式二:应用.class办法Class clz = String.class;// 形式三:应用类对象的getClass()办法String str = new String("Hello");Class clz = str.getClass();上述三种形式,个别罕用第一种,字符串参数能够传入也能够写在配置文件中。第二种须要导入类包,依赖太强,不导包就抛编译谬误。第三种对象都有了还要反射干什么。 ...

July 23, 2021 · 1 min · jiezi

关于nacos:nacos第二章

Nacos 反对服务注册与发现,能够说这个性能时每一个服务治理的根底性能,其余模块都是基于服务注册与发现实现的。开始实操练习:在Nacos源码中有个model是example[nacos-example],这个模块在develop分支中有三个demo类, App.java、ConfigExample.java、NamingExample.java这一节次要介绍下这个NamingExample.java类,代码如下: public class NamingExample { public static void main(String[] args) throws NacosException { /* 设置属性, serverAddr:连贯nacos的ip与port namespace:命名空间如果不设置则默认是public 设置的话须要在nacos console上也创立好,否则找不到相应服务的 */ Properties properties = new Properties(); properties.setProperty("serverAddr", System.getProperty("serverAddr")); properties.setProperty("namespace", System.getProperty("namespace")); /* * 这是一个工厂办法,用来创立NamingService的实现类 */ NamingService naming = NamingFactory.createNamingService(properties); /* * 向nacos注册服务 */ naming.registerInstance("nacos.test.3", "11.11.11.11", 8888, "TEST1"); naming.registerInstance("nacos.test.3", "2.2.2.2", 9999, "DEFAULT"); /* * 获取服务名称为nacos.test.3的所有实例信息 */ System.out.println(naming.getAllInstances("nacos.test.3")); /* * 与 registerInstance 相同,这个是登记服务实例的 */ naming.deregisterInstance("nacos.test.3", "2.2.2.2", 9999, "DEFAULT"); System.out.println(naming.getAllInstances("nacos.test.3")); /* * 订阅服务 */ naming.subscribe("nacos.test.3", new EventListener() { @Override public void onEvent(Event event) { System.out.println(((NamingEvent) event).getServiceName()); System.out.println(((NamingEvent) event).getInstances()); } }); }}当初一一办法来看一边 ...

July 10, 2021 · 2 min · jiezi

关于nacos:解决Nacos-单机模式下报错server-is-DOWN-nowplease-try-again-later

原文地址:Nacos 单机模式下报错:server is DOWN now,please try again later! 问题形容Spring Boot利用启动时连贯 Nacos 失败,报如下谬误: com.alibaba.nacos.api.exception.NacosException: failed to req API:/nacos/v1/ns/instance after all servers([127.0.0.1:8848]) tried: ErrCode:503, ErrMsg:server is DOWN now, please try again later! at com.alibaba.nacos.client.naming.net.NamingProxy.reqApi(NamingProxy.java:552) ~[nacos-client-1.3.3.jar:na] at com.alibaba.nacos.client.naming.net.NamingProxy.reqApi(NamingProxy.java:491) ~[nacos-client-1.3.3.jar:na] at com.alibaba.nacos.client.naming.net.NamingProxy.reqApi(NamingProxy.java:486) ~[nacos-client-1.3.3.jar:na]解决删除 nacos 目录下 data/protocol 目录,重新启动 nacos 服务。 cd nacos/data# 删除 protocol 目录rm -rf protocol/# 重启sh startup.sh -m standalone

July 8, 2021 · 1 min · jiezi

关于nacos:深入浅出讲解MSE-Nacos-20新特性

简介:随着云原生时代的到来,微服务曾经成为利用架构的支流,Nacos也凭借简略易用、稳固牢靠、性能卓越的外围竞争力成为国内微服务畛域首选的注册核心和配置核心;Nacos2.0更是把性能做到极致,让业务疾速倒退的用户再也不必放心性能问题;同时阿里云MSE也提供Nacos2.0托管服务,一键开明享受阿里十年积淀微服务所有能力! 作者|风卿 前言MSE从2020年1月公布Nacos1.1.3版本引擎,反对在私有云环境全托管的形式应用Nacos作为注册核心。2020年7月公布Nacos1.2.1版本反对元配置数据管理,反对微服务利用在运行时动静批改配置信息和路由规定等。随着用户的深刻应用,Nacos1.X版本的性能问题也慢慢裸露进去。通过对1.X版本的内核革新,Nacos2.0专业版性能晋升10倍,根本能满足用户对微服务场景的性能要求。 除了性能的晋升,专业版具备更高的SLA保障,并且在配置数据上具备更高的安全性,同时通过MCP协定与Istio生态买通,作为Istio的注册核心。 MSE Nacos1.X根底版架构整体1.X架构能够粗略分为五层,别离是接入层、通信层、性能层、同步层和长久化层。 • 用户通过接入层拜访Nacos,比方SDK、SCA、Dubbo、Console,Nacos也提供了HTTP协定的open API拜访形式。 • 通信层蕴含HTTP和UDP,Nacos次要通过HTTP进行通信,少部分服务推送性能会用到UDP。 • 性能层目前有Naming和Config两大部分,别离提供服务发现和配置管理能力。 • 同步层蕴含AP模式的Distro协定(服务注册)和CP模式的Raft协定(服务元信息),以及配置告诉的Notify同步形式 • Nacos的数据长久化有用到Mysql、Derby和本地文件,配置数据、用户信息、权限数据存储在Mysql或者Derby中,长久化的服务数据则寄存在本地文件 MSE Nacos1.X根底版架构问题目前1.X的架构存在几个问题: • 每个服务实例都通过心跳续约,在Dubbo场景每个接口对应一个服务,当Dubbo的利用接口数较多时须要心跳续约TPS会很高。 • 心跳续约感知时缩短,须要达到续约超时工夫能力删除实例,个别须要15S,时效性较差 • 通过UDP推送变更数据不牢靠,须要客户端定时进行数据全量对账保证数据的正确性,大量有效查问,整体服务的QPS很高 • 通信形式基于HTTP短链接的形式,Nacos侧开释连贯会进入TIME_WAIT状态,当QPS较高时会有连贯耗尽导致报错的危险,当然这里通过SDK引入HTTP连接池能缓解,但不能根治 • 配置的长轮询形式会导致相干数据进入JVM Old区申请和开释内存,引起频繁的CMS GC MSE Nacos2.0专业版架构及新模型1.X架构的问题外围点在于连贯模型上,2.0架构降级为长连贯模型,在通信层通过gRPC和RSocket实现长连贯数据传输和推送能力,在连贯层新减少申请处理器、流控和负载平衡等性能 2.0架构解决的问题: • 利用POD依照长连贯维度进行心跳续约,不须要依照实例级,大大降低反复申请 • 长连贯断开时能够疾速感知到,不必期待续约超时时长就能够移除实例 • NIO流式推送机制绝对于UDP更牢靠,并且能够升高利用对账数据频率 • 没有连贯重复创立的开销,大幅升高TIME_WAIT连贯多问题 • 长连贯也解决了配置模块长轮询CMS GC问题 2.0架构带来的问题: • 绝对于Tomcat HTTP短连贯模型,长连贯模型须要本人治理连贯状态,减少了复杂性• 长连贯gRPC基于HTTP2.0 Stream,绝对于HTTP的open API可观测性和易用性升高了 2.0架构整体来说升高了资源开销,进步了零碎吞吐量,在性能上有大幅晋升,但同时也减少了复杂度 MSE Nacos2.0专业版性能Nacos分为服务发现模块和配置管理模块,这里先对服务发现场景进行性能测试。 应用200台施压机,每个施压机模仿500个客户端,每个客户端注册5个服务,订阅5个服务,最高能够提供10W个长连贯、50W个服务实例和订阅者压测场景 服务发现压测次要压变更态和稳固态两种场景: • 变更态:施压机施压阶段会大量连贯Nacos注册和订阅服务,这个阶段服务端的压力绝对会比拟大,须要看整体注册和订阅是否最终齐全胜利。 • 稳固态:当施压机申请都胜利之后就会进入稳固状态,客户端和服务端之间只须要维持长连贯心跳即可,这个阶段服务端的压力会比拟小。如果在变更态服务端的压力过大会产生申请超时、连贯断开等问题,不能进入稳固态 服务发现也会在MSE上对低版本做降级,比照降级前后的性能变动曲线,这样的性能比照更直观 配置管理模块在理论应用中是写少读多的场景,次要瓶颈点在单台机器性能上,压测场景次要基于单台机器的读性能和连贯撑持数 ...

July 7, 2021 · 1 min · jiezi

关于nacos:Nacos-20-升级前后性能对比压测

简介: Nacos 2.0 通过降级通信协议和框架、数据模型的形式将性能晋升了约 10 倍,解决继 Nacos 1.0 公布逐渐裸露的性能问题。本文通过压测 Nacos 1.0,Nacos 1.0 降级 Nacos 2.0 过程中,Nacos 2.0 进行全面性能比照,直观的展现 Nacos 2.0 所带来的性能晋升。作者|席翁 Nacos 2.0 通过降级通信协议和框架、数据模型的形式将性能晋升了约 10 倍,解决继 Nacos 1.0 公布逐渐裸露的性能问题。本文通过压测 Nacos 1.0,Nacos 1.0 降级 Nacos 2.0 过程中,Nacos 2.0 进行全面性能比照,直观的展现 Nacos 2.0 所带来的性能晋升。 压测筹备 环境筹备为了不便 Nacos 部署降级和展现外围性能指标,咱们是从阿里云微服务引擎 MSE(_https://cn.aliyun.com/product...)中购买的一个 2 核 CPU+4G 内存的三节点 Nacos 集群。 压测模型为了展现不同规模下的零碎体现,咱们采纳逐渐增压的形式进行压测,将压力分为 3个批次进行逐渐启动,并察看每个批次下集群的运行体现。同时会在压力集群之外,再减少一个 Dubbo 服务的 Demo ,并应用 Jmeter 以 100 TPS 的压力不停的调用,以模仿不同压力下,对理论业务调用存在的可能影响。 压测过程中,会在适当的时候对服务端和客户端进行降级;服务端的降级将间接应用 MSE 提供的一键降级性能,客户端的降级会应用分批次轮流重启的形式进行。 压测过程 Nacos1.X Server + Nacos1.X Client ...

July 7, 2021 · 1 min · jiezi

关于nacos:Docker环境下Nacos使用MySQL存储

1、Docker下载镜像docker pull nacos/nacos-server笔者下载时曾经到1.3.2 其中mysqljar曾经更新至8.0.16 2、创立数据库create database nacos_confighttps://github.com/alibaba/na... 复制sql并执行 3、创立Nacos容器docker run -d \-e PREFER_HOST_MODE=hostname \-e MODE=standalone \-e SPRING_DATASOURCE_PLATFORM=mysql \-e MYSQL_MASTER_SERVICE_HOST=数据库ip \-e MYSQL_MASTER_SERVICE_PORT=数据库端口 \-e MYSQL_MASTER_SERVICE_USER=用户名 \-e MYSQL_MASTER_SERVICE_PASSWORD=明码 \-e MYSQL_MASTER_SERVICE_DB_NAME=对应的数据库名 \-e MYSQL_SLAVE_SERVICE_HOST=从数据库ip \-p 8848:8848 \--name nacos-sa-mysql \--restart=always \nacos/nacos-server4、批改容器docker exec -it nacos bash#进入nacos容器:docker exec -it nacos bash #进入conf文件夹cd conf#批改配置参数vim application.properties# springserver.servlet.contextPath=${SERVER_SERVLET_CONTEXTPATH:/nacos}server.contextPath=/nacosserver.port=${NACOS_APPLICATION_PORT:8848}spring.datasource.platform=${SPRING_DATASOURCE_PLATFORM:mysql}nacos.cmdb.dumpTaskInterval=3600nacos.cmdb.eventTaskInterval=10nacos.cmdb.labelTaskInterval=300nacos.cmdb.loadDataAtStart=falsedb.num=${MYSQL_DATABASE_NUM:1}db.url.0=jdbc:mysql://${MYSQL_SERVICE_HOST:mysql地址}:${MYSQL_SERVICE_PORT:端口}/${MYSQL_SERVICE_DB_NAME:数据库名}?serverTimezone=GMT%2B8&characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true#db.url.1=jdbc:mysql://${MYSQL_SERVICE_HOST}:${MYSQL_SERVICE_PORT:3306}/${MYSQL_SERVICE_DB_NAME}?serverTimezone=GMT%2B8&characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=truedb.user=${MYSQL_SERVICE_USER:oam}db.password=${MYSQL_SERVICE_PASSWORD:Ssl_qjy&^986_}### The auth system to use, currently only 'nacos' is supported:nacos.core.auth.system.type=${NACOS_AUTH_SYSTEM_TYPE:nacos}### The token expiration in seconds:nacos.core.auth.default.token.expire.seconds=${NACOS_AUTH_TOKEN_EXPIRE_SECONDS:18000}### The default token:nacos.core.auth.default.token.secret.key=${NACOS_AUTH_TOKEN:SecretKey012345678901234567890123456789012345678901234567890123456789}### Turn on/off caching of auth information. By turning on this switch, the update of auth information would have a 15 seconds delay.nacos.core.auth.caching.enabled=${NACOS_AUTH_CACHE_ENABLE:false}server.tomcat.accesslog.enabled=${TOMCAT_ACCESSLOG_ENABLED:false}server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D# default current work dirserver.tomcat.basedir=## spring security config### turn off securitynacos.security.ignore.urls=/,/error,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/v1/auth/**,/v1/console/health/**,/actuator/**,/v1/console/server/**# metrics for elastic searchmanagement.metrics.export.elastic.enabled=falsemanagement.metrics.export.influx.enabled=falsenacos.naming.distro.taskDispatchThreadCount=10nacos.naming.distro.taskDispatchPeriod=200nacos.naming.distro.batchSyncKeyCount=1000nacos.naming.distro.initDataRatio=0.9nacos.naming.distro.syncRetryDelay=5000nacos.naming.data.warmup=true相干文章:DOCKER内部署单机NACOS应用MYSQL8.0存储SpringCloud Alibaba之Nacos集群、长久化 ...

May 10, 2021 · 1 min · jiezi

关于nacos:小白也能懂的-Nacos-服务模型介绍

简介:了解了 Nacos 的服务模型,也有利于咱们理解 Nacos 背地的工作原理,从而确保咱们正确地应用 Nacos。作者:岛风前言依照目前市场上的支流应用场景,Nacos 被分成了两块性能:服务注册发现(Naming)和配置核心(Config)。在之前的文章中我介绍了 Nacos 配置核心的实现原理,明天这篇文章所介绍的内容则是与 Nacos 服务注册发现性能相干,来聊一聊 Nacos 的服务模型。说到服务模型,其实须要辨别视角,一是用户视角,一个内核视角。即 Nacos 用户视角看到的服务模型和 Nacos 开发者设计的内核模型可能是齐全不一样的,而明天的文章,是站在用户视角察看的,旨在探讨 Nacos 服务发现的最佳实际。服务模型介绍个别我在聊注册核心时,都会以 Zookeeper 为引子,这也是很多人最相熟的注册核心。但如果你真的写过或看过应用 Zookeeper 作为注册核心的适配代码,会发现并不是那么容易,再加上注册核心波及到的一致性原理,这就导致很多人对注册核心的第一印象是:这个货色好难! 但归根到底是因为 Zookeeper 基本不是专门为注册核心而设计的,其提供的 API 以及内核设计,并没有预留出「服务模型」的概念,这就使得开发者须要自行设计一个模型,去填补 Zookeeper 和服务发现之间的鸿沟。微服务架构逐步深入人心后,Nacos、Consul、Eureka 等注册核心组件进入公众的眼帘。能够发现,这些”真正“的注册核心都有各自的「服务模型」,在应用上也更加的不便。为什么要有「服务模型」?实践上,一个根底组件能够被塑造成任意的模样,如果你违心,一个数据库也能够被设计成注册核心,这并不是”夸大“的修辞手法,在阿里还真有人这么干过。那么代价是什么呢?肯定会在业务倒退到肯定体量后遇到瓶颈,肯定会遇到某些极其 case 导致其无奈失常工作,肯定会导致其扩展性低下。正如刚学习数据结构时,同学们常见的一个疑难一样:为什么栈只能先进后出。不是所有开发都是中间件专家,所以 Nacos 设计了本人的「服务模型」,这尽管限度了使用者的”想象力“,但保障了使用者在正确地应用 Nacos。花了肯定的篇幅介绍 Nacos 为什么须要设计「服务模型」,再来看看理论的 Nacos 模型是个啥,其实没那么玄乎,一张图就能表白分明: 与 Consul、Eureka 设计有别,Nacos 服务发现应用的畛域模型是命名空间-分组-服务-集群-实例这样的多层构造。服务 Service 和实例 Instance 是外围模型,命名空间 Namespace 、分组 Group、集群 Cluster 则是在不同粒度实现了服务的隔离。为了更好的了解两个外围模型:Service 和 Instance,咱们以 Dubbo 和 SpringCloud 这两个曾经适配了 Nacos 注册核心的微服务框架为例,介绍下二者是如何映射对应模型的。• Dubbo。将接口三元组(接口名+分组名+版本号)映射为 Service,将实例 IP 和端口号定义为 Instance。一个典型的注册在 Nacos 中的 Dubbo 服务:providers:com.alibaba.mse.EchoService:1.0.0:DUBBO• Spring Cloud。将利用名映射为 Service,将实例 IP 和端口号定义为 Instance。一个典型的注册在 Nacos 中的 Spring Cloud 服务:helloApp上面咱们将会更加具体地阐释 Nacos 提供的 API 和服务模型之间的关系。环境筹备须要部署一个 Nacos Server 用于测试,我这里抉择间接在 https://mse.console.aliyun.com/ 购买一个 MSE 托管的 Nacos,读者们能够抉择购买 MSE Nacos 或者自行搭建一个 Nacos Server。MSE Nacos 提供的可视化控制台,也能够帮忙咱们更好的了解 Nacos 的服务模型。下文的一些截图,均来自 MSE Nacos 的商业化控制台。疾速开始先来实现一个最简略的服务注册与发现 demo。Nacos 反对从客户端注册服务实例和订阅服务,具体代码如下:Properties properties = new Properties();properties.setProperty(PropertyKeyConst.SERVER_ADDR, "mse-xxxx-p.nacos-ans.mse.aliyuncs.com:8848");String serviceName = "nacos.test.service.1";String instanceIp = InetAddress.getLocalHost().getHostAddress();int instancePort = 8080;namingService.registerInstance(serviceName, instanceIp, instancePort);System.out.println(namingService.getAllInstances(serviceName));上述代码定义了一个 service:nacos.test.service.1;定义了一个 instance,以本机 host 为 IP 和 8080 为端口号,察看理论的注册状况:并且控制台也打印出了服务的详情。至此一个最简略的 Nacos 服务发现 demo 就曾经实现了。对一些细节稍作解释:• 属性 PropertyKeyConst.SERVER_ADDR 示意的是 Nacos 服务端的地址。• 创立一个 NamingService 实例,客户端将为该实例创立独自的资源空间,包含缓存、线程池以及配置等。Nacos 客户端没有对该实例做单例的限度,请小心保护这个实例,以防新建多于预期的实例。• 注册服务 registerInstance 应用了最简略的重载办法,只须要传入服务名、IP、端口就能够。上述的例子中,并没有呈现 Namespace、Group、Cluster 等前文提及的服务模型,我会在上面一节具体介绍,这个例子次要是为了演示 Nacos 反对的一些缺省配置,其中 Service 和 Instance 是必不可少的,这也验证了前文提到的服务和实例是 Nacos 的一等公民。通过截图咱们能够发现缺省配置的默认值:• Namespace:默认值是 public 或者空字符串,都能够代表默认命名空间。• Group:默认值是 DEFAULT_GROUP。• Cluster:默认值是 DEFAULT。构建自定义实例为了展现出 Nacos 服务模型的全貌,还须要介绍下实例相干的 API。例如咱们心愿注册的实例中,有一些可能被调配更多的流量;或者可能传入一些实例的元信息存储到 Nacos 服务端,例如 IP 所属的利用或者所在的机房,这样在客户端能够依据服务下挂载的实例元信息,来自定义负载平衡模式。Nacos 也提供了另外的注册实例接口,使得用户在注册实例时能够指定实例的属性:/** ...

April 14, 2021 · 3 min · jiezi

关于nacos:重磅官宣Nacos20-发布性能提升-10-倍

简介: 继 Nacos 1.0 公布以来,Nacos 迅速被成千上万家企业采纳,并构建起弱小的生态。然而随着用户深刻应用,逐步裸露一些性能问题,因而咱们启动了 Nacos 2.0 的隔代产品设计,时隔半年咱们终于将其全副实现,实测性能晋升 10 倍,置信能满足所有用户的性能需求。上面由我代表社区为大家介绍一下这款跨代产品。 作者 | 席翁起源 | 阿里巴巴云原生公众号 继 Nacos 1.0 公布以来,Nacos 迅速被成千上万家企业采纳,并构建起弱小的生态。然而随着用户深刻应用,逐步裸露一些性能问题,因而咱们启动了 Nacos 2.0 的隔代产品设计,时隔半年咱们终于将其全副实现,实测性能晋升 10 倍,置信能满足所有用户的性能需求。上面由我代表社区为大家介绍一下这款跨代产品。 Nacos 简介Nacos 是一个更易于构建云原生利用的动静服务发现、配置管理和服务治理平台。它孵化于阿里巴巴,成长于十年双十一的洪峰考验,积淀了简略易用、稳固牢靠、性能卓越的外围竞争力。 Nacos 2.0 架构全新 2.0 架构不仅将性能大幅晋升 10 倍,而且内核进行了分层形象,并且实现插件扩大机制。 Nacos 2.0 架构档次如下图,它相比Nacos1.X的最次要变动是: 通信层对立到 gRPC 协定,同时欠缺了客户端和服务端的流量管制和负载平衡能力,晋升的整体吞吐。将存储和一致性模型做了充沛形象分层,架构更简略清晰,代码更加强壮,性能更加强悍。设计了可拓展的接口,晋升了集成能力,如让用户扩大实现各自的平安机制。 Nacos2.0 服务发现降级一致性模型Nacos2.0 架构下的服务发现,客户端通过 gRPC,发动注册服务或订阅服务的申请。服务端应用 Client 对象来记录该客户端应用 gRPC 连贯公布了哪些服务,又订阅了哪些服务,并将该 Client 进行服务间同步。因为理论的应用习惯是服务到客户端的映射,即服务下有哪些客户端实例;因而 2.0 的服务端会通过构建索引和元数据,疾速生成相似 1.X 中的 Service 信息,并将 Service 的数据通过  gRPC Stream 进行推送。 Nacos2.0 配置管理降级通信机制配置管理之前用 Http1.1 的 Keep Alive 模式 30s 发一个心跳模仿长链接,协定难以了解,内存耗费大,推送性能弱,因而 2.0 通过 gRPC 彻底解决这些问题,内存耗费大量升高。 ...

April 6, 2021 · 2 min · jiezi

关于nacos:重磅官宣Nacos20发布性能提升10倍

简介: Nacos2.0 作为一个跨代版本,彻底解决了 Nacos1.X 的性能问题,将性能晋升了 10 倍。 作者:席翁 继 Nacos 1.0 公布以来,Nacos 迅速被成千上万家企业采纳,并构建起弱小的生态。 然而随着用户深刻应用,逐步裸露一些性能问题,因而咱们启动了 Nacos 2.0 的隔代产品设计,时隔半年咱们终于将其全副实现,实测性能晋升10倍,置信能满足所有用户的性能需求。上面由我代表社区为大家介绍一下这款跨代产品。 Nacos 简介Nacos 是一个更易于构建云原生利用的动静服务发现、配置管理和服务治理平台。它 孵化于 阿里巴巴,成长于十年双十一的洪峰考验,积淀了简略易用、稳固牢靠、性能卓越的外围竞争力。 Nacos 2.0 架构全新2.0 架构不仅将性能大幅晋升10倍,而且内核进行了分层形象,并且实现插件扩大机制。 Nacos 2.0 架构档次如下图,它相比Nacos1.X的最次要变动是: 通信层对立到gRPC协定,同时欠缺了客户端和服务端的流量管制和负载平衡能力,晋升的整体吞吐。将存储和一致性模型做了充沛形象分层,架构更简略清晰,代码更加强壮,性能更加强悍。设计了可拓展的接口,晋升了集成能力,如让用户扩大实现各自的平安机制。 Nacos2.0 服务发现降级一致性模型Nacos2架构下的服务发现,客户端通过Grpc,发动注册服务或订阅服务的申请。服务端应用Client对象来记录该客户端应用Grpc连贯公布了哪些服务,又订阅了哪些服务,并将该Client进行服务间同步。因为理论的应用习惯是服务到客户端的映射,即服务下有哪些客户端实例;因而2.0的服务端会通过构建索引和元数据,疾速生成相似1.X中的Service信息,并将Service的数据通过Grpc Stream进行推送。 Nacos2.0 配置管理降级通信机制配置管理之前用Http1.1的Keep Alive模式30s发一个心跳模仿长链接,协定难以了解,内存耗费大,推送性能弱,因而2.0通过gRPC彻底解决这些问题,内存耗费大量升高。 Nacos2.0 架构劣势Nacos2.0大幅升高了资源耗费,晋升吞吐性能,优化客户端和服务端交互,对用户更加敌对;尽管可观测性稍微降落,然而整体性价比十分高。 Nacos2.0 性能晋升因为Nacos由服务发现和配置管理两大模块形成,业务模型略有差别,因而咱们上面别离介绍一下具体压测指标。 Nacos2.0 服务发现的性能晋升服务发现场景咱们次要关注客户端数,服务数实例数,及服务订阅者数在大规模场景下,服务端在推送及稳固状态时的性能体现。同时还关注在有大量服务在进行高低线时,零碎的性能体现。 容量及稳固状态测试该场景次要关注随着服务规模和客户端实例规模上涨,零碎性能体现。 能够看到2.0.0版本在10W级客户端规模下,可能稳固的撑持,在达到稳固状态后,CPU的损耗非常低。尽管在最后的大量注册阶段,因为存在刹时的大量注册和推送,因而有肯定的推送超时,然而会在重试后推送胜利,不会影响数据一致性。 反观1.X版本,在10W、5W级客户端下,服务端齐全处于Full GC状态,推送齐全失败,集群不可用;在2W客户端规模下,尽管服务端运行状态失常,但因为心跳解决不及时,大量服务在摘除和注册阶段重复进行,因而达不到稳固状态,CPU始终很高。1.2W客户端规模下,能够稳固运行,但稳态时CPU耗费是更大规模下2.0的3倍以上。 频繁变更测试该场景次要关注业务大规模公布,服务频繁推送条件下,不同版本的吞吐和失败率。 频繁变更时,2.0和1.X在达到稳固状态后,均能稳固撑持,其中2.0因为不再有刹时的推送风暴,因而推送失败率归0,而1.X的UDP推送的不稳定性导致了有极小局部推送呈现了超时,须要重试推送。 Nacos2.0 配置管理的性能晋升因为配置是少写多读场景,所以瓶颈次要在单台监听的客户端数量以及配置的推送获取上,因而配置管理的压测性能次要集中于单台服务端的连贯数量以及大量推送的比拟。 Nacos2.0 连贯容量测试该场景次要关注不同客户端规模下的零碎压力。 Nacos2.0 最高单机可能撑持4.2w个配置客户端连贯,在连贯建设的阶段,有大量订阅申请须要解决,因而CPU耗费较高,但达到稳态后,CPU的耗费会变得很低。简直没有耗费。 反观Nacos1.X, 在客户端6000时,稳固状态的CPU始终很高,且GC频繁,次要起因是长轮训是通过hold申请来放弃连贯,每30s须要回一次 Response并且从新发动连贯和申请。须要做大量的上下文切换,同时还须要持有所有Request 和 Response。当规模达到1.2w客户端时,曾经无奈达到稳态,所以无奈撑持这个量级的客户端数。 Nacos2.0 频繁推送测试该场景关注不同推送规模下的零碎体现。 ...

March 30, 2021 · 1 min · jiezi

关于nacos:Rancher2x上部署单机版Nacos-140

Nacos 参考Nacos官网:https://nacos.io/en-us/参考Nacos官网应用k8s治理nacos:https://nacos.io/zh-cn/docs/u...1  筹备数据库Mysql数据库建表脚本 https://github.com/alibaba/na...筹备数据库:mysql.db.name: “nacos”mysql.port: “3306”2  Rancher上部署nacos镜像地址:nacos/nacos-server:1.4.02.1  配置映射名称:nacos配置映射键:custom.properties值: management.endpoints.web.exposure.include=*management.endpoint.health.show-details=alwaysspring.datasource.platform=mysqldb.num=1db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTCdb.user.0=rootdb.password.0=root2.2 部署服务 2.2.1 配置环境变量 2.2.2 配置数据卷抉择配置好的nacos映射 点击 启动 3 配置负载平衡 OK,拜访域名 nacos.com 高兴的游玩吧! 4 Nacos作为配置及注册核心应用4.1 依赖<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>环境隔离配置参考如下,本地调试切换环境批改spring.profiles.active值即可,若测试环境以namespace隔离增加对应的namespace,rancher部署服务时增加环境变量spring.profiles.active,值为对应的环境变量如dev即可spring: application: name: cart-service profiles: active: dev---spring: profiles: dev cloud: nacos: config: server-addr: http://nacos.di.com file-extension: yaml discovery: server-addr: http://nacos.di.com---spring: profiles: fat cloud: nacos: config: server-addr: http://nacos.fi.com file-extension: yaml discovery: server-addr: http://nacos.fi.com---spring: profiles: prod cloud: nacos: config: server-addr: http://nacos.prod.com file-extension: yaml discovery: server-addr: http://nacos.prod.com

March 11, 2021 · 1 min · jiezi

关于nacos:Nacos-Feign调用研究

FeignClient调用原理要启用FeignClient首先必须在启动类上加上注解@EnableFeignClients,EnableFeignClients代码如下 @Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)@Documented@Import(FeignClientsRegistrar.class)public @interface EnableFeignClients { ....留神到注解@Import(FeignClientsRegistrar.class),FeignClientsRegistrar实现了ImportBeanDefinitionRegistrar,在启动时会执行registerBeanDefinitions动静注册 class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) { registerDefaultConfiguration(metadata, registry); registerFeignClients(metadata, registry); } ...}registerDefaultConfiguration咱们首先看registerDefaultConfiguration,代码不多,间接贴代码 private void registerDefaultConfiguration(AnnotationMetadata metadata, BeanDefinitionRegistry registry) { Map<String, Object> defaultAttrs = metadata .getAnnotationAttributes(EnableFeignClients.class.getName(), true); if (defaultAttrs != null && defaultAttrs.containsKey("defaultConfiguration")) { String name; if (metadata.hasEnclosingClass()) { name = "default." + metadata.getEnclosingClassName(); } else { name = "default." + metadata.getClassName(); } registerClientConfiguration(registry, name, defaultAttrs.get("defaultConfiguration")); } }获取配置信息defaultAttrs注册默认配置类信息,配置类从defaultConfiguration中获取并且名称为 "default." + metadata.getClassName() 比方启动类为TestApplication,那么名称为default.com.test.TestApplicationregisterClientConfiguration将配置信息注册为FeignClientSpecification ...

March 5, 2021 · 3 min · jiezi

关于nacos:nacos-配置中心-V141

nacos 配置核心 V1.4.1参考文档:nacos官网文档 nacos服务端分为单机和集群两者,下文次要讲述单机版 1. 启动篇&部署篇nacos本地服务 git clone https://github.com/alibaba/nacos.gitcd nacos/mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U打包胜利后会呈现zip,解压后进入distribution/target下,应该会有个nacos-sever-$version.zip,只提取这个至某目录下,解压后进入/nacos/bin- startup.cmd 开启服务- shutdown.cmd 敞开服务如果startup.cmd启动报错,可能是配置文件中默认注明以集群的形式启动的,此时须要编辑startup.cmd,<26>行批改为set MODE = "standalone",即以单机模式启动;docker部署nacos docker pull nacos/nacos-server:1.4.1首先,咱们须要去初始化nacos的数据库在上文中nacos-sever-$version.zip解压后,进入/nacos/conf目录下,咱们会发现nacos-mysql.sql脚本,咱们能够应用该脚本进行初始化;另外,临时我只发现须要关注两个配置文件,logs和application.properties在服务器中咱们建设nacos文件夹,并在其中创立logs和config两个文件夹,目标是映射容器内两个文件夹;在config目录下创立application.properties,该文件可参考解压后的文件中/nacos/conf目录下的application.properties,留神开启mysql及以下属性- spring.datasource.platform=mysql- db.url.0- db.user.0- db.password.0配置对应的docker-compose,暂不介绍配置完后即可UP2. nacos关键点介绍认识:nacos能够看作一个配置管理核心,通常来说,咱们会把我的项目配置文件写在config下,然而须要批改时咱们须要拜访服务器对应目录下的配置文件进行批改,如果配置文件的变更须要设计多个我的项目,反复操作过多。nacos帮忙咱们解决的就是此类问题,它提供web模式的图形化界面,咱们可在界面中进行批改,配合@RefreshScope注解达到动静更新的目标。 nacos服务端登陆后,在配置管理-配置列表中可创立配置文件配置文件的命名规定为${prefix}-${spring.profiles.active}.${file-extension}通常来说,prefix默认为spring.application.name, 而file-extension为咱们在nacos外面创立配置文件的类型** 这里须要留神: spring.cloud.nacos.config.file-extension可指定file-extension,但必须与咱们nacos中创立的配置文件应用类型雷同 **nacos共有几个关键词需注意- data-id - group- namespace其中data-id为${prefix}-${spring.profiles.active}.${file-extension}group可指定,下文形容;** namespace是齐全隔离的,即不能在一个我的项目中逾越多个namespace **** @Value关键字可读取配置文件中的对应属性 ** 3. nacos解决方案:违反初衷的解决方案我感觉,namespace可作为我的项目名,group可作为版本号,每个我的项目通过namespace做到隔离性,通过group可用作版本隔离,且可用作profiles的隔离; 通常来说,一个我的项目能够分为5个配置文件 comment.properties 通用配置文件,多个我的项目可克隆复用我的项目名.properties 该我的项目配置文件,次要用来配置该我的项目中在环境切换时不变的属性,如mybatis扫描的相干配置,我的项目公有的配置参数等;我的项目名-profiles(dev,test,pro).properties 不同环境的公有配置,如ip的切换4. 根本应用如下spring: application: name: example cloud: nacos: config: prefix: 我的项目名up 优先级大于spring.application.name server-addr: 127.0.0.1:8848 file-extension: yml group: V1_GROUP namespace: 我的项目名 作为命名空间 (以下是依赖于其余配置文件,优先级下方大于上方) extension-configs: - data-id: comment.properties 通用配置 group: COMMENT_V_GROUP refresh: true - data-id: 我的项目名+profikes.properties group: V1_GROUP refresh: true

February 8, 2021 · 1 min · jiezi

关于nacos:用了3年Apollo这次我选择了Nacos原因不多说了

老板都闭口了,我能说不么? 本文探讨一下如何实现不同环境(开发、测试、灰度、正式)的配置管理问题。 就像Maven用groupId、artifactId、version三者来定位jar包在仓库中的地位一样,Nacos也提供了 Namespace (命名空间) 、Data ID (配置集ID)、 Group (组) 来确定一个配置文件(或者叫配置集)。 由此,实现多环境配置的计划也有三种: 1、用命名空间(namespace)来辨别不同的环境,一个命名空间对应一个环境; 2、用配置组(group)来辨别不同的环境,命名空间用默认的public即可,一个组对应一种环境; 3、用配置集ID(Data ID)名称来辨别不同的环境,命名空间和组用默认的即可,通过文件命名来辨别; 接下来,一一来看 http://{host}:{port}/nacos http://{host}:{port}/nacos/index.html 默认用户名明码都是nacos为了不便演示,这里建了一个名为example的Spring Boot我的项目pom.xml 1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4 <modelVersion>4.0.0</modelVersion> 5 <parent> 6 <groupId>org.springframework.boot</groupId> 7 <artifactId>spring-boot-starter-parent</artifactId> 8 <version>2.3.6.RELEASE</version> 9 <relativePath/> <!-- lookup parent from repository -->10 </parent>11 <groupId>com.example</groupId>12 <artifactId>example</artifactId>13 <version>0.0.1-SNAPSHOT</version>14 <name>example</name>15 16 <properties>17 <java.version>1.8</java.version>18 <spring-cloud-alibaba.version>2.2.3.RELEASE</spring-cloud-alibaba.version>19 </properties>20 21 <dependencies>22 <dependency>23 <groupId>org.springframework.boot</groupId>24 <artifactId>spring-boot-starter-web</artifactId>25 </dependency>26 <dependency>27 <groupId>com.alibaba.cloud</groupId>28 <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>29 </dependency>30 </dependencies>31 32 <dependencyManagement>33 <dependencies>34 <dependency>35 <groupId>com.alibaba.cloud</groupId>36 <artifactId>spring-cloud-alibaba-dependencies</artifactId>37 <version>${spring-cloud-alibaba.version}</version>38 <type>pom</type>39 <scope>import</scope>40 </dependency>41 </dependencies>42 </dependencyManagement>43 44 <build>45 <plugins>46 <plugin>47 <groupId>org.springframework.boot</groupId>48 <artifactId>spring-boot-maven-plugin</artifactId>49 </plugin>50 </plugins>51 </build>52 53 </project> bootstrap.yml ...

January 18, 2021 · 2 min · jiezi

关于nacos:nacos系列

Nacos分为服务发现(Naming)和配置核心(Config)。 注册核心Nacos - 启动Nacos - NacosNamingService初始化Nacos - 事件的注册、勾销与监听(EventDispatcher)Nacos - HostReactor的创立Nacos - 客户端实例列表获取Nacos - 客户端注册Nacos - 客户端心跳续约及客户端总结Nacos - 服务端解决注册申请Nacos - 服务端解决心跳申请Nacos - 服务端解决实例列表申请 配置核心暂无

January 5, 2021 · 1 min · jiezi

关于nacos:Nacos-服务端处理实例列表请求

服务端解决实例列表申请的入口是InstanceController#list。 InstanceController#listpublic ObjectNode list(HttpServletRequest request) throws Exception { // 其余略 // 获取服务列表 return doSrvIpxt(namespaceId, serviceName, agent, clusters, clientIP, udpPort, env, isCheck, app, tenant, healthyOnly);}InstanceController#doSrvIpxt这里次要是推送UDP申请,退出Client,Nacos - 服务端解决心跳申请的clients就是这里退出的。另外就是判断爱护阈值,如果比例低于阈值,则把衰弱和不衰弱的都返回,如果高于阈值,就只返回衰弱的实例。 public ObjectNode doSrvIpxt(String namespaceId, String serviceName, String agent, String clusters, String clientIP, int udpPort, String env, boolean isCheck, String app, String tid, boolean healthyOnly) throws Exception { ClientInfo clientInfo = new ClientInfo(agent); ObjectNode result = JacksonUtils.createEmptyJsonNode(); // 从serviceMap缓存获取Service Service service = serviceManager.getService(namespaceId, serviceName); long cacheMillis = switchDomain.getDefaultCacheMillis(); // now try to enable the push try { // 端口大于0,且客户端agent信息合乎则发表 if (udpPort > 0 && pushService.canEnablePush(agent)) { // 心跳那个章节的client就是这里加的 pushService .addClient(namespaceId, serviceName, clusters, agent, new InetSocketAddress(clientIP, udpPort), pushDataSource, tid, app); cacheMillis = switchDomain.getPushCacheMillis(serviceName); } } catch (Exception e) { Loggers.SRV_LOG .error("[NACOS-API] failed to added push client {}, {}:{}", clientInfo, clientIP, udpPort, e); cacheMillis = switchDomain.getDefaultCacheMillis(); } // 为空封装返回 if (service == null) { if (Loggers.SRV_LOG.isDebugEnabled()) { Loggers.SRV_LOG.debug("no instance to serve for service: {}", serviceName); } result.put("name", serviceName); result.put("clusters", clusters); result.put("cacheMillis", cacheMillis); result.replace("hosts", JacksonUtils.createEmptyArrayNode()); return result; } // 查看service状态 checkIfDisabled(service); List<Instance> srvedIPs; // 获取相干实例的ip srvedIPs = service.srvIPs(Arrays.asList(StringUtils.split(clusters, ","))); // filter ips using selector: // 对ip过滤 if (service.getSelector() != null && StringUtils.isNotBlank(clientIP)) { srvedIPs = service.getSelector().select(clientIP, srvedIPs); } // id为空封装返回 if (CollectionUtils.isEmpty(srvedIPs)) { if (Loggers.SRV_LOG.isDebugEnabled()) { Loggers.SRV_LOG.debug("no instance to serve for service: {}", serviceName); } if (clientInfo.type == ClientInfo.ClientType.JAVA && clientInfo.version.compareTo(VersionUtil.parseVersion("1.0.0")) >= 0) { result.put("dom", serviceName); } else { result.put("dom", NamingUtils.getServiceName(serviceName)); } result.put("name", serviceName); result.put("cacheMillis", cacheMillis); result.put("lastRefTime", System.currentTimeMillis()); result.put("checksum", service.getChecksum()); result.put("useSpecifiedURL", false); result.put("clusters", clusters); result.put("env", env); result.set("hosts", JacksonUtils.createEmptyArrayNode()); result.set("metadata", JacksonUtils.transferToJsonNode(service.getMetadata())); return result; } // 次要是把衰弱和不衰弱的辨别进去 Map<Boolean, List<Instance>> ipMap = new HashMap<>(2); ipMap.put(Boolean.TRUE, new ArrayList<>()); ipMap.put(Boolean.FALSE, new ArrayList<>()); for (Instance ip : srvedIPs) { ipMap.get(ip.isHealthy()).add(ip); } if (isCheck) { result.put("reachProtectThreshold", false); } double threshold = service.getProtectThreshold(); // 阈值爱护,衰弱实例和吧衰弱实例的比例小于阈值,则把衰弱和不衰弱的都返回 if ((float) ipMap.get(Boolean.TRUE).size() / srvedIPs.size() <= threshold) { Loggers.SRV_LOG.warn("protect threshold reached, return all ips, service: {}", serviceName); if (isCheck) { result.put("reachProtectThreshold", true); } ipMap.get(Boolean.TRUE).addAll(ipMap.get(Boolean.FALSE)); ipMap.get(Boolean.FALSE).clear(); } // 其余略,就是解决ipMap的信息返回值 return result;}总结流程图如下: ...

January 5, 2021 · 2 min · jiezi

关于nacos:Nacos-服务端处理心跳请求

服务端用InstanceController#beat办法接管心跳申请。 InstanceController#beat这里会判断是否曾经有实例,如果没有就创立实例,而后再开始查看心跳。 public ObjectNode beat(HttpServletRequest request) throws Exception { ObjectNode result = JacksonUtils.createEmptyJsonNode(); // 设置心跳工夫,会间接改客户端的心跳工夫 result.put(SwitchEntry.CLIENT_BEAT_INTERVAL, switchDomain.getClientBeatInterval()); String beat = WebUtils.optional(request, "beat", StringUtils.EMPTY); // 其余略 // 通过namespaceId, serviceName, clusterName, ip, port获取Instance Instance instance = serviceManager.getInstance(namespaceId, serviceName, clusterName, ip, port); // 如果没有,则注册 if (instance == null) { // 这个是通过beat判断的,如果是第一次,则beat有信息,就会创立clientBeat // 如果不是第一次,失常instance不为空的,所以此时为空阐明可能被移除了 if (clientBeat == null) { result.put(CommonParams.CODE, NamingResponseCode.RESOURCE_NOT_FOUND); return result; } // 其余略 // 注册 serviceManager.registerInstance(namespaceId, serviceName, instance); } // 从serviceMap缓存获取Service Service service = serviceManager.getService(namespaceId, serviceName); if (service == null) { throw new NacosException(NacosException.SERVER_ERROR, "service not found: " + serviceName + "@" + namespaceId); } // 不是第一次,组装clientBeat if (clientBeat == null) { clientBeat = new RsInfo(); clientBeat.setIp(ip); clientBeat.setPort(port); clientBeat.setCluster(clusterName); } // 解决心跳 service.processClientBeat(clientBeat); result.put(CommonParams.CODE, NamingResponseCode.OK); if (instance.containsMetadata(PreservedMetadataKeys.HEART_BEAT_INTERVAL)) { result.put(SwitchEntry.CLIENT_BEAT_INTERVAL, instance.getInstanceHeartBeatInterval()); } result.put(SwitchEntry.LIGHT_BEAT_ENABLED, switchDomain.isLightBeatEnabled()); return result;}ServiceManager#getInstance通过ip和端口获取实例 ...

January 5, 2021 · 4 min · jiezi

关于nacos:Nacos-服务端处理注册请求

Nacos - 客户端注册曾经讲过了,那这里讲一下服务端是怎么解决申请的。解决客户的申请在InstanceController里,咱们看看register办法。 InstanceController#register这里次要是封装Instance,并调用serviceManager的registerInstance办法进行服务注册。 public String register(HttpServletRequest request) throws Exception { // 获取namespaceId final String namespaceId = WebUtils .optional(request, CommonParams.NAMESPACE_ID, Constants.DEFAULT_NAMESPACE_ID); // 获取serviceName final String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME); // 验证serviceName的合法性 NamingUtils.checkServiceNameFormat(serviceName); // 封装并验证Instance的合法性 final Instance instance = parseInstance(request); // 服务注册 serviceManager.registerInstance(namespaceId, serviceName, instance); return "ok";}ServiceManager#registerInstance判断是否曾经注册过,如果没有注册,则创立一个Service并注册,而后再增加实例。 public void registerInstance(String namespaceId, String serviceName, Instance instance) throws NacosException { // 是否曾经注册过,如果没有注册,则创立一个Service并注册 createEmptyService(namespaceId, serviceName, instance.isEphemeral()); // 从注册的服务中取Service Service service = getService(namespaceId, serviceName); if (service == null) { throw new NacosException(NacosException.INVALID_PARAM, "service not found, namespace: " + namespaceId + ", service: " + serviceName); } // 增加实例 addInstance(namespaceId, serviceName, instance.isEphemeral(), instance);}ServiceManager#createEmptyService间接调用createServiceIfAbsent办法。 ...

January 5, 2021 · 4 min · jiezi

关于nacos:Nacos-客户端心跳续约及客户端总结

Nacos - 客户端注册中提到了心跳续约。 public void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException { String groupedServiceName = NamingUtils.getGroupedName(serviceName, groupName); if (instance.isEphemeral()) { // 封装心跳信息 BeatInfo beatInfo = beatReactor.buildBeatInfo(groupedServiceName, instance); // 开启定时工作续约 beatReactor.addBeatInfo(groupedServiceName, beatInfo); } serverProxy.registerService(groupedServiceName, groupName, instance);}BeatReactor#addBeatInfo把心跳工作放入线程池。 public void addBeatInfo(String serviceName, BeatInfo beatInfo) { NAMING_LOGGER.info("[BEAT] adding beat: {} to beat map.", beatInfo); String key = buildKey(serviceName, beatInfo.getIp(), beatInfo.getPort()); BeatInfo existBeat = null; //fix #1733 // 移除旧的BeatInfo if ((existBeat = dom2Beat.remove(key)) != null) { existBeat.setStopped(true); } //存入dom2Beat dom2Beat.put(key, beatInfo); // 开启定时工作 executorService.schedule(new BeatTask(beatInfo), beatInfo.getPeriod(), TimeUnit.MILLISECONDS); MetricsMonitor.getDom2BeatSizeMonitor().set(dom2Beat.size());}BeatReactor.BeatTask#run向服务器发送心跳,如果没有心跳信息,则从新注册。 ...

January 4, 2021 · 1 min · jiezi

关于nacos:Nacos-客户端注册

Nacos - 启动中提到了注册的入口,这里就讲一下注册的细节。Tomcat启动胜利后,会调用AbstractAutoServiceRegistration的onApplicationEvent办法,他会持续调用AbstractAutoServiceRegistration#bind。 AbstractAutoServiceRegistration#bindpublic void bind(WebServerInitializedEvent event) { ApplicationContext context = event.getApplicationContext(); if (context instanceof ConfigurableWebServerApplicationContext) { if ("management".equals(((ConfigurableWebServerApplicationContext) context) .getServerNamespace())) { return; } } // 设置端口号 this.port.compareAndSet(0, event.getWebServer().getPort()); this.start();}AbstractAutoServiceRegistration#startpublic void start() { if (!isEnabled()) { if (logger.isDebugEnabled()) { logger.debug("Discovery Lifecycle disabled. Not starting"); } return; } // only initialize if nonSecurePort is greater than 0 and it isn't already running // because of containerPortInitializer below // 没启动过才注册 if (!this.running.get()) { // 公布InstancePreRegisteredEvent事件 this.context.publishEvent( new InstancePreRegisteredEvent(this, getRegistration())); // 注册 register(); if (shouldRegisterManagement()) { // 注册registerManagement registerManagement(); } // 公布InstanceRegisteredEvent事件 this.context.publishEvent( new InstanceRegisteredEvent<>(this, getConfiguration())); // 设置状态为启动 this.running.compareAndSet(false, true); }}NacosAutoServiceRegistration#registerprotected void register() { if (!this.registration.getNacosDiscoveryProperties().isRegisterEnabled()) { log.debug("Registration disabled."); return; } // 小于0从新设置端口 if (this.registration.getPort() < 0) { this.registration.setPort(getPort().get()); } super.register();}AbstractAutoServiceRegistration#registerregistration的注入在启动的时候曾经说过了。 ...

January 4, 2021 · 2 min · jiezi

关于nacos:Nacos-实例列表获取

实例列表获取次要是HostReactor#getServiceInfo办法。Nacos - 启动中namingService.subscribe注册监听的时候,也会调用这个办法。 getServiceInfopublic ServiceInfo getServiceInfo(final String serviceName, final String clusters) { // 如果产生故障转移,就从文件缓存里取 NAMING_LOGGER.debug("failover-mode: " + failoverReactor.isFailoverSwitch()); String key = ServiceInfo.getKey(serviceName, clusters); if (failoverReactor.isFailoverSwitch()) { return failoverReactor.getService(key); } // 从serviceInfoMap里取 ServiceInfo serviceObj = getServiceInfo0(serviceName, clusters); // serviceInfoMap没有 if (null == serviceObj) { serviceObj = new ServiceInfo(serviceName, clusters); serviceInfoMap.put(serviceObj.getKey(), serviceObj); updatingMap.put(serviceName, new Object()); // 内存没有,从服务器取 updateServiceNow(serviceName, clusters); updatingMap.remove(serviceName); } else if (updatingMap.containsKey(serviceName)) { // 如果正在更新,则wait,防止多线程同时调用服务器 if (UPDATE_HOLD_INTERVAL > 0) { // hold a moment waiting for update finish synchronized (serviceObj) { try { serviceObj.wait(UPDATE_HOLD_INTERVAL); } catch (InterruptedException e) { NAMING_LOGGER .error("[getServiceInfo] serviceName:" + serviceName + ", clusters:" + clusters, e); } } } } // 开启定时工作更新服务列表 scheduleUpdateIfAbsent(serviceName, clusters); // 从内存里取 return serviceInfoMap.get(serviceObj.getKey());}updateServiceNow从服务器获取,NamingProxy会调用NamingProxy#reqApi,他会随机取一个server,调用NamingProxy#callServer。NamingProxy的代码就略了。 ...

January 4, 2021 · 4 min · jiezi

关于nacos:Nacos-HostReactor的创建

Nacos - NacosNamingService初始化中提到NacosNamingService初始化会初始化EventDispatcher、NamingProxy、BeatReactor、HostReactor。其中EventDispatcher曾经说了,NamingProxy的定时工作次要是默认每30毫秒更新服务器地址、默认每5毫秒登陆获取token等信息,这里过了。BeatReactor初始化的时候并没有开启定时工作,前面来说,那只剩下HostReactor了。咱们看看他的构造函数,会创立一个FailoverReactor和PushReceiver对象。 public HostReactor(EventDispatcher eventDispatcher, NamingProxy serverProxy, BeatReactor beatReactor, String cacheDir, boolean loadCacheAtStart, int pollingThreadCount) { // 其余略 this.failoverReactor = new FailoverReactor(this, cacheDir); this.pushReceiver = new PushReceiver(this);}FailoverReactorFailoverReactor的构造函数,会调用他的init办法: public FailoverReactor(HostReactor hostReactor, String cacheDir) { //其余略 this.init();}在init里会有三个工作: FailoverReactor.SwitchRefresher,默认每5秒检测是否开启故障转移,如果开启,则把文件数据读入serviceMap。FailoverReactor.DiskFileWriter,默认每天把服务信息写入本地。创立10秒后调用DiskFileWriter#run,检测本地缓存文件,如果没有则创立缓存文件。public void init() { executorService.scheduleWithFixedDelay(new SwitchRefresher(), 0L, 5000L, TimeUnit.MILLISECONDS); executorService.scheduleWithFixedDelay(new DiskFileWriter(), 30, DAY_PERIOD_MINUTES, TimeUnit.MINUTES); // backup file on startup if failover directory is empty. executorService.schedule(new Runnable() { //其余略 }, 10000L, TimeUnit.MILLISECONDS);}FailoverReactor.SwitchRefresher,默认每5秒检测是否开启故障转移,如果开启,则把文件数据读入serviceMap。 ...

January 4, 2021 · 2 min · jiezi

关于nacos:Nacos-事件的注册取消与监听EventDispatcher

咱们在Nacos - NacosNamingService初始化提过,NacosNamingService对象创立的时候,会创立一个EventDispatcher对象。EventDispatcher的构造方法如下,创立一个线程池,而后放入Notifier工作。 public EventDispatcher() { this.executor = Executors.newSingleThreadExecutor(new ThreadFactory() { @Override public Thread newThread(Runnable r) { Thread thread = new Thread(r, "com.alibaba.nacos.naming.client.listener"); thread.setDaemon(true); return thread; } }); this.executor.execute(new Notifier());}Notifier的Runnable的类,所以放入线程池的时候,会执行run办法。他次要是从阻塞队列changedServices取出ServiceInfo,而后依据ServiceInfo的key取出他对应的EventListener汇合,再执行EventListener的onEvent办法。 @Overridepublic void run() { while (!closed) { ServiceInfo serviceInfo = null; try { // changedServices是LinkedBlockingQueue,从阻塞队列取值 serviceInfo = changedServices.poll(5, TimeUnit.MINUTES); } catch (Exception ignore) { } // 没取值,从新从阻塞队列取 if (serviceInfo == null) { continue; } try { // 从observerMap取到EventListener汇合 List<EventListener> listeners = observerMap.get(serviceInfo.getKey()); if (!CollectionUtils.isEmpty(listeners)) { for (EventListener listener : listeners) { // 执行onEvent办法 List<Instance> hosts = Collections.unmodifiableList(serviceInfo.getHosts()); listener.onEvent(new NamingEvent(serviceInfo.getName(), serviceInfo.getGroupName(), serviceInfo.getClusters(), hosts)); } } } catch (Exception e) { NAMING_LOGGER.error("[NA] notify error for service: " + serviceInfo.getName() + ", clusters: " + serviceInfo.getClusters(), e); } }}在Nacos - 启动中,提到NacosWatch实例化的时候,就会调用namingService.subscribe,他会调用EventDispatcher#addListener办法,在这里会把监听放入observerMap的map里,而后调用serviceChanged办法。 ...

January 4, 2021 · 1 min · jiezi

关于nacos:Nacos-NacosNamingService初始化

Nacos - 启动提到了NacosWatch#start会获取NamingService,他托管NacosServiceManager来实现这件事。 NacosServiceManager#getNamingService为空的时候,去创立一个NamingService public NamingService getNamingService(Properties properties) { // 为空的时候,去创立一个NamingService if (Objects.isNull(this.namingService)) { buildNamingService(properties); } // 返回namingService return namingService;}NacosServiceManager#buildNamingService加锁保障只能有一个namingService private NamingService buildNamingService(Properties properties) { if (Objects.isNull(namingService)) { // 加锁保障只能有一个namingService synchronized (NacosServiceManager.class) { if (Objects.isNull(namingService)) { namingService = createNewNamingService(properties); } } } return namingService;}最终调用NamingFactory#createNamingService来创立NamingService对象。 private NamingService createNewNamingService(Properties properties) { try { return createNamingService(properties); } catch (NacosException e) { throw new RuntimeException(e); }}// NacosFactory中的办法public static NamingService createNamingService(Properties properties) throws NacosException { return NamingFactory.createNamingService(properties);}NamingFactory#createNamingService通过反射的形式创立了com.alibaba.nacos.client.naming.NacosNamingService对象。 ...

December 31, 2020 · 1 min · jiezi

关于nacos:Nacos-启动

看了Eureka系列、Ribbon系列、Feign系列、Zuul系列,我置信大家应该晓得怎么找到看源码的入口了,一个是须要用的注解,一个是spring.factories。咱们还是从注解先来。 @EnableDiscoveryClient这个注解做了两件事,一个是import了EnableDiscoveryClientImportSelector,另外一个就是默认autoRegister为true,开启主动注册。 @Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@Import(EnableDiscoveryClientImportSelector.class)public @interface EnableDiscoveryClient { boolean autoRegister() default true;}EnableDiscoveryClientImportSelector的selectImports办法,通过下面的autoRegister来判断,如果为true,则import了AutoServiceRegistrationConfiguration,如果为false,pring.cloud.service-registry.auto-registration.enabled设置为false。这个参数决定了是否引入主动注册。 @Overridepublic String[] selectImports(AnnotationMetadata metadata) { // 其余略 boolean autoRegister = attributes.getBoolean("autoRegister"); if (autoRegister) { List<String> importsList = new ArrayList<>(Arrays.asList(imports)); importsList.add( "org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationConfiguration"); imports = importsList.toArray(new String[0]); } else { // 其余略 // spring.cloud.service-registry.auto-registration.enabled设置为false map.put("spring.cloud.service-registry.auto-registration.enabled", false); // 其余略 } return imports;}NacosServiceAutoConfiguration注解的局部看完了,咱们开始看spring.factories。首先是NacosServiceAutoConfiguration。这里只加载了NacosServiceManager,是service外围治理类,NamingService就是他治理的。 NacosDiscoveryAutoConfiguration这个是用于服务发现的,他加载了两个类,NacosDiscoveryProperties和NacosServiceDiscovery。NacosDiscoveryProperties是配置类,咱们配置注册核心的信息就是在这里配置。NacosServiceDiscovery次要是用于服务发现。 NacosServiceRegistryAutoConfigurationNacosServiceRegistryAutoConfiguration,这个是用于主动注册的。咱们看到他下面的注解信息,@AutoConfigureAfter确保AutoServiceRegistrationConfiguration先加载,而后判断spring.cloud.service-registry.auto-registration.enabled是否为true,为true才能够加载。所以下面@EnableDiscoveryClient的autoRegister如果设置为false,则不加载。因为spring.cloud.service-registry.auto-registration.enabled默认是true的,所以@EnableDiscoveryClient其实不引入,也是能够加载NacosServiceRegistryAutoConfiguration。 @Configuration(proxyBeanMethods = false)@EnableConfigurationProperties@ConditionalOnNacosDiscoveryEnabled@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true)@AutoConfigureAfter({ AutoServiceRegistrationConfiguration.class, AutoServiceRegistrationAutoConfiguration.class, NacosDiscoveryAutoConfiguration.class })public class NacosServiceRegistryAutoConfiguration这个类会加载NacosServiceRegistry、NacosRegistration、NacosAutoServiceRegistration。NacosServiceRegistry、NacosRegistration会注入到NacosAutoServiceRegistration。NacosServiceRegistry次要用于注册、勾销注册。NacosRegistration是以后实例的信息,比方实例名称、实例id、端口、ip等。NacosAutoServiceRegistration继承了NacosAutoServiceRegistration,NacosAutoServiceRegistration又继承了AbstractAutoServiceRegistration。AbstractAutoServiceRegistration实现了ApplicationListener<WebServerInitializedEvent>接口,通过WebServerInitializedEvent就晓得了,当tomcat启动胜利后,会调用onApplicationEvent(WebServerInitializedEvent event)办法。这个办法会实现注册操作,前面再来解说。 ...

December 31, 2020 · 1 min · jiezi

关于nacos:Nacos-下载及配置

下载: 查看官网 准备:JAVA_HOME变量正确配置(集群)配置mysql,建数据库 运行: bin目录下start.cmd,命令行进入启动命令:D:\dev\nacos\bin>startup.cmd -m standalone 默认明码均为nacos

September 30, 2020 · 1 min · jiezi

聊聊nacossdkgo的ConfigProxy

序本文主要研究一下nacos-sdk-go的ConfigProxy ConfigProxynacos-sdk-go-v0.3.2/clients/config_client/config_proxy.go type ConfigProxy struct { nacosServer nacos_server.NacosServer clientConfig constant.ClientConfig}ConfigProxy定义了nacosServer、clientConfig属性NewConfigProxynacos-sdk-go-v0.3.2/clients/config_client/config_proxy.go func NewConfigProxy(serverConfig []constant.ServerConfig, clientConfig constant.ClientConfig, httpAgent http_agent.IHttpAgent) (ConfigProxy, error) { proxy := ConfigProxy{} var err error proxy.nacosServer, err = nacos_server.NewNacosServer(serverConfig, clientConfig, httpAgent, clientConfig.TimeoutMs, clientConfig.Endpoint) proxy.clientConfig = clientConfig return proxy, err}NewConfigProxy方法创建ConfigProxy,并设置其nacosServer、clientConfig属性GetServerListnacos-sdk-go-v0.3.2/clients/config_client/config_proxy.go func (cp *ConfigProxy) GetServerList() []constant.ServerConfig { return cp.nacosServer.GetServerList()}GetServerList方法委托nacosServer.GetServerList()来获取serverListGetConfigProxynacos-sdk-go-v0.3.2/clients/config_client/config_proxy.go func (cp *ConfigProxy) GetConfigProxy(param vo.ConfigParam, tenant, accessKey, secretKey string) (string, error) { params := util.TransformObject2Param(param) if len(tenant) > 0 { params["tenant"] = tenant } var headers = map[string]string{} headers["accessKey"] = accessKey headers["secretKey"] = secretKey result, err := cp.nacosServer.ReqConfigApi(constant.CONFIG_PATH, params, headers, http.MethodGet, cp.clientConfig.TimeoutMs) return result, err}GetConfigProxy方法通过nacosServer.ReqConfigApi获取configProxySearchConfigProxynacos-sdk-go-v0.3.2/clients/config_client/config_proxy.go ...

July 1, 2020 · 2 min · jiezi

聊聊nacossdkgo的NacosServer

序本文主要研究一下nacos-sdk-go的NacosServer NacosServernacos-sdk-go-v0.3.2/common/nacos_server/nacos_server.go type NacosServer struct { sync.RWMutex securityLogin security.AuthClient serverList []constant.ServerConfig httpAgent http_agent.IHttpAgent timeoutMs uint64 endpoint string lastSrvRefTime int64 vipSrvRefInterMills int64}NacosServer定义了securityLogin、serverList、httpAgent、timeoutMs、endpoint、lastSrvRefTime、vipSrvRefInterMills属性NewNacosServernacos-sdk-go-v0.3.2/common/nacos_server/nacos_server.go func NewNacosServer(serverList []constant.ServerConfig, clientCfg constant.ClientConfig, httpAgent http_agent.IHttpAgent, timeoutMs uint64, endpoint string) (NacosServer, error) { if len(serverList) == 0 && endpoint == "" { return NacosServer{}, errors.New("both serverlist and endpoint are empty") } securityLogin := security.NewAuthClient(clientCfg, serverList, httpAgent) ns := NacosServer{ serverList: serverList, securityLogin: securityLogin, httpAgent: httpAgent, timeoutMs: timeoutMs, endpoint: endpoint, vipSrvRefInterMills: 10000, } ns.initRefreshSrvIfNeed() _, err := securityLogin.Login() if err != nil { return ns, err } securityLogin.AutoRefresh() return ns, nil}NewNacosServer创建NacosServer及securityLogin,然后执行securityLogin.AutoRefresh()callConfigServernacos-sdk-go-v0.3.2/common/nacos_server/nacos_server.go ...

June 28, 2020 · 5 min · jiezi

聊聊nacossdkgo的NamingProxy

序本文主要研究一下nacos-sdk-go的NamingProxy NamingProxynacos-sdk-go-v0.3.2/clients/naming_client/naming_proxy.go type NamingProxy struct { clientConfig constant.ClientConfig nacosServer nacos_server.NacosServer}NamingProxy定义了clientConfig、nacosServer属性NewNamingProxynacos-sdk-go-v0.3.2/clients/naming_client/naming_proxy.go func NewNamingProxy(clientCfg constant.ClientConfig, serverCfgs []constant.ServerConfig, httpAgent http_agent.IHttpAgent) (NamingProxy, error) { srvProxy := NamingProxy{} srvProxy.clientConfig = clientCfg var err error srvProxy.nacosServer, err = nacos_server.NewNacosServer(serverCfgs, clientCfg, httpAgent, clientCfg.TimeoutMs, clientCfg.Endpoint) if err != nil { return srvProxy, err } return srvProxy, nil}NewNamingProxy通过nacos_server.NewNacosServer创建srvProxy.nacosServerRegisterInstancenacos-sdk-go-v0.3.2/clients/naming_client/naming_proxy.go func (proxy *NamingProxy) RegisterInstance(serviceName string, groupName string, instance model.Instance) (string, error) { log.Printf("[INFO] register instance namespaceId:<%s>,serviceName:<%s> with instance:<%s> \n", proxy.clientConfig.NamespaceId, serviceName, utils.ToJsonString(instance)) params := map[string]string{} params["namespaceId"] = proxy.clientConfig.NamespaceId params["serviceName"] = serviceName params["groupName"] = groupName params["clusterName"] = instance.ClusterName params["ip"] = instance.Ip params["port"] = strconv.Itoa(int(instance.Port)) params["weight"] = strconv.FormatFloat(instance.Weight, 'f', -1, 64) params["enable"] = strconv.FormatBool(instance.Enable) params["healthy"] = strconv.FormatBool(instance.Healthy) params["metadata"] = utils.ToJsonString(instance.Metadata) params["ephemeral"] = strconv.FormatBool(instance.Ephemeral) return proxy.nacosServer.ReqApi(constant.SERVICE_PATH, params, http.MethodPost)}RegisterInstance构造params,然后通过proxy.nacosServer.ReqApi(constant.SERVICE_PATH, params, http.MethodPost)发送POST请求DeregisterInstancenacos-sdk-go-v0.3.2/clients/naming_client/naming_proxy.go ...

June 27, 2020 · 3 min · jiezi

聊聊nacossdkgo的BeatReactor

序本文主要研究一下nacos-sdk-go的BeatReactor BeatReactornacos-sdk-go-v0.3.2/clients/naming_client/beat_reactor.go type BeatReactor struct { beatMap cache.ConcurrentMap serviceProxy NamingProxy clientBeatInterval int64 beatThreadCount int beatThreadSemaphore *nsema.Semaphore beatRecordMap cache.ConcurrentMap}BeatReactor定义了beatMap、serviceProxy、clientBeatInterval、beatThreadCount、beatThreadSemaphore、beatRecordMap属性NewBeatReactornacos-sdk-go-v0.3.2/clients/naming_client/beat_reactor.go func NewBeatReactor(serviceProxy NamingProxy, clientBeatInterval int64) BeatReactor { br := BeatReactor{} if clientBeatInterval <= 0 { clientBeatInterval = 5 * 1000 } br.beatMap = cache.NewConcurrentMap() br.serviceProxy = serviceProxy br.clientBeatInterval = clientBeatInterval br.beatThreadCount = Default_Beat_Thread_Num br.beatRecordMap = cache.NewConcurrentMap() br.beatThreadSemaphore = nsema.NewSemaphore(br.beatThreadCount) return br}NewBeatReactor方法创建了BeatReactor,并初始化其属性AddBeatInfonacos-sdk-go-v0.3.2/clients/naming_client/beat_reactor.go func (br *BeatReactor) AddBeatInfo(serviceName string, beatInfo model.BeatInfo) { log.Printf("[INFO] adding beat: <%s> to beat map.\n", utils.ToJsonString(beatInfo)) k := buildKey(serviceName, beatInfo.Ip, beatInfo.Port) br.beatMap.Set(k, &beatInfo) go br.sendInstanceBeat(k, &beatInfo)}AddBeatInfo方法通过buildKey构建key,然后将其放进去beatMap,之后异步执行br.sendInstanceBeatRemoveBeatInfonacos-sdk-go-v0.3.2/clients/naming_client/beat_reactor.go ...

June 26, 2020 · 1 min · jiezi

聊聊nacossdkgo的HostReactor

序本文主要研究一下nacos-sdk-go的HostReactor HostReactornacos-sdk-go-v0.3.2/clients/naming_client/host_reator.go type HostReactor struct { serviceInfoMap cache.ConcurrentMap cacheDir string updateThreadNum int serviceProxy NamingProxy pushReceiver PushReceiver subCallback SubscribeCallback updateTimeMap cache.ConcurrentMap updateCacheWhenEmpty bool}HostReactor定义了serviceInfoMap、cacheDir、updateThreadNum、serviceProxy、pushReceiver、subCallback、updateTimeMap、updateCacheWhenEmpty属性NewHostReactornacos-sdk-go-v0.3.2/clients/naming_client/host_reator.go func NewHostReactor(serviceProxy NamingProxy, cacheDir string, updateThreadNum int, notLoadCacheAtStart bool, subCallback SubscribeCallback, updateCacheWhenEmpty bool) HostReactor { if updateThreadNum <= 0 { updateThreadNum = Default_Update_Thread_Num } hr := HostReactor{ serviceProxy: serviceProxy, cacheDir: cacheDir, updateThreadNum: updateThreadNum, serviceInfoMap: cache.NewConcurrentMap(), subCallback: subCallback, updateTimeMap: cache.NewConcurrentMap(), updateCacheWhenEmpty: updateCacheWhenEmpty, } pr := NewPushRecevier(&hr) hr.pushReceiver = *pr if !notLoadCacheAtStart { hr.loadCacheFromDisk() } go hr.asyncUpdateService() return hr}NewHostReactor方法创建HostReactor,然后通过NewPushRecevier创建pushReceiver,对于notLoadCacheAtStart为false的则执行loadCacheFromDisk,之后异步执行asyncUpdateServiceloadCacheFromDisknacos-sdk-go-v0.3.2/clients/naming_client/host_reator.go ...

June 25, 2020 · 2 min · jiezi

聊聊nacossdkgo的NamingClient

序本文主要研究一下nacos-sdk-go的NamingClient NamingClientnacos-sdk-go-v0.3.2/clients/naming_client/naming_client.go type NamingClient struct { nacos_client.INacosClient hostReactor HostReactor serviceProxy NamingProxy subCallback SubscribeCallback beatReactor BeatReactor indexMap cache.ConcurrentMap}NamingClient定义了hostReactor、serviceProxy、subCallback、beatReactor、indexMap属性NewNamingClientnacos-sdk-go-v0.3.2/clients/naming_client/naming_client.go func NewNamingClient(nc nacos_client.INacosClient) (NamingClient, error) { naming := NamingClient{} clientConfig, err := nc.GetClientConfig() if err != nil { return naming, err } serverConfig, err := nc.GetServerConfig() if err != nil { return naming, err } httpAgent, err := nc.GetHttpAgent() if err != nil { return naming, err } err = logger.InitLog(clientConfig.LogDir) if err != nil { return naming, err } naming.subCallback = NewSubscribeCallback() naming.serviceProxy, err = NewNamingProxy(clientConfig, serverConfig, httpAgent) if err != nil { return naming, err } naming.hostReactor = NewHostReactor(naming.serviceProxy, clientConfig.CacheDir+string(os.PathSeparator)+"naming", clientConfig.UpdateThreadNum, clientConfig.NotLoadCacheAtStart, naming.subCallback, clientConfig.UpdateCacheWhenEmpty) naming.beatReactor = NewBeatReactor(naming.serviceProxy, clientConfig.BeatInterval) naming.indexMap = cache.NewConcurrentMap() return naming, nil}NewNamingClient方法创建NamingClient,并设置其subCallback、serviceProxy、hostReactor、beatReactor、indexMap属性RegisterInstancenacos-sdk-go-v0.3.2/clients/naming_client/naming_client.go ...

June 24, 2020 · 4 min · jiezi

Nacos集群搭建

一、Nacos简介Nacos(Naming and Configuration Service)致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。 详情查看Nacos官方文档二、Nacos安装1、Nacos依赖Nacos基于java开发的,运行依赖于java环境。 依赖64 bit JDK 1.8+,前往官网下载JDK2、Nacos安装下载编译后压缩包,最新稳定版本unzip nacos-server-$version.zip 或者 tar -xvf nacos-server-$version.tar.gz cd nacos/bin三、Nacos部署1、单实例部署单实例部署不适合生产环境,单点故障是致命的。 Linux单实例非集群模式启动命令startup.sh -m standaloneLinux单实例非集群模式关闭命令shutdown.sh访问nacos管理页面,初始化用户名密码均为nacos 2、集群部署1、集群架构 高可用Nginx集群Nacos集群(至少三个实例)高可用数据库集群(取代Nacos内嵌数据库)2、本地虚拟机模拟集群部署本地环境准备系统版本机器IP部署应用应用版本CentOS 7.6192.168.15.146Nginx1.18.0CentOS 7.6192.168.15.145Nacos1.2.1CentOS 7.6192.168.15.147Nacos1.2.1CentOS 7.6192.168.15.148Nacos1.2.1CentOS 7.6192.168.15.141MySQL5.7.24在本地PC机上利用VMware workstation虚拟出如上表所示的几台机器,其中Nginx和MySQL都是采用的单实例,仅做练习使用。 搭建步骤初始化nacos必须的数据库表并配置找到Nacos安装目录下提供的数据库脚本文件 在MySQL实例创建nacos_config库并导入脚本 修改修改Nacos配置文件,指向MySQL实例,替换其内嵌数据库 #*************** 切换Nacos内嵌数据库平台为MySQL ***************#spring.datasource.platform=mysqldb.num=1db.url.0=jdbc:mysql://192.168.15.141:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTCdb.user=rootdb.password=123456说明:三台nacos实例都需要切换MySQL平台,均需执行以上操作 nacos集群配置复制cluster.conf文件 Nacos集群配置,修改cluster.conf文件[root@localhost conf]# vim ./cluster.conf#it is ip#example192.168.15.145192.168.15.147192.168.15.148说明:三台nacos实例都需要做以上集群配置,至此关于nacos的配置结束了,可以尝试以集群模式启动三个nacos实例了 以集群模式分别启动三个nacos实例 尝试访问nacos管理页,测试三个实例是否正常 说明:如果三个实例以集群模式正常启动,那么分别访问三个实例的管理页就是展示以上登录页了。如果不能访问,则可能防火墙未开放nacos服务的端口,可执行如下命令。 [root@localhost bin]# firewall-cmd --add-port=8848/tcp --permanentsuccess[root@localhost bin]# firewall-cmd --reloadsuccess[root@localhost bin]# firewall-cmd --list-allpublic (active) target: default icmp-block-inversion: no interfaces: ens33 sources: services: ssh dhcpv6-client ports: 27017/tcp 8848/tcp protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: [root@localhost bin]# Nginx配置Nginx安装参考,Nginx源码安装修改Nginx配置文件nginx.confworker_processes 1;events { worker_connections 1024;}http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; #nacos集群负载均衡 upstream nacos-cluster { server 192.168.15.145:8848; server 192.168.15.147:8848; server 192.168.15.148:8848; } server { listen 80; server_name 192.168.15.146; location / { #root html; #index index.html index.htm; proxy_pass http://nacos-cluster; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } }}启动Nginx/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf微服务配置微服务父pom配置<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.atguigu.springcloud</groupId> <artifactId>cloud2020</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <!-- 模块 --> <modules> <module>cloud-alibaba-nacos-config-client-3377</module> </modules> <!-- 统一管理jar版本 --> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <junit.version>4.12</junit.version> <log4j.version>1.2.17</log4j.version> <lombok.version>1.16.18</lombok.version> <mysql.version>5.1.47</mysql.version> <druid.version>1.1.16</druid.version> <mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version> </properties> <!-- 统一依赖管理 --> <dependencyManagement> <dependencies> <!-- spring boot 2.2.2 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot</artifactId> <version>2.2.2.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> <!-- spring cloud Hoxton.SR1 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR1</version> <type>pom</type> <scope>import</scope> </dependency> <!-- spring cloud alibaba 2.1.0.RELEASE --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2.1.0.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> <!-- mysql连接器 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> </dependency> <!--druid 数据源--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>${druid.version}</version> </dependency> <!-- mybatis 整合 spring --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>${mybatis.spring.boot.version}</version> </dependency> <!-- junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> </dependency> <!-- log4j --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>${log4j.version}</version> </dependency> <!-- lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <fork>true</fork> <addResources>true</addResources> </configuration> </plugin> </plugins> </build></project>微服务pom依赖<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>cloud2020</artifactId> <groupId>com.atguigu.springcloud</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>cloud-alibaba-nacos-config-client-3377</artifactId> <dependencies> <!-- nacos config --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <!-- nacos discovery --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!-- web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- actuator --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!-- test --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- devtools --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <!-- lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> </dependencies></project>微服务bootstrap.yml配置server: port: 3377spring: application: name: nacos-config-client cloud: nacos: discovery: #server-addr: my.nacos.com:8848 #nacos集群配置(Nginx) server-addr: 192.168.15.146:80 config: #server-addr: my.nacos.com:8848 #nacos集群配置(Nginx) server-addr: 192.168.15.146:80 #指定yaml格式的配置 file-extension: yaml #指定分组 group: DEV_GROUP #指定命名空间ID namespace: my_nacos_namespace微服务启动类配置package com.atguigu.springcloud;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;@SpringBootApplication@EnableDiscoveryClientpublic class NacosConfigClientMain3377 { public static void main(String[] args) { SpringApplication.run(NacosConfigClientMain3377.class, args); }}微服务Controller读取nacos配置package com.atguigu.springcloud.controller;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Value;import org.springframework.cloud.context.config.annotation.RefreshScope;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;@RestController@Slf4j@RefreshScope //支持Nacos的动态刷新功能public class ConfigClientController { @Value("${config.info}") private String configInfo; @GetMapping("/config/info") public String getConfigInfo() { return configInfo; }}在nacos管理页上维护一个配置 ...

June 7, 2020 · 2 min · jiezi

搭建SpringCloud微服务框架三读取Nacos的配置信息

搭建微服务框架(读取Nacos的配置信息)本篇文章来记录下使用Nacos进行远程配置文件读取的操作,类似于 SpringCloud-Config 组件的功能本文源地址:读取Nacos的配置信息 Github地址:SQuid 介绍Nacos不仅仅只具备服务注册发现功能,它同时也具备远程动态读取配置文件的功能。 如果你认为这个功能没什么用,那么就真的大错特错了,举例: 一些关键性的配置项拿我当前公司的项目上来举例,一些服务的调用时间,我们还是写在项目上的 properties 文件中,像企业级应用,我们设置的服务调用时间在一部分对外的接口上会出现超时的情况, 这个时候,如果可以直接在 Nacos Config 上进行修改,效率也会提升不少。 数据库配置信息以Mysql的连接池配置来说,如果配置文件全部都写在项目的 resource 目录下,万一代码泄露或者被某些想要报复社会的人拿到,后果的话,大家都懂的, 绝对的 Welcome to 51Job。 使用我们这次直接在上篇文章中搭建的 squid-example-provider 中来实现,一如既往的开始第一步,引入依赖文件: <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency>在 squid-example-provider 中引入 Nacos Config 依赖后,我们开始来进行下一步的操作。 Nacos新建配置:登入Nacos控制台,进入配置管理,配置列表,新增一个配置: KeyValueData ID由项目中的 bootstrap.properties 指定。Group分组信息,可以自己填写。标签N/A归属应用归属的应用的信息,可以自己填写。描述本次配置的描述。配置格式根据自己项目需求来选择。配置内容对应配置格式的配置文件。 项目resource下新建 bootstrap.properties完成Nacos的新建配置后,我们这个时候可以来到项目中新建一个 bootstrap.properties 文件,之前的 application.yaml 文件可以删除掉了,之所以命名为 bootstrap.properties,是因为SpringCloud的加载配置顺序优先级properties文件大于yaml。 KeyValuespring.profiles.active配置文件的属性,比如上面Nacos里的Data ID是以-test结尾,这里我们就写 test。spring.application.name应用名称,写项目名就好了spring.cloud.nacos.config.file-extension加载的配置文件格式。spring.cloud.nacos.config.server-addrNacos的地址。 spring.profiles.active=test spring.application.name=squid-example-provider spring.cloud.nacos.config.file-extension=yaml spring.cloud.nacos.config.server-addr=yanzhenyidai.com:8848启动项目配置完成后,我们可以启动 Application 类,来检验是否可以成功读取到配置文件信息。 总结Nacos的Config配置功能真的很方便,而且支持热加载形式,感兴趣的朋友可以更深层次的了解。 参考资料: Nacos(GITHUB) Nacos(WIKI)

May 29, 2020 · 1 min · jiezi