随笔分类 - 服务器开发
服务器开发
摘要:公司的pyc做了加密, 前段时间研究了一下怎么解密. 最开始的思路是反汇编pypy的dll, 找到import代码的实现, 然后写一个解码的函数. 但是对反编译的东西不熟悉, 想要找到解密的地方比较困难. 最后放弃了这个思路. 后面看到了一篇pyc文件格式的文章, 得知pyc文件其实就是文件头+ma
阅读全文
摘要:受限于当时的基础设施, 只能做到这样的程度: C# Protobuf如何做到0分配内存的序列化 但是Protobuf 3.13开始提供对Span的支持, 就意味着可以真正做到0分配内存, 对GC非常友好: Add ParseFrom(ReadOnlySequence<byte>) method to
阅读全文
摘要:优化C#服务器的思路和工具的使用 优化服务器之前, 需要先对问题的规模做合理的预估, 然后对关键的数据做采样, 做对比, 看和自己的预估是否一致, 误差大在什么地方, 是预估的不对, 还是系统实现有问题. 策划对某游戏服务器的要求是3000到5000人在线. 大概的估算 玩了玩游戏, 在前期任务的流
阅读全文
摘要:通过P/Invoke加速C#程序 任何语言都会提供FFI机制(Foreign Function Interface, 叫法不太一样), 大多数的FFI机制是和C API. C#提供了P/Invoke来和操作系统, 第三方扩展进行交互. FFI通常用来和老的代码交互, 例如有大量的遗留代码, 重写成本
阅读全文
摘要:C# Alloc Free编程之实践 上一篇说了Alloc Free编程的基本理论. 这篇文章就说怎么具体做实践. 常识 之所以说是常识, 那是因为我们在学任何一门语言的时候, 都能在各种书上看到各种各样的best practice. 这些内容也确实是最佳实践, 需要去遵守. 但是现实代码里面看到,
阅读全文
摘要:C# Alloc Free编程 首先Alloc Free这个词是我自创的, 来源于Lock Free. Lock Free是说通过原子操作来避免锁的使用, 从而来提高并行程序的性能; 与Lock Free类似, Alloc Free是说通过减少内存分配, 从而提高托管内存语言的性能. 基础理论 对于
阅读全文
摘要:C#多线程逻辑编程 多线程编程以难著称, 有很多人碰见多线程编程就会畏缩, 不敢前进, 言必称死锁/卡死. 但是合理编程是不会碰到死锁这种问题. 对语言了解 工欲善其事必先利其器, 必须要对语言提供的同步机制和期扩展有所了解. Linux系统(库)提供的同步机制有: 锁 原子操作 条件变量 其中原子
阅读全文
摘要:网络框架的选择 C++语言里面有asio和libuv等网络库, 可以方便的进行各种高效编程. 但是C#里面, 情况不太一样, C#自带的网络API有多种. 例如: Socket TcpStream(同步接口和BeginXXX异步接口) TcpStream Async/Await Pipeline I
阅读全文
摘要:估计很多人在网上看到各种各样的DeepClone实现, 例如: 1. 通过BinaryFormatter进行二进制序列化 这玩意儿序列化出来的东西还带namespace类型, 尺寸非常大, 调试一下就知道极其不靠谱 有些人又开始动歪脑筋了, 说我搞一个JSON序列化, 或者BSON序列化可不可以 2
阅读全文
摘要:题目很简单, 就是IMessage对象怎么变成Byte[] 答案1: msg.ToByteArray() 这肯定不符合我们的要求 答案2: using var memoryStream = new MemoryStream(); using var codedOutputStream = new C
阅读全文
摘要:长链接发送request/response时, 绝大部分包都是小包, 而每个小包都要消耗一个IP包, 成本大约是20-30us, 普通千兆网卡的pps大约是60Wpps, 所以想要提高长链接密集IO的应用性能, 需要做包的合并, 也称为了scatter/gather io或者vector io. 在
阅读全文
摘要:网上的教程大都是手动通过protoc编译, 比较难用 给当前工程添加"Google.Protobuf"和"Grpc.Tools"的引用(通过nuget), 然后添加proto文件, 编辑.csproj文件 <Project Sdk="Microsoft.NET.Sdk"> <PropertyGrou
阅读全文
摘要:服务器内经常会有一些多读少写的场景, 具体问题需要分析一下, 如果是这种场景, 这边提供一个思路来降低多线程程序锁的冲突, 进而极大的提升程序的性能. 例如一个Dictionary<String, String> A, 需要多读少写, 不会很频繁的写, 而且不会修改Value值, 那么可以构造一个A
阅读全文
摘要:Linux下有vsyscall来优化一些例如time(NULL), gettimeofday这种调用的消耗; 但是Windows下, 没有类似的东西, 但是思路还是有的 1. 程序启动的时候, 获取一下准确的时间戳 2. 然后每次需要获取时间的时候, 获取一下流逝的时间, 可以通过获取CPU的tic
阅读全文
摘要:又拾起了rust语言, 想写一点东西玩一玩, 但是发现连一个获取本机IP地址的库都没有, 还得挽起袖子自己撸. https://crates.io/crates/local_ipaddress 没有用ifconfig, 也没有扫描网卡, 就开了一个UdpSocket尝试着去连一个IP地址, 然后看本
阅读全文
摘要:先吐槽一下libmysqlclientAPI的设计, 多个线程同时去connect居然会core掉. 后来Google了一番, 才发现mysql_real_connect不是线程安全的, 需要一些额外的处理. 具体就是: 首先调用一次mysql_library_init, 在整个程序生命周期中只需要
阅读全文
摘要:前两天给我们的json写一个解析函数, 之前用的正宗的json parser, 支持完整的json特性. 但是实际上我们用到特性, 只有key-value的映射, value的类型只有数字和字符串两种类型. 由于parse的速度比较慢, 所以我打算自己用字符串解析一遍. 第一个能工作的原型出来的时候
阅读全文
摘要:还是上次那个json解析程序的优化, 虽然速度已经比较理想, 但是看到IndexOf占到整个解析时长的20%+, 心里还是不爽. 我写的IndexOf是按照UTF16字符, 一个字符一个字符去比较的, 所以当时能想到的办法, 就是一次比较多个字符. 大概是五六年前, 我看过某一个libc里面实现的s
阅读全文
摘要:这两天在看C# SIMD相关的东西, 在爆栈上面搜到一段代码, 表示很震惊, 还是得贴出来… 这段代码里面的sseAssemblyBytes, 实际上是一段汇编代码, 他先把这段汇编代码拷贝到虚拟内存里面去, 然后设置这块内存可以被执行EXECUTE_READWRITE, 从而在这块内存上创建一个函
阅读全文
摘要:上古时期的程序员, 肯定都知道Handle对象, 一般中文翻译成句柄. 一般的Handle在实现上, 都是一个整数, 而这个整数可以理解为一个指针, 指针指向的地址呢, 又保存了另外一个指针. 之所以这么搞, 是因为这样搞可以让真实的对象可以挪动. 考虑一个一个对象A, 保存在Handle里面, 由
阅读全文