目录
将Spring Cloud项目的eureka迁移至nacos
一点背景
Nacos支持基于DNS和基于RPC的服务发现(可以作为springcloud的注册中心),动态配置服务(可以做配置中心),动态DNS服务。
官方文档:Nacos提供了一组简单易用的特性集,帮助您快速实现动态服务发现,服务配置,服务元数据及流量管理。Nacos帮助更加敏捷和容易地Nacos是基于以“服务”为中心的现代应用架构(例如微服务范式,云原生范式)的服务基础设施。
Nacos 的关键特性包括:
- 服务发现和服务健康监测
- 动态配置服务,带管理界面,支持丰富的配置维度。
- 动态 DNS 服务
- 服务及其元数据管理
安装与运行
环境:win10,docker,JDK1.8
安装Nacos服务器
docker下安装Nacos服务器:
docker pull nacos/nacos-server
启动容器即可,访问http://localhost:8848/nacos,如下图
首次登录默认用户名密码都是nacos。
进去之后会看到配置管理,服务管理,权限控制,集群管理等功能。
Spring Cloud项目的demo(官方demo)
项目结构:
首先配置provider。导入依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>
在ProviderApplication里面:
@SpringBootApplication
@EnableDiscoveryClient
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
@RestController
class EchoController {
@RequestMapping(value = "/echo/{string}", method = RequestMethod.GET)
public String echo(@PathVariable String string) {
System.out.println(string);
return "Hello Nacos Discovery " + string;
}
}
}
配置provider的application.properties:
server.port=8080
spring.application.name=service-provider
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
这样provider就搭建好了,在localhost的8080端口,可以访问localhost:8080/echo/2020看到:
provider的功能是返回一个字符串:Hello Nacos Discovery + url里面的一个参数。
进入NacosServer里面,可以看到:
下面继续搭建一个consumer
首先是导入依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>
在ConsumerApplication里面:
@SpringBootApplication
@EnableDiscoveryClient
public class ConsumerApplication {
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
@RestController
public class TestController {
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value = "/echos/{str}", method = RequestMethod.GET)
public String echo(@PathVariable String str) {
System.out.println("str:"+str);
return restTemplate.getForObject("http://service-provider/echo/2020" + str, String.class);
}
}
}
consumer的application.proprierties:
server.port=8070
spring.application.name=service-consumer
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
Consumer的功能是调用Provider的功能,把这个run起来,访问:localhost:8070/echos/mxb,结果:
在控制台可以看出,Consumer调用了Provider的服务,通过http://service-provider/echo/2020访问到了服务。
Nacos和Eureka
功能差异
这张表的来自博客:Spring Cloud - Nacos与Eureka区别及如何选型-Perkins4j2
模块 | Nacos | Eureka | 说明 |
---|---|---|---|
注册中心 | 是 | 是 | 服务治理基本功能,负责服务中心化注册 |
配置中心 | 是 | 否 | Eureka需要配合Config实现配置中心,且不提供管理界面 |
动态刷新 | 是 | 否 | Eureka需要配合MQ实现配置动态刷新,Nacos采用Netty保持TCP长连接实时推送 |
可用区AZ | 是 | 是 | 对服务集群划分不同区域,实现区域隔离,并提供容灾自动切换 |
分组 | 是 | 否 | Nacos可用根据业务和环境进行分组管理 |
元数据 | 是 | 是 | 提供服务标签数据,例如环境或服务标识 |
权重 | 是 | 否 | Nacos默认提供权重设置功能,调整承载流量压力 |
健康检查 | 是 | 是 | Nacos支持由客户端或服务端发起的健康检查,Eureka是由客户端发起心跳 |
负载均衡 | 是 | 是 | 均提供负责均衡策略,Eureka采用Ribion |
管理界面 | 是 | 否 | Nacos支持对服务在线管理,Eureka只是预览服务状态 |
部署安装
模块 | Nacos | Eureka | 说明 |
---|---|---|---|
MySql | 是 | 否 | Nacos需要采用MySql进行数据进行持久化 |
MQ | 否 | 是 | Eureka需要采用MQ进行配置中心刷新 |
配置中心 | 是 | 否 | Eureka结合Config或者Consul实现配置中心 |
配置文件 | 在线编辑 | 本地文件或者Git远程文件 | Eureka结合Config或者Consul |
集群 | 是 | 是 | Nacos需要配置集群ip再启动 |
Nacos持久化
将Nacos持久化是为了将我们的配置信息、命名空间、用户管理等等信息进行保存。我们之前在运行Nacos的时候,默认将数据存在一个Nacos自带的数据库中,这种方法不适合项目级别的开发,需要我们配置mysql数据库进行持久化。
踩坑:之前尝试采用上面那个demo的docker容器连接本地数据库,但是失败了,浪费了很多时间,于是老老实实先按照官方文档能跑起来再说。
在0.7版本之前,在单机模式时nacos使用嵌入式数据库实现数据的存储,不方便观察数据存储的基本情况。0.7版本增加了支持mysql数据源能力。
按照官方文档,首先将项目clone到本地,并进入:
git clone https://github.com/nacos-group/nacos-docker.git
cd nacos-docker
单机模式下,运行:
docker-compose -f example/standalone-mysql-5.7.yaml up
这样会创建四个容器:
这些分别是:
- Nacos
- Mysql5.7
- Grafana 开源的度量分析和可视化工具,可以通过将采集的数据查询然后可视化的展示,并及时通知。
- Prometheus SoundCloud 开源监控告警解决方案
在日志里面可以看到,Grafana已经自动执行了官方的nacos-db.sql:
https://github.com/alibaba/nacos/blob/develop/distribution/conf/nacos-mysql.sql
踩坑:我尝试在docker上启动一个Nacos,再连接我本地配好的数据库(Mysql5.7)但是尝试了半天也没成功,一直报错(No Datasource Set.)就没继续尝试,决定先把这个跑起来再说,个人感觉项目上应该不会遇到这个问题,遇到再说。
我们接下来在数据库里面可以查看nacos的表,数据库相关信息例如用户名和密码等等在env文件夹的配置文件里面,是root,密码root,nacos密码nacos。
登录到数据库查看现有表:
use nacos_devtest
select table_name from information_schema.tables where table_schema='nacos_devtest' and table_type='base table';
然后登陆localhost:8080/nacos,尝试插入一个命名空间:
在数据库中可以查看到这个插入:
这样就实现了将nacos上的信息持久化到了MySQL中。
将Spring Cloud项目的eureka迁移至nacos
在项目中,考虑将eureka迁移至nacos,举一个实际的例子将其中一个服务进行替换。替换的方法比较简单,但是第一次试验坑比较多。
首先在pom.xml中加上项目的依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>
同时,去掉Eureka的依赖:spring-cloud-starter-netflix-eureka-client
修改application.yml的内容:
新增nacos的配置
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
删掉之前的Eureka的配置。
在application上加上
@EnableDiscoveryClient
踩坑:实际测试此时还是跑不起来这个服务的,报错:同时发现两个注册中心,解决方法参考:Eureka切换Nacos时发现两个注册中心的解决方法
我最终采用了暴力删除依赖,找到External Libraries → “spring-cloud-netflix-eureka-client:***” →“Open Library Settings”→“Delete”。
这样就运行起来了。
测试
我们还是采用刚刚那个demo,对这个demo中的消费者consumer进行简单的修改:
@SpringBootApplication
@EnableDiscoveryClient
public class ConsumerApplication {
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
@RestController
public class TestController {
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value = "/echos", method = RequestMethod.GET)
public String echo() {
// System.out.println("str:"+str);
return restTemplate.getForObject("http://catalog/api/v1/catalog/system/tag", String.class);
}
}
}
配置文件采用相同的配置,localhost端口8070。
运行起来这个consumer,可以在Nacos控制台里面看到服务列表里面有新的服务注册了
然后访问localhost:8070/echos,可以看到:服务已经正常的启动了。
参考文献
Spring Cloud - Nacos与Eureka区别及如何选型
docker 安装 nacos/nacos-server 镜像并配置本地数据库
Nacos(二):SpringCloud项目中接入Nacos作为注册中心