docker-compose方式部署

官方Demo

1. 下载demo

  1. git clone https://github.com/nacos-group/nacos-docker.git
  2. cd nacos-docker/example

2. 执行脚本

因为官方它这个要内嵌数据库,我们生产一般不会在去为它单独搞一个msql,直接用我们业务现成的。
所以需要在我们现有的mysql执行db脚本(创建数据库和表,它这边默认是nacos_config)

  1. sql执行脚本:
  2. https://github.com/alibaba/nacos/blob/develop/distribution/conf/nacos-mysql.sql
  3. https://github.com/alibaba/nacos/blob/develop/distribution/conf/schema.sql

3. 编辑docker-compose文件

修改compose文件(指定版本号和修改连接mysql的配置文件)

  1. version: "3"
  2. services:
  3. nacos:
  4. image: nacos/nacos-server:1.4.2
  5. container_name: nacos-standalone-mysql
  6. environment:
  7. - PREFER_HOST_MODE=hostname
  8. - SPRING_DATASOURCE_PLATFORM=mysql
  9. - MODE=standalone
  10. - MYSQL_SERVICE_HOST=192.168.1.148
  11. - MYSQL_SERVICE_DB_NAME=nacos_config
  12. - MYSQL_SERVICE_PORT=3307
  13. - MYSQL_SERVICE_USER=root
  14. - MYSQL_SERVICE_PASSWORD=123456
  15. - NACOS_APPLICATION_PORT=8848
  16. - MYSQL_SERVICE_DB_PARAM=characterEncoding=utf8&connectTimeout=10000&socketTimeout=30000&autoReconnect=true&useSSL=false
  17. - JVM_XMS=512m
  18. - JVM_MMS=320m
  19. volumes:
  20. - ./standalone-logs/:/home/nacos/logs
  21. ports:
  22. - "8848:8848"
  23. restart: always

4. 查看日志

启动成功后,查看start.out日志,会发现我们连接外部数据库是ok的
image.png
如果你连接的不是外部数据库,默认是采用嵌入式的数据库则日志启动如下:
image.png

5. 更换mysql用户名:

当然如果你希望换个用户名,需要链接mysql实例进行操作,我是为了省事。

  1. CREATE USER 'nacos'@'%' IDENTIFIED BY 'nacos';
  2. grant all privileges on nacos_config.* to 'nacos'@'%' identified by 'nacos';
  3. flush privileges;

备注:nacos默认优先读取配置中心的数据,而非本地配置的数据,切记!
参考文档:
官方文档:https://nacos.io/zh-cn/docs/quick-start-docker.html

k8s单机版

service

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: nacos-headless
  5. namespace: prod
  6. labels:
  7. app: nacos
  8. annotations:
  9. service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
  10. spec:
  11. type: NodePort
  12. ports:
  13. - port: 8848
  14. nodePort: 30002
  15. name: server
  16. targetPort: 8848
  17. selector:
  18. app: nacos

ConfigMap

  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4. name: nacos-config-map
  5. namespace: prod
  6. data:
  7. prefer.host.mode: "hostname"
  8. spring.datasource.platform: "mysql"
  9. mode: "standalone"
  10. nacos.application.port: "8848"
  11. mysql.service.host: "10.10.10.145"
  12. mysql.service.db.name: "nacos_config"
  13. mysql.service.port: "30001"
  14. mysql.service.user: "root"
  15. mysql.service.password: "123456"
  16. mysql.service.db.param: "characterEncoding=utf8&connectTimeout=10000&socketTimeout=30000&autoReconnect=true&useSSL=false"
  17. jvm.xms: "512m"
  18. jvm.mms: "320m"

StatefulSet

  1. apiVersion: apps/v1
  2. kind: StatefulSet
  3. metadata:
  4. name: nacos
  5. namespace: prod
  6. spec:
  7. serviceName: nacos
  8. replicas: 1
  9. template:
  10. metadata:
  11. labels:
  12. app: nacos
  13. selector:
  14. matchLabels:
  15. app: nacos
  16. spec:
  17. containers:
  18. - name: nacos
  19. imagePullPolicy: IfNotPresent
  20. image: nacos/nacos-server:1.4.2
  21. resources:
  22. requests:
  23. memory: "2Gi"
  24. cpu: "500m"
  25. ports:
  26. - containerPort: 8848
  27. env:
  28. - name: PREFER_HOST_MODE
  29. value: "hostname"
  30. - name: SPRING_DATASOURCE_PLATFORM
  31. value: "mysql"
  32. - name: MODE
  33. value: "standalone"
  34. - name: NACOS_APPLICATION_PORT
  35. value: "8848"
  36. - name: MYSQL_SERVICE_HOST
  37. value: "10.10.10.145"
  38. - name: MYSQL_SERVICE_DB_NAME
  39. value: "nacos_config"
  40. - name: MYSQL_SERVICE_PORT
  41. value: "30001"
  42. - name: MYSQL_SERVICE_USER
  43. value: "root"
  44. - name: MYSQL_SERVICE_PASSWORD
  45. value: "123456"
  46. - name: MYSQL_SERVICE_DB_PARAM
  47. value: "characterEncoding=utf8&connectTimeout=10000&socketTimeout=30000&autoReconnect=true&useSSL=false"
  48. - name: JVM_XMS
  49. value: "512m"
  50. - name: JVM_MMS
  51. value: "320m"
  52. volumeMounts:
  53. - name: logs
  54. mountPath: /home/nacos/logs
  55. volumes:
  56. - name: logs
  57. hostPath:
  58. path: /root/project-server/nacos/k8s/logs

StatefulSet(comfigmap)

  1. apiVersion: apps/v1
  2. kind: StatefulSet
  3. metadata:
  4. name: nacos
  5. namespace: prod
  6. spec:
  7. serviceName: nacos-headless
  8. replicas: 1
  9. template:
  10. metadata:
  11. labels:
  12. app: nacos
  13. spec:
  14. containers:
  15. - name: nacos
  16. imagePullPolicy: IfNotPresent
  17. image: nacos/nacos-server:1.4.2
  18. resources:
  19. requests:
  20. memory: "2Gi"
  21. cpu: "500m"
  22. ports:
  23. - containerPort: 8848
  24. env:
  25. - name: PREFER_HOST_MODE
  26. valueFrom:
  27. configMapKeyRef:
  28. name: nacos-config-map
  29. key: prefer.host.mode
  30. - name: SPRING_DATASOURCE_PLATFORM
  31. valueFrom:
  32. configMapKeyRef:
  33. name: nacos-config-map
  34. key: spring.datasource.platform
  35. - name: MODE
  36. valueFrom:
  37. configMapKeyRef:
  38. name: nacos-config-map
  39. key: mode
  40. - name: NACOS_APPLICATION_PORT
  41. valueFrom:
  42. configMapKeyRef:
  43. name: nacos-config-map
  44. key: nacos.application.port
  45. - name: MYSQL_SERVICE_HOST
  46. valueFrom:
  47. configMapKeyRef:
  48. name: nacos-config-map
  49. key: mysql.service.host
  50. - name: MYSQL_SERVICE_DB_NAME
  51. valueFrom:
  52. configMapKeyRef:
  53. name: nacos-config-map
  54. key: mysql.service.db.name
  55. - name: MYSQL_SERVICE_PORT
  56. valueFrom:
  57. configMapKeyRef:
  58. name: nacos-config-map
  59. key: mysql.service.port
  60. - name: MYSQL_SERVICE_USER
  61. valueFrom:
  62. configMapKeyRef:
  63. name: nacos-config-map
  64. key: mysql.service.user
  65. - name: MYSQL_SERVICE_PASSWORD
  66. valueFrom:
  67. configMapKeyRef:
  68. name: nacos-config-map
  69. key: mysql.service.password
  70. - name: MYSQL_SERVICE_DB_PARAM
  71. valueFrom:
  72. configMapKeyRef:
  73. name: nacos-config-map
  74. key: mysql.service.db.param
  75. - name: JVM_XMS
  76. valueFrom:
  77. configMapKeyRef:
  78. name: nacos-config-map
  79. key: jvm.xms
  80. - name: JVM_MMS
  81. valueFrom:
  82. configMapKeyRef:
  83. name: nacos-config-map
  84. key: jvm.mms
  85. volumeMounts:
  86. - name: logs
  87. mountPath: /home/nacos/logs
  88. volumes:
  89. - name: logs
  90. hostPath:
  91. path: /root/project-server/backend/nacos/logs
  92. selector:
  93. matchLabels:
  94. app: nacos

问题点

1. 通过nacos发现getway内部容器里面无法ping通外网

当我们把应用部署在148服务器上后,我们启动本地105的一个服务,发现自己某个服务已经注册到nacos,但是转发到我本地105服务失败了,检测发现内部无法ping 通105和百度,需要重启下docker。在检查下网络是否通畅。

  1. systemctl 方式
  2. 守护进程重启
  3. sudo systemctl daemon-reload
  4. 重启docker服务
  5. sudo systemctl restart docker
  6. 关闭docker
  7. sudo systemctl stop docker
  8. service 方式
  9. 重启docker服务
  10. sudo service docker restart
  11. 关闭docker
  12. sudo service docker stop

再见了nacos

下面文章转载于:文章地址

在阐述Service Mesh服务注册发现机制前,先简单回顾下在以Spring Cloud为代表的传统微服务中是如何实现服务注册与发现的。

nacos基本原理

先说下nacos基本原理:微服务启动时会通过集成的服务发现SDK,向注册中心(应用配置的注册中心地址)发送注册信息,注册中心在收到服务注册请求后将存储服务的基本信息,比如我们这里存储服务是mysql;之后,如有服务消费者要调用该服务,那么调用方通过服务发现组件(例如Ribbon)就可以向注册中心查询目标微服务的地址列表,并通过获取的服务地址列表,以某种负载策略向目标微服务发起调用了。
而当服务节点发现变更时,新的节点会被重新注册,而下线的节点基于服务探活机制也会及时从服务注册中心被踢除,基于这样的服务注册/发现机制,微服务之间的通信顺畅就能得到保证。从这个角度看,注册中心与服务之间的健康性检查就显得很重要,如果注册中心不能及时将下线或故障的节点从可用服务器地址列表剔除,那么就很可能会造成微服务某些调用的失败。
那么一般怎样进行服务健康性检查呢?从方式上看,主流的健康性检查方式,主要有以下3种:

健康检查方式

1. 微服务主动探活

服务主动探活就是微服务定期向注册中心发送租约信息以表面自己的存活。在实际场景中主动探活是我们使用注册中心时用得最多的一种方式,如果服务规模不大,或者使用了类似于Eureka这样的最终一致性注册中心,那么主动探活就是一种最佳选择,它可以较大程度地避免服务部署在Kubernetes集群后,因为Pod IP重用而导致的旧有服务节点依然存活的问题,毕竟续约信息都是带着服务基础信息上报到注册中心的。
但这种方式也有明显的弊端,它会造成注册中心写操作压力变大。如果大量的服务同时发布,节点产生较大的变动,那么就可能产生大量的通知事件,从而对整个微服务体系的稳定产生较大影响。
此外,主动续约,也并不完全说明服务是健康的,因为某些特殊情况下可能会存在虽然服务无法对外提供服务,但还能正常向注册中心发出租约信息的问题。

2. 注册中心发起健康性检查

前面分析了微服务主动探活方式的优缺点,而如果由注册中心发起健康性检查会怎么样呢?
这种方式是指微服务在注册时,同时向注册中心暴露自己的健康检查端点(如/actuator/health),注册中心通过定期访问来探测服务节点是否存活。
不过这种方式也不是完全没有问题,例如前面提到的Pod IP重用问题,如果其他微服务重用了之前节点的IP,那么就会发生失效节点被激活的假象。当然也有相应的解决方案,例如后面会讲到Istio微服务注册发现时Envoy会对服务名称进行二次Check的方式。

3.调用方负载均衡器进行健康性检查

第3种方案比较极端,注册中心不进行任何服务探活,全部由微服务调用方所在的负载均衡器进行探活。这种方案常见的一种场景就是gRPC的失效节点自动摘除功能。但这种方案依然具有IP被重用问题,所以此种方式在实际的场景中并不是很受欢迎。
前面讲了微服务注册发现常见的三种服务探活方式,其实三种方案各有利弊。以Spring Cloud微服务体系中,使用最广泛的几种注册中心为例,如Eureka、Consul、Nacos,它们的对比如下表所示:
image.png
从表格中可以看到,除了Eureka主要采用服务主动探活方式外,Consul及Nacos都采用了多种服务探活方式,从而尽量规避不同方式的弊端,这也是为什么目前大部分实践逐步抛弃Eureka而采用Consul或Nacos的原因。
除了健康性检查外,上面表格还分别列出了这几种注册中心的一致性协议。这里顺带普及下CAP理论。CAP是分布式系统中重要的一种概念,它分别由一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)三部分组成。在CAP理论中,一个分布式系统不可能三种都满足,一般只能同时满足其中的两种,而作为分布式系统分区容错基本都是要满足的所以Partition tolerance基本必不可少。例如Eureka和Nacos只能满足可用性和分区容错性,而无法满足一致性;Consul则只能满足一致性和分区容错性,而无法完全满足可用性。
在注册中心的场景中,一致性一般要求并不高,只要能达到最终一致性即可。毕竟在微服务架构中,涉及节点的注册和反注册,注册中心和客户端之间的通信需要一定时间,一致性本身也很难达到。所以在注册中心的选型中,一般会优先选择AP的系统,这也是目前还在以Spring Cloud构建微服务的实践中,除了自研外,开源技术中会优先选择Nacos作为服务注册中心的原因。

弊端

传统微服务体系中,注册中心无疑是整个微服务体系最重要的组成部分,没有服务注册中心提供的统一服务注册发现功能,微服务本身就无从谈起。不过相较于Service Mesh架构中服务注册发现,很大程度上是依赖于基础设施(例如数据面[envoy]、控制面[istio]以及Kubernetes集群),而无需微服务亲力亲为。在Spring Cloud传统架构中,服务注册、发现及健康性检查等服务治理逻辑则都需要微服务自己上下打点。
虽然不用重复造轮子,都有现成的服务治理组件及框架,但从应用运行形态上说,与服务注册发现相关的逻辑都是微服务直接与注册中心产生的交互。从系统架构上看,这种方式显然是将服务治理逻辑与业务应用耦合了,其运行逻辑如下图所示: