当前位置: 首页 > article >正文

golang go语言 组建微服务架构详解 - 代码基于开源框架grpc+nacos服务管理配置平台

整体介绍:

本文主要介绍如何用go语言 来组建微服务的框架,grpc+服务管理 

示例框架 代码由grpc+nacos go sdk 组成。 grpc负责将调用序列化并传递到远端,nacos负责服务发现和服务管理。

grpc和nacos都是开源产品。代码复制下来就能跑。

微服务解决了什么问题?

微服务架构通过将应用拆分为一系列小而自治的服务,解决了单体应用在扩展性和维护性上的问题。它主要提升了系统的可用性和稳定性,同时促进了开发团队间的高效协作。

例如,在一个快速成长的项目中,随着业务增长,订单处理、商品展示等功能模块逐渐庞大复杂。采用微服务后,可以将这些功能独立部署为单独的服务,每个服务由专门的小团队负责。

这样不仅加快了新功能的迭代速度,也使得故障隔离变得更容易,从而提高了整体系统的健壮性。

团队规模扩大时,这种模式有助于明确职责划分,减少沟通成本,进而加速产品开发周期。

微服务实战中的应用拆分

在对一个典型的交易网站进行微服务切分时,可以采用领域驱动设计(DDD)的思想。

首先,识别出业务中的核心领域,比如用户管理、商品展示与管理、交易处理以及评价系统等。每个领域对应着一个或多个关键实体。以淘宝为例,它可以被拆分为“用户”、“商品”、“交易”和“评价”四大主要领域,领域主要和团队的角色分工相关。

然后 规划和构建领域内的核心方法,“用户”领域负责账号注册、登录验证和个人信息管理;“商品”领域则专注于商品的发布、搜索与分类;“交易”领域涵盖下单、支付及订单状态跟踪等功能;而“评价”领域则处理买家对卖家或商品的反馈。

最后,用微服务框架来实现,本例假设前两步已经做好,那么就可以用grpc+nacos来实现服务调用和服务管理。

这种按照业务领域来划分的方式,不仅使得每个服务都能由专门的团队独立开发维护,而且还能提高系统的可扩展性和灵活性,便于后续的技术迭代升级。

Nacos Go SDK 概述

Nacos 是一个动态服务发现、配置管理和服务管理平台,旨在帮助开发者更容易地构建、维护和管理微服务架构。

它提供了包括服务注册与发现、动态配置、DNS 服务等多种功能,并支持多种主流的编程语言。这个产品最新推出了Nacos go sdk,开源免费,可以作为Go语言微服务的最佳拍档。

服务注册与发现流程解析

在Nacos中,服务注册和服务发现是两个核心的功能,这两个功能共同保证了微服务架构下的服务能够被有效管理和访问。以下将基于提供的知识内容,对服务注册和服务发现的主要流程进行介绍,并提及如何使用gRPC和Nacos Go SDK来实现这些过程。

服务注册

  1. 启动服务实例:首先,开发者需要启动一个或多个服务实例。每个实例拥有自己独立的网络地址(IP:Port)。
  1. 配置Nacos客户端:接下来,在服务实例内部配置Nacos客户端的相关参数,包括Nacos服务器的地址等信息。如果使用的是Nacos Go SDK,则需按照其文档指南初始化客户端。
  1. 注册服务至Nacos:通过调用Nacos客户端提供的API(对于Go语言环境而言就是通过Nacos Go SDK),将当前服务实例的信息提交给Nacos服务端。这里提交的信息可能包括但不限于服务名、IP地址、端口号以及元数据(如版本号)。对于支持gRPC协议的服务来说,还需要额外指定服务所使用的协议类型为gRPC。
  1. 健康检查设置:配置好自动健康检查机制。一旦服务成功注册到Nacos之后,Nacos会定期对该服务执行健康状态检测以确保其实例处于可用状态。这一步骤对于保持整个服务体系稳定运行非常重要。

服务发现

  1. 客户端初始化:与服务注册类似,任何希望查找特定服务位置的应用程序都需要先完成Nacos客户端的初始化工作。
  1. 请求获取服务列表:应用程序通过Nacos客户端向Nacos服务器发起查询请求,询问指定名称的服务有哪些正在运行中的实例。这里同样可以利用Nacos Go SDK简化开发流程。
  1. 解析服务信息:从Nacos返回的结果中解析出所需的服务实例详情,比如它们的具体IP地址及端口等信息。如果目标服务支持gRPC通信方式的话,还需注意选择合适的服务实例来进行后续交互。
  1. 建立连接并调用服务:根据获取到的服务实例信息,客户端可以直接与其建立TCP连接(对于gRPC服务则是gRPC连接),然后开始发送请求并接收响应。

综上所述,借助于Nacos强大的服务注册与发现能力,结合gRPC高效的数据传输效率以及Nacos Go SDK提供的便捷接口支持,可以轻松构建起一套灵活可靠的服务管理体系。在整个过程中,重要的是正确配置各项参数,并合理设计系统的健壮性和容错性,以应对可能出现的各种异常情况。

基于gRPC和Nacos的服务发现与注册构建过程

实际的构建过程,基于grpc 和 nacos 的服务发现和服务注册

1. GRPC Prerequisites

在开始之前,请确保已安装protoc及其Go插件,以生成gRPC服务所需的Go代码。这可以通过执行以下命令完成:

$ go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
$ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest

之后,更新您的环境变量PATH来包含这些工具:

$ export PATH="$PATH:$(go env GOPATH)/bin"
2. Nacos-sdk-go 安装

接着,通过运行下面的命令安装Nacos Go SDK:

$ go get -u github.com/nacos-group/nacos-sdk-go/v2
3. Grpc proto文件准备 & 代码生成

创建一个简单的gRPC服务定义(这里假设为helloworld.proto),然后使用protoc工具生成对应的Go语言实现:

// helloworld.proto
service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {}
  rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
}

message HelloRequest { string name = 1; }
message HelloReply { string message = 1; }

运行如下命令来从.proto文件生成Go代码:

protoc --go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
helloworld/helloworld.proto
4. Go Grpc Server与Nacos集成

现在我们有了基本的服务接口和数据结构定义,接下来是服务器端的实现,并将其与Nacos结合用于服务注册。这部分代码展示了如何初始化gRPC服务并将其注册到Nacos:

import (
    "context"
    "flag"
    "fmt"
    "log"
    "net"
    "os"
    "os/signal"
    "syscall"

    pb "your_project_path/helloworld" // 导入自动生成的pb包
    grpc "google.golang.org/grpc"
    "github.com/nacos-group/nacos-sdk-go/v2/clients"
    constant "github.com/nacos-group/nacos-sdk-go/v2/common/constant"
    vo "github.com/nacos-group/nacos-sdk-go/v2/vo"
)

var port = flag.Uint64("port", 50051, "The server port")

type server struct{ pb.UnimplementedGreeterServer }

func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
    log.Printf("Received: %v", in.GetName())
    return &pb.HelloReply{Message: "Hello " + in.GetName()}, nil
}

func main() {
    flag.Parse()
    lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }
    s := grpc.NewServer()
    pb.RegisterGreeterServer(s, &server{})

    clientConfig := constant.ClientConfig{
        NamespaceId:         "public",
        TimeoutMs:           5000,
        NotLoadCacheAtStart: true,
        LogDir:              "/tmp/nacos/log",
        CacheDir:            "/tmp/nacos/cache",
        LogLevel:            "info",
    }
    serverConfigs := []constant.ServerConfig{{IpAddr: "mse-51d24ce0-p.nacos-ans.mse.aliyuncs.com", Port: 8848}}
    namingClient, _ := clients.CreateNamingClient(map[string]interface{}{
        "serverConfigs": serverConfigs,
        "clientConfig":  clientConfig,
    })

    serviceName, groupName, clusterName := "example.grpc.server", "DEFAULT_GROUP", "cluster-a"
    _, err = namingClient.RegisterInstance(vo.RegisterInstanceParam{
        Ip:          "127.0.0.1",
        Port:        *port,
        ServiceName: serviceName,
        Weight:      10,
        Enable:      true,
        Healthy:     true,
        Ephemeral:   true,
        Metadata:    map[string]string{"idc": "shanghai"},
        ClusterName: clusterName,
        GroupName:   groupName,
    })
    if err != nil {
        log.Fatalf("Error registering service: %v", err)
    }

    go func() {
        if err := s.Serve(lis); err != nil {
            log.Fatalf("failed to serve: %v", err)
        }
    }()

    sigCh := make(chan os.Signal, 1)
    signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
    <-sigCh
    fmt.Println("Shutting down...")

    _, err = namingClient.DeregisterInstance(vo.DeregisterInstanceParam{
        Ip:          "127.0.0.1",
        Port:        *port,
        ServiceName: serviceName,
        Ephemeral:   true,
        Cluster:     clusterName,
        GroupName:   groupName,
    })
    if err != nil {
        log.Printf("Error deregister service: %v", err)
    }
    s.GracefulStop()
    fmt.Println("grpc server is stopped")
}
5. Go Grpc Client与Nacos集成

最后一步是客户端代码,它通过Nacos发现服务实例并调用远程方法。

const defaultName = "world"
var name = flag.String("name", defaultName, "Name to greet")

func main() {
    flag.Parse()
    clientConfig := constant.ClientConfig{
        NamespaceId:         "public",
        TimeoutMs:           5000,
        NotLoadCacheAtStart: true,
        LogDir:              "/tmp/nacos/log",
        CacheDir:            "/tmp/nacos/cache",
        LogLevel:            "info",
    }
    serverConfigs := []constant.ServerConfig{{IpAddr: "mse-51d24ce0-p.nacos-ans.mse.aliyuncs.com", Port: 8848}}
    namingClient, _ := clients.CreateNamingClient(map[string]interface{}{
        "serverConfigs": serverConfigs,
        "clientConfig":  clientConfig,
    })

    instance, err := namingClient.SelectOneHealthyInstance(vo.SelectOneHealthInstanceParam{
        ServiceName: "example.grpc.server",
        GroupName:   "DEFAULT_GROUP",
        Clusters:    []string{"cluster-a"},
    })
    if err != nil {
        log.Fatalf("failed to select instances: %v", err)
    }

    addr := fmt.Sprintf("%s:%d", instance.Ip, instance.Port)
    conn, err := grpc.Dial(addr, grpc.WithInsecure())
    if err != nil {
        log.Fatalf("did not connect: %v", err)
    }
    defer conn.Close()
    c := pb.NewGreeterClient(conn)

    ctx, cancel := context.WithTimeout(context.Background(), time.Second)
    defer cancel()
    r, err := c.SayHello(ctx, &pb.HelloRequest{Name: *name})
    if err != nil {
        log.Fatalf("could not greet: %v", err)
    }
    log.Printf("Greeting: %s", r.GetMessage())
}
解释

以上步骤描述了从设置环境直到创建gRPC服务并通过Nacos进行服务发现的完整流程。首先,您需要准备好必要的开发工具如protoc;其次,通过编写.proto文件定义服务接口;然后,分别实现服务端和客户端程序,并将它们与Nacos服务发现机制集成起来。这样做的好处在于能够动态地发现可用的服务实例,并支持负载均衡等功能。


http://www.kler.cn/a/393476.html

相关文章:

  • Python 项目组织最佳实践:从脚本到大型项目的进化之路
  • 每日一题 343. 整数拆分
  • windows 默认的消息ID有那些---我与大模型对话
  • CI/CD是什么?
  • EasyGBS国标GB28181公网平台P2P远程访问故障诊断:云端服务端排查指南
  • Ubuntu22.04 LTS 安装nvidia显卡驱动
  • 详解基于C#开发Windows API的SendMessage方法的鼠标键盘消息发送
  • 时序预测 | 改进图卷积+informer时间序列预测,pytorch架构
  • FPGA实现PCIE3.0视频采集转SDI输出,基于XDMA+GS2971架构,提供工程源码和技术支持
  • ASR+LLM+TTS在新能源汽车中的实战
  • 安装luasocket模块时提示“sudo: luarocks:找不到命令“问题,该如何解决?
  • SDL读取PCM音频
  • Docker在微服务架构中的最佳实践
  • 云速搭助力用友 BIP 平台快速接入阿里云产品
  • 计算机网络(8)数据链路层之子层
  • 沈阳乐晟睿浩科技有限公司引领新潮流
  • linux提权-RSYNC未授权访问覆盖
  • SQLite Where 子句
  • 【HAProxy08】企业级反向代理HAProxy高级功能之自定义日志格式与IP透传
  • 华为机试笔记
  • LeetCode【0038】外观数列
  • Go 语言已立足主流,编程语言排行榜24 年 11 月
  • 【基于轻量型架构的WEB开发】课程 作业3 Spring框架
  • 前端基础的讲解-JS(10)
  • Scala学习记录,case class,迭代器
  • 如何制作代购系统:从概念到实现