写点什么

手写实现分布式锁

  • 2022 年 4 月 09 日
  • 本文字数:1330 字

    阅读完需:约 4 分钟

前言

分布式锁需要考虑很多事情,第一网络是否正常,第二个提供分布式锁这台机器的高可用性。

​一、网络模块封装

明线

io 检测部分的接口:

  • 添加读事件是因为当有客户端连接事件来临时,我们好去处理这个事件。

  • 写事件这是因为当我们服务端作为客户端去连接第三方服务时候,需要注册写事件。

  • 删除事件就比如关闭连接时,我们需要将事件从检测模块中删除。

  • 修改事件就比如当客户端发来事件我们需要检测读事件,但是接收失败了我们要把读事件修改为注册写事件进行反馈。

  • 检测事件肯定是必须的啦!io 操作:绑定监听,接收连接,建立连接,关闭 fd,读,写,fd 属性。

暗线

需要注意的是:fd 类型中 clientfd 写事件触发的情况,服务器收到客户端的数据可以直接调用 write()函数,只有当写入失败时才要注册写事件,检测何时可写。应该将发送失败的数据缓存起来,等事件可写了,再将缓冲区的数据进行发送。

断开连接或者错误,都是交给读写操作。

二、协程调度

没有协程之前,当成功接收到一个数据后,要调用多个回调函数,(解析数据、查库拿数据、返回给客户端)等等。现在我们考虑的是,将三个序列利用协程的方式进行粘合,三个回调变成一个协程回调执行序列。

为每一个 fd 执行一个序列,每个协程是一个执行序列。

lua 虚拟机不支持协程,并且没有类似于 pthread_create()函数,也就是说主协程被自动创建。lua 虚拟机同时只能有一个协程在运行。主协程负责调度其他协程。

主协程会进行事件检测,不断地从 epoll 中去取事件,根据事件去唤醒其他协程。


  • lua 和 go 语言中的协程方案是最完善的。

  • epoll 注册写事件触发,说明三次握手后同步包可以发送了,表示连接已经建立成功了。

  • 异步的执行逻辑,同步的写法。

  • 当连接建立成功后,connectfd 和 clientfd 的流程变成一样。

三、异步连接池

为什么需要异步连接池?

现在所有的连接已经变成一个执行序列,连接由异步变为同步。此时,一个连接同时只能在一个协程中运行,是并发不是并行,也就是说只有一个执行序多个对列,依次执行。

pool_size 是尺子最大连接数,backlog 堆积的操作数。

四、缓冲池设计 用户读写缓冲区

Mark 老师举例,4 个协程在使用,4 个协程在等待,超出的协程会报错。cache 记录的是随时可用连接,free 记录的是正在使用的连接。connect>8 是要报错,小于 pool_size 要创建或是从 cache 里去取,cache 没有说明都在 free 里。

给连接池起名字,默认是 ip:端口格式,比如 127.0.0.1:8888。

​五、定时器设计

定时器是在 lua 层实现了一个最小堆,每一个任务生成一个协程,但是要考虑回收协程,尤其是在删除的时候。这块做的还不完善,Mark 老师也希望大家一起帮忙搞一搞,先记下这件事吧!

六、总结

Mrk 老师说道:做任何事情,拆分的思想很重要,联想起以前一个数学老师的话,“老太太吃柿子,要捡软的捏。”以后遇到问题和困难,也应该先按照这个思路去处理问题。作为开发还有一点是非常重的,就是测试的能力,这方面得想办法学习提升一下。通过本节课,我初步了解了分布式锁,感觉对于 skynet 也有了更好的认识。在成长的路上,有 Mark 老师陪伴,好幸福啊~

技术参考

C++后台开发系统学习地址:C/C++Linux服务器开发高级架构师/C++后台开发架构师​

以下学习资料,C++后台开发面试题,教学视频,C++后台开发学习路线图,免费分享有需要的可以自行添加:学习资料群720209036 自取

用户头像

Linux服务器开发qun720209036,欢迎来交流 2020.11.26 加入

专注C/C++ Linux后台服务器开发。

评论

发布
暂无评论
手写实现分布式锁_分布式锁_Linux服务器开发_InfoQ写作平台