@JaySon
2016-08-28T09:16:41.000000Z
字数 2163
阅读 1353
腾讯
KM上的介绍: 微线程框架原理介绍
栈空间只有128K(虽然有接口可以调大栈空间), 如果需要创建大的局部变量, 可以用new申请堆空间(注意释放内存),或者用std::string, std::vector等辅助(STL内部是使用new申请的堆空间,且已经做好了内存管理,不过可能存在一定的复制开销)
微线程中尽量少用static变量,除非是使用const static。
因为微线程切换上下文的时候,可能导致static中的变量不可信。
微线程本身是异步非阻塞的,尽量不要在其中自己使用tcp/udp收发包,阻塞的网络IO会导致spp并发量减少,不能最大程度发挥spp的性能。利用框架内的mt_tcpsendrcv
/mt_udpsendrcv
来进行网络IO阻塞的请求,框架会在阻塞的时候切换到另外的微线程(协程)处理,从而提高并发处理量。
hiredis中的API内使用的是阻塞的模式。
但是hiredis中有单纯对包进行格式化的函数可以利用,KM上已经有人结合hiredis对包格式化的函数与spp微线程的异步IO请求,但只有GET/SET/Expire, HSET/HGET/HGETALL未实现,代码质量也挺好,可以在其上进行扩展使用。
spp微线程封装高性能redis-client API
部分代码中存在使用l5获取IP:port之后马上调用ApiRouteResultUpdate,这是错误的用法。L5用法
利用l5做负载均衡,需要上报的是跟IP:port之间交互总耗时,l5用于评估server的负载,再做负载均衡。
获取了IP:port之后马上调用ApiRouteResultUpdate,会让l5一直认为通讯的server一直处于低负载。
另外l5连接时传入的超时时间是float型的秒,而不是毫秒。
有两个类之间的设计如下
class A {
void sendXX() {
B b* = getBPtr();
b->filterYY(this, ...); // 把this传入B, 导致两个类高度耦合,而且在编译时出现循环依赖
}
void sendYY() {...}
};
class B {
int filterYY(A* pa, ...) {
if (xx) {
// ...
} else {
pa->sendYY(); // 类A类B高度耦合
}
}
};
面向对象的一个设计思想就是一个类的一个函数只做好一件事,类B的filterXX函数本来只应判断是否需要过滤,通过返回值告知caller该数据是否需要过滤。
但是实现中把类A的sendYY的功能也放到filterXX中做了,结果需要A传入this指针,一方面导致了编译的循环依赖(虽然可以通过前置声明来解决),另外一方面导致代码结构混乱(本来收发包的函数应该归拢在类A甚至更上面一层,类B只是做数据解析的工作)。
int isExist(...) {
if (...) {
return -1; // 不存在
} else {
return 0; // 存在
}
}
结果导致外面调用的时候出现
if ( isExist(xx) == 0 && isExist(yy) == 0) {
// do sth
}
看到这样的代码第一反应是xx,yy两者都不存在的时候才doSth,但是实际上是完全相反的情况。
定位问题时可以加 monitor/LOG 来对问题进行定位,但是定位完了之后,需要清理冗余的上报/LOG的清理。毕竟monitor/ERROR_LOG是用于监控是否异常的工具而不是debug的工具。
monitor/ERROR_LOG过多,会导致问题早就暴露了但被淹没在信息海中,不被发现。
实测protobuf序列化之后的二进制数据中可能含有\x00
的字符,如果想使用std::string存储protobuf字符串的话,构造函数时不能使用string(const char *)
的构造方法,要使用string(const char* s, size_t n)
的方法指定大小。
取出时使用str.data()结合str.size()使用。不要使用str.c_str()与strlen(cstr)
虽然大数据处理的瓶颈不在于实时系统,但是一个代码结构不清晰的系统是难以维护&扩展的。早晚会造成疲于奔命处理bug的状态。
比较好的C++代码实践,可以参考《Effective C++》和Google的C++编码规范
《More Effective C++》比较老旧,其中涉及到的一些坑在后面的C++标准中被修正,其最佳实践也变了。虽然有"More",但个人感觉看《Effective C++》的第三版足矣。
《Modern Effective C++》主要介绍C++11对C++的一些填坑以及良好的代码实践,目前C++11难以推行,可以不读。
腾讯在基础组件、框架上有多年的积累,不要放弃这些积累从原点开始跑,使用之前阅读相关的文档,经验。
当然使用之前要review一下代码,看其是否适用、稳定。