基于golang从头开始构建基于docker的微服务实战笔记

这篇博客详细记录了使用Golang和Docker构建微服务的过程,包括利用gRPC和protobuf定义服务,Docker和go-micro的结合,docker-compose与数据存储,JWT认证以及NATS作为事件代理。在实践中遇到了NATS连接问题,通过修改配置文件解决了问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考博文

https://ewanvalentine.io/microservices-in-golang-part-1/
这个博文是作者微服务系统的第一篇,本学习笔记基于目前的5篇而成

part 1 利用gRPC ,protobuf定义服务

本人在学习过程中没有严格按照博文中放在github目录,而是在主目录中创建一个wdyshippy的目录,目录中文件结构如下

.
├── consignment-cli
│   ├── cli.go
│   ├── consignment-cli
│   ├── consignment.json
│   ├── Dockerfile
│   └── Makefile
└── consignment-service
    ├── consignment-service
    ├── Dockerfile
    ├── main.go
    ├── Makefile
    └── proto
        └── consignment
            ├── consignment.pb.go
            └── consignment.proto

4 directories, 11 files

执行的protoc命令


protoc -I. --go_out=plugins=grpc:/home/wdy/wdyshippy/consignment-service proto/consignment/consignment.proto

如果make build时报错

makefile:2: *** 遗漏分隔符

原因是在编写makefile文件时,命令前面应该是tab写为了空格

在这个阶段中,consignment-service的Makefile文件内容如下

build:
    protoc -I. --go_out=plugins=grpc:$(GOPATH)/src/github.com/ewanvalentine/shipper/consignment-service \
      proto/consignment/consignment.proto

part 2 - Docker and go-micro

创建Dockefiel

$ touch consignment-service/Dockerfile

写入如下内容

FROM alpine:latest

RUN mkdir /app
WORKDIR /app
ADD consignment-service /app/consignment-service

CMD ["./consignment-service"]

原作者提示如果是在linux机子上编译测试时,将alpine改为debian

FROM debian:latest

RUN mkdir /app
WORKDIR /app
ADD consignment-service /app/consignment-service

CMD ["./consignment-service"]

WORKDIR 表示 /app目录作为上下文目录用来装载我们的程序consignment-service

接下来为Makefile文件增加内容用来生成docker image

build:
    ... 
    GOOS=linux GOARCH=amd64 go build
    docker build -t consignment-service .

除此之外再添加

run: 
    docker run -p 50051:50051 consignment-service

用来执行consignment-service

docker run -p 后面的参数,第一个端口号是对外的端口,第二个是内部的端口。

Go-micro

使用Go-micro来加入service discovery功能

首先安装

go get -u github.com/micro/protobuf/{proto,protoc-gen-go}

修改makefile文件中protoc的参数,将参数plugins=后面的grpc更改为micro

build:
    protoc -I. --go_out=plugins=micro:/home/wdy/wdyshippy/consignment-service proto/consignment/consignment.proto
    ...

...

代码也要相应修改

import中 要引入 micro “github.com/micro/go-micro”

// consignment-service/main.go
package main

import (

    // Import the generated protobuf code
    "fmt"

    pb "github.com/EwanValentine/shippy/consignment-service/proto/consignment"
    micro "github.com/micro/go-micro"
    "golang.org/x/net/context"
)

server接口实现时,response的位置改变为输入参数,输出参数只有error

func (s *service) CreateConsignment(ctx context.Context, req *pb.Consignment, res *pb.Response) error {
...
func (s *service) GetConsignments(ctx context.Context, req *pb.GetRequest, res *pb.Response) error {
  ...

还有就是server的初始化

func main() {

    repo := &Repository{}

    // Create a new service. Optionally include some options here.
    srv := micro.NewService(

        // This name must match the package name given in your protobuf definition
        micro.Name("go.micro.srv.consignment"),
        micro.Version("latest"),
    )

    // Init will parse the command line flags.
    srv.Init()

    // Register handler
    pb.RegisterShippingServiceHandler(srv.Server(), &service{repo})

    // Run the server
    if err := srv.Run(); err != nil {
   
   
        fmt.Println(err)
    }
}

最后就是不需要在代码中硬编码端口号,Go-micro通过环境变量或命令行参数来传递。

run:
    docker run -p 50051:50051 \
        -e MICRO_SERVER_ADDRESS=:50051 \
        -e MICRO_REGISTRY=mdns consignment-service

如上,通过 -e MICRO_SERVER_ADDRESS=:50051 指定服务地址,通过-e MICRO_REGISTRY=mdns指定service discovery功能使用mdns。在实际项目中mdns很少使用,大部分使用consul。

除了服务端代码更改外,客户端代码也需要更改

import (
    ...
    "github.com/micro/go-micro/cmd"
    microclient "github.com/micro/go-micro/client"

)

func main() {
    cmd.Init()

    // Create new greeter client
    client := pb.NewShippingServiceClient("go.micro.srv.consignment", microclient.DefaultClient)
    ...
}

通过docker启动consignment-service后,执行客户端程序会连接失败,原因在于server允许在docker中使用的是docker中的dmns,和客户端使用的不是同一个,所以发现不了server,解决方法就是把客户端程序也放入到docker 中,使用同一个dmns。

创建consignment-cli/Makefile文件

build:
    GOOS=linux GOARCH=amd64 go build
    docker build -t consignment-cli .

run:
    docker run -e MICRO_REGISTRY=mdns consignment-cli

Dockerfile文件

FROM alpine:latest

RUN mkdir -p /app
WORKDIR /app

ADD consignment.json /app/consignment.json
ADD consignment-cli /app/consignment-cli

CMD ["./consignment-cli"]

作者最后又提供了一个更加标准的Dockerfile文件,这个文件中包含了consignment-service的开发环境和生存环境

在开发环境中通过引用github.com/golang/dep/cmd/dep 来自动更新包依赖

RUN go get -u github.com/golang/dep/cmd/dep

# Create a dep project, and run `ensure`, which will pull in all 
# of the dependencies within this directory.
RUN dep init && dep ensure

完整文件如下

# consignment-service/Dockerfile

# We use the official golang image, which contains all the 
# correct build tools and libraries. Notice `as builder`,
# this gives this container a name that we can reference later on. 
FROM golang:1.9.0 as builder

# Set our workdir to our current service in t
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值