BlueAirHost船新版本, 安全和性能之间如何妥协?

BlueAirHost还有3个月就要一周年了, 我准备到时候给它升级下, 不管是服务器配置还是软件层面.

首先是安全方面, EasyPanel漏洞频出, 界面也不大好看, 我准备换一个CyberPanel.

CyberPanel是最近新出来的面板, 不管是外观还是安全性, 或者是性能都要甩EP一截.

DA是买不起的, 这辈子都买不起的.

在LiteSpeed开启Br/Gzip压缩的情况下, 服务器的CPU占比会增加一些(当然不会很高, 本来主机服务器只是占内存, CPU一般都是闲着没事干), 但是相比来说还是带宽钱贵一些.

PHP可以做RootDir的限定和以不同的用户身份执行PHP. 这样主机之间的文件都是安全的.

WHMCS版本需要更新, 然后我最近正好改了NeWorld的开源模版, 扔上去就成.

最近心态略崩

因为感觉不到活在这个世界上的意义. 然后感觉自己可能得了轻度抑郁症. 回国得找个心理医生看一眼.

哦对了, 最近有一位女生让我的心跳动了一下, 然后又继续死了. 233. 原因很清楚, 我很明白死宅是找不到女朋友的, 找到了也维护不好关系.

微信公众号实在是没有东西更了. 那就凉一会吧

各平台Socket阻塞/非阻塞模型解析

首先,介绍几种常见的I/O模型及其区别,如下:

  • blocking I/O 阻塞IO
  • nonblocking I/O 非阻塞IO
  • I/O multiplexing (select and poll) I/O复用
  • signal driven I/O (SIGIO) 信号驱动的I/O
  • asynchronous I/O (the POSIX aio_functions) 异步I/O

blocking I/O

这个不用多解释吧,阻塞套接字。下图是它调用过程的图示:

重点解释下上图,下面例子都会讲到。首先application调用 recvfrom()转入kernel,注意kernel有2个过程,wait for data和copy data from kernel to user。直到最后copy complete后,recvfrom()才返回。此过程一直是阻塞的.

 

nonblocking I/O:
与blocking I/O对立的,非阻塞套接字,调用过程图如下:

可以看见,如果直接操作它,那就是个轮询。。直到内核缓冲区有数据。

I/O multiplexing (select and poll)
最常见的I/O复用模型,select。

select先阻塞,有活动套接字才返回。与blocking I/O相比,select会有两次系统调用,但是select能处理多个套接字。

signal driven I/O (SIGIO)
只有UNIX系统支持,感兴趣的课查阅相关资料

I/O multiplexing (select and poll)相比,它的优势是,免去了select的阻塞与轮询,当有活跃套接字时,由注册的handler处理。

asynchronous I/O (the POSIX aio_functions)
很少有*nix系统支持,windows的IOCP则是此模型

完全异步的I/O复用机制,因为纵观上面其它四种模型,至少都会在由kernel copy data to appliction时阻塞。而该模型是当copy完成后才通知application,可见是纯异步的。好像只有windows的完成端口是这个模型,效率也很出色。

下面是以上五种模型的比较

可以看出,越往后,阻塞越少,理论上效率也是最优。

=====================分割线==================================

5种模型的比较比较清晰了,剩下的就是把select,epoll,iocp,kqueue按号入座那就OK了。

select和iocp分别对应第3种与第5种模型,那么epoll与kqueue呢?其实也于select属于同一种模型,只是更高级一些,可以看作有了第4种模型的某些特性,如callback机制。

那么,为什么epoll,kqueue比select高级?

答案是,他们无轮询。因为他们用callback取代了。想想看,当套接字比较多的时候,每次select()都要通过遍历FD_SETSIZE个Socket来完成调度,不管哪个Socket是活跃的,都遍历一遍。这会浪费很多CPU时间。如果能给套接字注册某个回调函数,当他们活跃时,自动完成相关操作,那就避免了轮询,这正是epoll与kqueue做的。

windows or *nix (IOCP or kqueue/epoll)?

诚然,Windows的IOCP非常出色,目前很少有支持asynchronous I/O的系统,但是由于其系统本身的局限性,大型服务器还是在UNIX下。而且正如上面所述,kqueue/epoll 与 IOCP相比,就是多了一层从内核copy数据到应用层的阻塞,从而不能算作asynchronous I/O类。但是,这层小小的阻塞无足轻重,kqueue与epoll已经做得很优秀了。

提供一致的接口,IO Design Patterns

实际上,不管是哪种模型,都可以抽象一层出来,提供一致的接口,广为人知的有ACE,Libevent这些,他们都是跨平台的,而且他们自动选择最优的I/O复用机制,用户只需调用接口即可。说到这里又得说说2个设计模式,Reactor and Proactor。有一篇经典文章http://www.artima.com/articles/io_design_patterns.html值得阅读,Libevent是Reactor模型,ACE提供Proactor模型。实际都是对各种I/O复用机制的封装。

 

CrossPlatformSocket::LibUV并发实战

因为最近出于性能的原因我尝试了重写EasyCrossPlatform的Socket Wrapper.

选择一个高性能的底层库非常重要, 我盯上了LibUV, 它的跨平台底层包括Windows的IOCP, Mac/NetBSD的Kqueue, Linux的Epoll. 不兼容这些高性能框架的情况下还写了一个Unix的Poll兼容层.

这里需要注意的是, LibUV是相当于一个LibEvent + Socket封装的库, 所有的Socket操作都是事件驱动的, 当然这样也就造成LibUV的速度异常的快.

具体可以看我 EasyCrossPlatform 中TCPSocket和UDPSocket实现的代码

继续写EasyCrossPlatform

因为考虑到要编译成静态库的问题, 最近我对于EasyCrossPlatform的研究一直停滞不前(CMake很难啊!)

然后发现一个好东西, XMake, 语法简单, 又好用, Bug又少. 果断迁移到XMake.

目前编译成功了. 项目托管到了一个单独的Org.

链接

日常哲学思考

最近没再研究EasyCrossPlatform这个C++库了, 而是在跟爸妈在葡萄牙玩.

偶然听到之前跟自己关系还不错的同学练出了一身肌肉, 看了下照片, 的确爆炸.

只是不知道我个人对这种过量的肌肉反胃. 再想到他练这一身肌肉肯定又是为了勾搭妹子. 也没满18岁, 已经和妹子做过生命大和谐了.

但是我又有什么可以评判别人的资本呢, 自己作为一个宅男(或者我妈干脆叫我死宅), 不仅是不懂人情事故也不会跟别人打好关系, 只是一腔热血坚持所谓的三观和正义, 和”政治正确”.

首先是我自己的思想太封建和传统了, 别人开放不代表我一定要这样, 但我必须要接受. 如果我不接受, 我就变成了傻逼, 或者说即将被时代淘汰的人. 再说我自己不也很憧憬做那种生命大和谐之事么, 怎么别人做了我就要装作看不起的嫉妒呢?

以上思想令我陷入了沉思. 嗯, 人类的本性啊, 看来自己的思想还是不够理性, 还是要再学习一个.

哦对了, 我最近又想了一下自己存在的意义, 感觉好像是没有的(#笑)

也许人在世界上就是孤独的吧, 我也尝试着忍受了, 但是这一眼望不到头的孤独, 是闹咋样!

我也尝试不随大流, 大家说什么什么帅什么什么好的时候, 我尝试着不去效仿. 大家谈女朋友的时候, 我笑笑遍过. 也许这就导致我现在朋友不多, 没有人关心我的境界? (排除我的家长). 我不知道啊, 我也不知道我到底要去哪里, 到底要做什么.

附: 部分旅游照片

EasyCrossPlatform::Self::Re_Define()

因为之前C++水平很差, 然后只知道大多数库用的都是静态库, 然后程序引用时候直接链接就行了. 但是一直搜不到相关的资料. 我搜的关键词都是预编译, 预编译头啦什么的. 知道今天为了给EasyCrossPlatform做MySQL接口, 查了一下MySQL的API的文档. 哦, 原来那玩意儿叫编译成静态/动态库. 哦, 原来这么好用.

于是又看了一下CMake的小部分文档, 准备明天继续浪. 加油吧.

C++堆和栈区别

因为最近在编写C++跨平台轮子, 研究了一下C++的内存机制.

C++中的内存一共三个内存区域

  1. 栈(Stack) – C++自动管理的动态内存区域, 一般是函数调用时复制参数和局部变量使用, 定长, 实现方法类似数据结构中的栈, 或者说数组.
  2. 堆(Heap) – C++程序员动态分配的内存区域. 需要手动释放. 效率没有栈高, 实现方式类似链表(std::list)
  3. 静态储存区(Static) – C++静态和全局变量区域. 编译时就决定了长度. 储存的是Const变量和全局变量. 已初始化的全局变量和Const变量会丢在一起(相邻), 未初始化的会丢在一起(相邻).

简单来说, 堆就是用new, delete, malloc, free这些方法的内存, 栈就是函数参数和定长数组用的内存.

继续阅读“C++堆和栈区别”

浅谈MySQL性能优化(索引篇)

由于大家都很喜爱MySQL(因为PHP支持啊233), 然而MySQL在性能上的表现并不是那么的OK. 所以对MySQL进行适当的优化是很必要的.

MySQL有个东西叫索引(index), 是对你的字段建立一个索引, 然后这样你用WHERE查询的时候 就可以快速查询到你所需SELECT语句对应的内容

如果说普通MySQL运行的是一辆自行车的话, 有索引的MySQL就是一架飞机. 当然索引太多速度也会降下来.

注意, 索引虽然会加速SELECT语句, 但是对Update, Insert语句的反应速度会降低. 因为MySQL需要花时间来建立索引.

一般情况都是,与应用程序中使用的查询条件相关列才需要创建索引。而创建不需要用的索引明显会造成资源浪费。如果应用程序都是一些小表,索引创建与否并没有明显差别,但是随着表越来越多,表数据越来越大,创建索引带来的性能变化就会戏剧性的提高。

建立索引

CREATE INDEX indexName ON mytable(username(length));

这样就创建了一个索引了.

然后我们需要在索引中

添加字段名

ALTER table tableName ADD INDEX indexName(columnName)

删除Index中的字段名

ALTER TABLE testalter_tbl DROP INDEX c;

如果是CHAR,VARCHAR类型,length可以小于字段实际长度;如果是BLOB和TEXT类型,必须指定 length。

您只需建议WHERE语句发生的最多的字段, 其他字段并不需要建立索引.

删除索引

DROP INDEX [indexName] ON mytable;

就好了

 

手臂要爆炸了

因为在佐治亚州读书, 本人出国前不需要检查哪些漏掉的疫苗. 因为可以在当地补针.

今天学校的卫生中心直接跟我来了一个惊喜, 之前Email里发给我的是只打一个疫苗的 今天一看是4个.

一路登记, 等待都是非常的紧张. 最后发现美国人真的强. 打针不到1秒, 俩个手臂一个手臂俩个疫苗 每个疫苗一块肌肉. 4秒钟打完了. 期间疼痛基本可以无视. 本人询问可否使用肌肉时得到了肯定的答复, 而且说是运动越多越可以帮助血液循环, 加速疫苗进入身体. 我现在右臂酸痛的一批(打之前跟我说了这个疫苗会酸), 其他手臂基本没有感觉. 总之体验还行, 就是有些惊吓