什么是分库分表分库:按照一定的规则将数据分到多个苦中,主要解决单个库连接并发过多,单机数据库顶不住压力的问题分表:将单个数据库里的某一张表,按照某个规则分为多张表,主要解决单张表数据过多的问题,减轻单表压力怎么分分库按业务不同来分,专库专用,微服务使用数据库的场景就是典型代表分表将字段较多的表,拆分成多个表,就是大表拆分成多个小表。访问次数频繁的字段拆分至核心表,数据库加载数据时会更多只加载核心表数据到内存中,减少磁盘IO,提高性能将一张表按一定的规则(简单的有哈希)切分成多个结构相同的表,按照规则来存储/读取数据,切分出来的每张表只储存原表的一部分数据。能够解决单表数据量过大。还可以将切分的表存放至不同的库中,实现分布式,进一步提高性能Go中可以如何实现在代码中实现,如repo层/data层中手动对传入的参数进行计算,侵入性比较强,但是调试方便ORM框架中使用中间件,由中间件来解析语句并计算,应用代码中无感,如GORM的Sharding在应用于数据库中加一层代码,由数据库代理来实现,类似第二种方案,只不过是外部中间件完成
使用kratos自带http transport实现文件下载上传功能,并且可以使用中间件。文件的下载接口可以使用proto定义,上传目前还未找到完美方法,为了统一,采用不定义在proto中定义,自行在server中实现。为什么上传接口不能使用proto定义?上传接口实际上可以使用proto定义,但是在解析入参时是不能解析上传的字节类型,入参的Content-Type类型只支持: x-www-form-urlencoded、json、xml、proto、yaml,而上传文件我希望以只读字节流readCloser的方式,这样可以方便使用io.Copy()的方式实现上传,而不是将文件数据转换成[]byte进行传输看一段官方的实现方式原代码 · GitHub,已简化。func downloadFile(ctx http.Context) error { f := excelize.NewFile() return f.Write(ctx.Response()) } func main() { var opts = []http.ServerOption{
限流限制某服务在一段时间可以被调用的频率。一般用于防止客户端请求过多,导致服务端拥堵的手段,也是防止ddos的一种手段。常用限流算法有三种:滑动限流漏斗限流令牌桶限流time/rate是官方实现的令牌桶算法限流器Go官方限流time/rate安装go get golang.org/x/time/rate构造限流器相关函数type Limit float64 func Every(interval time.Duration) Limit { if interval <= 0 { return Inf } return 1 / Limit(interval.Seconds()) } func NewLimiter(r Limit, b int) *Limiter { return &Limiter{ limit: r, burst: b, } }NewLimiter有两个参数:第一个是填充令牌的速度,默认已秒为单位。如r=10,则说明这个限流器会每秒填充10个令牌。第二个是为桶的容
默认环境:debian11、go1.20。创建文件Dockerfile,写入一下内容FROM golang:1.20.4 MAINTAINER cdx cdxccx@outlook.com ENV password="root" RUN echo 'root:$password' |chpasswd RUN apt update && \ apt-get install -y openssh-server && \ apt clean && \ rm -rf /tmp/* /var/lib/apt/lists/* /var/tmp* && \ echo "PermitRootLogin yes" >> /etc/ssh/sshd_config && \ echo "export PATH=/usr/local/go/bin:$PATH" >> /root/.bash
知识小点常量创建整数常量时,不管多长的数字,精度都不会丢失,因为它是“常量”基础类型基础类型包括:数字类型、布尔类型、字符类型。比较在go中必须是两个类型相同的值才可以比较,接口则需要也实现了相应的接口才可比较。如果其中一个是常量,则需要和常量能兼容的类型才可以比较。如果都不满足,则需要转换成相同类型才可以比较。值类型与引用类型int、float、bool、string这些基本类型属于值类型,数组和结构也属于值类型,这些的变量直接指向内存中的值。 指针、切片、map、chan为引用类型,引用类型储存的是值所在的内存地址,或者内存地址中第一个值所在的位置,内存地址又称为指针。当引用类型被使用=进行复制时,是对内存地址的复制,并非值的复制,当修改其中一个的值时,也会改变另一个变量的值。不管是值类型还是引用类型,都可以使用&进行取地址。内存逃逸分析栈空间:系统自己申请和释放堆空间:程序员自己申请和释放,在go中由GC搞定go build -gcflags=-m 可以检查代码的编译优化情况,包括逃逸情况和函数是否内联指针逃逸指针是指向堆中的指针,此时会发生逃逸到堆上栈空间不足局部变量下,编译