Eureka-Client

Golang实现eureka-client

原理

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

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

其中主要逻辑如下:

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

实现

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

注册信息

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

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

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

  1. {
  2. "instance":{
  3. "instanceId":"192.168.1.107:golang-example:10000",
  4. "hostName":"192.168.1.107",
  5. "ipAddr":"192.168.1.107",
  6. "app":"golang-example",
  7. "port":{
  8. "@enabled":"true",
  9. "$":10000
  10. },
  11. "securePort":{
  12. "@enabled":"true",
  13. "$":443
  14. },
  15. "status":"UP",
  16. "overriddenStatus":"UNKNOWN",
  17. "dataCenterInfo":{
  18. "name":"MyOwn",
  19. "@class":"com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo"
  20. }
  21. }
  22. }

定时心跳、刷新服务列表

服务启动后,接下来就是维持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进行心跳
  1. func (c *Client) Start() {
  2. c.mutex.Lock()
  3. c.Running = true
  4. c.mutex.Unlock()
  5. refreshTicker := time.NewTicker(c.EurekaClientConfig.RefreshIntervalSeconds)
  6. heartbeatTicker := time.NewTicker(c.EurekaClientConfig.HeartbeatIntervalSeconds)
  7. go func() {
  8. for range refreshTicker.C {
  9. if c.Running {
  10. if err := c.doRefresh(); err != nil {
  11. fmt.Println(err)
  12. }
  13. } else {
  14. break
  15. }
  16. }
  17. }()
  18. go func() {
  19. if err := c.doRegister(); err != nil {
  20. fmt.Println(err)
  21. }
  22. for range heartbeatTicker.C {
  23. if c.Running {
  24. if err := c.doHeartbeat(); err != nil {
  25. fmt.Println(err)
  26. }
  27. } else {
  28. break
  29. }
  30. }
  31. }()
  32. }

例子

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

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net/http"
  6. "os"
  7. "os/signal"
  8. "syscall"
  9. client "github.com/xuanbo/eureka-client"
  10. )
  11. func main() {
  12. // 1.创建客户端
  13. c := client.NewClient(&client.EurekaClientConfig{
  14. DefaultZone: "http://127.0.0.1:8080/eureka/",
  15. App: "golang-example",
  16. Port: 10000,
  17. })
  18. // 2.启动client,注册到server。并定心跳、刷新服务列表
  19. c.Start()
  20. sigs := make(chan os.Signal)
  21. exit := make(chan bool, 1)
  22. signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
  23. // 随便弄一个请求
  24. http.HandleFunc("/services", func(writer http.ResponseWriter, request *http.Request) {
  25. // 3.获取所有服务(status均为UP)
  26. services := c.Services
  27. b, _ := json.Marshal(services)
  28. _, _ = writer.Write(b)
  29. })
  30. server := &http.Server{
  31. Addr: ":10000",
  32. Handler: http.DefaultServeMux,
  33. }
  34. // 启动http服务
  35. go func() {
  36. if err := server.ListenAndServe(); err != nil {
  37. fmt.Println(err)
  38. }
  39. }()
  40. // 关闭
  41. go func() {
  42. fmt.Println(<-sigs)
  43. // 停止http服务
  44. if err := server.Close(); err != nil {
  45. panic(err)
  46. }
  47. // 4.停止客户端,并删除注册信息
  48. c.Shutdown()
  49. exit <- true
  50. }()
  51. <-exit
  52. }

主要是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. 使用window.performance分析web前端性能

    参考链接:https://blog.csdn.net/lovenjoe/article/details/80260658

  2. return *this和return this有什么区别?

    return *this返回的是当前对象的克隆或者本身(若返回类型为A, 则是克隆, 若返回类型为A&, 则是本身 ). return this返回当前对象的地址(指向当前对象的指针). 转: ...

  3. 将OrCAD Capture CIS的设计文件(.dsn)导入到PADS Logic VX.2.3

    操作系统:Windows 10 x64 工具1:PADS Logic VX.2.3 启动PADS Logic VX.2.3,选择菜单:File > Import... 在File Import对 ...

  4. javascript 总结(常用工具类的封装)

    1. type 类型判断 isString (o) { //是否字符串 return Object.prototype.toString.call(o).slice(8, -1) === 'Strin ...

  5. Trie for string LeetCode

    Trie build and search class TrieNode { public: TrieNode * next[]; bool is_word; TrieNode(bool b = fa ...

  6. RabbitMQ 消息确认机制以及lazy queue+ disk消息持久化

    一:Basic的一些属性,一些方法 1. 消费端的确认 自动确认: message出队列的时候就自动确认[broke] basicget... 手工确认: message出队列之后,要应用程序自己去确 ...

  7. Kubernetes 1.10.0离线安装

    讲述如何通过离线的方式安装Kubernetes,主要用于对Kubernetes的研究学习,不建议在生产环境使用,安装包获取地址: 链接:https://pan.baidu.com/s/1nX5_mem ...

  8. 记一次线上Zabbix对Redis监控实录

    前言:Redis作为缓存服务器我想大家都比较的熟悉,那么,如果想要更好的维护和监控,那么我们会对其redis服务器统一监控起来,如何监控呢?如果在生产环境一台服务器部署多个redis,这样就会出现多个 ...

  9. Manacher算法 (马拉车算法)

    #include<iostream> #include<string.h> #include<algorithm> using namespace std; ]; ...

  10. Mac下brew安装JDK的教程

    ---恢复内容开始--- 安装命令: brew cask install java 默认应该会下载jdk7 也可以指定下载版本brew cask install java6 注意: brew inst ...