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服务发现机制集成起来。这样做的好处在于能够动态地发现可用的服务实例,并支持负载均衡等功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/914713.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

软件测试项目实战

软件测试是使用人工或者自动的手段来运行或者测定某个软件系统的过程&#xff0c;其目的在于检验它是否满足规定的需求或弄清预期结果与实际结果之间的差别。 在软件投入使用前&#xff0c;要经过一系列的严格测试&#xff0c;才能保证交付质量。 一、引言 1.编写目的 本文档…

基于百度飞桨paddle的paddlepaddle2.4.2等系列项目的运行

PPASR 必看&#xff01;&#xff01;&#xff01; PaddleSpeech develop --> PaddlePaddle 2.5.0/2.5.1 PaddleSpeech < 1.4.1 --> PaddlePaddle < 2.4.2 1.创建虚拟环境 conda create --name test python3.10 2.激活环境&#xff0c;安装ppasr的paddlepaddl…

MySQL数据库专栏(四)MySQL数据库链接操作C#篇

摘要 本篇文章主要介绍C#链接MySQL数据库的接口介绍&#xff0c;使用实例及注意事项&#xff0c;辅助类的封装及调用实例&#xff0c;可以直接移植到项目里面使用。 目录 1、添加引用 2、接口介绍 2.1、MySqlConnection 2.2、MySqlCommand 2.3、MySqlDataReader…

【Pikachu】File Inclusion文件包含实战

永远也不要忘记能够笑的坚强&#xff0c;就算受伤&#xff0c;我也从不彷徨。 1.File Inclusion(文件包含漏洞)概述 File Inclusion(文件包含漏洞)概述 文件包含&#xff0c;是一个功能。在各种开发语言中都提供了内置的文件包含函数&#xff0c;其可以使开发人员在一个代码…

计算机网络基本概念总结

IP地址 概念 使网络中的设备都有唯一的地址标识&#xff0c;用于表示其在网络中的位置。 格式 IP地址是一个32位的二进制数&#xff0c;通常被分割为4个8位二进制数&#xff08;也就是4个字节&#xff09;&#xff0c;如&#xff1a;01100100.00001000.00001010.00000110。通常…

CSS回顾-基础知识详解

一、引言 在前端开发领域&#xff0c;CSS 曾是构建网页视觉效果的关键&#xff0c;与 HTML、JavaScript 一起打造精彩的网络世界。但随着组件库的大量涌现&#xff0c;我们亲手书写 CSS 样式的情况越来越少&#xff0c;CSS 基础知识也逐渐被我们遗忘。 现在&#xff0c;这种遗…

RabbitMq项目实战--延迟队列实现超时订单处理

简单实现版 RabbitMq创建队列绑定交换机_rabbitmq 绑定交换机-CSDN博客 Configuration public class RabbitmqConfig {Value("${rabbitmq.exchange}")private String exchange;Value("${rabbitmq.host}")private String host;Value("${rabbitmq.por…

Vivado+Vscode联合打造verilog环境

一、Vivado下载安装 详细参考我另一篇文章&#xff1a; Vivado2022.2下载安装_fpga vivado下载-CSDN博客https://blog.csdn.net/weixin_61081689/article/details/143460790?spm1001.2014.3001.5501 二、Vscode下载安装 详细参考我另一篇文章&#xff1a; VscodeAnacond…

Unity 热更新 之 一篇文章完全入门AssetBundle

本篇知识来源于unity官方手册以及siki学院的相关教程,链接如下,仅作学习分享 AssetBundle&#xff08;创建打包&#xff09;入门学习(基于Unity2017) - SiKi学院|SiKi学堂 - unity|u3d|虚幻|ue4/5|java|python|人工智能|视频教程|在线课程 目录 0.热更新是什么 1.AssetBundl…

思考:linux Vi Vim 编辑器的简明原理,与快速用法之《 7 字真言 》@ “鱼爱返 说 温泉啊“ (**)

Linux vi/vim | 菜鸟教程 https://zhuanlan.zhihu.com/p/602675406 Linux Vim编辑器的基本使用_vim文本编辑器-CSDN博客 这里提出使用 vi / vim 进行简单的编辑操作的原因&#xff0c;主要是在容器镜像中&#xff0c;普遍都是使用这个。 在 linux 服务器应用场景&#x…

【网络安全 | 甲方建设】DDOS 防范教程

未经许可,不得转载。 文章目录 前言DDoSDDoS种类针对DDoS CC攻击的防护备份网站拦截HTTP请求带宽扩容使用CDN隐藏服务器真实IP关闭不必要的服务或端口限制SYN/ICMP流量启用反向代理前言 假设你是一个电商平台的管理员,网站每天都处理大量的用户请求,比如用户浏览商品、加入…

【WRF模拟】全过程总结:WPS预处理及WRF运行

【WRF模拟】全过程总结:WPS预处理及WRF运行 1 数据准备1.1 嵌套域设置(Customize domain)-基于QGis中gis4wrf插件1.2 静态地理数据1.2.1 叶面积指数LAI和植被覆盖度Fpar(月尺度)1.2.2 地面反照率(月尺度)1.2.3 土地利用类型+不透水面积1.2.4 数据处理:geotiff→tiff(W…

【青牛科技】 GC6153——TMI8152 的不二之选,可应用于摇头机等产品中

在电子工程领域&#xff0c;不断寻求性能更优、成本更低的解决方案是工程师们的永恒追求。今天&#xff0c;我们要为广大电子工程师带来一款极具竞争力的产品 —— GC6153&#xff0c;它将成为 TMI8152 的完美替代之选。 一、产品背景 随着科技的飞速发展&#xff0c;电子设备…

Openstack9--安装etcd分布式键-值对存储系统

只需在控制节点安装 yum -y install etcd 编辑配置文件 配图画线处需要更改&#xff0c;如果改行被#注释请删掉# 以取消注释 vi /etc/etcd/etcd.conf 修改的 ETCD_LISTEN_PEER_URLS"http://192.168.10.10:2380" ETCD_LISTEN_CLIENT_URLS"http://192.168.1…

Go语言开发基于SQLite数据库实现用户表增删改查项目搭建(一)

背景 前几天我们不是写了个关于go语言解决rtsp协议只播放部分的问题(业务问题)这个么 里面用到了mysql&#xff0c;但不够轻量级&#xff0c;如果有的项目地需要的话&#xff0c;我们还需要部署mysql 其实这个项目就使用了一个表&#xff0c;没必要搞mysql&#xff0c;那有没有…

论文阅读-Event-based Visible and Infrared Fusion via Multi-task Collaboration

一、前言 可见光图像与红外图像融合&#xff08;VIF&#xff09;通过结合热红外图像与可见光图像的丰富纹理&#xff0c;提供了一个全面可靠的场景描述。然而&#xff0c;传统的VIF系统可能在极端光照和高动态运动场景中捕获过曝或欠曝的图像&#xff0c;进而导致融合结果下降…

TDesign了解及使用

文章目录 1、概述2、快速开始2.1使用 npm 安装2.2通过 浏览器引入 安装2.3、使用 3、简单案例3.1 路由创建3.2、 页面创建3.3、 Table组件3.4、序号展示3.5、 图片展示及预览3.6、 性别字段处理 1、概述 TDesign 是腾讯推出的设计系统&#xff0c;旨在提供一致的设计语言和视觉…

C++初阶——list

一、什么是list list是一个可以在序列的任意位置进行插入和删除的容器&#xff0c;并且可以进行双向迭代。list的底层是一个双向链表&#xff0c;双向链表可以将它们包含的每个元素存储在不同且不相关的存储位置。通过将每个元素与前一个元素的链接和后一个元素的链接关联起来&…

ElasticSearch备考 -- 集群配置常见问题

一、集群开启xpack安全配置后无法启动 在配置文件中增加 xpack.security.enabled: true 后无法启动&#xff0c;日志中提示如下 Transport SSL must be enabled if security is enabled. Please set [xpack.security.transport.ssl.enabled] to [true] or disable security b…

NAT网络工作原理和NAT类型

NAT基本工作流程 通常情况下&#xff0c;某个局域网中&#xff0c;只有路由器的ip是公网的&#xff0c;局域网中的设备都是内网ip&#xff0c;内网ip不具备直接与外部应用通信的能力。 处于内网的设备如何借助NAT来实现访问外网的应用&#xff1f; 对于开启了NAT功能的局域网…