一、Spring Cloud Alibaba 1、简介 Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。 主要功能 服务限流降级 :默认支持 WebServlet、WebFlux, OpenFeign、RestTemplate、Spring Cloud Gateway, Zuul, Dubbo 和 RocketMQ 限流降级功能的接入,可以在运行时通过控制台实时修改限流降级规则,还支持查看限流降级 Metrics 监控。 Nacos(Naming Configuration Service) 是一个易于使用的动态服务发现、配置和服务管理平台,用于构建云原生应用程序。 服务发现是微服务架构中的关键组件之一 Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。 1. Nacos = 注册中心+配置中心组合 Kubernetes Service 3、为何使用Nacos? 为何使用注册中心呢?我们以入住酒店的前台为例子,稍微加以解释。先设想一个没有服务前台的酒店,客人入住需要自己寻找合适居住的房间,客人不知道每个房间的情况,无法确定那个房间是打扫干净可以入住,客人只能逐个房间寻找,如果遇到已经居住房客的房间一定很尴尬,显然这是不正常的情况。正常的情况是酒店会安排服务台,酒店打扫干净可以入住的房间会登记注册到服务台,这样客人来住店,只需要在前台就可以查找到可以入住的房间,这样就无需等待快速的入住。显然,服务器提供发注册和发现机制可以让房客快速找到合适的房间,快速解决入住问题。 采用微服务以后,软件微服务组件各自独立,但最终还要组合为一个整体作为一个软件系统服务于最终客户,这时软件组件之间也需要彼此通讯,彼此调用方法。微服务架构内部发起通讯调用方法的一方成为“服务消费者”,提供远程方法调用的服务器称为“服务提供者”,往往为了提高系统性能,会提供多个服务器作为服务提供者,此时服务消费者找到服务提供者的过程,就类似于用户在找房间的过程。为了帮助服务消费者快速的发现服务提供者,在微服务框架中都会引入**注册中心。注册中心类似于酒店的前台,提供在软件服务的注册和发现功能,服务提供者会先在注册中心进行注册,声明可以对外提供服务,而服务消费者只需要在注册中心就可以快速发现找到可以使用的服务,快速使用服务。注册中心实现了服务提供和服务消费的快速撮合功能。 2、Nacos下载和安装4.1、启动 1、解压后找到bin目录 2、执行指令: Linux/Unix/Mac sh startup.sh -m standalone 如果您使用的是ubuntu系统,或者运行脚本报错提示[[符号找不到,可尝试如下运行: bash startup.sh -m standalone Windows startup.cmd -m standalone 默认账号密码是:nacos/nacos :8848/nacos/#/login 5、Nacos代替Eureka Nacos可以直接提供注册中心(Eureka)+配置中心(Config),所以它的好处显而易见,我们在上节课成功安装和启动了Nacos以后就可以发现Nacos本身就是一个小平台,它要比之前的Eureka更加方便,不需要我们在自己做配置。 三、Nacos之服务注册中心 1、Nacos服务注册中心服务发现是微服务架构中的关键组件之一。在这样的架构中,手动为每个客户端配置服务列表可能是一项艰巨的任务,并且使得动态扩展极其困难。Nacos Discovery 帮助您自动将您的服务注册到 Nacos 服务器,Nacos 服务器会跟踪服务并动态刷新服务列表。此外,Nacos Discovery 将服务实例的一些元数据,如主机、端口、健康检查 URL、主页等注册到 Nacos。 spring-cloud-alibaba官网 点击 Reference Doc. 如何引入Nacos Discovery进行服务注册/发现 <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>
server.port=8070 spring.application.name=service-provider spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
@SpringBootApplication @EnableDiscoveryClient public class NacosProviderApplication { public static void main(String[] args) { SpringApplication.run(NacosProviderApplication.class, args); } @RestController class EchoController { @RequestMapping(value = "/echo/{string}", method = RequestMethod.GET) public String echo(@PathVariable String string) { return "Hello Nacos Discovery " + string; } } }
application.properties server.port=8080 spring.application.name=service-consumer spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848 通过 Spring Cloud 原生注解 @EnableDiscoveryClient 开启服务注册发现功能。给 RestTemplate 实例添加 @LoadBalanced 注解,开启 @LoadBalanced 与 Ribbon 的集成: @SpringBootApplication @EnableDiscoveryClient public class NacosConsumerApplication { @LoadBalanced @Bean public RestTemplate restTemplate() { return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(NacosConsumerApplication.class, args); } @RestController public class TestController { private final RestTemplate restTemplate; @Autowired public TestController(RestTemplate restTemplate) {this.restTemplate = restTemplate;} @RequestMapping(value = "/echo/{str}", method = RequestMethod.GET) public String echo(@PathVariable String str) { return restTemplate.getForObject("" + str, String.class); } } }
注意:要先启动Nacos,然后再来启动服务 2、远程调用与Ribbon1、什么是Ribbon 它是一个基于HTTP和TCP客户端负载均衡器。它虽然只是一个工具类库,它却是每一个微服务的基础设施。因为实际上,对于服务间调用、API网关请求转发都需要经过Ribbon负载均衡来实现。总体来说,Ribbon的主要作用是:从注册服务器端拿到对应服务列表后以负载均衡的方式访问对应服务。 要注意的是Nacos已经整合了Ribbon,所以我们想要使用只需要导入Spring Cloud Alibaba Nacos的依赖就可以直接使用了。 2、具体使用 现在如果我们需要远程访问那么可以使用RestTemplate,其中getForObject是最常用方法,同时还要在服务消费者中配置RestTemplate: @Bean @LoadBalanced public RestTemplate restTemplate(){ return new RestTemplate(); } restTemplate.getForObject(arg1,arg2,arg3...); 第一个参数url表示被调用的目标Rest接口位置 1. url的第一部分是在Nacos中注册的服务提供者名称,如果多个服务提供者注册相同名称, Ribbon会自动寻找其中一个服务提供者,并且调用接口方法。这个就是负载均衡功能。 2. url后半部是控制器的请求路径。 第二个参数是返回值类型 1. JavaBean类型或者JavaBean数组类型,如果控制器返回的是List集合,需要使用数组类型接收。 第三个参数是可变参数 1. 是传递给url的动态参数,使用参数时候需要在url上需要使用{1}、{2}、{3}进行参数占位, 这样传递的参数就会自动替换占位符。 验证Nacos自带负载均衡: 重复上面 <<1、Nacos服务注册中心>>创建2个服务提供者9001,9002,服务消费者8001,请求,查看是否自动负载均衡。 总结:因为Nacos中本身就集成了Ribbon所以它本身就自带负载均衡 3、各种服务注册中心对比服务注册与发现框架 CAP模型 控制台管理 社区活跃度 Eureka AP 支持 低(2.x版本闭源) Zookeeper CP 不支持 中 Consul CP 支持 高 Nacos AP/CP 支持 高 CAP模型 计算机专家 埃里克·布鲁尔(Eric Brewer)于 2000 年在 ACM 分布式计算机原理专题讨论会(简称:PODC)中提出的分布式系统设计要考虑的三个核心要素: 一致性(Consistency):同一时刻的同一请求的实例返回的结果相同,所有的数据要求具有强一致性(Strong Consistency) 可用性(Availability):所有实例的读写请求在一定时间内可以得到正确的响应 分区容错性(Partition tolerance):在网络异常(光缆断裂、设备故障、宕机)的情况下,系统仍能提供正常的服务 以上三个特点就是CAP原则(又称CAP定理),但是三个特性不可能同时满足,所以分布式系统设计要考虑的是在满足P(分区容错性)的前提下选择C(一致性)还是A(可用性),即:CP或AP。 CP原则:一致性 + 分区容错性原则 CP 原则属于强一致性原则,要求所有节点可以查询的数据随时都要保持一直(同步中的数据不可查询),即:若干个节点形成一个逻辑的共享区域,某一个节点更新的数据都会立即同步到其他数据节点之中,当数据同步完成后才能返回成功的结果,但是在实际的运行过程中网络故障在所难免,如果此时若干个服务节点之间无法通讯时就会出现错误,从而牺牲了以可用性原则(A),例如关系型数据库中的事务。 AP原则:可用性原则 + 分区容错性原则 AP原则属于弱一致性原则,在集群中只要有存活的节点那么所发送来的所有请求都可以得到正确的响应,在进行数据同步处理操作中即便某些节点没有成功的实现数据同步也返回成功,这样就牺牲一致性原则(C 原则)。 Nacos支持CP和AP Nacos无缝支持一些主流的开源生态,同时再阿里进行Nacos设计的时候重复的考虑到了市场化的运作(市面上大多都是以单一的实现形式为主,例如:Zookeeper使用的是 CP、而 Eureka采用的是AP),在Nacos中提供了两种模式的动态切换。 Nacos 何时选择切换模式 1. 一般来说,如果不需要储存服务界别的信息且服务实例通过nacos-client注册,并能够保持心跳上报,那么就可以选择AP模式。如Spring Cloud 和 Dubbo,都适用于AP模式,AP模式为了服务的可用性减弱了一致性,因此AP模式下只支持注册临时实例。 2. 如果需要在服务级别编辑或者储存配置信息,那么CP是必须的,K8S服务和DNS服务则是用于CP模式。CP模式下则支持注册持久化实例,此时则是以Raft协议为集群运行模式,该模式下注册实例之前必须先注册服务,如果服务不存在,则会返回错误。 切换命令(默认是AP): curl -X PUT '$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP' 注意:临时和持久化的区别主要在健康检查失败后的表现,持久化实例健康检查失败后会被标记成不健康,而临时实例会直接从列表中被删除。 四、Nacos之服务配置中心Nacos不仅仅可以作为注册中心来使用,同时它支持作为配置中心 1、添加依赖<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> 2、YML配置 要注意的是这里我们要配置两个,因为Nacos同SpringCloud-config一样,在项目初始化时,要保证先从配置中心进行配置拉取,拉取配置之后,才能保证项目的正常启动。 bootstrap.yml # nacos配置 server: port: 8085 spring: application: name: nacos-config-client cloud: nacos: discovery: server-addr: localhost:8848 #Nacos服务注册中心地址 config: server-addr: localhost:8848 #Nacos作为配置中心地址 file-extension: yaml #指定yaml格式的配置 application.yml spring: profiles: active: dev # 表示开发环境 业务类 这里的@RefreshScope实现配置自动更新,意思为如果想要使配置文件中的配置修改后不用重启项目即生效,可以使用@RefreshScope配置来实现 @RestController @RequestMapping("/config") @RefreshScope //实现Nacos配置自动更新 public class ConfigController { @Value("${useLocalCache:false}") private boolean useLocalCache; @RequestMapping("/get") public boolean get() { return useLocalCache; } } 3、Nacos配置规则在 Nacos Spring Cloud 中,dataId 的完整格式如下:Nacos官网说明 ${prefix}-${spring.profiles.active}.${file-extension} prefix 默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix来配置。 spring.profiles.active 即为当前环境对应的 profile。 注意:当 spring.profiles.active 为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成 ${prefix}.${file-extension} file-exetension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 properties 和 yaml 类型。 # ${spring.application.name}-${spring.profiles.active}.${file-extension} # nacos-config-client-dev.yaml # 微服务名称-当前环境-文件格式 五、Nacos命名空间分组和DataID三者关系 1、命名空间(Namespace)用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的 Group 或 Data ID 的配置。Namespace 的常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。 2、配置分组(Group)Nacos 中的一组配置集,是组织配置的维度之一。通过一个有意义的字符串(如 Buy 或 Trade )对配置集进行分组,从而区分 Data ID 相同的配置集。当您在 Nacos 上创建一个配置时,如果未填写配置分组的名称,则配置分组的名称默认采用 DEFAULT_GROUP 。配置分组的常见场景:不同的应用或组件使用了相同的配置类型,如 database_url 配置和 MQ_topic 配置。 3、配置集 ID(Data ID) Nacos 中的某个配置集的 ID。配置集 ID 是组织划分配置的维度之一。Data ID 通常用于组织划分系统的配置集。一个系统或者应用可以包含多个配置集,每个配置集都可以被一个有意义的名称标识。Data ID 通常采用类 Java 包(如 com.taobao.tc.refund.log.level)的命名规则保证全局唯一性。此命名规则非强制。 三者关系 这三者的关系类似于Java里面的package名和类名,最外层的Namespace是可以用于区分部署环境的,Group和DataID逻辑上区分两个目标对象。
默认情况 Namespace=public,Group=DEFAULT_GROUP,默认Cluster是DEFAULT 具体情况 Nacos默认的命名空间是public,我们就可以利用Namespace来实现隔离,比如我们现在有三个环境:开发、测试、生产环境,我们就可以创建三个Namespace,不同的Namespace之间是隔离的。 1、DataID方案 2.通过spring.profile.active属性就能进行多环境下配置文件的读取 spring: profiles: # active: dev #表示开发环境 active: test #表示测试环境 2、Group方案 1. 新建Group DEV_GROUP TEST_GROUP 2. 完成以上配置以后,接下来就需要通过bootstrap+application来配合完成,具体方式:在config下增加一条Group的配置即可,可以配置为DEV_GROUP或TEST_GROUP # nacos配置 server: port: 8001 spring: application: name: nacos-config-client cloud: nacos: discovery: server-addr: localhost:8848 #Nacos服务注册中心地址 config: server-addr: localhost:8848 #Nacos作为配置中心地址 file-extension: yaml #指定yaml格式的配置 group: TEST_GROUP #增加分组 3、Namespace空间方案 1. 新建dev/test的Namespace # nacos配置 server: port: 8001 spring: application: name: nacos-config-client cloud: nacos: discovery: server-addr: localhost:8848 #Nacos服务注册中心地址 config: server-addr: localhost:8848 #Nacos作为配置中心地址 file-extension: yaml #指定yaml格式的配置 group: TEST_GROUP #增加分组 namespace: 4ba4bf0e-210c-41ce-954c-23538de1dcbc #指定命名空间 六、Nacos部署模式Nacos部署环境 单机模式支持mysql 1.安装数据库,版本要求:5.6.5+ 2.初始化mysql数据库,数据库初始化文件:mysql-schema.sql 3.修改conf/application.properties文件,增加支持mysql数据源配置(目前只支持mysql),添加mysql数据源的url、用户名和密码。 spring.datasource.platform=mysql db.num=1 db.url.0=jdbc:mysql://11.162.196.16:3306/nacos_devtest?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&serverTimezone=UTC db.user=root db.password=123456 注意:这里需要注意几个点,一个是url地址需要改,另外数据库的用户和密码也需要更改,同时还有一个是官网上在db.url.0=jdbc:mysql这个属性上少了一个属性为serverTimezone=UTC需要我们手动添加 在Linux系统中解压此文件,并且把其中nacos目录拷贝到nacos目录中 tar -zxvf nacos-server-x.x.x.tar.gz cd nacos/bin 配置集群配置文件 # ip:port 200.8.9.16:8848 200.8.9.17:8848 200.8.9.18:8848 启动服务器 Stand-alone mode sh startup.sh -m standalone 集群模式 使用内置数据源 sh startup.sh -p embedded 使用外置数据源 sh startup.sh // 关闭防火墙服务-但是开启还会自动启动 systemctl stop firewalld // 彻底关闭-开机不会启动防火墙 systemctl disable firewalld Nginx配置 修改nginx.conf worker_processes 1; events { worker_connections 1024; } stream { upstream nacos { server 200.8.9.16:8848; server 200.8.9.17:8848; server 200.8.9.18:8848; } server { listen 81; proxy_pass nacos; } } server: port: 9002 spring: application: name: nacos-provider cloud: nacos: discovery: # server-addr: localhost:8848 # 换成nginx的81端口,做集群 server-addr: :81 |