自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(64)
  • 收藏
  • 关注

原创 RPC 原理详解

RPC(Remote Procedure Call),即远程过程调用,它允许像调用本地服务一样调用远程服务。是一种服务器-客户端(Client/Server)模式。远程:指的是需要经过网络的,而不是应用内部、机器内部进行的。过程:也就是方法。可以跨过一段网络,调用另外一个网络节点上的方法。以上就是对远程过程调用的简单理解。同步调用:客户方等待调用执行完成并返回结果。异步调用:客户方调用后不用等待执行结果返回,但依然可以通过回调通知等方式获取返回结果。

2023-11-03 18:31:22 1377

原创 MySQL逻辑架构

首先我们需要了解在 InnoDB 存储引擎中,缓冲池都包括了哪些。在 InnoDB 存储引擎中有一部分数据会放到内存中,缓冲池则占了这部分内存的大部分,它用来存储各种数据的缓存,如下图所示:从图中,你能看到 InnoDB 缓冲池包括了数据页、索引页、插入缓冲、锁信息、自适应 Hash 和数据字典信息等。缓存池的重要性:缓存原则:位置 * 频次”这个原则,可以帮我们对 I/O 访问效率进行优化。首先,位置决定效率,提供缓冲池就是为了在内存中可以直接访问数据。其次,频次决定优先级顺序。

2023-10-13 21:47:33 1156 2

原创 MySQL存储引擎

MySQL从3.23.34a开始就包含InnoDB存储引擎。大于等于5.5之后,默认采用InnoDB引擎。InnoDB是MySQL的 默认事务型引擎 ,它被设计用来处理大量的短期(short-lived)事务。可以确保事务的完整提交(Commit)和回滚(Rollback)。除非有非常特别的原因需要使用其他的存储引擎,否则应该优先考虑InnoDB引擎。表名.frm:存储表结构(在MySQL8.0时,合并到表名.ibd中)表名.ibd:存储数据和索引InnoDB是 为处理巨大数据量的最大性能设计。

2023-10-13 21:46:05 241

原创 在Gin框架中加入Zap日志中间件

在使用gin.Default()的同时是用到了gin框架内的两个默认中间件Logger()和Recovery()。所以我们可以模仿Logger()和Recovery()的实现,使用我们的日志库来接收gin框架默认输出的日志。这样就能在gin框架中使用我们上面定义好的两个中间件来代替gin框架默认的Logger()和Recovery()了。这样只需要在main.go文件中导入Logger()函数,那么就实现了Gin框架中使用Zap日志了。

2023-10-12 20:10:48 534

原创 日志管理工具Zap笔记

以上就是Zap库的基本使用。Zap提供了两种类型的日志记录器:Sugared Logger和Logger。对于性能要求不是非常高的应用可以使用Sugared Logger。相比于Logger,Sugared Logger提供了printf风格的日志记录。对于性能要求非常高的应用需要使用Logger来保证性能。不管是Logger还是Sugared Logger,它们都有三个预制化的日志:zap.NewProduction()、zap.NewDevelopment()和zap.Example()。

2023-10-12 17:12:33 263

原创 validator库的使用详解

在做API开发时,需要对请求参数的校验,防止用户的恶意请求。例如日期格式,用户年龄,性别等必须是正常的值,不能随意设置。以前会使用大量的if判断参数的值是否符合规范,现在可以使用validator库来进行参数校验。我们只需要在结构体的Tag中添加validator标签就可以实现参数校验。同时Gin框架当前内部也集成了validator.v10这个库,在Gin框架中只要在结构体的Tag中添加binding标签就可以实现参数校验。

2023-10-11 21:08:39 752

原创 Swagger-go学习笔记

在前后端分离的项目开发过程中,如果后端开发人员能够提供一份清晰明了的接口文档,那么就能极大地提高前后端开发人员的沟通效率和开发效率。可是编写接口文档历来都是令人头痛的,而且后续接口文档的维护也十分耗费精力。最好是有一种方案能够既满足我们输出文档的需要又能随代码的变更自动更新,而Swagger正是那种能帮我们解决接口文档问题的工具。

2023-10-10 18:20:24 353

原创 Docker Compose

对于现代应用来说,大多都是通过很多的微服务互相协同组成的一个完整应用。例如,订单管理、用户管理、品类管理、缓存服务、数据库服务等,它们构成了一个电商平台的应用。而部署和管理大量的服务容器是一件非常繁琐的事情。而 Docker Compose 就是解决这类问题的。Docker Compose 是一个需要在 Docker 主机上进行安装的 Docker 容器编排外部工具。

2023-09-21 10:39:54 314

原创 go-redis 框架基本使用

使用事务后,Redis会按照命令的顺序执行这些命令,并且在执行过程中不会立即返回结果,只有在所有命令都执行完毕后,才会一次性返回所有命令的执行结果。使用流水线就是将多个执行的命令放入 pipeline 中,然后使用1次读写操作就像执行单个命令一样执行它们,就相当于把多个命令打包,然后一起发送给redis服务器,让redis服务器一次性执行完毕。我们需要一个函数,可以安全地减少用户的积分。这段代码的目的是监视用户的当前积分,如果在事务执行过程中,其他客户端改变了这个键的值(也就是用户的积分),那么。

2023-09-19 16:40:44 448 1

原创 docker 安装 redis

在/root 中 mkdir 一个名称为 cluster 的目录,并将前面的配置文件/root/redisSave/redis.conf复制到这里。此时,再查看另外两个 redis 容器的状态数据,发现 redis-slave1 成为了 redis-slave2 的 slave,即 redis-slave2 成为了新的 master。对于该启动命令需要注意的是,其后面运行的命令为 redis-server,且加载的配置文件为挂载点目录/etc/redis 中的 redis.conf。

2023-09-17 21:34:58 591

原创 docker 网络(单机环境)

先来看看那种比较正式的定义。Namespace是将内核的全局资源做封装,使得每个Namespace都有一份独立的资源,因此不同的进程在各自的Namespace内对同一种资源的使用不会互相干扰。这样的解释可能不清楚。举个例子:在Linux系统上,你想要改变系统的主机名,这个主机名就是一个内核的全局资源。但是内核通过实现UTS Namespace,可以将不同的进程分隔在不同的UTS Namespace中,在某个Namespace修改主机名时,另一个Namespace的主机名还是保持不变。

2023-09-16 15:02:35 552

原创 docker 数据持久化

数据卷是宿主机中的一个特殊的文件/目录,这个文件/目录与容器中的另一个文件/目录进行了直接关联,在任何一端对文件/目录的写操作,在另一端都会同时发生相应变化。在宿主中的这个文件/目录就称为数据卷,而容器中的这个关联文件/目录则称为该数据卷在该容器中的挂载点。数据卷的设计目的就是为了实现数据持久化,其完全独立于容器的生命周期,属于宿主机文件系统,但不属于 UnionFS。因此,容器被删除时,不会删除其挂载的数据卷。

2023-09-15 20:06:23 282

原创 Dockerfile详解

然后使用docker history test:1.0和docker history test:2.0这两条命令查看它们每层的镜像ID,会发现test1.0和test:2.0的前五个镜像层的ID一模一样,这也说明了test:2.0的镜像在构建过程中复用了test:1.0的镜像层。Dockerfile 文件内容没有变化,但 RUN 命令的外部依赖发生了变化,例如本例中要安装的 vim 软件源发生了变更(版本变化、下载地址变化等),那么从发生变化的这个指令层开始的所有镜像层 cache 全部失效。

2023-09-13 09:48:15 509

原创 CMD 命令和 ENTRYPOINT 命令的区别

Dockerfile的命令命令是否可以被覆盖是否可以添加选项CMD cal可以被覆盖不能添加选项,添加选项后会报错可以被覆盖不能添加选项,添加选项后会报错不可以被覆盖,添加的命令会被忽略不能添加选项,添加的选项被忽略不可以被覆盖,添加命令后会报错可以添加选项不可以被覆盖,添加的命令会被忽略不能添加选项,添加的选项被忽略在总结之前先来看看docker run命令的语法:可以看到:IMAGE的后面是可以接命令和参数的,但命令和参数并不是必须的,所以用 [ ] 括起来了。

2023-09-12 08:44:26 142

原创 docker容器详解

Docker容器运行的本质是运行一个进程,该进程在其自己的隔离环境中运行,该环境由Linux内核的特性(如cgroups和namespaces)提供。Docker 容器存在的意义就是为了运行容器中的应用,对外提供服务,所以启动容器的目的就是启动运行该容器中的应用。容器中的应用运行完毕后,容器就会自动终止。所以,如果不想让容器启动后立即终止运行,则就需要使容器应用不能立即结束。通常采用的方式有两种,使应用处于与用户交互的状态或等待状态。下面以tomcat镜像为例,进行容器的相关操作。

2023-09-11 10:32:51 356

原创 docker镜像详解

Docker镜像是Docker容器的基础组件,它包含了运行一个应用程序所需的一切,包括代码、运行时环境、系统工具、库和依赖等。Docker镜像的本质,可以分为以下几个方面来解释。文件系统层:Docker镜像是由多个文件系统层(Filesystem Layers)组成的。每个层都是只读的,并且包含了文件和目录的变更。这种分层的文件系统结构使得镜像的构建和复用变得非常高效。每个层只需要存储差异部分,大大减小了镜像的体积。只读性:Docker镜像是只读的,一旦创建就不能被修改。

2023-09-10 15:07:09 1194

原创 初识docker

现在的服务器都牛的很,动不动128G内存,24个CPU,Linux本身就是个多租户的操作系统,可以多人共用,但是如果某个程序狂吃内存和CPU,占用了太多系统资源,这就会影响其他程序的运行。但是云主机提供商呢?不同的用户之间不认识,共用一台强大的计算机,结果某个程序耗尽了资源,其他用户肯定不乐意了。相对虚拟机的重量级虚拟化方案,Linux内核级的一些隔离方案让人们看到了希望,cgroups、namespace、tc、quota、chroot、lxc,终于,Docker出现了,Docker利用这些成熟的技术。

2023-09-09 10:04:56 605 1

原创 Lua 脚本语法学习

例如,如果要为一个 table 扩展加号(+)运算功能,则可重写该 table 元表的__add 元方法,而具体的运算规则,则是定义在该重写的元方法中的。由于协同函数的本质就是函数,所以协同函数的调用方式就是标准的函数调用方式。从 Lua 5.1 开始,Lua 加入了标准的模块管理机制,可以把一些公用的代码放在一个文件里,以 API 接口的形式在其他地方调用,有利于代码的重用和降低代码耦合度。table.maxn(table)该函数返回指定 table 的数组中的最大索引值,即数组包含元素的个数。

2023-06-17 14:37:08 3601

原创 GORM---高级查询

数据表Users表:Email表:子查询是指一个查询语句嵌套在另一个查询语句内部的查询,内部的查询是外部查询的条件。运行结果如下:由于平均年龄需要计算,所以内层的SELECT语句的作用是为了得到平均年龄(connect.DB.Table(“users”).Select(“AVG(age)”)),外层的SELECT语句的作用就是条件判断。运行结果如下:虽然这个子查询的例子的实际意义不大,但实在是想不出什么好的例子了。首先subQuery变量存储的是内层SELECT语句的查询结果,就是查询在users表中

2023-06-13 18:09:16 1359

原创 Redis 分布式集群操作

可以将新的节点添加到系统中。添加成功后,通过 redis-cli -c -p 6386 cluster nodes 命令可以看到其它 master 节点都分配有 slot,只有新添加的 master 还没有相应的 slot。可以看到当写入name的时候redis会去计算name的hash值,hash值为5798,对应节点的端口号为6381,于是自动重定向到6381的节点上存储数据。需要添加两个新的节点:端口号为 6386 的节点为 master节点,其下会有一个端口号为 6387 的 slave 节点。

2023-06-13 14:42:10 1197

原创 分布式系统常见的数据分区算法

带有限负载的一致性哈希算法也有一个问题,那就是每台服务器的性能配置可能存在不一样,如果规定数量过小的话,对于配置高的服务器来说有点浪费,这是因为服务器之间可能存在差异,叫做服务器之间的异构性,为了解决服务器之间的异构性问题,引入了一种叫做带虚拟节点的一致性哈希算法,带虚拟节点的一致性哈希算法核心思想是:根据每个节点的性能为每个节点划分不同数量的虚拟节点,即。然后选取数据本身或可以代表数据特征的数据的一部分作为 key,计算 hash(key)与节点数量 N 的模,该计算结果即为该数据的存储节点的序号。

2023-06-10 12:09:15 1094 1

原创 Go项目配置管理工具---Viper

命令行参数环境变量配置文件显然,对于Go项目而言,单个去读取命令行、环境变量、配置文件并不难,但一个个读取却是很麻烦,有没有一个第三方库可以帮我们一次性读取上面几种数据源的配置呢?有的,就是使用 viper 库,viper支持读取不同数据源和不同格式的配置文件,是Go项目读取配置的神器。

2023-06-09 09:22:20 2884 6

原创 GORM---初级查询

如果FirstOrCreate方法不能找到相应的记录,则底层会使用insert的SQL语句创建一条记录,并添加Attrs方法设置的属性到新纪录中。在使用FirstOrInit这个方法的大前提下,不管怎么写,都不会把返回的数据插入到数据库,因为FirstOrInit这个方法只是用来做查询操作。根据给定的条件初始化一个新的对象 (仅支持 struct 和 map 查询条件),从数据库中查询符合条件的记录,如果找到了,则返回该记录;如果没有找到,则创建一条新的数据记录,并将其保存到数据库中。

2023-06-06 13:49:21 692

原创 GORM---创建

使用 CreateInBatches()方法。该方法可以一次性将多条数据记录批量插入到数据库中,从而提高插入数据的效率。CreateInBatches 方法的用法与 Create 方法基本相同,只是需要传入一个额外的参数,表示每批次插入的数据记录数量。使用CreateInBatches方法的好处就是CreateInBatches方法能够保证原子性,如果其中一条数据插入失败,则整个插入操作都会进行回滚。

2023-06-04 14:39:59 1663

原创 五种经典IO模型详解

信号驱动的 I/O 模型是一种异步 I/O 模型,它允许应用程序在等待 I/O 操作完成时继续执行其他任务。在这种模型中,当应用程序发起一个 I/O 操作时,它并不会一直等待操作完成。相反,它会注册一个信号处理程序,该处理程序在 I/O 操作完成时被调用。这意味着,当 I/O 操作完成时,内核会发送一个信号告知应用程序,应用程序可以在信号处理程序中获取 I/O 操作的结果。信号驱动的 I/O 模型适用于大量的 I/O 操作,因为它可以同时处理多个 I/O 操作,而不必等待一个操作完成后才开始下一个操作。

2023-06-02 20:14:34 972 2

原创 IO多路复用详解

在IO多路复用模型中,引入了一种新的系统调用,查询IO的就绪状态。在Linux系统中,对应的系统调用为select/poll/epoll系统调用。通过该系统调用,一个进程可以监视多个文件描述符,一旦某个描述符就绪(一般是内核缓冲区可读/可写),内核能够将就绪的状态返回给应用程序。随后,应用程序根据就绪的状态,进行相应的IO系统调用。在IO多路复用模型中通过select/poll/epoll系统调用,单个应用程序的线程,可以不断地轮询成百上千的socket连接,当某个或者某些socket网络连接有IO就绪的状

2023-05-30 10:55:17 1283

原创 修改线程栈的大小

如果栈太大会影响程序性能,如果栈太小可能会发生溢出,溢出会触发异常,操作系统会调用异常处理程序解决溢出,异常处理程序会进行栈扩展。想要改变默认线程栈的大小,但又不想自己手动处理线程栈的分配问题,使用pthread_attr_getstacksize函数和pthread_attr_setstacksize函数就非常方便,短短几行代码就能实现。接着调用pthread_create()创建线程,该线程打印自己线程栈的大小,完毕后调用 pthread_attr_destroy()来销毁属性对象。

2023-05-23 16:26:57 1199

原创 哨兵机制原理详解

当Sentinel通过频道信息发现一个新的Sentinel时,它不仅会为新Sentinel创建相关记录信息,还会创建一个连向新Sentinel的命令连接,而新Sentinel也同样会创建连向这个Sentinel的命令连接,最终监视同一master的多个Sentinel将形成相互连接的网络。在 Sentinel 的配置文件中有 master 的IP和端口号,所以 Sentinel 在初始时是知道 master 节点的位置,于是 Sentinel 可以向 master 建立命令连接和订阅连接。

2023-05-20 17:38:53 1082

原创 Redis 哨兵模式的实现详解

哨兵模式是Redis的高可用方式,哨兵节点是特殊的redis服务,不提供读写服务,主要用来监控所有的redis节点。哨兵架构下client端第一次从哨兵找出redis的主节点,后续就直接访问redis的主节点,不会每次都通过sentinel代理访问redis的主节点,当redis的主节点挂掉时,哨兵会第一时间感知到,并且在slave节点中重新选出来一个新的master,然后将新的master信息通知给client端,从而实现高可用。

2023-05-18 22:27:37 2199 5

原创 Redis---订阅和发布

​ 消息系统中的订阅者订阅了某类消息后,只要存储系统中存在该类消息,其就可不断的接收并消费这些消息。而 Redis 构成的消息系统中,发布/订阅的消息都是以频道 Channel 分类的。​ Redis的发布与订阅功能可以让客户端通过广播方式,将消息(message)同时发送给可能存在的多个客户端,并且发送消息的客户端不需要知道接收消息的客户端的具体信息。说明:如果没有频道被指定,也就是一个无参数的 UNSUBSCRIBE 命令被执行,那么客户端使用 SUBSCRIBE 命令订阅的所有频道都会被退订。

2023-05-14 16:55:14 1563

原创 Redis的主从集群搭建与配置

如果真需要设置,一定要每个主机的密码都设置为相同的。集群中的 Master 节点负责处理客户端的读写请求,而 Slave 节点仅能处理客户端的读请求。如果其原本就有下一级的 Slave,那么,其就直接变为了这些 Slave 的真正的 Master 了。​ Nagle 算法的工作原理是,网络在接收到要发送的数据后,并不直接发送,而是等待着数据量足够大(由 TCP 网络特性决定)时再一次性发送出去。不过,上一级 Slave 的状态仍为 Slave,只不过,其是更上一级的 Slave。

2023-05-11 21:50:54 863

原创 AOF 持久化详解

是把所有对内存进行修改的指令(写操作)以独立日志文件的方式进行记录,重启时通过执行 AOF 文件中的 Redis 命令来恢复数据。

2023-05-09 22:19:09 2221 1

原创 RDB 持久化详解

Redis 是内存数据库,数据都是存储在内存中,为了避免进程退出导致数据的永久丢失,需要定期将 Redis 中的数据以某种形式(数据或命令)从内存保存到硬盘。当下次 Redis 重启时,利用持久化文件实现数据恢复。除此之外,为了进行灾难备份,可以将持久化文件拷贝到一个远程位置。Redis 的持久化机制有两种:RDB(Redis Data Base) 内存快照AOF(Append Only File) 增量日志。

2023-04-27 16:29:02 1324

原创 Redis---事务

因为Redis的事务在EXEC命令执行之前并不会产生实际效果,所以很多Redis客户端都会使用流水线去包裹事务命令,并将入队的命令缓存在本地,等到用户输入EXEC命令之后,再将所有事务命令通过流水线一并发送至服务器,这样客户端在执行事务时就可以达到“打包发送,打包执行”的最优效果。此后客户端 B 对该 key 的值进行了修改,这个修改不仅修改了 key 的 value 本身,同时也增加了 version 的值,例如使其 version 变为了 2.0,并将该 version 记录到了该 key信息中。

2023-04-25 19:50:26 84

原创 GDB的基本使用

fp: 帧指针(当前堆栈帧)$pc: 程序计数器。$ps: 处理器状态。

2023-04-18 16:34:47 261

原创 Redis---基准测试

在Redis安装完毕后会自动安装一个redis-benchmark测试工具,是一个压力测试工具,模拟 N 个客户端同时发出 M 个请求,用于测试 Redis 的性能。使用 redis-benchmark --help 来查看基准参数。当以下值为默认值的时候,则可以省略。序号选项描述默认值1-h指定服务器主机名。127.0.0.12-p指定服务器端口63793-s指定服务器 socket4-c指定并发连接数505-n指定请求数1000006-d。

2023-04-16 17:31:30 426

原创 关于Go语言的json技巧

Go语言内置的 json 包使用 RFC3339 标准中定义的时间格式,对我们序列化时间字段的时候有很多限制。= nil {也就是内置的json包不认识我们常用的字符串时间格式,如 2023-04-10 00:00:01。时间类型字段的 JSON 序列化和反序列化,但是我认为这种方法并不是很实用。其实如果真的遇到前端传递过来的非标准的时间字段(像"2023-04-10 00:00:01"),办法就是定义两个结构体,第一个结构体的时间类型为string,第二个结构体的时间类型为Time。

2023-04-15 19:28:43 122

原创 Redis---有序集合

Redis 有序集合和集合一样也是 string 类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。有序集合的成员是唯一的,但分数(score)却可以重复。对于相同分数的成员会按照字母序的顺序进行排序。集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。

2023-04-13 18:00:53 858

原创 Redis---集合

Redis 存储数据的 Value 可以是一个 Set 集合,且集合中的每一个元素均 String 类型。Set与 List 非常相似,但不同之处是 Set 中的元素具有无序性与不可重复性,而 List 则具有有序性与可重复性。集合对象的编码可以是 intset 或者 hashtable。集合中最大的成员数为 232- 1 (4294967295, 每个集合可存储40多亿个成员)。

2023-04-10 17:19:05 947

原创 Go语言的omitempty选项

在使用Golang的时候,不免会使用Json和结构体的相互转换,这时候常用的就是和两个函数。这时候在定义json结构体的时候,我们会用到这个字段,这个字段作用就是,看似简单,但是却有很多小坑,这篇文章带你稍微研究一下他的用途和功能。omit:v. 删除;忽略;漏掉;遗漏;不做;未能做;adj. 省略了的;省去的;

2023-04-10 08:34:44 1585

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除