在使用k8s的容器化,是否选择nacos作为服务发现的注册中心?

1,024 阅读4分钟

结论:在当前容器化、k8s流行的背景下,不太建议使用nacos作注册中心(当然,nacos作配置中心使用,也是个不错的选择)。nacos作注册中心,适用那种只使用java编程语言、非k8s部署方式的情况下。

一、背景

  1. 微服务的配置信息,经历了程序配置文件->git config->配置中心(nacos、apollo);
  2. 注册中心常用的解决方案,zookeeper(dubbo)、eureka、nacos
  3. 微服务部署过程中,既要注册中心、也需要配置中心,但如果分别搭建2套组件,一方面占用更多资源;另一方面,维护成本也会增加;
  4. nacos既可作为配置中心,又可以作为注册中心,在微服务发展中因此脱颖而出;
  5. 随着容器化的发展,特别是k8s的兴起,nacos不一定是最优秀的解决方案;

二、二种微服务调用解决方案

  1. 直接通过ip:port访问(一般通过nginx等方式做负载均衡)
    一般情况下,通过nginx等方式做服务的负载均衡,但很难做到服务的动态发现

  1. 注册中心
    (1)服务提供者注册到注册中心,注册中心记录服务提供者的IP、PORT;
    (2)服务消费者订阅注册中心数据,获取服务提供者的(IP、PORT),然后通过IP、PORT调用服务提供者的接口;
    (3)通过注册中心,做到服务的动态发现

三、nacos作注册中心,存在的问题

  1. 微服务部署在docker容器中,可能会导致服务在注册中心登记的IP为容器的ip,从而导致服务无法调用;
  2. 微服务部署在不同的k8s集群,也会导致微服务相互调不通;
  3. 微服务部署的服务器,如果是双网卡的,也很容易会导致微服务无法调用;
  4. 跨语言调用支持,例如有一些微服务是基于java的,一些微服务是基于python的,java服务调用python服务,不能通过nacos注册中心来调用(间接方法,通过sidecar来注册到nacos);
  5. 微服务间调用,容易受nacos影响(nacos宕机);
  6. 开发环境,nacos可能只部署一个,所有开发都注册到这个nacos上,容易导致被调用方不是调用方期望的。例如开发A想调用开发环境上服务S的接口,开发B这时在自己电脑上开发测试服务S,二者都注册到了nacos上,这时开发A有可能调到了开发B电脑上的服务S。这时开发B重启服务、修复接口,会导致开发A调用有问题;

四、微服务调用方案建议

  1. 在k8s越来越流行,很多公司都上k8s了;
  2. 在k8s集群内部,可以通过k8s serviceName的方式调用服务提供者的接口;
  3. 在k8s集群外部,调用k8s集群的服务,可以通过k8s ingress将集群内部的服务暴露出来,让服务消费者调用;
  4. 通过这种方式,能解决服务动态发现、跨语言调用(java调用python服务)二大问题;

五、java Feign调用配置说明

  1. 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;
  2. url参数放到注册中心,默认为空,这时可以通过注册中心调用微服务;
  3. 在开发测试生产环境时,一般通过指定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作注册中心,就可以解决。

文章转载自:zhuanlan.zhihu.com/p/669805255