1. 服务管理
本文结合SpringCloud实现服务注册至Nacos及其管理
我们先看下官网整体的流程
由图可知,
- 服务提供者注册服务至Nacos
- 服务调用者通过Nacos发现服务提供者
- 服务调用者调用可用服务提供者的接口获取数据
1.1 新建命名空间
登录nacos后,我们点击命名空间菜单,然后点击新建命名空间,输入必须信息,保存后查看详情如下:
命名空间名称:suanfaxiaosheng
命名空间ID:119f6bfd-adcf-4462-925b-7b412f287880
配置数:0 / 200
描述:算法小生
命名空间的作用,主要用于隔离不同的配置与服务,做到相互隔离,如A与B产品分别对应不同的命名空间
1.2 结合SpringCloud进行服务注册
代码可在算法小生中回复,nacos即可获取
- 在pom.xml文件中新增微服务相关配置
<properties>
<spring-cloud.version>2021.0.5</spring-cloud.version>
</properties>
<dependencyManagement>
<dependencies>
<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>
- 在idea中我们新建模块,命名为nacos-service-provider,并选择JDK17版本【我用的idea2022.2】,并新增pom.xml文件内容用于服务注册发现
<dependencies>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2021.1</version>
</dependency>
</dependencies>
- 在nacos-service-provider模块的resource目录下,我们新建application.yml文件,配置如下
server:
port: 8070
spring:
application:
name: nacos-service-provider
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
# 刚才创建的命名空间ID
namespace: 119f6bfd-adcf-4462-925b-7b412f287880
username: nacos
password: nacos
- 新建包
online.shenjian.nacos.service.provider
并在包下创建相关类如下
@SpringBootApplication
@EnableDiscoveryClient
public class NacosServiceProviderApplication {
public static void main(String[] args) {
SpringApplication.run(NacosServiceProviderApplication.class, args);
}
}
@RestController
public class HelloWorldController {
@GetMapping("/hello")
public String helloWorld(@RequestParam String name) {
return "hello:" + name;
}
}
- 服务启动后,我们观测nacos,发现相关服务已注册
由图我们可以看到,服务注册的时候也产生了一个订阅者。Nacos客户端通过一个定时任务,每6秒从注册中心获取实例列表,当发现实例发生变化时,发布变更事件,订阅者进行业务处理,然后更新内存中和本地的缓存中的实例,那么在调用其他服务的时候,就可以直接访问可用的服务
2. 配置管理
上文中我们学习到服务的注册,本文我们进行服务的调用及配置管理相关的实践
2.1 服务调用实践
接着上篇文章的代码,我们新建模块nacos-service-consumer
- 在pom.xml目录下新增依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2021.1</version>
</dependency>
</dependencies>
- 在resources目录下新建application.yml文件,内容如下
server:
port: 8071
spring:
application:
name: nacos-service-consumer
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
namespace: 119f6bfd-adcf-4462-925b-7b412f287880
username: nacos
password: nacos
- 创建相关类,所在包目录会有所注释,不存在请自行创建
// package online.shenjian.nacos.consumer;
@SpringBootApplication
@EnableDiscoveryClient
public class NacosServiceConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(NacosServiceConsumerApplication.class, args);
}
}
// package online.shenjian.nacos.consumer.config;
@Component
public class RestTemplateConfig {
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
// package online.shenjian.nacos.consumer;
@RestController
public class HelloWorldController {
private final RestTemplate restTemplate;
public HelloWorldController(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@GetMapping(value = "/hello")
public String echo(@RequestParam String name) {
// 调用注册到nacos的服务,名称即spring.application.name指定的名称
return restTemplate.getForObject("http://nacos-service-provider/hello?name={name}", String.class, name);
}
}
- 在nacos-service-provider模块中加入包,主要是负载均衡,否则consumer调用会报unknown host异常
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
- 启动provider与consumer,访问
http://127.0.0.1:8071/hello?name=suanfaxiaosheng
得到如下响应,服务调用成功
代码均已提交至git上,之前有放过链接,后续文章代码均会在对应目录中,如果有任何问题,可以在公众号算法小生中与我沟通
2.2 配置管理实践
- 在nacos配置管理中命名空间suanfaxiaosheng中新建consumer.yaml配置,选择yaml配置格式,创建结果如下,会自动生成MD5摘要,每次修改均会变动
- 在consumer模块中在pom.xml新增依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2021.1</version>
</dependency>
<!-- 2020.0.0及以后版本不在默认加载bootstrap 文件,需要手工添加[大坑] -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
- 在consumer中新建bootstrap.yml
spring:
cloud:
nacos:
# 服务发现的部分也移动至这边,按照官网步骤来
discovery:
server-addr: 127.0.0.1:8848
namespace: 119f6bfd-adcf-4462-925b-7b412f287880
username: nacos
password: nacos
config:
# 是否支持配置管理
enabled: true
server-addr: 127.0.0.1:8848
namespace: 119f6bfd-adcf-4462-925b-7b412f287880
file-extension: yaml
# 多个配置文件的话可以是0 1 2这样依次配置,其中值越大,优先级越高,在yml中即靠后优先级高
extension-configs:
# 刚才在nacos配置管理中定义的data-id,注意带上文件扩展名
- data-id: consumer.yaml
group: DEFAULT_GROUP
# 默认不支持动态更新
refresh: true
- 在cosunmer中新建NacosConfig.java文件用于测试配置刷新
// package online.shenjian.nacos.consumer.config;
@RestController
@RequestMapping("/config")
// @RefreshScope动态刷新基于Cglib动态代理
@RefreshScope
@ConditionalOnProperty(name = "spring.cloud.nacos.config.enable", matchIfMissing = true)
public class NacosConfig {
@Value("${cache.useLocalCache:false}")
private boolean useLocalCache;
@GetMapping("/get")
public boolean getConfig() {
return useLocalCache;
}
}
- 访问
http://127.0.0.1:8071/config/get
后得到结果如下为true,说明nacos的配置生效
当我们修改cache.useLocalCache值为false并发布后,可以控制台打印消息如下且值已变更
- 我们在nacos配置管理->监听查询中,输入对应配置信息我们可以看到对应的IP及配置MD5信息
我们可以通过该MD5值与当前配置MD5比对,已检查配置变更是否推送到Client端
- 当然,在历史版本中,我们也可以选择先前的版本进行回滚配置
3. 权限管理
本文介绍nacos的权限管理模块:基于RBAC(Role-Based Access Control)权限模型,即基于角色的权限控制。后续笔者会在公众号算法小生专门开设一个系列,从Vue前端到后端一整套流程实现RBAC权限系统与大家分享
3.1 容器当前状态保存至镜像
我们把配置文件与命名空间提交至镜像,防止我们docker镜像重启后内容丢失
# 查看当前容器id为004b8eb73158
docker container ls
docker commit -m '保留配置' 004b8eb73158 nacos/nacos-server:2.0.3
sha256:bb7b3d783485e1f9bb23dcc6d09da3e5d2d5105ead464a9b0a4b1eb360b3798d
3.2 调整docker-compose.yml
version: "3"
services:
nacos:
// 修改版本为2.0.3
image: nacos/nacos-server:2.0.3
container_name: nacos
environment:
- PREFER_HOST_MODE=hostname
- MODE=standalone
- NACOS_AUTH_ENABLE=true // 开启权限认证
ports:
- "8848:8848"
- "9848:9848"
删除旧容器后,我们$ docker-compose up -d
启动新容器
3.3 权限管理配置
- 我们新建命名空间TEST
- 用户管理中:新建用户shenjian,密码123456
- 角色管理中:新建角色ROLE_DEV,对应用户选择shenjian
- 权限管理中:我们选择角色ROLE_DEV,资源suanfaxiaosheng,读写权限
3.4 权限验证
我们切换至用户shenjian,无论配置管理还是服务管理中,访问public与TEST均提示无权限,只有suanfaxiaosheng可以进行操作,验证正常