结论:在当前容器化、k8s流行的背景下,不太建议使用nacos作注册中心(当然,nacos作配置中心使用,也是个不错的选择)。nacos作注册中心,适用那种只使用java编程语言、非k8s部署方式的情况下。
一、背景
- 微服务的配置信息,经历了程序配置文件->git config->配置中心(nacos、apollo);
- 注册中心常用的解决方案,zookeeper(dubbo)、eureka、nacos
- 微服务部署过程中,既要注册中心、也需要配置中心,但如果分别搭建2套组件,一方面占用更多资源;另一方面,维护成本也会增加;
- nacos既可作为配置中心,又可以作为注册中心,在微服务发展中因此脱颖而出;
- 随着容器化的发展,特别是k8s的兴起,nacos不一定是最优秀的解决方案;
二、二种微服务调用解决方案
- 直接通过ip:port访问(一般通过nginx等方式做负载均衡)
一般情况下,通过nginx等方式做服务的负载均衡,但很难做到服务的动态发现
- 注册中心
(1)服务提供者注册到注册中心,注册中心记录服务提供者的IP、PORT;
(2)服务消费者订阅注册中心数据,获取服务提供者的(IP、PORT),然后通过IP、PORT调用服务提供者的接口;
(3)通过注册中心,做到服务的动态发现
三、nacos作注册中心,存在的问题
- 微服务部署在docker容器中,可能会导致服务在注册中心登记的IP为容器的ip,从而导致服务无法调用;
- 微服务部署在不同的k8s集群,也会导致微服务相互调不通;
- 微服务部署的服务器,如果是双网卡的,也很容易会导致微服务无法调用;
- 跨语言调用支持,例如有一些微服务是基于java的,一些微服务是基于python的,java服务调用python服务,不能通过nacos注册中心来调用(间接方法,通过sidecar来注册到nacos);
- 微服务间调用,容易受nacos影响(nacos宕机);
- 开发环境,nacos可能只部署一个,所有开发都注册到这个nacos上,容易导致被调用方不是调用方期望的。例如开发A想调用开发环境上服务S的接口,开发B这时在自己电脑上开发测试服务S,二者都注册到了nacos上,这时开发A有可能调到了开发B电脑上的服务S。这时开发B重启服务、修复接口,会导致开发A调用有问题;
四、微服务调用方案建议
- 在k8s越来越流行,很多公司都上k8s了;
- 在k8s集群内部,可以通过k8s serviceName的方式调用服务提供者的接口;
- 在k8s集群外部,调用k8s集群的服务,可以通过k8s ingress将集群内部的服务暴露出来,让服务消费者调用;
- 通过这种方式,能解决服务动态发现、跨语言调用(java调用python服务)二大问题;
五、java Feign调用配置说明
- feign的一般配置如下所示,FeignClient注解,有2个关键参数name,url。当url为空时,FeignClient会根据name="serviceName"在注册中心获取微服务的IP、端口,调用接口;如果url不会空时,会通过url参数,调用接口。例如:
(1) name="service1"、url为空,service1在注册中心的ip、端口为(127.0.0.1:8080),则调用method1时,访问url为 http://127.0.0.1:8080/method1;
(2)url="http://abc:3000",name可以为空,也可以非空,则调用method1访问url为 http://abc:3000/method1; - url参数放到注册中心,默认为空,这时可以通过注册中心调用微服务;
- 在开发测试生产环境时,一般通过指定url的方式来调用微服务
(1)开发、测试环境可能部署在容器或k8s集群上,通过注册中心,不一定能调得通;
(2)开发、测试环境,nacos一般只部署一套,如果开发人员做开发时,注册到了nacos,会导致开发、测试环境异常,影响别的开发、测试同事;
(3)生产环境的发布,服务停止、启动,会导致服务短暂调不通(原因:由于nacos是基于AP(CAP理论)实现的,先保证可以,不能保证数据的一致性,即有一些微服务,当前是不可用的,但nacos没有马上更新)
@FeignClient(name = "service1", url = "${base-url:}")
public interface TradePasswordFeignClient {
@PostMapping("/method1")
ResultWrapper<String> method1();
}
六、nacos作为注册中心的适合场景
如果生产环境不是使用k8s部署,所有微服务都是基于java实现的,这种情况nacos作注册中心比较合适。因为,如果通过url的方式访问,微服务要配置一个统一网关,将微服务暴露出来;同时,做负载均衡,这样很麻烦,直接使用nacos作注册中心,就可以解决。