crow-han(基于go-micro框架的微服务脚手架)-02-添加一个微服务实战(已k8s为例)

本文详细介绍了如何在GoMicro框架中添加一个新的K8s微服务,包括配置文件、连接K8s、编写服务代码、处理handler、生成proto文件、实现接口调用和添加Swagger文档。同时,文章还涵盖了服务的启动、调试和接口测试流程。
摘要由CSDN通过智能技术生成

1. 目录结构

在这里插入图片描述

  • bin
    编译好的二进制文件

  • cmd
    各微服务的main函数和相关初始化函数

  • docker
    容器相关,包括docker-compose.yml和dockerFile

  • internal:内部代码(不需要对外)

    • app:各微服务私有的代码
    • cache:redis相关的代码
    • conf:配置和变量相关的
    • models:数据库相关
    • pkg:各微服务公用的方法等代码
  • pkg:公共代码,外部可能用到的

  • sql:sql文件

  • MakeFile

  • README.md

2. 添加自己的微服务

已获取k8s的node节点列表为例,写一个k8s的微服务接入crow-han中

2.1 配置文件和必要的函数

2.1.1 配置文件

  • cmd目录下创建k8s目录

以后放置微服务k8s的main函数、初始化相关代码、配置文件等

  • 该目录下创建etc目录放置配置文件
  • etc目录下创建kube.conf 文件,将k8s服务器master上 ~/.kube/config文件内容拷贝进去。

2.1.2 连接k8s

internal/conf 目录下创建 connect_k8s.go文件

以下这段是链接k8s的代码。这段代码可以作为微服务k8s的私有代码放在internal/app/k8s中,也可以最为脚手架公用配置放在internal/conf中。考虑到我之后将按照crow-han的风格,在微服务k8s的main函数中初始化k8s链接,为避免以后出现循环调用的可能,这里选择了后者。

ackage conf

import (
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
)

var K8sClientSet *kubernetes.Clientset

func ConnectK8s() (clientSet *kubernetes.Clientset, err error) {
	configPath := "etc/kube.conf"
	config, err := clientcmd.BuildConfigFromFlags("", configPath)
	if err != nil {
		return nil, err
	}
	clientSet, err = kubernetes.NewForConfig(config)
	if err != nil {
		return nil, err
	}
	return clientSet, nil
}

2.2 k8s服务相关代码

internal/app下添加k8s目录(放置该微服务处理逻辑的一些代码),在下边创建 nodes.go文件(放置node操作相关的代码,我们这里写一个获取nodeList作为示例)。

package service

import (
	"context"
	"crow-han/internal/conf"
	coreV1 "k8s.io/api/core/v1"
	metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func GetNodeList() (nodeList *coreV1.NodeList, err error) {
	nodeList, err = conf.K8sClientSet.CoreV1().Nodes().List(context.TODO(), metaV1.ListOptions{})
	if err != nil {
		return nodeList, err
	}
	return nodeList, nil
}

2.3 proto

2.3.1 创建proto文件

  • proto目录下创建k8s目录,下边创建k8s.proto文件
syntax = "proto3";

package k8s;

option go_package = "./proto/k8s;k8s";

service K8s {
  rpc GetNodeList(GetNodeListRequest) returns (GetNodeListResponse) {}
}

message GetNodeListRequest {
}

message GetNodeListResponse {
   string NodeList = 1;
}

GetNodeListResponse这个是微服务返回给gateway的返回值,GetNodeList() 返回是*coreV1.NodeList,通常我们可以转换成proto的格式。但是因为这个node返回值比较复杂,所以这里我返回一个字串(json)然后在gateway再解析回来。

2.3.2 编译proto

  • 编译proto
 protoc --proto_path=. --micro_out=. --go_out=:. proto/k8s/k8s.proto
  • 生成文件
    此时 proto/k8s目录下生成k8s.pb.go k8s.pb.micro.go两个文件

2.4 handler

internal/app/k8s目录下创建 /handler目录,下边创建 nodes.go 文件

package handler

import (
	"context"
	"crow-han/internal/app/k8s/service"
	pb "crow-han/proto/k8s"
	"encoding/json"
	"github.com/toolkits/pkg/logger"
)

type Nodes struct{}

func (e *Nodes) GetNodeList(ctx context.Context, req *pb.GetNodeListRequest, rsp *pb.GetNodeListResponse) error {
	logger.Infof("Received K8s.GetNodeList request: %v", req)

	nodeList, err := service.GetNodeList()
	if err != nil {
		logger.Error(err)
		return err
	}

	output, err := json.Marshal(&nodeList)
	if err != nil {
		logger.Error(err)
	}
	rsp.NodeList = string(output)

	return nil
}

2.5 k8s的main函数

在cmd目录下创建k8s目录,目录下创建main.go文件,内容如下

package k8s

import (
	"crow-han/internal/app/k8s/handler"
	"crow-han/internal/cache"
	"crow-han/internal/conf"
	pb "crow-han/proto/k8s"
	"fmt"
	"github.com/go-micro/plugins/v4/registry/consul"
	"github.com/kelseyhightower/envconfig"
	"go-micro.dev/v4/registry"

	"go-micro.dev/v4"
	"go-micro.dev/v4/logger"
)

func init() {
	//初始化变量
	err := envconfig.Process("crow", &conf.MyEnvs)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Printf("%+v\n", &conf.MyEnvs)

	//初始化日志
	conf.LoggerInit()
	logger.Info("logger init")
	//mysql初始化
	var tx conf.MyConnect
	tx.ConnectMysql()

	//初始化redis
	//redis初始化
	conf.RedisConnect()
	cache.CheckRides()

	//初始化k8s
	conf.K8sClientSet, err = conf.ConnectK8s()
	if err != nil {
		fmt.Println(err)
	}
}

var (
	service = "k8s"
	version = "latest"
)

func main() {
	// Create service
	srv := micro.NewService()

	consulRegis := consul.NewRegistry(func(options *registry.Options) {
		options.Addrs = []string{
			conf.MyEnvs.ConsulAddr,
		}
	})

	srv.Init(
		micro.Name(service),
		micro.Version(version),
		micro.Registry(consulRegis),
	)

	// Register handler
	if err := pb.RegisterK8SHandler(srv.Server(), new(handler.Nodes)); err != nil {
		logger.Fatal(err)
	}

	if err := srv.Run(); err != nil {
		logger.Fatal(err)
	}
}

3. gateway调用

3.1 调用微服务

internal/app/gate-way/service目录下创建k8s_nodes.go文件,内容如下:

package service

import (
	"context"
	k8sProto "crow-han/proto/k8s"
	"encoding/json"
	"github.com/gin-gonic/gin"
	"github.com/toolkits/pkg/logger"
	coreV1 "k8s.io/api/core/v1"
)

func GetNodeList(c *gin.Context) {

	//调用k8s
	userSrv := k8sProto.NewK8SService("k8s", srv.Client())
	respSr, err := userSrv.GetNodeList(context.Background(), &k8sProto.GetNodeListRequest{})
	logger.Infof("%+v", respSr)
	if err != nil {
		logger.Error(err)
		SetErr(c, 500, err, err.Error())
		return
	}
    //将结果转换为原结构体
	var resp *coreV1.NodeList
	json.Unmarshal([]byte(respSr.NodeList), &resp)
	
	SetOK(c, resp)
}

3.2 router

internal/app/gate-way/service/router.go文件中添加一条路由规则

func ServerRouter() {
    ……
	groupV1 := r.Group("/api/v1")
	{
	  ……
	  groupV1.GET("/k8s/node/list", user(), GetNodeList) //添加这条路由
	}

说明:需要user验证的加上验证方法 user(),不想验证可以不加。

4. 添加文档 swagger

  • internal/app/gate-way/service/k8s_nodes.go文件的GetNodeList()函数前添加如下注释
// GetNodeList 查看node列表
// @Summary 查看node列表
// @Description 查看node列表
// @Tags Node
// @Success 200 {object} response.Response{data=v1.NodeList} "{"requestId": "string","code": 200,"msg": "ok","data": [...]}"
// @Failure 500 {object} response.Response{msg=string} "{"requestId": "string","code": 500,"msg": "string","status": "error","data": null}"
// @Router /api/v1/k8s/node/list [get]
// @Security Bearer
func GetNodeList(c *gin.Context) {
  ……
}

详细方法见另一篇博文《GO语言gin框架实战-03-swagger和接口文档》

  • 编译swagger
cd internal/app/gate-way/service
swag init --parseDependency --parseInternal --parseDepth 2 -g .\router.go

5. 调试

5.1 启动服务

5.2 swagger接口测试

  • 获取token
    默认用户名密码:admin/liubei@161
    在这里插入图片描述
    输出结果
    在这里插入图片描述
  • Bearer验证
    点开锁标记,输入 Bearer xxxxxxxxxxx(xxxx 是刚才获取的token值)
    在这里插入图片描述
  • 验证我们之前写的接口

在这里插入图片描述

输出如下:
在这里插入图片描述


在这里插入图片描述

Docker+k8s微服务实战课程 课程目录 一、初识微服务 1 微服务-导学 2 软件架构的进化 3 什么是微服务 4 画出微服务架构图 5 微服务架构的优势和不足 二、微服务带来的问题及解决方案分析 1 微服务架构带来的问题 2 微服务间如何通讯 3 服务发现、部署更新和扩容 4 springboot&springcloud(上) 5 springboot&springcloud(下) 三、微服务开发 1 微服务业务分析 2 Thirft安装和验证 3 Python开发信息服务 4 开发用户服务(上) 5 开发用户服务(下) 6 开发用户EdgeService_A 7 开发用户EdgeService_B 8 开发用户EdgeService_C 9 开发用户EdgeService_D 10 dubbo入门操练(上) 11 dubbo入门操练(下) 12 开发课程服务 13 开发课程EdgeService 14 APIGatewayZuul 四、服务编排前奏 1 服务docker化(上) 2 服务docker化(下) 3 docker下的服务通讯(上) 4 docker下的服务通讯(下) 5 镜像仓库 6 三大平台扬帆起航 五、服务编排-Mesos 1 了解Mesos 2 画出Mesos集群架构图 3 集群环境搭建_A 4 集群环境搭建_B 5 集群环境搭建_C 6 调整微服务适应Mesos 7 微服务部署_A 8 微服务部署_B 9 微服务部署_C 六、服务编排-DockerSwarm 1 了解Swarm 2 集群环境搭建(上) 3 集群环境搭建(下) 4 调整微服务及服务配置 5 微服务部署 七、服务编排-Kubernetes 1 了解kubernetes(上) 2 了解kubernetes(下) 3 环境搭建前奏 4 预先准备环境 5 基础集群部署(上) 6 基础集群部署(下) 7 小试牛刀 8 kube-proxy和kube-dns 9 理解认证、授权 10 为集群添加认证授权(上) 11 为集群添加认证授权(下) 12 再试牛刀 13 部署我们的微服务 八、CICD和DevOps 1 了解CICD和DevOps 2 准备GitLab和Jenkins 3 CICD实践(上) 4 CICD实践(下) 九、课程总结
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玄德公笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值