# nacos-help **Repository Path**: debug_life/nacos-help ## Basic Information - **Project Name**: nacos-help - **Description**: nacos帮助文档 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-11-09 - **Last Updated**: 2022-11-22 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # nacos-help ## 部署 ### 版本 2.1.2 ### 开发环境 * 服务器:12.99.237.67 * 目录:/usr/local/nacos ### 生产环境 * 服务器:待定 * 目录:/usr/local/nacos ### 目录结构 * bin - 运行程序 * startup.sh - Linux环境下的启动脚本 * shutdown.sh - Linux环境下的关闭脚本 * startup.cmd - Windows环境下的启动脚本 * shutdown.cmd - Windows环境下的关闭脚本 * config - 配置 * application.properties - nacos服务配置参数 * application.properties.example - nacos服务配置参数样例 * cluster.conf.example - 集群节点配置样例 * derby-schema.sql * mysql-schema.sql * nacos-logback.xml - nacos服务日志相关配置 * 1.4.0-ipv6_support-update.sql * data * logs - 日志 * status - 状态 * target - nacos服务jar包 ### 启停 * 启动 ```shell cd /usr/local/nacos/bin/ sh startup.sh -m standalone ``` * 停止 ```shell cd /usr/local/nacos/bin/ sh shutdown.sh ``` ## 管理平台 ### 平台信息 * 开发环境登录地址:http://12.99.237.67:8848/nacos/#/login * 生产环境登录地址:http://待定:8848/nacos/#/login * 管理员:nacos/****** * 查询用户:queryuser/nbcb,111 * 修改用户:modifyuser/nbcb,111 ### 平台功能 #### 登录 ![登录页面](https://gitee.com/debug_life/nacos-help/raw/master/image/2022-11-11_172810_%E7%99%BB%E5%BD%95%E9%A1%B5%E9%9D%A2.gif) #### 命名空间 用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的 Group 或 Data ID 的配置。命名空间的常用场景之一就是区分隔离不同环境的配置,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。 * 列表 列表页面中展示所有新增的命名空间,其中 `public` 为保留空间,无法修改和删除,其他命名空间即对应各个开发环境。 ![列表页面]() * 新建 在列表页面点击 `新建命名空间` 按钮,打开新建页面,填写 `命名空间ID` 、 `命名空间名` 、 `描述` 等内容后点击确定按钮即可进行命名空间新建。 `命名空间ID` 的值即为中的 `spring.cloud.nacos.config.namespace`的值。 ![新建命名空间]() #### 配置管理 ##### 配置列表 * 切换命名空间 在配置列表页面的头部,可以点击不同命名空间的名称进行切换命名空间。 ![切换命名空间]() * 查询 在配置列表页面的 `Data ID` 或者 `Group` 条件输入框输入筛选条件,点击查询按钮进行模糊查询。 ![查询]() * 新建配置集 点击配置列表页面左上角的 `创建配置` 按钮或者右上角的 `+` 按钮打卡新建页面。 ![新建配置按钮]() 补充 `Data ID` 、`Group` 、 `描述` 、 `配置格式` 、 `配置内容`等内容。 1. `Data ID` 为 配置前缀 + 配置格式,配置前缀一般为微服务配置的应用名 `spring.application.name`。 2. `Group` 默认为 `DEFAULT_GROUP` 即可。 3. `配置格式` 选择 `YAML`。 4. `配置内容` 填写 `YAML` 格式的配置。 点击 `发布` 按钮即可新建配置集。 ![新建配置页面]() * 编辑配置集 点击配置列表页面的指定配置集的操作栏中的 `编辑` 按钮打开配置编辑页面,可修改配置内容,然后点击发布按钮进行编辑发布。配置重新编辑发布后,微服务应用的配置会即时自动刷新。 ![配置编辑按钮]() ![配置编辑页面]() * 查询配置集详情 点击配置列表页面的指定配置集的操作栏中的 `详情` 按钮打开配置详情页面。 ![配置详情按钮]() ![配置详情页面]() 点击配置详情页面的右下角的 `配置对比` 按钮,可以和其他任意一个配置集进行对比。 ![配置对比1]() ![配置对比2]() 点击配置详情页面的右下角的 `版本对比` 按钮,可以和上一版本的配置集进行对比。 ![配置版本对比1]() ![配置版本对比2]() * 删除配置集 点击配置列表页面的指定配置集的操作栏中的 `删除` 按钮打开配置删除确认框,点击确定按钮则删除该配置集。配置集整个被删除后,需要微服务应用重启后方才生效,否则微服务应用的配置不会自动刷新,仍旧使用删除掉的配置集的配置。 ![配置删除页面]() ![配置删除页面成功]() * 克隆配置集 勾选配置列表页面的指定配置集,点击左下角的 `克隆` 按钮,可以将指定配置集克隆到任意命名空间,同时可以修改克隆的配置集的 `Data ID` 和 `Group`。 ![配置克隆页面]() * 导出配置集 勾选配置列表页面的指定配置集,点击左下角的导出的 `新版导出选中的配置` 按钮导出指定配置集。或者点击左下角的导出的 `新版导出查询结果` 按钮导出查询到的所有配置集。 * 导入配置集 点击列表页面右上的 `导入配置` 按钮,选择导出的配置文件压缩包进行导入。 ![导入配置集按钮]() ![导入配置集页面]() ![导入配置集]() ![导入配置集成功]() ##### 历史版本 * 查询 历史版本可以查询30天内的增删改历史版本,进入历史版本页面不会默认查询,需要根据 `Data ID` 和 `Group` 的条件进行筛选查询。 ![历史查询条件必填]() 被删除的配置集的 `Data ID` 可能不在 `Data ID` 下拉选项中,可以直接手动输入并选择下拉选项进行筛选查询。 ![历史版本页面删除的配置集不在下拉选中]() ![历史查询条件手动输入并选择]() ![历史版本查询列表]() * 详情 点击历史版本列表页面的指定配置集的操作栏中的 `详情` 按钮打开配置详情页面。 ![历史版本配置详情按钮]() ![历史版本配置详情页面]() * 回滚 点击历史版本列表页面的指定配置集的操作栏中的 `回滚` 按钮打开配置回滚页面。点击配置回滚页面上的 `回滚配置` 按钮即可回滚到上一版本。 ![历史版本配置回滚按钮]() ![历史版本配置回滚页面]() * 比较 点击历史版本列表页面的指定配置集的操作栏中的 `比较` 按钮打开配置比较页面。可以比较最新版本和指定版本的内容区别。如果最近一次的操作是删除配置集,则比较功能无法使用。 ![历史版本配置比较按钮]() ![历史版本配置比较页面]() * 快捷跳转 可在 `配置管理 - 配置列表` 页面的配置集的操作栏点击 `更多 - 历史版本` 按钮,快捷跳转到该配置集的历史版本。 ![历史版本快捷跳转按钮]() ![历史版本快捷跳转页面]() ##### 监听查询 * 配置维度查询 根据配置集条件来查询指定命名空间下的指定配置集被哪些微服务客户端使用 ![监听查询-配置]() * IP维度查询 根据微服务客户端IP条件来查询指定命名空间下该微服务客户端使用哪些配置集 ![监听查询-IP]() * 快捷跳转 可在 `配置管理 - 配置列表` 页面的配置集的操作栏点击 `更多 - 监听查询` 按钮,快捷跳转到该配置集的监听查询。 ![监听查询快捷跳转按钮]() ![监听查询快捷跳转页面]() #### 权限控制 权限控制可以创建用户,为用户设置角色,为角色设置权限,如果为用户设置 `ROLE_ADMIN` 角色,则默认为管理员权限。 ##### 用户列表 * 创建用户 点击用户列表页面右上角的创建用户按钮,打开创建用户页面,输入用户名、密码、确认密码,点击确定按钮即可创建用户。 ![创建用户]() * 查询用户 可在用户列表页面输入用户名条件进行模糊查询用户。 ![查询用户]() * 修改用户(仅支持修改密码) 点击用户列表页面指定用户操作栏的修改按钮,打开修改用户页面,输入密码、确认密码,点击确定按钮即可修改用户密码。 ![修改用户]() * 删除用户 点击用户列表页面指定用户操作栏的删除按钮,打开删除用户确认框,点击确定按钮即可删除用户。 ![删除用户]() ##### 角色管理 * 绑定角色 点击角色管理页面右上角的绑定角色按钮,打开绑定角色页面,输入角色名和用户名,点击确定按钮即可为指定用户绑定指定角色。 ![绑定角色]() * 查询用户绑定角色信息 可在角色管理页面输入用户名和角色名条件进行模糊查询用户绑定角色信息。 ![查询用户绑定角色信息]() * 删除用户绑定角色信息 点击角色管理页面指定用户绑定角色信息操作栏的删除按钮,打开删除确认框,点击确定按钮即可删除用户绑定角色信息。 ![删除用户绑定角色信息]() ##### 权限管理 * 添加权限 点击权限管理页面右上角的添加权限按钮,打开添加权限页面,输入角色名,选择资源(命名空间)和动作(只读、只写、读写),点击确定按钮即可为指定角色添加指定权限。 * 查询角色权限信息 可在权限管理页面输入角色名条件进行模糊查询角色权限信息。 ![查询角色权限信息]() * 删除角色权限信息 点击权限管理页面指定角色权限信息操作栏的删除按钮,打开删除确认框,点击确定按钮即可删除角色权限信息。 ![删除角色权限信息]() ## 微服务客户端代码DEMO ### 代码目录结构 ![代码DEMO目录结构]() ### pom.xml引入依赖 ```xml com.alibaba.cloud spring-cloud-starter-alibaba-nacos-config 2.2.6.RELEASE ``` 版本 2.1.x.RELEASE 对应的是 Spring Boot 2.1.x 版本。版本 2.0.x.RELEASE 对应的是 Spring Boot 2.0.x 版本,版本 1.5.x.RELEASE 对应的是 Spring Boot 1.5.x 版本。 更多版本对应关系参考:[官方版本说明](https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E)。 如果版本不对服务启动时可能会报错。 ### bootstrap.yml ```yaml server: port: 8001 # 应用端口 spring: application: name: config-demo # 应用名,默认的配置集id前缀 profiles: active: dev cloud: nacos: username: queryuser # nacos认证用户名 password: nbcb,111 # nacos认证密码 config: server-addr: 192.168.10.150:8848 # nacos配置服务地址 namespace: ${spring.profiles.active} # nacos配置所属的命名空间id,namespace为空则使用nacos默认命名空间即public group: DEFAULT_GROUP # 配置分组,对配置集进行分组,从而区分配置集id相同的配置集,默认为DEFAULT_GROUP # name: config-demo # 可以替换spring.application.name作为配置集id前缀 file-extension: yaml # 配置集后缀,同样是配置集的文件扩展名, yaml 或者 properties # prefix: config-demo # 配置集id前缀,可以替换spring.cloud.nacos.config.name和spring.application.name,优先级最高 shared-configs: # 读取共享的配置集 - data-id: common.yaml # 配置集id,必须带上后缀 # group: DEFAULT_GROUP # 配置分组,默认为DEFAULT_GROUP refresh: true # 是否自动刷新配置,默认是否 extension-configs: # 读取扩展的配置集 - data-id: extension1.properties # 配置集id,必须带上后缀 refresh: true # 是否自动刷新配置,默认是否 - data-id: extension2.yaml # 配置集id,必须带上后缀 refresh: true # 是否自动刷新配置,默认是否 ``` * `spring.cloud.nacos.config`下可以设置主配置、共享配置、扩展配置的参数。 * `spring.cloud.nacos.config.namespace`指的是命名空间id,不是命名空间名。所有读取的配置集都是在指定命名空间下的。 * 主配置的配置集id(dataId)的完整格式为`${prefix}-${spring.profiles.active}.${file-extension}`: 1. `prefix` 默认为 `spring.application.name` 的值,也可以通过`spring.cloud.nacos.config.prefix` 或者 `spring.cloud.nacos.config.name` 来配置。使用优先级如下:`spring.cloud.nacos.config.prefix` > `spring.cloud.nacos.config.name` > `spring.application.name`。 2. `spring.profiles.active` 即为当前环境对应的profile。当 `spring.profiles.active` 为空时,对应的连接符 `-` 也将不存在,dataId的完整格式变成 `${prefix}.${file-extension}`。 3. `file-exetension` 为配置内容的数据格式,可以通过配置项 `spring.cloud.nacos.config.file-extension` 来配置。目前只支持 `properties` 和 `yaml` 类型。 4. 服务启动时会读取dataId为 `${prefix}-${spring.profiles.active}.${file-extension}` 、 `${prefix}-${spring.profiles.active}` 、 `${prefix}` 的配置集。相同的配置优先级如下:`${prefix}-${spring.profiles.active}.${file-extension}` > `${prefix}-${spring.profiles.active}` > `${prefix}`。 * `spring.cloud.nacos.config.shared-configs`可以设置共享配置参数。共享配置即一些如数据源之类的公共配置,共享配置参数只有 `data-id` 、 `group` 和 `refresh` 。共享配置读取配置集是完全根据 `data-id` 的值来匹配的, `data-id` 最好是 `${prefix}.${file-extension}` 这样的,即带上类型后缀,然后nacos管理平台上面的配置集id也带上类型后缀,如果不带类型后缀则会默认按 `properties` 类型来读取配置。可以设置多个共享配置,后面的共享配置优先于前面的。 * `spring.cloud.nacos.config.extension-configs`可以设置扩展配置参数。扩展配置和共享配置基本一致,只是扩展配置优先级大于共享配置。扩展配置可用于覆盖共享配置中的指定配置项或者设置特定的配置项,如共享配置中有数据源的配置项,但有一个服务需要特定的数据源,此时就可以设置一个扩展配置来进行覆盖。 * 配置优先级:主配置 > 扩展配置 > 共享配置 ### 代码中配置参数注入方式 1. 使用@ConfigurationProperties注解一个配置参数类,设置@ConfigurationProperties的prefix表示将该前缀的所有配置参数设置到该配置参数类实例对应的成员变量中,成员变量名称和配置参数名称对应。配置参数类实例可进行注入使用。 2. 使用@Value获取一个指定名称的配置参数,参数名称以 `${}` 包裹。 ```java package com.sword.demo.business.properties; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; /** * 用户参数 * @author sword * @date 2022/1/12 8:20 */ @Data @ConfigurationProperties(prefix = UserProperties.PREFIX) @Component public class UserProperties { /** * 用户参数前缀 */ public static final String PREFIX = "user"; /** * 用户id */ private String id; /** * 用户名称 */ private String name; /** * 用户住址 */ private String address; /** * 用户年龄 */ private Integer age; /** * 用户学历 */ private String education; } package com.sword.demo.business.interfaces.api; import com.sword.demo.business.properties.UserProperties; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.Data; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.context.annotation.ScopedProxyMode; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * 用户接口 * @author sword * @date 2022/1/11 21:15 */ @RestController @Api(tags = "用户接口") @RequestMapping("/user") @RequiredArgsConstructor @RefreshScope(proxyMode = ScopedProxyMode.DEFAULT) @Data public class UserApi { /** * 用户参数 */ private final UserProperties userProperties; /** * 用户名称 */ @Value("${user.name}") private String userName; /** * 获取用户名称 * @return java.lang.String * @author sword * @date 2022/1/11 21:16 */ @GetMapping("/name") @ApiOperation("获取用户名称") public String getUserName() { return userName; } /** * 获取用户名称(通过私有方法),如果@RefreshScope的proxyMode不设置为ScopedProxyMode.DEFAULT,则此方法会返回null * @return java.lang.String * @author sword * @date 2022/1/11 21:16 */ @GetMapping("/name/private-method") @ApiOperation("获取用户名称(通过私有方法)") private String getUserNameByPrivateMethod() { return userName; } /** * 获取用户名称(通过私有方法和成员变量Getter方法),如果@RefreshScope的proxyMode不设置为ScopedProxyMode.DEFAULT, * 此方法可以正常返回数据 * @return java.lang.String * @author sword * @date 2022/1/11 21:16 */ @GetMapping("/name/private-method/getter-method") @ApiOperation("获取用户名称(通过私有方法和成员变量Getter方法)") private String getUserNameByPrivateMethodAndGetterMethod() { return getUserName(); } /** * 获取用户 * @return java.lang.String * @author sword * @date 2022/1/11 21:16 */ @GetMapping("") @ApiOperation("获取用户") public UserProperties getUser() { return userProperties; } } ``` 在nacos管理平台的配置管理页面修改配置并发布后,被@ConfigurationProperties注解的配置参数类实例会刷新修改的参数的值并在下次被使用到时生效,如果在某个方法正在使用该配置参数类实例的过程中配置被刷新,则该方法读取到的参数还是老的,并不会即时变成新的。 @Value同理,且需要在注入@Value注解的参数的类上额外添加@RefreshScope,否则在刷新配置后@Value注解的参数不会跟着刷新,@ConfigurationProperties注解的配置参数类实例不会有这个问题。 @RefreshScope如果不将proxyMode设置为ScopedProxyMode.DEFAULT,则其默认值为ScopedProxyMode.TARGET_CLASS,使用CGLIB进行代理,此时调用私有方法获取变量时会获取CGLIB代理对象的变量而不是目标对象的,所以会返回null,见上述方法 `getUserNameByPrivateMethod()`。 ScopedProxyMode.DEFAULT即ScopedProxyMode.NO,当需要代理目标对象会根据目标对象的类型来判断使用JDK代理还是CGLIB代理,如果目标对象有实现接口就使用JDK代理,否则就使用CGLIB代理。 使用@Value和@RefreshScope时,最好使用成员变量的公有的GETTER方法来获取对应的成员变量,如上述方法 `getUserNameByPrivateMethodAndGetterMethod()`,这样可以避免后续的一些可能会忽视的问题。 ### nacos配置 ![Nacos配置]() common.yaml ```yaml user: id: "000000" name: 路人甲 address: 和义大道 age: 17 education: 大学本科 ``` extension1.properties ```properties user.age=20 user.education=研究生 ``` extension2.yaml ```yaml user: education: 博士 ``` config-demo.yaml ```yaml user: id: "999999" name: "今夜无名123" ``` 读取优先级:config-demo.yaml > extension2.yaml > extension1.properties > common.yaml ### 配置获取结果 * 获取用户 请求:`curl -X GET "http://127.0.0.1:8001/user" -H "accept: */*"` 结果: ```json { "code": "000000", "msg": "调用成功", "data": { "id": "999999", "name": "今夜无名123", "address": "和义大道", "age": 20, "education": "博士" } } ``` * 获取用户名称 请求:`curl -X GET "http://127.0.0.1:8001/user/name" -H "accept: */*"` 结果: ```json { "code": "000000", "msg": "调用成功", "data": "今夜无名123" } ``` * 获取用户名称(通过私有方法) 请求:`curl -X GET "http://127.0.0.1:8001/user/name/private-method" -H "accept: */*"` 结果: ```json { "code": "000000", "msg": "调用成功", "data": "今夜无名123" } ``` * 获取用户名称(通过私有方法和成员变量Getter方法) 请求:`curl -X GET "http://127.0.0.1:8001/user/name/private-method/getter-method" -H "accept: */*"` 结果: ```json { "code": "000000", "msg": "调用成功", "data": "今夜无名123" } ``` ## 微服务客户端代码DEMO(本地直接读取外部配置文件版本) 本地代码变动比较频繁,且往往是多人同时开发,如果本地也使用nacos作配置中心的话,可能无法很好的做到配置隔离,即一个人的配置修改可能会影响到其他人的正常开发,所以代码可以稍作修改,本地开发不再使用nacos配置中心,而是直接读取外部配置文件。 ### 代码目录结构 ![代码DEMO目录结构local]() ### 外部配置文件 * 在项目根目录下新建目录 `config/local` 。 * 在 `config/local` 新建对应的配置文件,内容同[nacos配置](#nacos配置),文件名称需要带上local。 ### bootstrap.yml `spring.profiles.active` 由 `dev` 改为 `local`。 ### bootstrap-local.yml ```yaml spring: cloud: nacos: config: enabled: false # 本地环境不使用nacos配置中心 config: name: common,extension1,extension2,${spring.application.name} # 读取的配置文件名称 ``` * 由于 `spring.profiles.active` 改为 `local` ,则会读取 `bootstrap-local.yml` 的配置。 * `spring.cloud.nacos.config.enabled` 设置为 `false` 即可不再使用nacos配置中心。 * `spring.config.name` 为配置文件名称,可多个,以逗号相隔,越后面的名称对应的配置文件优先级越高。 * 配置文件的默认查找路径是 `"classpath:/,classpath:/config/,file:./,file:./config/*/,file:./config/"`,越后面的路径里的配置文件优先级越高。 * 应用启动时会根据 `查找路径` 、`spring.config.name` 、`spring.profiles.active`来确定配置文件路径。本例最终确定有效的配置文件路径为 `file:./config/*/config-demo-local.yml` 、`file:./config/*/extension2-local.yml` 、`file:./config/*/extension1-local.properties` 、`file:./config/*/common-local.yml` ### 配置获取结果 * 获取用户 请求:`curl -X GET "http://127.0.0.1:8002/user" -H "accept: */*"` 结果: ```json { "code": "000000", "msg": "调用成功", "data": { "id": "999999", "name": "wukongjian", "address": "和义大道", "age": 20, "education": "博士" } } ``` 这里有一个问题,就是返回name并不是配置文件里设置的内容,原因是该配置为 `user.name`,系统配置里也有这个配置,默认读取的是主机当前用户的名称,然后系统配置的优先级比外部配置高,无法覆盖。所以配置的key尽量不要和系统配置里的key一致。如果读取Nacos配置中心的配置则没有这个问题,因为Nacos的配置优先级更高。 ## 快乐永赢系统代码DEMO 以dm-system为例。 ## 开发上线流程 ### dev阶段 * 如果有新增的配置,可用modifyuser用户登录开发环境的nacos管理平台在dev命名空间下做相应的新增操作。 * 如果有修改的配置,建议不要直接在nacos管理平台上修改,而是先在