Golang-动手实现一个分布式注册中心

本文通过一个日志微服务实例,详细介绍了如何使用Golang构建一个分布式注册中心。内容涵盖日志服务的Server和Client实现,主启动程序LogService,服务启动与注册的流程,以及服务注册与发现的详细步骤,包括客户端和服务端的关键操作。
摘要由CSDN通过智能技术生成

动手实现一个分布式注册中心

以一个日志微服务为例,将日志服务注册到注册中心展开!

image-20220707120752999

日志服务

log/Server.go

其实这一个日志类的功能就是有基本的写文件功能,然后就是注册一个http的接口去写日志进去

package log

import (
	"io/ioutil"
	stlog "log"
	"net/http"
	"os"
)

var log *stlog.Logger

type fileLog string

// 编写日志的方法
func (fl fileLog) Write(data []byte) (int, error) {
   
	f, err := os.OpenFile(string(fl), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
	if err != nil {
   
		return 0, err
	}
	defer f.Close()
	return f.Write(data)
}

// 启动一个日志对象 参数为日志文件名
func Run(destination string) {
   
	log = stlog.New(fileLog(destination), "[go] - ", stlog.LstdFlags)
}
// 自身注册的一个服务方法
func RegisterHandlers() {
   
	http.HandleFunc("/log", func(w http.ResponseWriter, r *http.Request) {
   
		switch r.Method {
   
		case http.MethodPost:
			msg, err := ioutil.ReadAll(r.Body)
			if err != nil || len(msg) == 0 {
   
				w.WriteHeader(http.StatusBadRequest)
				return
			}
			write(string(msg))
		default:
			w.WriteHeader(http.StatusMethodNotAllowed)
			return
		}
	})
}

func write(message string) {
   
	log.Printf("%v\n", message)
}

log/Client.go

提供给外部服务的接口,定义好日志的命名格式,来显示调用接口去使用已经注册好的日志接口并且返回状态

package log

import (
	"bytes"
	"distributed/registry"
	"fmt"
	"net/http"

	stlog "log"
)

func SetClientLogger(serviceURL string, clientService registry.ServiceName) {
   
	stlog.SetPrefix(fmt.Sprintf("[%v] - ", clientService))
	stlog.SetFlags(0)
	stlog.SetOutput(&clientLogger{
   url: serviceURL})
}

type clientLogger struct {
   
	url string
}

func (cl clientLogger) Write(data []byte) (int, error) {
   
	b := bytes.NewBuffer([]byte(data))
	res, err := http.Post(cl.url+"/log", "text/plain", b)
	if err != nil {
   
		return 0, err
	}
	if res.StatusCode != http.StatusOK {
   
		return 0, fmt.Errorf("Failed to send log message. Service responded with %d - %s", res.StatusCode, res.Status)
	}
	return len(data), nil
}

主启动程序LogService

启动服务Logservice,主要执行start方法,里面有细节实现服务注册与服务发现

package main

import (
	"context"
	"distributed/log"
	"distributed/registry"
	"distributed/service"
	"fmt"
	stlog "log"
)

func main() {
   
  // 初始化启动一个日志文件对象
	log.Run("./distributed.log")
  // 日志服务注册的端口和地址
	host, port := "localhost", "4000"
	serviceAddress := fmt.Sprintf("http://%s:%s", host, port)
  // 初始化注册对象
	r := registry.Registration{
   
		ServiceName:      registry.LogService, // 自身服务名
		ServiceURL:       serviceAddress,  // 自身服务地址
		RequiredServices: make([]registry.ServiceName, 0),// 依赖服务
		ServiceUpdateURL: serviceAddress + "/services", // 服务列表
		HeartbeatURL: serviceAddress + "/heartbeat",  // 心跳
	}
  // 启动日志服务包含服务注册,发现等细节
	ctx, err := service.Start(
		context.Background(),
		host,
		port
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值