golang 分布式微服务DAO层构建

这篇具有很好参考价值的文章主要介绍了golang 分布式微服务DAO层构建。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

构建云原生项目的dao层
配置读写分离的mysql集群

1. 编写yml配置文件

搭建一主二从的mysql集群、单机redis

db.yml

mysql:
  source: # 主数据库
    driverName: mysql
    host: 127.0.0.1
    port: 3309
    database: db_tiktok
    username: tiktokDB
    password: tiktokDB
    charset: utf8mb4

  replica1: # 从数据库
    driverName: mysql
    host: 127.0.0.1
    port: 3310
    database: db_tiktok
    username: tiktokDB
    password: tiktokDB
    charset: utf8mb4
  replica2: # 从数据库
    driverName: mysql
    host: 127.0.0.1
    port: 3311
    database: db_tiktok
    username: tiktokDB
    password: tiktokDB
    charset: utf8mb4

redis:
  addr: 127.0.0.1
  port: 6379
  password: 123456
  db: 0 # 数据库编号

2. 使用viper,读对应yml文件,保存到生成的对象中

var (
	_db       *gorm.DB
	config    = viper.Init("db")
	zapLogger = zap.InitLogger()
)

其中viper init方法的逻辑如下:

// Init 初始化Viper配置
func Init(configName string) Config {
	config := Config{Viper: V.New()}
	v := config.Viper
	v.SetConfigType("yml")      //设置配置文件类型
	v.SetConfigName(configName)
	//设置配置文件搜索路径
	v.AddConfigPath("./config") //设置配置文件路径 !!!注意路径问题
	v.AddConfigPath("../config")
	v.AddConfigPath("../../config")
	//读取配置文件的内容
	if err := v.ReadInConfig(); err != nil {
		//global.SugarLogger.Fatalf("read config files failed,errors is %+v", err)
		log.Fatalf("errno is %+v", err)
	}
	return config
}

3. 从viper的config中,构建目标数据库的dsn

func getDsn(driverWithRole string) string {
	username := config.Viper.GetString(fmt.Sprintf("%s.username", driverWithRole))
	password := config.Viper.GetString(fmt.Sprintf("%s.password", driverWithRole))
	host := config.Viper.GetString(fmt.Sprintf("%s.host", driverWithRole))
	port := config.Viper.GetInt(fmt.Sprintf("%s.port", driverWithRole))
	Dbname := config.Viper.GetString(fmt.Sprintf("%s.database", driverWithRole))

	// data source name
	dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local", username, password, host, port, Dbname)

	return dsn
}

例如现在要获取mysql “一主二从” 的主机dsn:

dsn1 := getDsn("mysql.source")

4. 拿到dsn之后,可以使用gorm连接数据库

将一主二从都连接上文章来源地址https://www.toymoban.com/news/detail-661381.html

	var err error
	_db, err = gorm.Open(mysql.Open(dsn1), &gorm.Config{
		Logger:                 logger.Default.LogMode(logger.Info),
		PrepareStmt:            true,
		SkipDefaultTransaction: true,
	})
	if err != nil {
		panic(err.Error())
	}

	dsn2 := getDsn("mysql.replica1")
	dsn3 := getDsn("mysql.replica2")

5. 配置mysql数据库读写分离

  • dbresolver 的作用是将数据库的读写操作分发到不同的数据库实例上。在配置中,Sources 字段表示主数据库(写操作)的连接信息,Replicas 字段表示从数据库(读操作)的连接信息。通过配置这些连接信息,dbresolver 可以根据一定的策略将读操作分发到从数据库实例上,以减轻主数据库的读压力,提高系统的并发性能。
  • 代码中,Sources 设置了一个主数据库连接,Replicas 则设置了两个从数据库连接。这样 dbresolver 就知道在进行数据库操作时应该选择主数据库还是从数据库。同时,Policy 字段指定了负载均衡策略,这里采用的是随机策略即 RandomPolicy。最后,TraceResolverMode 字段表示是否在日志中打印数据库的主从模式,对于调试和跟踪非常有用。
	// 配置dbresolver
	_db.Use(dbresolver.Register(dbresolver.Config{
		// use `db1` as sources, `db2` as replicas
		Sources:  []gorm.Dialector{mysql.Open(dsn1)},
		Replicas: []gorm.Dialector{mysql.Open(dsn2), mysql.Open(dsn3)},
		// sources/replicas load balancing policy
		Policy: dbresolver.RandomPolicy{},
		// print sources/replicas mode in logger
		TraceResolverMode: false,
	}))

6. 创建表

	// AutoMigrate会创建表,缺失的外键,约束,列和索引。如果大小,精度,是否为空,可以更改,则AutoMigrate会改变列的类型。出于保护您数据的目的,它不会删除未使用的列
	// 刷新数据库的表格,使其保持最新。即如果我在旧表的基础上增加一个字段age,那么调用autoMigrate后,旧表会自动多出一列age,值为空
	if err := _db.AutoMigrate(&User{}, &Video{}, &Comment{}, &FavoriteVideoRelation{}, &FollowRelation{}, &Message{}, &FavoriteCommentRelation{}); err != nil {
		zapLogger.Fatalln(err.Error())
	}

整体代码

var (
	_db       *gorm.DB
	config    = viper.Init("db")
	zapLogger = zap.InitLogger()
)

func getDsn(driverWithRole string) string {
	username := config.Viper.GetString(fmt.Sprintf("%s.username", driverWithRole))
	password := config.Viper.GetString(fmt.Sprintf("%s.password", driverWithRole))
	host := config.Viper.GetString(fmt.Sprintf("%s.host", driverWithRole))
	port := config.Viper.GetInt(fmt.Sprintf("%s.port", driverWithRole))
	Dbname := config.Viper.GetString(fmt.Sprintf("%s.database", driverWithRole))

	// data source name
	dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local", username, password, host, port, Dbname)

	return dsn
}

func init() {
	zapLogger.Info("Redis server connection successful!")

	dsn1 := getDsn("mysql.source")

	var err error
	_db, err = gorm.Open(mysql.Open(dsn1), &gorm.Config{
		Logger:                 logger.Default.LogMode(logger.Info),
		PrepareStmt:            true,
		SkipDefaultTransaction: true,
	})
	if err != nil {
		panic(err.Error())
	}

	dsn2 := getDsn("mysql.replica1")
	dsn3 := getDsn("mysql.replica2")
	// 配置dbresolver
	_db.Use(dbresolver.Register(dbresolver.Config{
		// use `db1` as sources, `db2` as replicas
		Sources:  []gorm.Dialector{mysql.Open(dsn1)},
		Replicas: []gorm.Dialector{mysql.Open(dsn2), mysql.Open(dsn3)},
		// sources/replicas load balancing policy
		Policy: dbresolver.RandomPolicy{},
		// print sources/replicas mode in logger
		TraceResolverMode: false,
	}))
	// AutoMigrate会创建表,缺失的外键,约束,列和索引。如果大小,精度,是否为空,可以更改,则AutoMigrate会改变列的类型。出于保护您数据的目的,它不会删除未使用的列
	// 刷新数据库的表格,使其保持最新。即如果我在旧表的基础上增加一个字段age,那么调用autoMigrate后,旧表会自动多出一列age,值为空
	if err := _db.AutoMigrate(&User{}, &Video{}, &Comment{}, &FavoriteVideoRelation{}, &FollowRelation{}, &Message{}, &FavoriteCommentRelation{}); err != nil {
		zapLogger.Fatalln(err.Error())
	}

	db, err := _db.DB()
	if err != nil {
		zapLogger.Fatalln(err.Error())
	}
	db.SetMaxOpenConns(100)
	db.SetMaxIdleConns(20)
}

func GetDB() *gorm.DB {
	return _db
}

到了这里,关于golang 分布式微服务DAO层构建的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Golang链路追踪:实现高效可靠的分布式系统监控

    在当今互联网应用的架构中,分布式系统已经成为主流。分布式系统的优势在于能够提供高可用性、高并发性和可扩展性。然而,随着系统规模和复杂性的增加,系统的监控和调试变得越来越困难。为了解决这个问题,链路追踪技术应运而生。 本文将介绍链路追踪的概念和原

    2024年02月08日
    浏览(41)
  • Golang实现Redis分布式锁解决秒杀问题

    先写一个脚本sql,插入2000个用户 登录是通过2个字段,一个是mobile,一个是password,生成了mobile从1到2000,密码默认是123456 然后写一个单元测试,实现新注册的2000个用户登录,然后获取token 我们使用有缓冲的通道和sync.WaitGroup信号量,来控制协程的数量,经过测试,发现limi

    2024年02月14日
    浏览(42)
  • 在CSDN学Golang分布式中间件(ElasticSearch)

    倒排索引是一种用于快速查找文本中特定单词或短语的数据结构。它将文本中的每个单词或短语与包含该单词或短语的文档列表相关联。这使得可以轻松地查找包含给定单词或短语的所有文档。 在 Go 中,可以使用 map 和 slice 来实现倒排索引。具体来说,可以使用一个 map 将每

    2024年02月15日
    浏览(47)
  • 一键构建分布式云原生平台

    🏆作者简介: 哪吒 ,CSDN2022博客之星Top1、CSDN2021博客之星Top2、多届新星计划导师✌、博客专家💪 , 专注Java硬核干货分享,立志做到Java赛道全网Top N。 🏆本文收录于 Java基础教程系列(进阶篇) ,本专栏是针对大学生、初级Java工程师精心打造, 针对Java生态,逐个击破,

    2023年04月17日
    浏览(39)
  • 华为云分布式云原生UCS,助力MetaERP构建企业级高可用分布式业务

    本文分享自华为云社区《华为云分布式云原生UCS,助力MetaERP构建企业级高可用分布式业务》,作者:云容器大未来。 华为云最近成为《Forrester Wave™: Multicloud Container Platforms, Q4 2023》报告中唯一入选的中国厂商,市场表现强劲。华为云分布式云原生 UCS 作为本次参评的关键服

    2024年02月03日
    浏览(40)
  • 使用Docker构建分布式应用程序

    作者:禅与计算机程序设计艺术 Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的Linux或Windows机器上,也可以实现虚拟化。 传统的应用分为三层结构:应用运行环境、应用逻辑和资源管理,Doc

    2024年02月08日
    浏览(79)
  • 使用Spring Cloud构建分布式应用

    Spring Cloud是一组构建分布式系统的框架,它提供了各种工具和库,帮助开发人员构建高可用、可伸缩、灵活的分布式应用程序。本文将介绍如何使用Spring Cloud构建分布式应用程序。 微服务架构 Spring Cloud是基于微服务架构设计的,该架构将应用程序划分为一组小型、自治的服

    2024年02月06日
    浏览(72)
  • 在CSDN学Golang场景化解决方案(EFK分布式日志系统方案)

    在 Golang EFK 分布式日志系统方案中,ElasticSearch 是一个分布式搜索引擎和数据存储库,它可以用于存储和搜索大量的日志数据。以下是 ElasticSearch 分布式集群部署的步骤: 下载 ElasticSearch:从 ElasticSearch 官网上下载最新版本的 ElasticSearch。 解压缩并安装 ElasticSearch:将下载下来

    2024年02月14日
    浏览(44)
  • 【golang项目-GeeCache】动手写分布式缓存 day1 - 实现LRU算法

    【go项目-geecache】动手写分布式缓存 - day1 - 实现LRU算法 【go项目-geecache】动手写分布式缓存 - day2 - 单机并发缓存 【go项目-geecache】动手写分布式缓存 - day3 - HTTP 服务端 【go项目-geecache】动手写分布式缓存 - day4 - 一致性哈希(hash) 【go项目-geecache】动手写分布式缓存 - day5 - 分布

    2023年04月20日
    浏览(39)
  • golang/云原生/Docker/DevOps/K8S/持续 集成/分布式/etcd 教程

    3-6个月帮助学员掌握golang后端开发岗位必备技术点 教程时长: 150+小时 五大核心专栏,原理+源码+案例分析+项目实战直击工作岗位 golang:解决go语言编程问题 工程组件:解决golang工程化问题 分布式中间件:解决技术栈单一及分布式开发问题 云原生:解决云原生分布式部署及监

    2024年02月07日
    浏览(76)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包