Go 分布式系统实战:Kafka + gRPC + Etcd 构建消息队列系统

Go 分布式系统实战:Kafka + gRPC + Etcd 构建消息队列系统

《一条龙开发指南:MCP AI Agent 理论+项目实战开发你的MCP Server》

🧑‍💻 面试人物设定

  • 姓名: 赵子昂
  • 年龄: 31 岁
  • 学历: 计算机硕士
  • 工作年限: 6 年
  • 公司背景: 某头部物流科技平台
  • 技术栈: Go, Kafka, gRPC, Etcd, Docker
  • 核心职责:
    • 使用 Go 构建分布式任务调度系统
    • 结合 Kafka 实现异步消息处理
    • 利用 Etcd 实现服务注册与发现
    • 设计高可用架构保障系统稳定性
  • 工作成果:
    • 成功上线多个任务处理模块,日均处理消息量提升至千万级
    • 将任务失败率控制在 0.01% 以下

🎤 第一轮面试:Go 分布式基础考察

面试官: “你好,请介绍一下你最近参与的 Go 项目。”

程序员: “您好!我最近主要负责一个基于 Kafka 和 gRPC 的分布式任务调度系统重构项目,使用 Etcd 实现服务注册与发现,并通过 Docker 容器化部署提升系统可扩展性。”

面试官: “你能写一个简单的 Go 并发任务吗?”

程序员: “当然可以,比如使用 Goroutine 和 Channel 实现并发任务。”

package main

import (
	"fmt"
	"sync"
	"time"
)

func worker(id int, jobs <-chan int, results chan<- int) {
	for job := range jobs {
		fmt.Printf("Worker %d started job %d\n", id, job)
		time.Sleep(time.Second)
		fmt.Printf("Worker %d finished job %d\n", id, job)
		results <- job * 2
	}
}

func main() {
	const numJobs = 5
	jobs := make(chan int, numJobs)
	results := make(chan int, numJobs)

	var wg sync.WaitGroup

	for w := 1; w <= 3; w++ {
		wg.Add(1)
		go func(id int) {
			defer wg.Done()
			for job := range jobs {
				fmt.Printf("Worker %d started job %d\n", id, job)
				time.Sleep(time.Second)
				fmt.Printf("Worker %d finished job %d\n", id, job)
				results <- job * 2
			}
		}(w)
	}

	for j := 1; j <= numJobs; j++ {
		jobs <- j
	}
	close(jobs)

	wg.Wait()
	close(results)

	for result := range results {
		fmt.Println("Result:", result)
	}
}

🧠 第二轮面试:Kafka 消息队列集成

面试官: “你是怎么使用 Kafka 的?”

程序员: “我们会使用 Sarama 库实现生产者和消费者的逻辑,并确保消息可靠投递。”

// 生产者示例
package main

import (
	"fmt"
	"github.com/Shopify/sarama"
)

func main() {
	config := sarama.NewConfig()
	config.Producer.RequiredAcks = sarama.WaitForAll
	config.Producer.Partitioner = sarama.NewRandomPartitioner
	config.Producer.Return.Successes = true

	producer, err := sarama.NewSyncProducer([]string{"localhost:9092"}, config)
	if err != nil {
		panic(err)
	}
	defer producer.Close()

	msg := &sarama.ProducerMessage{
		Topic: "test",
		Value: sarama.StringEncoder("Hello Kafka"),
	}

	partition, offset, err := producer.SendMessage(msg)
	if err != nil {
		fmt.Println("Send message failed, err:", err)
		return
	}
	fmt.Printf("Message sent to partition %d at offset %d\n", partition, offset)
}

⚙️ 第三轮面试:gRPC 服务通信

面试官: “你们是怎么使用 gRPC 的?”

程序员: “我们会定义 Protobuf 接口,并生成服务代码用于跨服务调用。”

// service.proto
syntax = "proto3";

option go_package = ".;pb";

package task;

service TaskService {
  rpc SubmitTask (TaskRequest) returns (TaskResponse);
  rpc GetTaskStatus (TaskID) returns (TaskStatus);
}

message TaskRequest {
  string task_id = 1;
  string payload = 2;
}

message TaskResponse {
  string status = 1;
  string message = 2;
}

message TaskID {
  string task_id = 1;
}

message TaskStatus {
  string status = 1;
  string result = 2;
}
// 服务端实现
func (s *server) SubmitTask(ctx context.Context, req *pb.TaskRequest) (*pb.TaskResponse, error) {
	fmt.Printf("Received task: %v\n", req)
	// 处理任务逻辑
	return &pb.TaskResponse{Status: "success", Message: "Task processed"}, nil
}

// 客户端调用
conn, _ := grpc.Dial("localhost:50051", grpc.WithInsecure())
defer conn.Close()
c := pb.NewTaskServiceClient(conn)

resp, _ := c.SubmitTask(context.Background(), &pb.TaskRequest{TaskId: "123", Payload: "data"})
fmt.Println("Response:", resp)

📊 第四轮面试:Etcd 服务注册与发现

面试官: “你是怎么使用 Etcd 的?”

程序员: “我们使用 Etcd 实现服务注册与发现,并设计心跳机制确保服务可用性。”

package main

import (
	"context"
	"fmt"
	"time"

	"go.etcd.io/etcd/client/v3"
)

func main() {
	cli, err := clientv3.New(clientv3.Config{
		Endpoints:   []string{"localhost:2379"},
		DialTimeout: 5 * time.Second,
	})
	if err != nil {
		panic(err)
	}
	defer cli.Close()

	// 注册服务
	leaseGrantResp, _ := cli.LeaseGrant(context.TODO(), 10)
	cli.Put(context.TODO(), "/services/task-service/127.0.0.1:50051", "active", clientv3.WithLease(leaseGrantResp.ID))
	fmt.Println("Service registered")

	// 心跳续约
	ch, _ := cli.KeepAlive(context.TODO(), leaseGrantResp.ID)
	for {
		select {
		case <-ch:
			// 续约成功
		default:
			time.Sleep(2 * time.Second)
		}
	}
}

📈 第五轮面试:服务部署与监控

面试官: “你是怎么部署和监控服务的?”

程序员: “我们主要使用 Docker 容器化部署,并结合 Prometheus + Grafana 实现可视化监控。”

# Dockerfile
FROM golang:1.21
WORKDIR /app
COPY . .
RUN go mod download && go build -o task-service
CMD ["./task-service"]

# 构建镜像
docker build -t task-service:latest .

# 启动容器
docker run -d -p 50051:50051 --name task-service task-service:latest

💬 结尾环节

面试官: “今天的面试就到这里,我们会综合评估你的表现,后续 HR 会联系你。”

程序员: “谢谢您今天的时间,期待有机会加入贵公司。”

《一条龙开发指南:MCP AI Agent 理论+项目实战开发你的MCP Server》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值