深入浅出高性能服务发现、配置框架Nacos系列 1: HelloWorld
Nacos是什么?
引用官方的介绍,他主要提供以下几个功能点:
- 动态配置服务
- 服务发现及管理
- 动态DNS服务
动态配置服务
就是通过一个系统,管理系统中的配置项,在配置项需要更新的时候,可以通过管理系统去操作更新,更新完了之后,会主动推送到订阅了这个配置的客户端
具体的使用场景,例如,在系统中,会有数据库的链接串,账号密码等配置信息,常规的做法是写在配置文件里面,如果需要修改更新,需要重新打包编译,如果你是分布式集群,那成本太大了,通常我们都会将它抽取出来,存放到db,或者一个管理系统,Nacos,就是这个管理系统,Nacos还提供主动通知的能力,DB是没有的,在自己的系统代码里面,可以监听某个配置,如果在管理系统上修改了配置项,客户端的监听函数,会立刻执行,在里面,你可以拿到最新的配置,执行自己的业务逻辑
服务发现及管理
这个主要是针对分布式的微服务集群系统,某A集群提供服务出去,其他应用集群,需要消费到A集群的服务,需要一个系统去管理A集群的ip列表,其他应用集群,去这个系统才能获取到A集群的ip列表,进行调用,同时该系统需要能够自动将A集群中无法工作的ip进行去除掉,这样才能保证调用方调用成功,Nacos就是提供这种能力的一个系统
动态DNS服务
这个理解起来也简单,我们平常在代码里面 ,访问一个http的api,通常是带一个域名的,请求的时候,一般会先去DNS域名服务器上面寻找该域名对应的ip,再发起http请求,Nacos可以充当这个DNS域名服务器的角色的,优点是什么呢?Nacos提供了比DNS域名服务器更方便的管理能力,新增一个域名,只需要在Nacos的控制台上面配置一下,同时它还提供了包括权重,健康检查,属性,路由等DNS服务器不具备的能力,比DNS的产品功能,稳定性,灵活性,超出太多了
Nacos除了能够解决上面提到的一些场景,大家可以自由发挥,反正它的能力在那里,至于怎么用,就靠你们聪明的脑袋了。
下面,我们尝试从Nacos的官方源码拉一份下来,进行一个服务的发布,订阅的简单流程,让大家更有体感去感受下Nacos的功能。
下载源码
Nacos的代码是托管在github上,https://github.com/alibaba/nacos
开始之前先start关注一下,加上watch,后续Nacos的邮件列表也会通知到你,可以关注到Nacos的最新实时消息.
我们首先直接下载Nacos的源码到本地,下载地址如下图:
然后,要从github上把代码拉下来,命令如下:
git clone git@github.com:alibaba/nacos.git
执行完之后,出现下图进度
编译启动
下载完后,在本地会有一个nacos的文件夹,进去后,执行编译打包的命令:
mvn -Prelease-nacos clean install -U -Dmaven.test.skip=true
执行完之后,在nacos/distribution/target文件夹里面,会生成如下几个工程文件:
忽略archive-tmp,将nacos-server-0.2.0.zip或者nacos-server-0.2.0.tar.gz直接copy到你的服务器上面,
然后解压开来,得到一个叫nacos的文件夹,里面的结构如下:
进入bin文件,里面有启动,关闭nacos server的脚本,我们执行一下启动脚本,注意,nacos server的启动,有2种方式,一种是集群模式,一种是单机模式,由于集群模式还需要一些其他的配置才能运行,今天我们就跑单机模式,需要加一个特殊参数,命令如下:
sh startup.sh -m standalone
命令执行完之后,出现提示:
nacos is starting,you can check the /home/caogu.wyp/test/nacos/logs/start.log
我们可以去/nacos/logs/start.log看下启动日志,是否有报错,如果有报错,自己分析一下,找不到原因,联系Nacos管理员 @超哥,他会很热心的帮你解决问题滴。
启动成功的日志如下:
同时, 我们也可以自己check下server的端口是否监听成功,执行
netstat -ano|grep 8080
发布一个服务
我们现在来用Java客户端,发布和订阅一个服务,客户端,我们有2种方式运行,一个是在自己工程里面,通过maven坐标下载进来,另外一种,直接从下载的Nacos源码里面,坐标如下:
com.alibaba.nacos nacos-client 0.1.0
由于我们有代码,我就直接在工程里面进行操作了,工程结构如下,直接在test模块里面,新建一个helloworld的包:
Pub类里面,是发布一条数据,代码如下:
public class Pub { public static void main(String[] args) throws NacosException, InterruptedException { //发布的服务名 String serviceName = "helloworld.services"; //构造一个nacos实例,入参是nacos server的ip和服务端口 NamingService naming = NamingFactory.createNamingService("100.81.0.34:8080"); //发布一个服务,该服务对外提供的ip为127.0.0.1,端口为8888 naming.registerInstance(serviceName, "127.0.0.1", 8888); Thread.sleep(Integer.MAX_VALUE); }}
启动之后,服务已经发布上去了
订阅一个服务
下面是Sub的代码:
public class Sub { public static void main(String[] args) throws NacosException, InterruptedException { //订阅的服务名 String serviceName = "helloworld.services"; //创建一个nacos实例 NamingService naming = NamingFactory.createNamingService("100.81.0.34:8080"); //订阅一个服务 naming.subscribe(serviceName, event -> { if (event instanceof NamingEvent) { System.out.println("订阅到数据"); System.out.println(((NamingEvent) event).getInstances()); } }); System.out.println("订阅完成,准备等数来"); Thread.sleep(Integer.MAX_VALUE); }}
我们尝试启动,会订阅到刚才发布的数据:
总结
上面流程,就是一个helloworld的服务发布和订阅,够简单吧,在实际的生产环境中,一个服务下面往往挂有好几个ip提供服务,在订阅端,拿到服务下面的所有地址列表后,通过负载均衡策略,例如随机策略,选择到一个ip进行调用,这样就完成了一次远程调用。