你好,我是程序员Alan.
我在《白话服务治理—高并发场景微服务实战(八)》中,简单介绍了微服务常见组件功能,从本篇开始我将进一步讲解各个组件的内容和应用。
服务调用的问题
在《需求分析—高并发常见微服务实战(二)》分析业务需求时,其中有个简单的功能点:订票服务可以请求不同的航空公司查询机票信息,订购指定航空公司航班机票。这里就涉及到两个或多个服务间的调用问题。
服务调用可以简单的分为单实例情况和多实例情况。
单实例情况
可以采用 IP + Port + 接口的形式,采用点对点的HTTP直接调用。这种情况有个明显的缺点就是如果服务增多,将会形成蜘蛛网的形式,非常不利于开发维护。
多实例情况
在实际生产场景中,我们通常会采用多实例集群部署,来应对服务的压力。但多实例部署后,直接面临一个问题,即调用方如何知晓调用哪个实例,当实例运行失败后,如何转移到别的实例上去处理请求?此时我们可能会选择Nginx负载均衡,但往往是静态的,在服务不可用时,如何动态的更新负载均衡列表,保证调用者的正常调用呢?
面对以上两种情况,我们需要将所有的服务统一的、动态的管理起来,此时注册中心就应运而生。
服务注册中心
服务注册中心作分布式服务框架的核心模块,要实现的功能是服务的注册、订 阅、注销、通知 。
所有的服务都与注册中心发生连接,由注册中心统一配置管理,不再由实例自身直接调用。服务管理过程大致过程如下图所示:
从图中,可以看到一个完整的,服务注册和发现的过程:
1.服务提供者启动时,将服务提供者的信息主动提交到服务注册中心进行服务注册。
2.服务调用者启动时,将服务提供者信息从注册中心下载到调用者本地,调用者从本地的 服务提供者列表中,基于某种负载均衡策略选择一台服务实例发起远程调用,这是一个点到点调用的方式。
3.服务注册中心能够感知服务提供者某个实例下线,同时将该实例服务提供者信息从注册中心清除,并通知服务调用者集群中的每一个实例,告知服务调用者不再调用本实例,以免调用失败。
从这个过程中可以看出,有了注册中心之后,服务节点的增加和减少对于客户端就是透明的。这样,除了可以实现不重启客户端,就能动态地变更服务节点以外,还可以实现优雅关闭的功能。
Nacos应用
目前业界有很多可供你来选择的注册中心组件,例如 ZooKeeper,阿里的微服务注册中心 Nacos,Spring Cloud 的 Eureka 等等。 我个人比较常用的组件是Nacos,它的定位是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
安装Nacos
Nacos官网地址:https://nacos.io/en-us/,本文采用Nacos 1.1.4 版本。
下载后解压,使用对应命令启动。
startup.cmd -m standalone
(standalone代表着单机模式运行,非集群模式)
启动日志如下:
启动成功后,打开http://127.0.0.1:8848/nacos,输入默认的用户名 nacos、密码 nacos,就可以看到如下界面。
可以看到Nacos左侧菜单栏看到Nacos提供的主要功能,本次我们只用到Nacos服务管理功能,其他功能后面章节再讲。
服务中应用Nacos
本文演示如何在Sping Boot项目中启动Nacos的服务发现功能。
1.添加依赖
<dependency><groupId>com.alibaba.boot</groupId><artifactId>nacos-discovery-spring-boot-starter</artifactId><version>0.2.7</version></dependency>
注意:版本 0.2.x.RELEASE 对应的是 Spring Boot 2.x 版本,版本 0.1.x.RELEASE 对应的是 Spring Boot 1.x 版本。
2. 在application.yml中配置Nacos server的地址
nacos: discovery: server-addr: 127.0.0.1:88483.使用注入Nacos的NamingServerice实例"discovery") (publicclassDiscoveryController { privateNamingServicenamingService; value="/get", method=GET) (publicList<Instance>get(StringserviceName) throwsNacosException { returnnamingService.getAllInstances(serviceName); } } publicclassNacosDiscoveryApplication { publicstaticvoidmain(String[] args) { SpringApplication.run(NacosDiscoveryApplication.class, args); } }
4.启动NacosDiscoveryApplication,curl http://localhost:8080/discovery/get?serviceName=example
,此时返回为空 JSON 数组[]。
5.通过调用 Nacos Open API 向 Nacos server 注册一个名称为 example 服务
curl -X POST 'http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=example&ip=127.0.0.1&port=8080'
6.再次访问 curl http://localhost:8080/discovery/get?serviceName=example
,此时返回内容为
[ { "instanceId": "127.0.0.1-8080-DEFAULT-example", "ip": "127.0.0.1", "port": 8080, "weight": 1.0, "healthy": true, "cluster": { "serviceName": null, "name": "", "healthChecker": { "type": "TCP" }, "defaultPort": 80, "defaultCheckPort": 80, "useIPPort4Check": true, "metadata": {} }, "service": null, "metadata": {} } ]
站在巨人的肩膀上
- Nacos文档
- SpringCloud微服务实战—码闻强