自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 Go语言日志log和zaplog

Go语言内置的log包实现了简单的日志服务。本包也提供了一个预定义的“标准”logger,可以通过调用函数Print系列、Fatal系列、和Panic系列来使用,比自行创建一个logger对象更容易使用。Fatal系列用于输出一条致命错误信息,并调用 os.Exit(1) 终止程序运行。这个函数会在打印完错误信息之后立即调用 os.Exit 退出程序。

2024-05-19 23:37:00 744 1

原创 微服务框架Go-kit 01 - 基础示例

Go kit 是一个用于构建可扩展、灵活和可维护微服务的框架和工具集合。它提供了一系列库和组件,涵盖了微服务开发的各个方面,包括服务发现、负载均衡、通信、日志记录、请求跟踪、限流、熔断等。在 Go kit 中,将服务的业务逻辑封装到 Service 接口的实现中,然后通过 Endpoint 将外部请求转发到相应的 Service 方法。最后,通过 Transport 处理请求和响应的传输细节。

2024-05-16 22:48:03 422

原创 快速入门go语言学习笔记

快速入门go语言

2024-05-10 17:12:31 2198

原创 gRPC框架

这是一个使用 Protocol Buffers(protobuf)和 Go gRPC 插件生成代码的示例命令。该命令根据 proto/user.proto 文件生成对应的 Go 代码。最后会在proto目录下生成user.pb.go和user_grpc.pb.go。如果查不到指令,检查一下环境变量。实现服务端和客户端的数据传输。先执行服务端,再执行客户端。

2023-12-15 10:38:59 911

原创 git操作

什么是仓库呢?就是可以用git管理的一个目录,这个仓库里所有的文件的改动(增加/修改/删除)都由git跟踪记录。也能通过git查看所有的记录,当然也能够通过git“还原”到某个记录点。远端仓库的别名一般是:origin。

2023-12-09 10:12:14 1578

原创 Docker入门

纯物理服务器部署部署非常慢:购买服务器 --> 部署操作系统 --> 安装应用,这仅仅是对于一台服务器的流程。如果对于集群,有多台服务器,部署就会非常慢成本非常高:服务器成本高资源浪费:如果每台服务器的配置都比较高,但是仅仅运行一个应用程序。那就造成资源浪费难于迁移和扩展:迁移时候,需要把服务器的所有配置流程重新造作一边。可能会被限定硬件厂商:应用程序如果是运行在A操作系统,那怎么配置在具有B操作系统的服务器上很多时候,我们只想要一个单独的执行环境,而不需要费劲虚拟出一个完整的计算机。

2023-12-06 18:47:14 1155

原创 Ubuntu安装docker

ubuntu22.04版本下,安装docker

2023-12-06 11:14:23 1223

原创 Go操作MySQL

Go语言中的database/sql包提供了保证SQL或类SQL数据库的泛用接口,并不提供具体的数据库驱动。使用database/sql包时必须注入(至少)一个数据库驱动。

2023-11-28 23:23:02 392

原创 C++11的多线程、function和bind、可变函数模板

文章目录一、C++11多线程thread1.1 线程thread1.1.1 构造函数1.1.2 主要成员函数1.1.3 范例示范1.2 互斥量1.2.1 独占互斥量std::mutex1.2.2 范例1.2.3 lock_guard和unique_lock的使用和区别1.3 条件变量1.3.1 wait函数1.3.2 wait_for函数1.3.3 wait_until函数1.3.4 notify_one函数1.3.5 notify_all函数1.4 异步操作1.4.1 std::aysnc和std::fu

2023-09-07 13:45:55 313

原创 匿名函数lambda

在C++14之前,lambda表示的形参只能指定具体的类型,没法泛型化。本专栏知识点是通过的系统学习,进行梳理总结写下文章,对c/c++linux课程感兴趣的读者,可以点击链接,详细查看详细的。上面提到的值捕获、引用捕获都是已经在外层作用域声明的变量,因此这些捕获方式捕获的均为左值,而不能捕获右值。手动书写捕获列表有时候是非常复杂的,这种机械性的工作可以交给编译器来处理,这时候可以在捕获列表中写一个。1)采用值捕获的方式,lambda不能修改其值,如果想要修改,使用mutable修饰。

2023-09-07 13:45:23 283

原创 C++新特性:右值引用,移动语义,完美转发

1)左值可以取地址、位于等号左边;2)而右值没法取地址,位于等号右边。例如int a = 6;1)a可以通过 & 取地址,位于等号左边,所以a是左值。2)6位于等号右边,6没法通过 & 取地址,所以6是个右值。又例如struct A {a_ = a;int a_;A a = A();1)同样的,a可以通过 & 取地址,位于等号左边,所以a是左值。2)A()是个临时值,没法通过 & 取地址,位于等号右边,所以A()是个右值。

2023-09-07 13:44:42 186

原创 C++新特性:智能指针

智能指针主要解决以下问题:1)内存泄漏:内存手动释放,使用智能指针可以自动释放2)共享所有权指针的传播和释放,比如多线程使用同一个对象时析构问题,例如同样的数据帧,但是业务A和业务B处理的逻辑不一样(都是只读)。可以用shared_ptr共享数据帧对象的所有权。线程A释放的时候,shared_ptr的引用计数count - 1,当为0的时候释放数据帧对象指针。主要类型:C++里面的四个智能指针:auto_ptrshared_ptrunique_ptrweak_ptr。

2023-09-07 13:44:00 1955

原创 图床项目性能测试

两两匹配可以调换顺序,比如(user,urlmd5)可以和(urlmd5,user)匹配,但是一个不行。本专栏知识点是通过的系统学习,进行梳理总结写下文章,对c/c++linux课程感兴趣的读者,可以点击链接,详细查看详细的。建立20个TCP连接,使用两个线程,用时20秒,对http://192.168.1.34进行压测。小规模测试的时候,建议一台客户端机器只模拟一个客户端 ./test_upload.sh 1。具体来说,进入fastdfs安装目录,进入test目录下,进行make。

2023-09-07 13:42:36 270

原创 图床项目数据库表设计

share_picture_list 和 share_file_list 类似,只是 share_picture_list 只存储共享图片相关的信息,及分享给未注册用户看的。share_file_list 是存储共享文件(包括图片文件)相关的信息,分享给已注册用户的。

2023-09-07 13:41:46 160

原创 图床项目详解

实现一个能够上传、存储、分享图片的后端项目。1)上传:上传文件,并且如果上传的文件在数据库中有记录,即md5匹配,则实现秒传效果。2)分享(共享)文件:共享文件给其他已注册的用户。其他注册用户可以在 “共享文件–>文件列表” 中看到共享的文件,并且可转存到自己的文件列表或者下载。同样在自己的 “共享文件–>文件列表”中,可以查看共享文件的信息,也可以取消共享若取消共享,除非其他用户已经转存,否则就看不到。

2023-09-07 13:41:10 690

原创 FastDFS介绍

FastDFS(Fast Distributed File System)是一个开源的分布式文件系统,它旨在提供高性能、高可靠性和可扩展性的文件存储解决方案,解决海量数据存储问题。其主要的功能包括:文件存储,同步和访问。特别适合以中小文件(建议范围:4KB < file_size

2023-09-07 13:40:00 485

原创 协程框架NtyCo的实现

讨论协程之前,我们需要先了解。在通过 accept 建立服务端与客户端的连接之后,需要行读写操作,也就是 handel 函数。根据同步和异步,有两种不同的处理方式。同步的处理方式异步的处理方式可见,同步和异步主要区别在于对于 handle 函数的处理。同步在需要等待 handle 函数处理完成,主循环才能继续执行,阻塞了 epoll_wait。而异步是单独为 handle 函数创建一个线程异步处理,主循环不需要等待 handle 函数。但是问题在于线程的创建、销毁,十分消耗资源。

2023-08-20 20:34:24 302

原创 从零实现kv存储V2.0

在,我们实现了基于array的kv存储引擎。本文继续完善,增加rbtree、hash、skiptable引擎。实际上,在框架确定的基础上,其他的引擎只需要添加接口即可。

2023-08-16 00:04:28 326

原创 从零实现kv存储V1.0:array初版

本节开始,逐步实现基于内存的kv存储引擎。

2023-08-14 20:44:46 367 1

原创 MySQL缓存策略

接下来,我们介绍几种提高MySQL访问性能的方式。

2023-08-11 14:32:45 572

原创 MySQL 事务原理:锁机制

锁机制用于管理对共享资源的并发访问,实现事务的隔离级别。

2023-08-08 20:06:09 380

原创 MySQL 事务原理:事务概述、隔离级别、MVCC

事务:并发连接场景下,用户定义的一个操作序列。这些操作要么都做,要么都不做,是一个不可分割的工作单位。MySQL的事务就是将多条SQL语句作为整体进行执行。1)事务的目的:事务将数据库从一种一致性状态转换为另一种一致性状态;保证系统始终处于一个完整且正确的状态。2)事务的组成:事务可由一条非常简单的 SQL 语句组成,也可以由一组复杂的SQL 语句组成。3)事务的特征:在数据库提交事务时,可以确保要么所有修改都已经保存,要么所有修改都不保存。事务是访问并更新数据库各种数据项的一个程序执行单元。

2023-08-08 11:34:00 315

原创 MySQL索引原理以及SQL优化

有时候需要索引很长的字符串,这会让索引变的大且慢,通常情况下可以使用某个列开始的部分字符串,这样大大的节约索引空间,从而提高索引效率,但这会降低索引的区分度,索引的区分度是指不重复的索引值和数据表记录总数的比值。它的作用是采用 LRU 算法将最常用的数据页(热点数据)保留在内存中,以减少对磁盘IO的需求。数据页内包含用户记录,每个记录之间用单向链表的方式组织起来,为了加快在数据页内高效查询记录,设计了一个页目录,页目录存储各个槽(分组),且主键值是有序的,于是可以通过二分查找法的方式进行检索从而提高效率。

2023-08-07 10:13:02 162

原创 MySQL操作命令详解:增删改查

它的作用是告诉 MySQL 解析器在遇到指定的分隔符时,将整个语句作为一个整体进行处理,而不会将其中的分号视为语句的结束。ANY 关键字:允许创建一个表达式,对子查询的返回值列表,进行比较,只要满足内层子查询中的,任意一个比较条件,就返回一个结果作为外层查询条件。2)安全:使用视图的用户只能访问他们被允许查询的结果集,对表的权限管理并不能限制到某个行某个列,但是通过视图就可以简单的实现。1)简单:使用视图的用户完全不需要关心后面对应的表的结构、关联条件和筛选条件,对用户来说已经是过滤好的复合条件的结果集。

2023-08-03 22:11:39 1178

原创 MySQL概述与体系结构

所谓的数据库,是指按照数据结构来组织、存储和管理数据的仓库;是一个长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合。之前我们了解了redis,本节开始介绍Mysql。MySQL和Redis是两种不同类型的数据库,它们有以下几个主要区别:1)数据库类型:MySQL是一种关系型数据库(RDBMS),而Redis是一种非关系型数据库(NoSQL)。关系型数据库使用表格来存储数据,而非关系型数据库使用键值对、文档、列族等方式来组织数据。

2023-08-03 22:11:12 390

原创 Redis 高可用:主从复制、哨兵模式、集群模式

1、高可用是分布式的概念。Redis的高可用性是指在Redis集群中,当主节点宕机了,通过切换备用节点顶替它继续运行,保持系统正常运行且数据可靠性不受影响。1)避免单点故障:通过配置和设置多个Redis节点,如果其中一个节点发生故障,其他节点可以接替工作,避免了单点故障对整个系统的影响。2)数据冗余和复制:通过数据的复制和持久化备份,Redis能够在主节点出现故障时,自动切换到备用节点,并恢复数据,确保数据的持久性和可用性。

2023-08-01 10:54:01 600

原创 redis 淘汰策略和持久化

AOF优点:数据可靠,丢失较少。持久化鬼哟踩代价较低(只记录写命令)。缺点:AOF文件过大,数据恢复慢。优点:RDB文件小,数据恢复快。缺点:数据一旦丢失,则丢失的数据量比较多。且持久化过程代价比较高(记录内存所以数据)。优点:充分利用 RDB 和 AOF 持久化各自的优点,以提供更好的数据安全性和快速恢复能力缺点:带来额外的存储空间占用和性能开销,因为需要同时维护 RDB 文件和 AOF 文件。

2023-07-30 21:57:22 420

原创 redis 存储原理与数据模型

然而,如果直接使用KEYS命令获取所有键,会对性能产生严重影响,因为KEYS命令会阻塞其他操作,并且在数据集较大时,返回所有键也会消耗大量内存。经过证明,当数据量足够大(256)时,通过概率构造的跳表趋向于理想跳表,并且此时如果删除节点,无需重构跳表结构,此时依然趋向于理想跳表。在 redis 实例中形成了很大的对象,比如一个很大的 hash 或很大的 zset,这样的对象在扩容的时候,会一次性申请更大的一块内存,这会导致卡顿;redis的EXPIRE机制用于设置键的过期时间,即在指定时间后自动删除键。

2023-07-29 17:58:27 1238 4

原创 redis线程模型

在 redis 6.0 版本之后,也采用了多个 I/O 线程来处理网络请求,这是因为随着网络硬件的性能提升,redis 的性能瓶颈有时会出现在网络 I/O 的处理上。通过这种队列模型和任务调度方式,主线程在兼顾生产者和消费者角色的同时,能够高效地将任务分发给对应的 I/O 线程进行处理,以提高并发性能和系统的吞吐量。2)IO密集型 —— 网络IO :当redis服务多个客户端时,如果数据请求或返回数据量比较大时,造成了IO密集型的情况,也是比较耗时的操作。首先需要注意的是,redis整体而言并不是单线程。

2023-07-29 14:12:34 792

原创 redis事务和异步连接

2)一致性(Consistency):事务的前后,所有的数据都保持一个一致的状态,不能违反数据的一致性检测;redis 客户端以 MULTI 开启一个事务,发送多个命令到服务端的队列,直到发送 EXEC 命令后redis 服务端才会执行队列中的命令,将队列作为一个整体来执行。2)假如开始有2个消费者,一个消费者突然挂掉了,另外一个消费者依然能收到消息,但是如果刚挂掉的消费者重新连上1)后,在断开连接期间的消息对于该消费者来说彻底丢失了;比如如下图,我们希望执行的顺序是命令1,命令2,命令3。

2023-07-22 11:23:50 259 1

原创 Redis入门基础命令

redis( Remote Dictionary Service – 远程字典服务),它是一款开源、高性能的键值存储数据库。它支持各种数据结构,包括**字符串(String)、哈希(Hash)、列表(List)、集合(Set)、有序集合(ZSet)**等,并提供了丰富的操作命令,可以对这些数据结构进行灵活的读写操作。redis以内存为主要存储介质,这使得它具有非常快速的读写性能。同时,Redis也支持将数据持久化到磁盘,以便在重启或崩溃恢复后保留数据。

2023-07-19 20:59:03 1198

原创 CMake基础入门

CMakeLists 所在的路径工程编译发生的目录。表示当前的构建目录,即执行 CMake 构建命令时所在的目录的路径。: 工程顶层目录。表示包含项目名的最近一个 CMakeLists.txt 文件所在的目录的路径。:表示当前正在处理的 CMakeLists.txt 文件的所在目录的绝对路径。:指定 C 编译器:指定 C++ 编译器:可执行文件输出的存放路径:库文件输出的存放路径: 构建的类型,例如 Debug(默认有-g) ,Release用于指定 cmake 的最小版本要求。

2023-07-18 15:25:20 382

原创 应用层协议设计及ProtoBuf

协议是一种约定,通过约定,不同的进程可以对⼀段数据产生相同的理解,从而可以相互协作,存在进程间通信的程序就⼀定需要协议。比如不同表的插头,需要根据不同的国标进行各种转换。如果我们两端进行通信没有约定好协议,那彼此是不知道对方发送的数据是什么意义。1)Protobuf 采用 Varints 编码和 Zigzag 编码来编码数据其中 Varints 编码的思想是移除数字高位的 0,用变长的二进制位来描述一个数字,对于小数字,其编码长度短,可提高数据传输效率。

2023-07-16 23:27:19 323

原创 gdb调试产生code文件以及遇到的“file format not recognized”问题解决

有时候,服务器程序运行一段时间后会突然崩溃,这并不是我们希望看到的,需要解决这个问题。只要程序在崩溃的时候有 core 文件产生,就可以使用这个 core 文件来定位崩溃的原因。当然,Linux 系统默认是不开启程序崩溃产生 core 文件这一机制的,我们可以使用 ulimit -c 命令来查看系统是否开启了这一机制。发现 core file size 那一行默认是 0,表示关闭生成 core 文件。1)使用(unlimited 是 -c 选项值)直接修改成不限制大小。2)然后执行。

2023-07-15 18:24:23 3449 1

原创 两种异步日志方案的介绍

如何实现高性能的日志1)批量写入:同步方式通过积攒一定的数据(如4M)或者设定超时时间,以此触发写入。如glog日志库。异步方式通过append积攒数据,异步落盘线程负责数据写入磁盘,如moduo日志库。2)唤醒机制:通知唤醒 notify + 超时唤醒 wait_timeout3)锁的粒度:为减少锁的粒度,减少刷新磁盘的时候日志接口阻塞,采用双队列方式。前台队列实现日志接口,后台队列实现刷新磁盘。4)内存分配:通过move语义,避免深拷贝;双缓冲,前台后台都设有。

2023-07-15 16:04:50 750

原创 分布式锁的实现方式

通常我们说的锁,指的是单机单进程中多线程环境下,当多个线程同时访问共享资源时,会引发并发访问的问题,可能导致数据不一致或竞态条件。通过使用锁,可以确保一次只有一个线程能够访问共享资源,从而避免这些问题。通常使用的锁有:1)互斥锁2)自旋锁3)信号量4)读写锁5)原子变量以及内存屏障6)条件变量那么,如果是多个进程相互竞争一个资源,如何保证资源只会被一个操作者持有呢?

2023-07-14 16:37:55 719

原创 内存泄漏检测组件

内存泄漏是在没有自动 gc 的编程语言里面,经常发生的一个问题。自动垃圾回收(Automatic Garbage Collection,简称 GC)是一种内存管理技术,在程序运行时自动检测和回收不再使用的内存对象,以避免内存泄漏和释放已分配内存的负担。因为没有 gc,所以分配的内存需要程序员自己调用释放。其核心原因是调用分配与释放没有符合开闭原则,没有配对,形成了有分配,没有释放的指针,从而产生了内存泄漏。free(p1);以上代码段,分配了两个s1大小的内存块,由 p1 与 p2 指向。

2023-07-11 21:19:57 240

原创 实现死锁检测组件

死锁,是指多个线程或者进程在运行过程中因争夺资源而造成的一种僵局,当进程或者线程处于这种僵持状态,若无外力作用,它们将无法再向前推进。如下图所示,以申请锁资源为例。线程 A 想申请线程 B 的锁,线程 B 想申请线程 C 的锁,线程 C 想申请线程 D 的锁,线程 D 想申请线程 A 的锁,从而构建了一个资源申请环。多个线程之间依次想要访问其他线程的资源,这样相互僵持形成的一个资源申请闭环。死锁的存在是因为有资源申请环的存在,所以只要能检测出资源申请环,就等同于检测出死锁的存在。

2023-07-11 21:19:02 412

原创 分别基于红黑树、timefd、多级时间轮实现定时器

分别基于红黑树、timefd、多级时间轮实现定时器

2023-07-07 16:29:15 739

原创 详解高性能无锁队列的实现

无锁队列(Lock-Free Queue)是一种并发数据结构,它允许多个线程在没有锁的情况下进行并发操作。传统的队列通常通过互斥锁来实现线程安全的操作,但互斥锁在高并发情况下可能会造成竞争和性能瓶颈。为了避免使用锁,无锁队列采用了基于原子操作的并发算法。无锁队列的设计目标是在保持线程安全的前提下提供高性能的并发操作。它通常使用 CAS(Compare and Swap)等原子指令来实现对队列头部和尾部指针的更新和操作。CAS 操作可以确保只有一个线程能够成功修改指针,其他线程则需要重试或者尝试其他操作。

2023-07-05 16:41:19 1296

百万服务器并发代码实现

百万服务器并发代码实现

2023-05-27

空空如也

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

TA关注的人

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