C++的backtrace
开始之前
很多语言的log模块都有一个功能,就是在打log的时候能够追溯调用栈,有的时候对查bug能有点帮助。之前我也想过给我们的log模块加上C++的backtrace的功能,迟迟一直没有做主要是两个原因:一是C++的backtrace在各个平台和编译器上都不太一样,比较冗杂;二是C/C++在编译优化之后,调用行之类的信息和甚至一些函数可能就被优化没了。所以能提供的信息就相当有限。前两天刚好有朋友问有没有提供这个,所以就花了点时间整理了下适配方案。
很多语言的log模块都有一个功能,就是在打log的时候能够追溯调用栈,有的时候对查bug能有点帮助。之前我也想过给我们的log模块加上C++的backtrace的功能,迟迟一直没有做主要是两个原因:一是C++的backtrace在各个平台和编译器上都不太一样,比较冗杂;二是C/C++在编译优化之后,调用行之类的信息和甚至一些函数可能就被优化没了。所以能提供的信息就相当有限。前两天刚好有朋友问有没有提供这个,所以就花了点时间整理了下适配方案。
前面有几篇blog就提到我有计划支持使用ECDH密钥交换。近期也是抽空把以前的DH密钥交换跨平台适配从atgateway抽离出来,而后接入了ECDH流程。
对DH和ECDH算法的具体原理这里不做具体介绍了,可以点击链接看。DH和ECDH的主要的作用就是在通信双方发送一些公有参数,保留私有参数,而后通过一系列计算双方都能够得到一个一致的结果。而这个运算的逆运算复杂度过高,在有限时间内不可解(至少量子计算机问世以前不可解),以保证密钥安全性。除了维基百科外,我还看到篇文章图画的很好看的:http://andrea.corbellini.name/2015/05/30/elliptic-curve-cryptography-ecdh-and-ecdsa/ 。而DH和ECDH得区别简单来说就是,前者使用了一个大素数和两个随机数,而后者使用了ECC算法和两个随机点。
实际应用中,有些加密算法的密钥碰撞计算难度反而比破解DH和ECDH要容易(比如atgateway支持的XXTEA算法,这个算法很简单所以也非常高效)。所以有些工程实践中会每隔一段时间再走一次密钥交换流程来更换密钥。
这本来是个早就可以写的分享。因为代码几周前就迁移并准备好了。而且这也是之前项目的工具,因为可以抽离出来通用化所以单独整理出来。
这个项目起源于我们之前哪个项目,客户端想要在Unity的C#里动态加载配置,而protobuf-net一方面大量使用反射而性能不太行,另一方面使用的时候得生成C#代码才行。客户端原来的做法是把消息扁平化了,使用protobuf-net得底层读写接口直接操作基本数据类型。这就失去了结构化带来的一系列好处。再加上后来我引入了跨平台导表工具,使用结构化得数据会非常方便,而手动把这个数据打散到客户端读取接口显然很浪费人力而且容易出错。所以我就干脆也使用protobuf-net的底层读写接口做了现在的DynamicMessage的支持,API设计是结合pbc和protobuf官方的API流程的。
Protobuf 的 proto3发布也有挺长一段时间了。现在很多新项目慢慢转变用proto3来开发。这篇文章主要记录一下我在给pbc写对proto3支持时的一些信息,也许对其他童鞋也有点助益。抛砖引玉一下。
pbc是云风开发的一个纯C的读写protobuf的很小巧的库,配合上它提供的lua-5.1和lua-5.3的binding可以很容易地在lua里完成对pb文件的注册和打解包。应该很多人都知道这个组件。
但是后来云风自己又发明了个sproto,然后主推在他的skynet框架中使用sproto,于是pbc就不再有功能维护了。
我们之前的也尝试直接使用了proto3,也是因为在迁移期,所以并没有使用全部的特性。但是仍然有一些向前不兼容的细节需要处理一下,所以有了这个改造
上个月,同学的公司,格奕,突然间跪了。这个月基本属于休息+四处溜达。同时空闲的时候也想整理下之前做得一些之前的做得一些小工具们。在不泄密的情况下开源出来吧(其实也就是想找github存放一下而已,也没什么特别NB的东西)。
其实很早就想把Blog迁移到静态化的博客系统了。不过一直没花时间来搞,当然主要原因还是懒。
这次下决心搞主要是因为,之前VPS迁移到Vultr,然后它的主机默认是没有交换区的。后来老是收到网站崩溃告警,每次去看都是MariaDB挂掉了,然后查了一下是内存不足。 然后,调整了几次参数,发现都不能解决问题。我这么个小站搞个高配机器显然是浪费。这种小网站都能耗尽1GB的内存我也是醉了。所以后来就干脆迁移到静态博客系统算了。
前段时间看到了一个完成读比较高的协程库-libgo,里面提供了线程安全的协程实现,并且也是使用锁。本来我并没有给libcopp里的功能加锁的打算,因为上层dispatcher还是比较容易做到安全分发的,所以原来并不保证线程安全。而且线程安全这种问题单元测试比较难写,可能还得碰点运气。但是思来想去,还是为线程安全做点什么吧。反正也不是很复杂。
由于我并没有给utils加互斥锁的跨平台适配,所以先就直接用了自旋锁,来锁住需要考虑线程安全的地方。其实需要加锁的地方并不多,无非是管理器的增删查和task的next函数需要加锁。这些逻辑都很短,功能也很简单,并不会占用太多时间,所以自旋锁的问题也不大。而且以后真发现有问题,换掉也不是什么难事儿。
之前的版本发完,有空来更新一下之前的gcc和llvm+clang工具链的编译脚本了。其实GCC 7是才release没多久但是llvm 4.0发布其实有一段时间了。
之前我的域名只有owent.net和www.owent.net买了SSL证书,现在有letsencrypt可以拿到免费的SSL签证,就稍微花了点时间把我的域名的其他部分接入了letsencrypt签证系统。另外根据其他人的一些配置建议,提高了HTTPS的安全性配置和性能配置(主要是缓存)。另外原本我的blog就已经启用了spdy,然而现在新版本的nginx(1.10)已经release,原先的spdy模块被取消,新增了http/2模块。但是直接换nginx掉包是不行滴(后面有说原因),所以顺带自己处理了一下HTTP/2和nginx新版本的问题。
并且也对公司里的域名和webserver也这么搞了一下。全面启用HTTPS。
使用_Markdown_写blog已经很久了,近期接触并且看了下流传已久的gitbook平台,感觉做得确实不错。、
之前写blog的时候一直用得是stackedit,是因为stackedit的对_Markdown_做了很多扩展,功能很强大,有自动目录、流程图、时序图等等,然后可以浏览器直接开很方便。但实际上这些功能写出的东西虽然不错,但是放到比如github上的时候,github不支持。目前大多数平台对_Mardown_的扩展都只是到了和github差不多的地步,没有到stackedit的程度。这也导致同样写得东西,复制到github或者其他的平台的时候还得过一遍样式,比较麻烦。而且这些扩展的功能也用得不太多。另外stackedit时不时被墙然后访问很不稳定也是挺麻烦的一件事儿。
再来说这个gitbook,看中他是觉得它做了一个可持续集成的功能。就是github _push_完以后可以通知gitbook然后让gitbook自动构建文档内容。这点和比如jenkins和travis等等的CI系统很像。然后支持构建成pdf、epub(开源电子书格式)、mobi(kindle电子书格式)和在线书籍。然后版式也挺漂亮,还支持模板,引用等等,感觉确实蛮适合出版发行的。虽然目前为止_Markdown_的功能丰富程度比起Latex还差不少,但是上手难度也比Latex低不少。还是非常有潜力的,而且gitbook支持用javascript写得插件,以后变数也可以很多。
接上文
虽然我很不愿意再设计一套BUS系统,但是现有的一些确实都没有特别符合我的口味的。所以还是尝试设计一个出来。
简单来说,我希望BUS系统可以简单、高效、稳定。
如何保证一个进程或线程能安全稳定地把一段消息发送到另一个进程和线程,甚至是另一台机器的进程或线程,再或是要通过代理转发到另一个进程或线程,一直是一个比较麻烦的问题。
C++ 11 标准发布,各大编译器都开始支持里面的各种新特性,其中一项比较有意思的就是lambda表达式。
C++ 11 Lambda表达式的四种声明方式
C++11标准里有动态模板参数已经是众所周知的事儿了。但是当时还有个主流编译器还不支持。 但是现在,主要的编译器。VC(Windows),GCC(Windows,Linux),Clang(Mac,IOS)都已经支持了。所以就可以准备用于生产环境了。 type_traits没啥好说的。主要是一些静态检测。主要还是要看动态模板参数和他们两的结合使用上。 动态模版参数标准文档见: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2242.pdf 和 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2555.pdf 虽然贴出来了。估计是没人看得。所以就直接说重点。
前几天我们项目的日志系统出现了一点问题,但是一直没有时间去深究。 昨天在同事的帮助下,无意中猜了一种可能性,结果还真被我猜中了,于是今天就特别研究了一下,记录下来。