教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 golang微服务框架对比_Golang 微服务教程(二)

golang微服务框架对比_Golang 微服务教程(二)

发布时间:2022-01-28   编辑:jiaochengji.com
教程集为您提供golang微服务框架对比,Golang 微服务教程(二)等资源,欢迎您收藏本站,我们将为您提供最新的golang微服务框架对比,Golang 微服务教程(二)资源
<h1 class="ql-align-center">Golang 微服务教程(二)</h1>

发表于 2018-05-12 | 阅读次数: | 字数统计: 3,763

原文链接:ewanvalentine.io,翻译已获作者 Ewan Valentine 授权。

本节未细致介绍 Docker,更多可参考:《第一本Docker书 修订版》

前言

在上一篇中,我们使用 gRPC 初步实现了我们的微服务,本节将 Docker 化该微服务并引入 go-micro 框架代替 gRPC 简化服务的实现。

Docker

背景

占据着云计算的优势,微服务架构越来越流行,同时它的云端分布式的运行环境也对我们的开发、测试和部署提出了很高的要求,容器(container)便是一项解决方案。

在传统软件开发中,应用直接部署在环境和依赖都准备好的系统上,或在一台物理服务器上部署在由 Chef 或 Puppet 管理的虚拟集群里。这种部署方案不利于横向扩展,比如要部署多台物理服务器,需要都安装相同的依赖,再部署,很是麻烦。

vagrant 这类管理多个虚拟机的工具,虽然使项目的部署更为遍历,但每个虚拟机都运行有一个完整的操作系统,十分耗费宿主主机的资源,并不适合微服务的开发和部署。

容器

特性

容器 是精简版的操作系统,但并不运行一个 kernel 或系统底层相关的驱动,它只包含一些 run-time 必需的库,多个容器共享宿主主机的 kernel,多个容器之间相互隔离,互补影响。可参考:Redhat topic

优势

容器的运行环境只包含代码所需要的依赖,而不是使用完整的操作系统包含一大堆不需要的组件。此外,容器本身的体积相比虚拟机是比较小的,比如对比 ubuntu 16.04 优势不言而喻:

<ul><li class="ql-align-justify">虚拟机大小</li></ul>
<ul><li class="ql-align-justify"/><li class="ql-align-justify">容器镜像大小</li></ul>

Docker 与容器

一般人会认为容器技术就是 Docker,实则不然,Docker 只是容器技术的一种实现,因为其操作简便且学习门槛低,所以如此流行。

Docker 化微服务

Dockerfile

创建微服务部署的 Dockerfile

<pre><code class="ql-align-right"># 若运行环境是 Linux 则需把 alpine 换成 debian# 使用最新版 alpine 作为基础镜像FROM alpine:latest# 在容器的根目录下创建 app 目录RUN mkdir /app# 将工作目录切换到 /app 下WORKDIR /app# 将微服务的服务端运行文件拷贝到 /app 下ADD consignment-service /app/consignment-service# 运行服务端CMD ["./consignment-service"]</code></pre>

alpine 是一个超轻量级 Linux 发行版本,专为 Docker 中 Web 应用而生。它能保证绝大多数 web 应用可以正常运行,即使它只包含必要的 run-time 文件和依赖,镜像大小只有 4 MB,相比上边 Ubuntu16.4 节约了 99.7% 的空间:

由于 docker 镜像的超轻量级,在上边部署和运行微服务耗费的资源是很小的。

编译项目

为了在 alpine 上运行我们的微服务,向 Makefile 追加命令:

<pre><code class="ql-align-right">build:...# 告知 Go 编译器生成二进制文件的目标环境:amd64 CPU 的 Linux 系统GOOS=linux GOARCH=amd64 go build# 根据当前目录下的 Dockerfile 生成名为 consignment-service 的镜像docker build -t consignment-service .</code></pre>

需手动指定 GOOS 和 GOARCH 的值,否则在 macOS 上编译出的文件是无法在 alpine 容器中运行的。

其中 docker build 将程序的执行文件 consignment-service 及其所需的 run-time 环境打包成了一个镜像,以后在 docker 中直接 run 镜像即可启动该微服务。

你可以把你的镜像分享到 DockerHub,二者的关系类比 npm 与 nodejs、composer 与 PHP,去 DockerHub 瞧一瞧,会发现很多优秀的开源软件都已 Docker 化,参考演讲:Willy Wonka of Containers

关于 Docker 构建镜像的细节,请参考书籍《第一本 Docker 书》第四章

运行 Docker 化后的微服务

继续在 Makefile 中追加命令:

<pre><code class="ql-align-right">build:...run:# 在 Docker alpine 容器的 50001 端口上运行 consignment-service 服务# 可添加 -d 参数将微服务放到后台运行docker run -p 50051:50051 consignment-service</code></pre>

由于 Docker 有自己独立的网络层,所以需要指定将容器的端口映射到本机的那个端口,使用 -p 参数即可指定,比如 -p 8080:50051 是将容器 50051端口映射到本机 8080 端口,注意顺序是反的。更多参考:Docker 文档

现在运行 make build && make run 即可在 docker 中运行我们的微服务,此时在本机执行微服务的客户端代码,将成功调用 docker 中的微服务:

Go-micro

为什么不继续使用 gRPC ?

管理麻烦

在客户端代码(consignment-cli/cli.go)中,我们手动指定了服务端的地址和端口,在本地修改不是很麻烦。但在生产环境中,各服务可能不在同一台主机上(分布式独立运行),其中任一服务重新部署后 IP 或运行的端口发生变化,其他服务将无法再调用它。如果你有很多个服务,彼此指定 IP 和端口来相互调用,那管理起来很麻烦

服务发现

为解决服务间的调用问题,服务发现(service discovery)出现了,它作为一个注册中心会记录每个微服务的 IP 和端口,各微服务上线时会在它那注册,下线时会注销,其他服务可通过名字或 ID 找到该服务类比门面模式。

为不重复造轮子,我们直接使用实现了服务注册的 go-micro 框架。

安装

<pre><code class="ql-align-right">go get -u github.com/micro/protobuf/protogo get -u github.com/micro/protobuf/protoc-gen-go</code></pre>

使用 go-micro 自己的编译器插件,在 Makefile 中修改 protoc 命令:

<pre><code class="ql-align-right">build:# 不再使用 grpc 插件protoc -I. --go_out=plugins=micro:$(GOPATH)/src/shippy/consignment-service proto/consignment/consignment.proto</code></pre>

服务端使用 go-micro

你会发现重新生成的 consignment.pb.go 大有不同。修改服务端代码 main.go 使用 go-micro

<pre><code class="ql-align-right">package mainimport (pb "shippy/consignment-service/proto/consignment""context""log""github.com/micro/go-micro") 仓库接口//type IRepository interface {Create(consignment *pb.Consignment) (*pb.Consignment, error) // 存放新货物GetAll() []*pb.Consignment // 获取仓库中所有的货物} 我们存放多批货物的仓库,实现了 IRepository 接口//type Repository struct {consignments []*pb.Consignment}func (repo *Repository) Create(consignment *pb.Consignment) (*pb.Consignment, error) {repo.consignments = append(repo.consignments, consignment)return consignment, nil}func (repo *Repository) GetAll() []*pb.Consignment {return repo.consignments} 定义微服务//type service struct {repo Repository} 实现 consignment.pb.go 中的 ShippingServiceHandler 接口// 使 service 作为 gRPC 的服务端 托运新的货物// func (s *service) CreateConsignment(ctx context.Context, req *pb.Consignment) (*pb.Response, error) {func (s *service) CreateConsignment(ctx context.Context, req *pb.Consignment, resp *pb.Response) error {// 接收承运的货物consignment, err := s.repo.Create(req)if err != nil {return err}resp = &pb.Response{Created: true, Consignment: consignment}return nil}// 获取目前所有托运的货物// func (s *service) GetConsignments(ctx context.Context, req *pb.GetRequest) (*pb.Response, error) {func (s *service) GetConsignments(ctx context.Context, req *pb.GetRequest, resp *pb.Response) error {allConsignments := s.repo.GetAll()resp = &pb.Response{Consignments: allConsignments}return nil}func main() {server := micro.NewService(// 必须和 consignment.proto 中的 package 一致micro.Name("go.micro.srv.consignment"),micro.Version("latest"),)// 解析命令行参数server.Init()repo := Repository{}pb.RegisterShippingServiceHandler(server.Server(), &service{repo})if err := server.Run(); err != nil {log.Fatalf("failed to serve: %v</code></pre>
到此这篇关于“golang微服务框架对比_Golang 微服务教程(二)”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
golang微服务框架对比_Golang 微服务教程(一)
golang微服务框架对比_Golang 微服务教程(二)
golang微服务框架对比_斗鱼开源首秀——基于 Go 的微服务框架 Jupiter
【GoLang】GoLang 微服务、开源库等参考资料
golang微服务框架对比_golang微服务框架gozero系列4:gozero文件服务
golang微服务框架对比_Golang 中的微服务 - 第一部分
云原生环境下微服务管理系统开发
基于Golang设计一套微服务架构[转]
支持多语言的微服务框架Tars-Go
golang微服务框架对比_最强开源微服务框架,全网独家整理

[关闭]
~ ~