Eureka-Client

Golang实现eureka-client

原理

根据Java版本的源码,可以看出client主要是通过REST请求来与server进行通信。

Java版本的核心实现:com.netflix.discovery.DiscoveryClient。

其中主要逻辑如下:

  • client启动时注册信息到server
  • 定时心跳、刷新服务列表,主要是两个线程池:heartbeatExecutor、cacheRefreshExecutor
  • client关闭时删除注册信息

实现

这里不限制语言,主要是发送REST请求到server。

注册信息

通过POST请求,将服务信息注册到server。

请求地址:POST /eureka/apps/{APP_NAME}

信息如下:(不是完整的信息)

{
"instance":{
"instanceId":"192.168.1.107:golang-example:10000",
"hostName":"192.168.1.107",
"ipAddr":"192.168.1.107",
"app":"golang-example",
"port":{
"@enabled":"true",
"$":10000
},
"securePort":{
"@enabled":"true",
"$":443
},
"status":"UP",
"overriddenStatus":"UNKNOWN",
"dataCenterInfo":{
"name":"MyOwn",
"@class":"com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo"
}
}
}

定时心跳、刷新服务列表

服务启动后,接下来就是维持client与server之间的心跳等。

定时心跳

默认情况下是30秒发送心跳信息到server。

请求地址:PUT /eureka/apps/{APP_NAME}/{INSTANCE_ID}?status=UP&lastDirtyTimestamp={TIMESTAMP}

定时刷新服务列表

默认情况下是30秒刷新服务列表。

刷新服务列表有全量和增量两种方式:

  • 全量:GET /eureka/apps
  • 增量(delta):GET /eureka/apps/delta

其中,全量就是每次都拉取到所有服务信息;而增量拉取变化的服务信息,然后本地去做更新。

为了方便我只实现了全量拉取,没有实现delta。

删除注册信息

在服务停止时,删除注册的信息即可。

请求地址:DELETE /eureka/apps/{APP_NAME}/{INSTANCE_ID}

Golang核心实现

有2个定时器:

  • refreshTicker来刷新服务列表
  • heartbeatTicker进行心跳
func (c *Client) Start() {
c.mutex.Lock()
c.Running = true
c.mutex.Unlock() refreshTicker := time.NewTicker(c.EurekaClientConfig.RefreshIntervalSeconds)
heartbeatTicker := time.NewTicker(c.EurekaClientConfig.HeartbeatIntervalSeconds) go func() {
for range refreshTicker.C {
if c.Running {
if err := c.doRefresh(); err != nil {
fmt.Println(err)
}
} else {
break
}
}
}() go func() {
if err := c.doRegister(); err != nil {
fmt.Println(err)
}
for range heartbeatTicker.C {
if c.Running {
if err := c.doHeartbeat(); err != nil {
fmt.Println(err)
}
} else {
break
}
}
}()
}

例子

下面是使用的例子,为了在client停止时删除注册信息,这里用到了signal。

package main

import (
"encoding/json"
"fmt"
"net/http"
"os"
"os/signal"
"syscall" client "github.com/xuanbo/eureka-client"
) func main() {
// 1.创建客户端
c := client.NewClient(&client.EurekaClientConfig{
DefaultZone: "http://127.0.0.1:8080/eureka/",
App: "golang-example",
Port: 10000,
})
// 2.启动client,注册到server。并定心跳、刷新服务列表
c.Start() sigs := make(chan os.Signal)
exit := make(chan bool, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) // 随便弄一个请求
http.HandleFunc("/services", func(writer http.ResponseWriter, request *http.Request) {
// 3.获取所有服务(status均为UP)
services := c.Services b, _ := json.Marshal(services)
_, _ = writer.Write(b)
})
server := &http.Server{
Addr: ":10000",
Handler: http.DefaultServeMux,
} // 启动http服务
go func() {
if err := server.ListenAndServe(); err != nil {
fmt.Println(err)
}
}() // 关闭
go func() {
fmt.Println(<-sigs) // 停止http服务
if err := server.Close(); err != nil {
panic(err)
} // 4.停止客户端,并删除注册信息
c.Shutdown() exit <- true
}() <-exit
}

主要是4步,用起来比较简单。

Github地址

Github

说明

未在生产中使用,只是想把Golang的服务与Java的Spring Cloud结合起来玩耍。

Just for fun!

Eureka-Client(Golang实现)的更多相关文章

  1. 【SpringCloud Eureka源码】从Eureka Client发起注册请求到Eureka Server处理的整个服务注册过程(下)

    目录 一.Spring Cloud Eureka Server自动配置及初始化 @EnableEurekaServer EurekaServerAutoConfiguration - 注册服务自动配置 ...

  2. 第一个Eureka程序,Eureka Client的自启动原理和简要过程

    https://blog.csdn.net/u011531425/article/details/81675289 在之前的Spring Cloud Config的基础上,搭建简单的Eureka Se ...

  3. eureka client服务续约源码分析

    必备知识: 1.定时任务 ScheduledExecutorService public class demo { public static void main(String[] args){ Sc ...

  4. 深入理解Eureka - Eureka Client获取注册信息机制

    深入理解Eureka - Eureka Client获取注册信息机 Eureka Client提供了定时获取注册信息的机制.Eureka Client获取注册信息的所有逻辑都在DiscoveryCli ...

  5. spring cloud Eureka client配置(consumer通过Eureka发起对provider的调用)

    参考:http://www.ityouknow.com/springcloud/2017/05/12/eureka-provider-constomer.html springboot版本:2.0.3 ...

  6. 为什么Eureka Client获取服务实例这么慢

    1. Eureka Client注册延迟 Eureka Client启动后不会立即向Eureka Server注册,而是有一个延迟时间,默认为40s 2. Eureka Server更新响应缓存 Eu ...

  7. 2.spring cloud eureka client配置

    红色加粗内容表示修改部分 1.把server项目打成jar包并启动 在项目根目录cmd执行  mvn clean package -Dmaven.test.skip=true mavne仓库地址建议 ...

  8. SpringCloud IDEA 教学 (三) Eureka Client

    写在前头 本篇继续介绍基于Eureka的SpringCloud微服务搭建,回顾一下搭建过程, 第一步:建立一个服务注册中心: 第二步:建立微服务并注入到注册中心: 第三步:建立client端来访问微服 ...

  9. Spring Cloud Eureka 3 (Eureka client注册服务提供者)

    在完成服务注册中心的搭建后我们来尝试下将一个既有的spring boot应用加入eureka的服务治理体系中 新建一个spring boot项目加入eureka client依赖 这里加入的eurek ...

  10. spring boot eureka client

    eureka client @EnableDiscoveryClient @SpringBootApplication public class DemoApplication { public st ...

随机推荐

  1. JavaScript—var lef const区别

    今天刚刚学JavaScript 因为以前学过.学起来也就轻松.今天在练习.流程控制语句的时候,用WebStrom 写的时候 var 声明变量的时候 下面老是有一条白线.开始以为是开发环境有问题 然后, ...

  2. Linux的简单命令

    Linux的简单命令 1.更改linux服务器的登录密码 成功登录后输入命令: passwd 然后按照提示操作即可 2.在当前路径下新建文件夹:mkdir 新建文件夹名 3.解压和压缩文件tar.gz ...

  3. day11 函数的参数列表

    """ 今日内容: 1.函数参数的分类 2.形参是对实参的值拷贝 3.实参的分类 4.形参的分类 5.打散机制 附1:字符串的比较 """ ...

  4. 2018-2019-2 20165231王杨鸿永《网络对抗》Exp1 PC平台逆向破解

    实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串. 该程序同时包含另一个代码片段,getShe ...

  5. [Kubernetes]PV,PVC,StorageClass之间的关系详解

    在Kubernetes中,容器化一个应用比较麻烦的地方莫过于对其"状态"的管理,而最常见的"状态",莫过于存储状态. 在[Kubernetes]深入理解Stat ...

  6. Centos6.8 yum安装MySQL5.6

    第一步:安装仓库wget http://repo.mysql.com//mysql57-community-release-el6-8.noarch.rpmrpm -ivh mysql-communi ...

  7. CRMEB系统开发文档

    CRMEB系统开发文档 https://gitee.com/ZhongBangKeJi/CRMEB hibernate:学习文档https://blog.csdn.net/u013087513/art ...

  8. P2444 [POI2000]病毒

    P2444 [POI2000]病毒 题目描述 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的.现在委员会已 ...

  9. VBA开发手记

    本博文,将主要记录VBA for Excel项目中遇到并解决的问题,不定期更新. 1.日期单元格前面加空格就变成文本了,find查找参数注意:what:=Cstr(Date),lookat:=2 2. ...

  10. Textwrap模块

    该模块首先提供了三个便捷的方法:wrap,fill和decent,也提供了TextWrapper类 textwrap.wrap(text,[width[,…]]) 这个方法是将一个字符串按照width ...