第003节:心跳机制与可选项配置

背景

在前面一节课中,我们指定了consul作为微服务的注册组件,并在consul中看到了注册的新服务。这其中还包含其他内容,本节课我们继续来看。

代码实现consul配置

上节课中,我们使用的–registry选项配置的形式来指定注册到consul组件中,其实这一配置也可以在代码中进行实现。上节课说了go-micro在创建服务时提供了很多可选项配置,其中就包含服务组件的指定。指定注册到consul的编程代码实现如下:

...
   //创建一个新的服务对象实例
    service := micro.NewService(
        micro.Name("student_service"),
        micro.Version("v1.0.0"),
        micro.Registry(consul.NewRegistry()),
    )
...

通过micro.Registry可以指定要注册的发现组件,这里我们注册到consul,因此调用consul.NewRegistry。

插件化

在前面的go-micro介绍课中,我们提到过go-micro是支持插件化的基础的微服务框架,不仅仅是go-micro,整个的micro都被设计成为“可插拔”的机制。

在上一节课的案例中,我们使用–registry选项指定将服务注册到对应的服务发现组件,我们选择的是注册到consul中。这里的–registry就是是“可插拔”的插件化机制的体现。因为在2019年最新的代码中,go-micro中默认将服务注册到mdns中,同时支持开发者手动指定特定的服务发现组件。

我们可以看到在这个过程中,我们的服务的程序没有发生任何变化,但是却轻松的实现了服务注册发现组件的更换,这就是插件化的优势,利用插件化能最大限度的解耦。

在go-micro框架中,支持consul,etcd,zookeeper,dns等组件实现服务注册和发现的功能。如果有需要,开发者可以根据自己的需要进行服务发现组件的替换。

服务注册发现的原理

让我们再回顾一下服务注册与发现的原理:服务注册发现是将所有的服务注册到注册组件中心,各服务在进行互相调用功能时,先通过查询方法获取到要调用的服务的状态信息和地址,然后向对应的微服务模块发起调用。我们学习过consul的工作原理和环境搭建,congsul的工作原理图如下所示:

第003节:心跳机制与可选项配置

未发现服务错误

回顾完了服务注册发现的原理,我们就可以知道,如果请求发起端程序不能在服务组件中发现对应的服务,则会产生错误。接下来我们利用程序演示错误。

首先,通过终端命令启动consul节点服务,以方便服务注册:

consul agent -dev
指定服务程序注册到consul

我们利用已经学习过的服务注册可选项指定注册到consul组件,详细命令如下:

go run main.go --registry=consul

通过该命令,可以成功将服务注册到consul组件,并启动服务开始运行。

运行客户端服务

由于服务端程序已经注册到consul,因此客户端程序在执行时也需要到consul中查询才能正确执行。运行客户端并注册到consul组件的命令是:

go run client.go --registry=consul

通过以上命令,程序可以正确得到执行,并输出正确结果。

未发现服务错误

我们可以主动让程序发生错误,来验证未发现的错误,以此来验证我们所学习的服务注册与发现的原理。在执行客户端程序时,我们不指定–registry选项,默认使用mdns,则命令为:

go run client.go

我们执行上述命令,运行客户端程序。由于我们的客户端程序会连接对应的服务的方法,但是对应的服务并没有注册到mdns中,因此,程序会发生错误。本案例中,客户端程序执行错误如下:

{"id":"go.micro.client","code":500,"detail":"error selecting student_service node: not found","status":"Internal Server Error"}

我们可以看到,程序返回了错误信息,提示我们服务未找到。

通过这个主动错误的示范,我们能更加深刻的理解go-micro与consul的插件式协同工作和微服务内部的原理。

弊端与解决方法

服务实例与发现组件的工作机制是:当服务开启时,将自己的相关信息注册到发现组件中,当服务关闭时,发送卸载或者移除请求。在实际生产环境中,服务可能会出现很多异常情况,发生宕机或者其他等情况,往往服务进程会被销毁,或者网络出现故障也会导致通信链路发生问题,在这些情况下,服务实例会在服务发现组件中被移除。

TTL和间隔时间

为了解决这个问题,go-micro框架提供了TTL机制和间隔时间注册机制。TTL是Time-To-Live的缩写,指定一次注册在注册组件中的有效期,过期后便会删除。而间隔时间注册则表示定时向注册组件中重新注册以确保服务在线。

  • 指令方式
    这两种注册方式都可以通过可选项指令来实现配置,具体的命令如下:

    go run main.go --registry=consul --register_ttl=10 --register_interval=5

    该命令表示我们每间隔5秒钟向服务注册组件注册一次,每次有效期限是10秒。

  • 编码方式
    除了使用指令的方式以外,还可以在代码中实现这两种参数的设定,在微服务创建时通过配置来完成。具体代码如下:

    ...
    service := micro.NewService(
    micro.Name("student_service"),
    micro.Version("v1.0.0"),
    micro.RegisterTTL(10*time.Second),
    micro.RegisterInterval(5*time.Second),
    )
    ...

    分别通过micro.RegisterTTL和micro.RegisterInterval来实现两个选项的设置。

原创文章,Golang中国出品,文章对应源码下载:https://www.qfgolang.com/?page_id=1973

发表评论

电子邮件地址不会被公开。 必填项已用*标注

联系我们

学习交流群:点击这里给我发消息

QR code