Платформа микросервисов golang серия go-zero -2: практика go-zero + gorm V2

Go

Зачем использовать ноль

Может быть и третий вариант

  • Круг golang невелик, а микросервисных фреймворков всего несколько: кроме go-micro и go-kit других вариантов почти нет. go-zero предоставляет для этого третью возможность.
  • go-micro не дружит с поддержкой webapi, ему нужно запускать микроинструкции, которые сложно настроить

Предпринимательским продуктам нужна основа для поддержки роста бизнеса

Какая структура нам нужна? Нам нужна структура, которая может поддерживать рост бизнеса! На ранней стадии эксплуатации продукта, например на этапе проверки требований, нам не нужно внедрять микросервисную архитектуру, поскольку эксплуатационные расходы слишком высоки. Достаточно монолитного приложения. С развитием бизнеса микросервисы становятся необходимыми.На данный момент мы надеемся не выполнять слишком большую нагрузку на код и гибко обновляться. Вот где стоит ноль

Что такое нулевой

Следующие Amway скопированы для конкретной ссылкиhttps://github.com/tal-tech/go-zerogo-zero — это веб- и RPC-фреймворк, объединяющий различные инженерные практики и обладающий следующими основными характеристиками:

  • Мощная поддержка инструментов с минимальным кодированием
  • Минималистичный интерфейс
  • Полностью совместим с сетью/http
  • Поддержка промежуточного программного обеспечения для легкого расширения
  • высокая производительность
  • Программирование, ориентированное на отказ, отказоустойчивая конструкция
  • Встроенное обнаружение сервисов, балансировка нагрузки
  • Встроенное ограничение тока, плавкие предохранители, сброс нагрузки, автоматический запуск и автоматическое восстановление
  • Автоматическая проверка параметров API
  • Каскадное управление тайм-аутом
  • Автоматический контроль кеша
  • Отслеживание ссылок, статистика, сигналы тревоги и т. д.
  • Высокая поддержка параллелизма, стабильная и безопасная каждый день во время эпидемии пикового трафика Xiao blackboard

как пользоваться

Прежде чем читать этот документ, обновите golang доgo14и выше, и включить поддержку модуля go, GO14 и выше предназначены только для поддержки Gorm

export GOPROXY=https://goproxy.io,direct
export GO111MODULE=on 

установить гоктл

goctl — это генератор кода для go-zero, в конце концов, ленивый артефакт写代码大多时间是体力活Как установить?Сначала скачайте исходный код!

git clone https://github.com/tal-tech/go-zero
cd go-zero/tools/goctl
go build goctl.go

Наконец, сгенерируйте копию goctl.exe в$gopath/binВниз

описание команды goctl

Просмотрите документацию самостоятельноhttps://github.com/tal-tech/go-zero/blob/master/tools/goctl/goctl.md

Инструкции, используемые в этой статье, следующие

goctl api      go       -api             open.api            -dir                     .
#代码说明如下
goctl api      go       -api             open.api            -dir                     .
 |      |        |         |                 |                  |                      | 
      生成api  go语言     指定api模板文件   模板文件名称         指定生成代码存放路径     当前文件夹

Создать проект

Сгенерировать файл go.mod

Создание проекта с помощью следующей команды

mkdir hello
cd hello
go mod init  hello

Определить Hello.API

API, разработанный в этой статье, выглядит следующим образом.

описывать Формат метод параметр возвращение
Регистрация пользователя /open/register post мобильный: номер мобильного телефона, пароль: пароль, код: код подтверждения изображения id: ID пользователя, token: токен пользователя
Логин пользователя /open/authorization post мобильный: номер мобильного телефона, пароль: пароль, код: код подтверждения изображения id: ID пользователя, token: токен пользователя
Запрос кода подтверждения изображения /open/verify get билет: идентификатор кода подтверждения изображения данные: изображения в формате base64

Согласно приведенному выше описанию, файл шаблона для написания апи выглядит следующим образом


type (
	UserOptReq struct {
		mobile string `json:"mobile"`
		passwd string `json:"passwd"`
		code   string `json:"code"`
	}

	UserOptResp struct {
		id    uint   `json:"id"`
		token string `json:"token"`
	}
	//图片验证码支持
	VerifyReq struct {
		ticket string `json:"ticket"`
	}
	//图片验证码支持
	VerifyResp struct {
		data string `json:"data"`
	}
)

service open-api {
	@doc(
        summary: 公开的api函数
        desc: >
        register 用户注册,
        authorization 用户登录,
        verify 图片验证码接口
    )
	@server(
		handler: registerHandler
		folder: open
	)
	post /open/register(UserOptReq) returns(UserOptResp)
	
	
	@server(
		handler: authorizationHandler
		folder: open
	)
	post /open/authorization(UserOptReq) returns(UserOptResp)

	@server(
		handler: verifyHandler
		folder: open
	)
	post /open/verify(VerifyReq) returns(VerifyResp)
	
}

Уведомление

  • В файле может быть только одна служба
  • Инструмент, наконец, сгенерирует различные структуры с моделью типа в качестве шаблона, поэтому параметры и структуры могут быть согласованы.
  • Если нам нужно управлять бизнесом в папках, мы можем использовать атрибут папки для определения

сгенерировать код

Создать инструкцию кода

goctl api  go   -api   open.api   -dir  .

Окончательная структура кода выглядит следующим образом

#tree /F /A
|   go.mod
|   go.sum
|   hello.api
|   open.go
|
+---etc
|       open-api.yaml
|
\---internal
    +---config
    |       config.go
    |
    +---handler
    |   |   routes.go
    |   |
    |   \---open
    |           authorizationhandler.go
    |           registerhandler.go
    |           verifyhandler.go
    |
    +---logic
    |   \---open
    |           authorizationlogic.go
    |           registerlogic.go
    |           verifylogic.go
    |
    +---svc
    |       servicecontext.go
    |
    \---types
            types.go                                          

запустить его

go run open.go

пройти тест

curl http://127.0.0.1:8888/open/register -X POST -H "Content-Type: application/json" -d {\"mobile\":\"15367151352\",\"passwd\":\"testpwd\",\"code\":\"asdf\"}
{"id":0,"token":""}

Интегрированный звездный продукт Gorm V2

Босс Jinzhu обновил интеграционный тест Gorm V2

конфигурационный файл

Профилиetc/open-api.yaml

Name: open-api
Host: 0.0.0.0
Port: 8888
DataSourceName: root:1D007648b4f8@(127.0.0.1:3306)/gozero?charset=utf8

существуетetc/open-api.yamlДобавьте параметр DataSourceName в существуетinternal/config/config.goДобавьте имя источника данных в

type Config struct {
	rest.RestConf
	DataSourceName string
}

По поводу конфигурационного файла, в системе есть встроенные ключевые слова типа Cache, а информации не так много, в принципе, можно настроить по желанию, а потом определить переменную с таким же именем в Conf.

Начать поддержку Горма

Исправлятьsvc/servicecontext.goкод показывает, как показано ниже

package svc

import (
	"hello/internal/config"
	"hello/internal/models"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/schema"
)

type ServiceContext struct {
	Config  config.Config
	DbEngin *gorm.DB
}

func NewServiceContext(c config.Config) *ServiceContext {
    //启动Gorm支持
	db, err := gorm.Open(mysql.Open(c.DataSourceName), &gorm.Config{
		NamingStrategy: schema.NamingStrategy{
			TablePrefix:   "tech_", // 表名前缀,`User` 的表名应该是 `t_users`
			SingularTable: true,    // 使用单数表名,启用该选项,此时,`User` 的表名应该是 `t_user`
		},
    })
    //如果出错就GameOver了
	if err != nil {
		panic(err)
    }
    //自动同步更新表结构,不要建表了O(∩_∩)O哈哈~
	db.AutoMigrate(&models.User{})

	return &ServiceContext{Config: c, DbEngin: db}
}

Новый файл модели

новыйmodels\models.goдокумент

//models\models.go文件
package models

import (
	"errors"
	"hello/internal/utils"

	"gorm.io/gorm"
)

type User struct {
	gorm.Model
	Mobile string `gorm:"index:mobile;type:varchar(13)"`
	Passwd string `gorm:"type:varchar(64)"`
}
//在创建前检验验证一下密码的有效性
func (u *User) BeforeCreate(db *gorm.DB) error {
	if len(u.Passwd) < 6 {
		return errors.New("密码太简单了")
    }
    //对密码进行加密存储
	u.Passwd = utils.Password(u.Passwd)
	return nil
}

utils.Password — это инструментарий, который мы написали, код выглядит следующим образом

package utils

import (
	"fmt"

	"golang.org/x/crypto/bcrypt"
)

//密码加密
func Password(plainpwd string) string {
    //谷歌的加密包
	hash, err := bcrypt.GenerateFromPassword([]byte(plainpwd), bcrypt.DefaultCost) //加密处理
	if err != nil {
		fmt.Println(err)
	}
	encodePWD := string(hash) // 保存在数据库的密码,虽然每次生成都不同,只需保存一份即可
	return encodePWD
}
//密码校验
func CheckPassword(plainpwd, cryptedpwd string) bool {
	err := bcrypt.CompareHashAndPassword([]byte(cryptedpwd), []byte(plainpwd)) //验证(对比)
	return err == nil
}

Реализовать бизнес-логику

существуетlogic\open\registerlogic.goИзмените код следующим образом

package logic

import (
	"context"

	"hello/internal/models"
	"hello/internal/svc"
	"hello/internal/types"

	"github.com/tal-tech/go-zero/core/logx"
)

type RegisterLogic struct {
	ctx context.Context
	logx.Logger
	svcCtx *svc.ServiceContext
}

func NewRegisterLogic(ctx context.Context, svcCtx *svc.ServiceContext) RegisterLogic {
	return RegisterLogic{
		ctx:    ctx,
		Logger: logx.WithContext(ctx),
		svcCtx: svcCtx,
	}
}

func (l *RegisterLogic) Register(req types.UserOptReq) (*types.UserOptResp, error) {
	user := models.User{
		Mobile: req.Mobile,
		Passwd: req.Passwd,
	}
	result := l.svcCtx.DbEngin.Create(&user)
	return &types.UserOptResp{
		Id: user.ID,
	}, result.Error
}

  • В RegisterLogic добавлен svcCtx * svc.ServiceContext, из-за необходимости использовать внутри DbEngin
  • NewRegisterLogic настроить svcCtx
  • Реализуйте логику в функции регистрацииresult := l.svcCtx.DbEngin.Create(&user)

пройти тест

>curl http://127.0.0.1:8888/open/register -X POST -H "Content-Type: application/json" -d {\"mobile\":\"15367151352\",\"passwd\":\"testpwd\"}
{"id":3,"token":""}

С нетерпением ждем обновленных функций

go-zero

Определение интерфейса хочет поддерживать несколько типов контента.

UserOptReq struct {
	mobile string `json:"mobile" form:"mobile" xml:"mobile"`
	passwd string `json:"passwd" form:"passwd" xml:"passwd"`
	code   string `json:"code" form:"code" xml:"code"`
}

Возможный обходной путь Исправлятьgithub.com/tal-tech/go-zero/rest/httpx/requests.goсерединаParseв следующую модель

func Parse(r *http.Request, v interface{}) error {
	if err := ParsePath(r, v); err != nil {
		return err
	}
	if strings.Contains(r.Header.Get(ContentType), multipartFormData) {
		return ParseForm(r, v)
	} else if strings.Contains(r.Header.Get(ContentType), urlencodeformdata) {
		return ParseForm(r, v)
	} else if strings.Contains(r.Header.Get(ContentType), applicationjson) {
		return ParseJsonBody(r, v)
	} else {
		return errors.New("不支持的请求类型")
	}
}

Поддерживает несколько методов для каждого файла

Например, следующий способ записи сгенерирует два метода в файле verify Handler.go.

	@server(
		handler: verifyHandler
		folder: open
	)
	post /open/verify(VerifyReq) returns(VerifyResp)
    post /open/authorization(UserOptReq) returns(UserOptResp)

gorm v2

рекомендуемое значение по умолчаниюSingularTableсобственностьtrue

NamingStrategy: schema.NamingStrategy{
			TablePrefix:   "tech_", // 表名前缀,`User` 的表名应该是 `t_users`
			SingularTable: true,    // 使用单数表名,启用该选项,此时,`User` 的表名应该是 `t_user`
		},

Рекомендуется улучшить функцию кеша

Рекомендуется обеспечить поддержку кеша, такого как redis/memcache/memory cache.

Это документ приобретает

Обратите внимание на публичный аккаунтbetaideaВведите gozero или gormv2, чтобы получить

Широкая реклама

Близятся хорошие новости для пользователей uniapp! После сотен тысяч тестов пользователей наша система обслуживания клиентов, наконец, предоставляет услуги внешнему миру. Вы все еще беспокоитесь о доступе к обслуживанию клиентов в торговом центре?Всего одна строка кода, и вы можете получить к нему доступ!! Всего одна строчка кода!!!!

/*kefu.vue*/
<template>
	<view>
		<IdeaKefu :siteid="siteId"  ></IdeaKefu>
	</view>
</template>

<script>
	import IdeaKefu from "@/components/idea-kefu/idea-kefu.vue"
    export default {
		components:{
			IdeaKefu
		},
		data() {
			return {
				siteId:2
			}
		}
    }   

Эффект отличный客服效果

Адрес документа разработкиkefu.techidea8.com/html/wiki/