A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 大蓝鲸小蟀锅 于 2020-3-6 11:05 编辑

服务发现
为了实现多个微服务之间的调用,我们除了需要Feign这种调用组件外还得依赖服务发现组件。主要的原因是每个微服务所在的机器ip并非总是固定的,并且每个微服务都可能部署多个实例在不同的机器上,所以我们不能把依赖的微服务ip地址写在代码或配置文件里,我们需要有个组件去动态的管理,这就是为什么微服务架构里服务发现功能是必须的。

那么服务发现组件是怎么实现服务发现的呢?我们以大家比较熟悉的MySQL来做类比,通过MySQL简单说明一下服务发现机制的实现。如下图:

简单说明一下什么是服务提供者与服务消费者:
· 服务提供者:服务的被调用方(即:为其他微服务提供接口的微服务)
· 服务消费者:服务的调用方(即:调用其他微服务接口的微服务)
· 例如:订单服务需要调用用户服务的接口,那么订单服务就是服务消费者,而用户服务则是服务提供者
· 服务提供者与服务消费者实际描述的是微服务之间的调用关系,一般都是成对出现的

当微服务启动的时候会向服务发现组件注册自身信息,在上图中就类似于向MySQL发送一条insert语句,将服务的元数据如服务名称、ip地址及服务状态等信息插入到MySQL中,如上图的registry表数据所示,这个过程称之为服务注册,所以服务发现组件内部会都维护类似于这样的一张注册表。

微服务在注册完成后,会读取服务发现组件中保存的其他微服务的元数据并缓存一份到本地,就类似于向MySQL发送一条select all语句。这样在调用其他服务的时候,就不需要每次都去服务发现组件上查询,而是从本地缓存去查找调用地址,这样可以减轻服务发现组件的压力。所以上图中的调用箭头并没有指向服务发现组件,而是直接指向服务提供者。这样的好处是哪怕是服务发现组件挂掉了,还能从本地缓存中获取其他微服务的调用地址。到这一步微服务之间就可以互相发现了,即完成基本的服务发现
但微服务有可能会挂掉或下线,此时其他服务不应该去发现一个不存在的服务。所以每个服务启动且向服务发现组件注册完成之后,都会通过心跳机制告知存活状态。上图中用last_heartbeat字段表示,若某个服务在超过一定的时间都没有发送心跳包的话,就会被服务发现组件检测到,此时就会删除注册表里该服务的注册信息,并通知其他服务更新本地缓存(若有新注册的服务也会通知其他服务更新本地缓存)。

搭建Nacos Server
关于什么是Nacos,官方文档已经描述得很详细了,Nacos官方文档地址如下:
所以这里只是简单概述一下,Nacos与Eureka一样,是服务发现组件,同时也是配置中心。Nacos解决了两个问题,一是服务A如何找到服务B;二是管理微服务的配置,让一个微服务的所有实例的配置都统一,并且可以实现配置修改后自动刷新等。
理论介绍也说得差不多了,本小节我们来动手搭建一个Nacos Server。过程很简单首先需要下载一个Nacos,下载地址如下:
然后我们需要选择一个合适的版本下载,即Nacos Server版本应尽量与Client端的版本对应。至于Client的版本我们可以到工程的pom.xml文件中找到Spring Cloud Alibaba的依赖管理项点击进去即可查看到:
如下可以看到Nacos Client的版本为1.0.0,所以与之对应选择1.0.0版本的Nacos Server进行下载:
注:我这里使用的Spring Cloud版本是Greenwich.SR1,Spring Cloud Alibaba的版本是0.9.0.RELEASE

由于不是生产环境所用,其实也无需严格选择对应的版本,只要能用就可以了,所以我这里选择下载最新的1.1.0版本(经过测试可用):
下载并解压后进入bin目录,双击startup.cmd,或在命令行中输入cmd startup.cmd即可运行Nacos Server:
启动成功:
使用浏览器访问localhost:8848进入Nacos Server的管理页面,此时需要输入账户密码,默认的账户密码都是nacos:
登录成功后,页面如下:
该管理页面支持中英文,可在右上角点击切换:
官方文档如下:

将微服务注册到Nacos
在上一小节中,我们已经完成了Nacos Server的搭建,而这一小节将演示如何将微服务注册到Nacos。我现在有一个用户中心微服务,其pom.xml文件如下,包含了Spring Cloud Alibaba及Nacos Client依赖,Spring Boot版本为2.1.6.RELEASE:
<dependencies>
    ...

    <!-- Nacos Client -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency></dependencies>
<dependencyManagement>
    <dependencies>
        <!--整合Spring Cloud-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Greenwich.SR1</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <!--整合Spring Cloud Alibaba-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>0.9.0.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies></dependencyManagement>
在配置文件中配置一下nacos server的地址及端口:
spring:
  cloud:
    nacos:
      discovery:
        # 指定nacos server的地址
        server-addr: 127.0.0.1:8848
  application:
    # 服务名称,必须的配置项,否则不会向nacos注册
    name: user-center
配置完成后启动项目,然后到nacos server的管理页面的服务列表上查看是否注册成功,注册成功的话会显示在服务列表里,如下:
点击详情可以看到详细信息:
经过以上这几个步骤,就可以非常简单地整合Nacos Client,并将微服务注册到Nacos Server上。通过同样的步骤,我将另一个内容中心微服务也注册到Nacos Server上。我们来写一个简单的测试用例,看看在内容中心上是否能发现用户中心,代码如下:
@Slf4j@SpringBootTest@RunWith(SpringRunner.class)public class DiscoveryClientTests {

    @Autowired
    private DiscoveryClient discoveryClient;

    /**
     * 测试服务发现,证明内容中心能找到用户中心
     */
    @Test
    public void getServiceInstancesTest(){
        // 获取用户中心微服务的所有实例信息
        List<ServiceInstance> instances = discoveryClient.getInstances("user-center");
        // 以json格式打印出来
        log.info(JsonUtil.obj2JsonPretty(instances));
    }
}
控制台输出的json信息如下,证明通过服务发现组件能让内容中心总是能找到用户中心:
[ {
  "serviceId" : "user-center",
  "host" : "192.168.190.1",
  "port" : 8080,
  "secure" : false,
  "metadata" : {
    "nacos.instanceId" : "192.168.190.1#8080#DEFAULT#DEFAULT_GROUP@@user-center",
    "nacos.weight" : "1.0",
    "nacos.cluster" : "DEFAULT",
    "nacos.healthy" : "true",
    "preserved.register.source" : "SPRING_CLOUD"
  },
  "uri" : "http://192.168.190.1:8080",
  "scheme" : null,
  "instanceId" : null


0 个回复

您需要登录后才可以回帖 登录 | 加入黑马